text:
/* global Reflect, Promise */

var extendStatics = function(d, b) {
    extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
    return extendStatics(d, b);
};

function __extends(d, b) {
    if (typeof b !== "function" && b !== null)
        throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
    extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

function __spreadArray(to, from) {
    for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
        to[j] = from[i];
    return to;
}

/**
 * @license
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var ERROR_NAME = 'FirebaseError';
// Based on code from:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types
var FirebaseError = /** @class */ (function (_super) {
    __extends(FirebaseError, _super);
    function FirebaseError(code, message, customData) {
        var _this = _super.call(this, message) || this;
        _this.code = code;
        _this.customData = customData;
        _this.name = ERROR_NAME;
        // Fix For ES5
        // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
        Object.setPrototypeOf(_this, FirebaseError.prototype);
        // Maintains proper stack trace for where our error was thrown.
        // Only available on V8.
        if (Error.captureStackTrace) {
            Error.captureStackTrace(_this, ErrorFactory.prototype.create);
        }
        return _this;
    }
    return FirebaseError;
}(Error));
var ErrorFactory = /** @class */ (function () {
    function ErrorFactory(service, serviceName, errors) {
        this.service = service;
        this.serviceName = serviceName;
        this.errors = errors;
    }
    ErrorFactory.prototype.create = function (code) {
        var data = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            data[_i - 1] = arguments[_i];
        }
        var customData = data[0] || {};
        var fullCode = this.service + "/" + code;
        var template = this.errors[code];
        var message = template ? replaceTemplate(template, customData) : 'Error';
        // Service Name: Error message (service/code).
        var fullMessage = this.serviceName + ": " + message + " (" + fullCode + ").";
        var error = new FirebaseError(fullCode, fullMessage, customData);
        return error;
    };
    return ErrorFactory;
}());
function replaceTemplate(template, data) {
    return template.replace(PATTERN, function (_, key) {
        var value = data[key];
        return value != null ? String(value) : "<" + key + "?>";
    });
}
var PATTERN = /\{\$([^}]+)}/g;

/**
 * @license
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
function getModularInstance(service) {
    if (service && service._delegate) {
        return service._delegate;
    }
    else {
        return service;
    }
}

/**
 * Component for service name T, e.g. `auth`, `auth-internal`
 */
var Component = /** @class */ (function () {
    /**
     *
     * @param name The public service name, e.g. app, auth, firestore, database
     * @param instanceFactory Service factory responsible for creating the public interface
     * @param type whether the service provided by the component is public or private
     */
    function Component(name, instanceFactory, type) {
        this.name = name;
        this.instanceFactory = instanceFactory;
        this.type = type;
        this.multipleInstances = false;
        /**
         * Properties to be added to the service namespace
         */
        this.serviceProps = {};
        this.instantiationMode = "LAZY" /* LAZY */;
        this.onInstanceCreated = null;
    }
    Component.prototype.setInstantiationMode = function (mode) {
        this.instantiationMode = mode;
        return this;
    };
    Component.prototype.setMultipleInstances = function (multipleInstances) {
        this.multipleInstances = multipleInstances;
        return this;
    };
    Component.prototype.setServiceProps = function (props) {
        this.serviceProps = props;
        return this;
    };
    Component.prototype.setInstanceCreatedCallback = function (callback) {
        this.onInstanceCreated = callback;
        return this;
    };
    return Component;
}());

/**
 * @license
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var _a;
/**
 * The JS SDK supports 5 log levels and also allows a user the ability to
 * silence the logs altogether.
 *
 * The order is a follows:
 * DEBUG < VERBOSE < INFO < WARN < ERROR
 *
 * All of the log types above the current log level will be captured (i.e. if
 * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and
 * `VERBOSE` logs will not)
 */
var LogLevel;
(function (LogLevel) {
    LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
    LogLevel[LogLevel["VERBOSE"] = 1] = "VERBOSE";
    LogLevel[LogLevel["INFO"] = 2] = "INFO";
    LogLevel[LogLevel["WARN"] = 3] = "WARN";
    LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
    LogLevel[LogLevel["SILENT"] = 5] = "SILENT";
})(LogLevel || (LogLevel = {}));
var levelStringToEnum = {
    'debug': LogLevel.DEBUG,
    'verbose': LogLevel.VERBOSE,
    'info': LogLevel.INFO,
    'warn': LogLevel.WARN,
    'error': LogLevel.ERROR,
    'silent': LogLevel.SILENT
};
/**
 * The default log level
 */
var defaultLogLevel = LogLevel.INFO;
/**
 * By default, `console.debug` is not displayed in the developer console (in
 * chrome). To avoid forcing users to have to opt-in to these logs twice
 * (i.e. once for firebase, and once in the console), we are sending `DEBUG`
 * logs to the `console.log` function.
 */
var ConsoleMethod = (_a = {},
    _a[LogLevel.DEBUG] = 'log',
    _a[LogLevel.VERBOSE] = 'log',
    _a[LogLevel.INFO] = 'info',
    _a[LogLevel.WARN] = 'warn',
    _a[LogLevel.ERROR] = 'error',
    _a);
/**
 * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR
 * messages on to their corresponding console counterparts (if the log method
 * is supported by the current log level)
 */
var defaultLogHandler = function (instance, logType) {
    var args = [];
    for (var _i = 2; _i < arguments.length; _i++) {
        args[_i - 2] = arguments[_i];
    }
    if (logType < instance.logLevel) {
        return;
    }
    var now = new Date().toISOString();
    var method = ConsoleMethod[logType];
    if (method) {
        console[method].apply(console, __spreadArray(["[" + now + "]  " + instance.name + ":"], args));
    }
    else {
        throw new Error("Attempted to log a message with an invalid logType (value: " + logType + ")");
    }
};
var Logger = /** @class */ (function () {
    /**
     * Gives you an instance of a Logger to capture messages according to
     * Firebase's logging scheme.
     *
     * @param name The name that the logs will be associated with
     */
    function Logger(name) {
        this.name = name;
        /**
         * The log level of the given Logger instance.
         */
        this._logLevel = defaultLogLevel;
        /**
         * The main (internal) log handler for the Logger instance.
         * Can be set to a new function in internal package code but not by user.
         */
        this._logHandler = defaultLogHandler;
        /**
         * The optional, additional, user-defined log handler for the Logger instance.
         */
        this._userLogHandler = null;
    }
    Object.defineProperty(Logger.prototype, "logLevel", {
        get: function () {
            return this._logLevel;
        },
        set: function (val) {
            if (!(val in LogLevel)) {
                throw new TypeError("Invalid value \"" + val + "\" assigned to `logLevel`");
            }
            this._logLevel = val;
        },
        enumerable: false,
        configurable: true
    });
    // Workaround for setter/getter having to be the same type.
    Logger.prototype.setLogLevel = function (val) {
        this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;
    };
    Object.defineProperty(Logger.prototype, "logHandler", {
        get: function () {
            return this._logHandler;
        },
        set: function (val) {
            if (typeof val !== 'function') {
                throw new TypeError('Value assigned to `logHandler` must be a function');
            }
            this._logHandler = val;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(Logger.prototype, "userLogHandler", {
        get: function () {
            return this._userLogHandler;
        },
        set: function (val) {
            this._userLogHandler = val;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * The functions below are all based on the `console` interface
     */
    Logger.prototype.debug = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        this._userLogHandler && this._userLogHandler.apply(this, __spreadArray([this, LogLevel.DEBUG], args));
        this._logHandler.apply(this, __spreadArray([this, LogLevel.DEBUG], args));
    };
    Logger.prototype.log = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        this._userLogHandler && this._userLogHandler.apply(this, __spreadArray([this, LogLevel.VERBOSE], args));
        this._logHandler.apply(this, __spreadArray([this, LogLevel.VERBOSE], args));
    };
    Logger.prototype.info = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        this._userLogHandler && this._userLogHandler.apply(this, __spreadArray([this, LogLevel.INFO], args));
        this._logHandler.apply(this, __spreadArray([this, LogLevel.INFO], args));
    };
    Logger.prototype.warn = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        this._userLogHandler && this._userLogHandler.apply(this, __spreadArray([this, LogLevel.WARN], args));
        this._logHandler.apply(this, __spreadArray([this, LogLevel.WARN], args));
    };
    Logger.prototype.error = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        this._userLogHandler && this._userLogHandler.apply(this, __spreadArray([this, LogLevel.ERROR], args));
        this._logHandler.apply(this, __spreadArray([this, LogLevel.ERROR], args));
    };
    return Logger;
}());

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
class PlatformLoggerServiceImpl {
    constructor(container) {
        this.container = container;
    }
    // In initial implementation, this will be called by installations on
    // auth token refresh, and installations will send this string.
    getPlatformInfoString() {
        const providers = this.container.getProviders();
        // Loop through providers and get library/version pairs from any that are
        // version components.
        return providers
            .map(provider => {
            if (isVersionServiceProvider(provider)) {
                const service = provider.getImmediate();
                return `${service.library}/${service.version}`;
            }
            else {
                return null;
            }
        })
            .filter(logString => logString)
            .join(' ');
    }
}
/**
 *
 * @param provider check if this provider provides a VersionService
 *
 * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider
 * provides VersionService. The provider is not necessarily a 'app-version'
 * provider.
 */
function isVersionServiceProvider(provider) {
    const component = provider.getComponent();
    return (component === null || component === void 0 ? void 0 : component.type) === "VERSION" /* VERSION */;
}

const name$o = "@firebase/app";
const version$1 = "0.7.0-2021719182840";

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const logger = new Logger('@firebase/app');

const name$n = "@firebase/app-compat";

const name$m = "@firebase/analytics-compat";

const name$l = "@firebase/analytics";

const name$k = "@firebase/app-check-compat";

const name$j = "@firebase/app-check";

const name$i = "@firebase/auth";

const name$h = "@firebase/auth-compat";

const name$g = "@firebase/database";

const name$f = "@firebase/database-compat";

const name$e = "@firebase/functions";

const name$d = "@firebase/functions-compat";

const name$c = "@firebase/installations";

const name$b = "@firebase/installations-compat";

const name$a = "@firebase/messaging";

const name$9 = "@firebase/messaging-compat";

const name$8 = "@firebase/performance";

const name$7 = "@firebase/performance-compat";

const name$6 = "@firebase/remote-config";

const name$5 = "@firebase/remote-config-compat";

const name$4 = "@firebase/storage";

const name$3 = "@firebase/storage-compat";

const name$2 = "@firebase/firestore";

const name$1 = "@firebase/firestore-compat";

const name$p = "firebase";

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * The default app name
 *
 * @internal
 */
const DEFAULT_ENTRY_NAME = '[DEFAULT]';
const PLATFORM_LOG_STRING = {
    [name$o]: 'fire-core',
    [name$n]: 'fire-core-compat',
    [name$l]: 'fire-analytics',
    [name$m]: 'fire-analytics-compat',
    [name$j]: 'fire-app-check',
    [name$k]: 'fire-app-check-compat',
    [name$i]: 'fire-auth',
    [name$h]: 'fire-auth-compat',
    [name$g]: 'fire-rtdb',
    [name$f]: 'fire-rtdb-compat',
    [name$e]: 'fire-fn',
    [name$d]: 'fire-fn-compat',
    [name$c]: 'fire-iid',
    [name$b]: 'fire-iid-compat',
    [name$a]: 'fire-fcm',
    [name$9]: 'fire-fcm-compat',
    [name$8]: 'fire-perf',
    [name$7]: 'fire-perf-compat',
    [name$6]: 'fire-rc',
    [name$5]: 'fire-rc-compat',
    [name$4]: 'fire-gcs',
    [name$3]: 'fire-gcs-compat',
    [name$2]: 'fire-fst',
    [name$1]: 'fire-fst-compat',
    'fire-js': 'fire-js',
    [name$p]: 'fire-js-all'
};

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @internal
 */
const _apps = new Map();
/**
 * Registered components.
 *
 * @internal
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const _components = new Map();
/**
 * @param component - the component being added to this app's container
 *
 * @internal
 */
function _addComponent(app, component) {
    try {
        app.container.addComponent(component);
    }
    catch (e) {
        logger.debug(`Component ${component.name} failed to register with FirebaseApp ${app.name}`, e);
    }
}
/**
 *
 * @param component - the component to register
 * @returns whether or not the component is registered successfully
 *
 * @internal
 */
function _registerComponent(component) {
    const componentName = component.name;
    if (_components.has(componentName)) {
        logger.debug(`There were multiple attempts to register component ${componentName}.`);
        return false;
    }
    _components.set(componentName, component);
    // add the component to existing app instances
    for (const app of _apps.values()) {
        _addComponent(app, component);
    }
    return true;
}
/**
 *
 * @param app - FirebaseApp instance
 * @param name - service name
 *
 * @returns the provider for the service with the matching name
 *
 * @internal
 */
function _getProvider(app, name) {
    return app.container.getProvider(name);
}

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const ERRORS = {
    ["no-app" /* NO_APP */]: "No Firebase App '{$appName}' has been created - " +
        'call Firebase App.initializeApp()',
    ["bad-app-name" /* BAD_APP_NAME */]: "Illegal App name: '{$appName}",
    ["duplicate-app" /* DUPLICATE_APP */]: "Firebase App named '{$appName}' already exists with different options or config",
    ["app-deleted" /* APP_DELETED */]: "Firebase App named '{$appName}' already deleted",
    ["invalid-app-argument" /* INVALID_APP_ARGUMENT */]: 'firebase.{$appName}() takes either no argument or a ' +
        'Firebase App instance.',
    ["invalid-log-argument" /* INVALID_LOG_ARGUMENT */]: 'First argument to `onLog` must be null or a function.'
};
const ERROR_FACTORY = new ErrorFactory('app', 'Firebase', ERRORS);
/**
 * Retrieves a {@link @firebase/app#FirebaseApp} instance.
 *
 * When called with no arguments, the default app is returned. When an app name
 * is provided, the app corresponding to that name is returned.
 *
 * An exception is thrown if the app being retrieved has not yet been
 * initialized.
 *
 * @example
 * ```javascript
 * // Return the default app
 * const app = getApp();
 * ```
 *
 * @example
 * ```javascript
 * // Return a named app
 * const otherApp = getApp("otherApp");
 * ```
 *
 * @param name - Optional name of the app to return. If no name is
 *   provided, the default is `"[DEFAULT]"`.
 *
 * @returns The app corresponding to the provided app name.
 *   If no app name is provided, the default app is returned.
 *
 * @public
 */
function getApp(name = DEFAULT_ENTRY_NAME) {
    const app = _apps.get(name);
    if (!app) {
        throw ERROR_FACTORY.create("no-app" /* NO_APP */, { appName: name });
    }
    return app;
}
/**
 * Registers a library's name and version for platform logging purposes.
 * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)
 * @param version - Current version of that library.
 * @param variant - Bundle variant, e.g., node, rn, etc.
 *
 * @public
 */
function registerVersion(libraryKeyOrName, version, variant) {
    var _a;
    // TODO: We can use this check to whitelist strings when/if we set up
    // a good whitelist system.
    let library = (_a = PLATFORM_LOG_STRING[libraryKeyOrName]) !== null && _a !== void 0 ? _a : libraryKeyOrName;
    if (variant) {
        library += `-${variant}`;
    }
    const libraryMismatch = library.match(/\s|\//);
    const versionMismatch = version.match(/\s|\//);
    if (libraryMismatch || versionMismatch) {
        const warning = [
            `Unable to register library "${library}" with version "${version}":`
        ];
        if (libraryMismatch) {
            warning.push(`library name "${library}" contains illegal characters (whitespace or "/")`);
        }
        if (libraryMismatch && versionMismatch) {
            warning.push('and');
        }
        if (versionMismatch) {
            warning.push(`version name "${version}" contains illegal characters (whitespace or "/")`);
        }
        logger.warn(warning.join(' '));
        return;
    }
    _registerComponent(new Component(`${library}-version`, () => ({ library, version }), "VERSION" /* VERSION */));
}

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
function registerCoreComponents(variant) {
    _registerComponent(new Component('platform-logger', container => new PlatformLoggerServiceImpl(container), "PRIVATE" /* PRIVATE */));
    // Register `app` package.
    registerVersion(name$o, version$1, variant);
    // Register platform SDK identifier (no version).
    registerVersion('fire-js', '');
}

/**
 * Firebase App
 *
 * @remarks This package coordinates the communication between the different Firebase components
 * @packageDocumentation
 */
registerCoreComponents();

/**
 * @license
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const LONG_TYPE = 'type.googleapis.com/google.protobuf.Int64Value';
const UNSIGNED_LONG_TYPE = 'type.googleapis.com/google.protobuf.UInt64Value';
function mapValues(
// { [k: string]: unknown } is no longer a wildcard assignment target after typescript 3.5
// eslint-disable-next-line @typescript-eslint/no-explicit-any
o, f) {
    const result = {};
    for (const key in o) {
        if (o.hasOwnProperty(key)) {
            result[key] = f(o[key]);
        }
    }
    return result;
}
/**
 * Takes data and encodes it in a JSON-friendly way, such that types such as
 * Date are preserved.
 * @internal
 * @param data - Data to encode.
 */
function encode(data) {
    if (data == null) {
        return null;
    }
    if (data instanceof Number) {
        data = data.valueOf();
    }
    if (typeof data === 'number' && isFinite(data)) {
        // Any number in JS is safe to put directly in JSON and parse as a double
        // without any loss of precision.
        return data;
    }
    if (data === true || data === false) {
        return data;
    }
    if (Object.prototype.toString.call(data) === '[object String]') {
        return data;
    }
    if (data instanceof Date) {
        return data.toISOString();
    }
    if (Array.isArray(data)) {
        return data.map(x => encode(x));
    }
    if (typeof data === 'function' || typeof data === 'object') {
        return mapValues(data, x => encode(x));
    }
    // If we got this far, the data is not encodable.
    throw new Error('Data cannot be encoded in JSON: ' + data);
}
/**
 * Takes data that's been encoded in a JSON-friendly form and returns a form
 * with richer datatypes, such as Dates, etc.
 * @internal
 * @param json - JSON to convert.
 */
function decode(json) {
    if (json == null) {
        return json;
    }
    if (json['@type']) {
        switch (json['@type']) {
            case LONG_TYPE:
            // Fall through and handle this the same as unsigned.
            case UNSIGNED_LONG_TYPE: {
                // Technically, this could work return a valid number for malformed
                // data if there was a number followed by garbage. But it's just not
                // worth all the extra code to detect that case.
                const value = Number(json['value']);
                if (isNaN(value)) {
                    throw new Error('Data cannot be decoded from JSON: ' + json);
                }
                return value;
            }
            default: {
                throw new Error('Data cannot be decoded from JSON: ' + json);
            }
        }
    }
    if (Array.isArray(json)) {
        return json.map(x => decode(x));
    }
    if (typeof json === 'function' || typeof json === 'object') {
        return mapValues(json, x => decode(x));
    }
    // Anything else is safe to return.
    return json;
}

/**
 * @license
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Type constant for Firebase Functions.
 */
const FUNCTIONS_TYPE = 'functions';

/**
 * @license
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Standard error codes for different ways a request can fail, as defined by:
 * https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
 *
 * This map is used primarily to convert from a backend error code string to
 * a client SDK error code string, and make sure it's in the supported set.
 */
const errorCodeMap = {
    OK: 'ok',
    CANCELLED: 'cancelled',
    UNKNOWN: 'unknown',
    INVALID_ARGUMENT: 'invalid-argument',
    DEADLINE_EXCEEDED: 'deadline-exceeded',
    NOT_FOUND: 'not-found',
    ALREADY_EXISTS: 'already-exists',
    PERMISSION_DENIED: 'permission-denied',
    UNAUTHENTICATED: 'unauthenticated',
    RESOURCE_EXHAUSTED: 'resource-exhausted',
    FAILED_PRECONDITION: 'failed-precondition',
    ABORTED: 'aborted',
    OUT_OF_RANGE: 'out-of-range',
    UNIMPLEMENTED: 'unimplemented',
    INTERNAL: 'internal',
    UNAVAILABLE: 'unavailable',
    DATA_LOSS: 'data-loss'
};
/**
 * An explicit error that can be thrown from a handler to send an error to the
 * client that called the function.
 */
class FunctionsError extends FirebaseError {
    constructor(
    /**
     * A standard error code that will be returned to the client. This also
     * determines the HTTP status code of the response, as defined in code.proto.
     */
    code, message,
    /**
     * Extra data to be converted to JSON and included in the error response.
     */
    details) {
        super(`${FUNCTIONS_TYPE}/${code}`, message || '');
        this.details = details;
    }
}
/**
 * Takes an HTTP status code and returns the corresponding ErrorCode.
 * This is the standard HTTP status code -> error mapping defined in:
 * https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
 *
 * @param status An HTTP status code.
 * @return The corresponding ErrorCode, or ErrorCode.UNKNOWN if none.
 */
function codeForHTTPStatus(status) {
    // Make sure any successful status is OK.
    if (status >= 200 && status < 300) {
        return 'ok';
    }
    switch (status) {
        case 0:
            // This can happen if the server returns 500.
            return 'internal';
        case 400:
            return 'invalid-argument';
        case 401:
            return 'unauthenticated';
        case 403:
            return 'permission-denied';
        case 404:
            return 'not-found';
        case 409:
            return 'aborted';
        case 429:
            return 'resource-exhausted';
        case 499:
            return 'cancelled';
        case 500:
            return 'internal';
        case 501:
            return 'unimplemented';
        case 503:
            return 'unavailable';
        case 504:
            return 'deadline-exceeded';
    }
    return 'unknown';
}
/**
 * Takes an HTTP response and returns the corresponding Error, if any.
 */
function _errorForResponse(status, bodyJSON) {
    let code = codeForHTTPStatus(status);
    // Start with reasonable defaults from the status code.
    let description = code;
    let details = undefined;
    // Then look through the body for explicit details.
    try {
        const errorJSON = bodyJSON && bodyJSON.error;
        if (errorJSON) {
            const status = errorJSON.status;
            if (typeof status === 'string') {
                if (!errorCodeMap[status]) {
                    // They must've included an unknown error code in the body.
                    return new FunctionsError('internal', 'internal');
                }
                code = errorCodeMap[status];
                // TODO(klimt): Add better default descriptions for error enums.
                // The default description needs to be updated for the new code.
                description = status;
            }
            const message = errorJSON.message;
            if (typeof message === 'string') {
                description = message;
            }
            details = errorJSON.details;
            if (details !== undefined) {
                details = decode(details);
            }
        }
    }
    catch (e) {
        // If we couldn't parse explicit error data, that's fine.
    }
    if (code === 'ok') {
        // Technically, there's an edge case where a developer could explicitly
        // return an error code of OK, and we will treat it as success, but that
        // seems reasonable.
        return null;
    }
    return new FunctionsError(code, description, details);
}

/**
 * Helper class to get metadata that should be included with a function call.
 * @internal
 */
class ContextProvider {
    constructor(authProvider, messagingProvider, appCheckProvider) {
        this.auth = null;
        this.messaging = null;
        this.appCheck = null;
        this.auth = authProvider.getImmediate({ optional: true });
        this.messaging = messagingProvider.getImmediate({
            optional: true
        });
        if (!this.auth) {
            authProvider.get().then(auth => (this.auth = auth), () => {
                /* get() never rejects */
            });
        }
        if (!this.messaging) {
            messagingProvider.get().then(messaging => (this.messaging = messaging), () => {
                /* get() never rejects */
            });
        }
        if (!this.appCheck) {
            appCheckProvider.get().then(appCheck => (this.appCheck = appCheck), () => {
                /* get() never rejects */
            });
        }
    }
    async getAuthToken() {
        if (!this.auth) {
            return undefined;
        }
        try {
            const token = await this.auth.getToken();
            return token === null || token === void 0 ? void 0 : token.accessToken;
        }
        catch (e) {
            // If there's any error when trying to get the auth token, leave it off.
            return undefined;
        }
    }
    async getMessagingToken() {
        if (!this.messaging ||
            !('Notification' in self) ||
            Notification.permission !== 'granted') {
            return undefined;
        }
        try {
            return await this.messaging.getToken();
        }
        catch (e) {
            // We don't warn on this, because it usually means messaging isn't set up.
            // console.warn('Failed to retrieve instance id token.', e);
            // If there's any error when trying to get the token, leave it off.
            return undefined;
        }
    }
    async getAppCheckToken() {
        if (this.appCheck) {
            const result = await this.appCheck.getToken();
            // If getToken() fails, it will still return a dummy token that also has
            // an error field containing the error message. We will send any token
            // provided here and show an error if/when it is rejected by the functions
            // endpoint.
            return result.token;
        }
        return null;
    }
    async getContext() {
        const authToken = await this.getAuthToken();
        const messagingToken = await this.getMessagingToken();
        const appCheckToken = await this.getAppCheckToken();
        return { authToken, messagingToken, appCheckToken };
    }
}

/**
 * @license
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const DEFAULT_REGION = 'us-central1';
/**
 * Returns a Promise that will be rejected after the given duration.
 * The error will be of type FunctionsError.
 *
 * @param millis Number of milliseconds to wait before rejecting.
 */
function failAfter(millis) {
    return new Promise((_, reject) => {
        setTimeout(() => {
            reject(new FunctionsError('deadline-exceeded', 'deadline-exceeded'));
        }, millis);
    });
}
/**
 * The main class for the Firebase Functions SDK.
 * @internal
 */
class FunctionsService {
    /**
     * Creates a new Functions service for the given app.
     * @param app - The FirebaseApp to use.
     */
    constructor(app, authProvider, messagingProvider, appCheckProvider, regionOrCustomDomain = DEFAULT_REGION, fetchImpl) {
        this.app = app;
        this.fetchImpl = fetchImpl;
        this.emulatorOrigin = null;
        this.contextProvider = new ContextProvider(authProvider, messagingProvider, appCheckProvider);
        // Cancels all ongoing requests when resolved.
        this.cancelAllRequests = new Promise(resolve => {
            this.deleteService = () => {
                return Promise.resolve(resolve());
            };
        });
        // Resolve the region or custom domain overload by attempting to parse it.
        try {
            const url = new URL(regionOrCustomDomain);
            this.customDomain = url.origin;
            this.region = DEFAULT_REGION;
        }
        catch (e) {
            this.customDomain = null;
            this.region = regionOrCustomDomain;
        }
    }
    _delete() {
        return this.deleteService();
    }
    /**
     * Returns the URL for a callable with the given name.
     * @param name - The name of the callable.
     * @internal
     */
    _url(name) {
        const projectId = this.app.options.projectId;
        if (this.emulatorOrigin !== null) {
            const origin = this.emulatorOrigin;
            return `${origin}/${projectId}/${this.region}/${name}`;
        }
        if (this.customDomain !== null) {
            return `${this.customDomain}/${name}`;
        }
        return `https://${this.region}-${projectId}.cloudfunctions.net/${name}`;
    }
}
/**
 * Modify this instance to communicate with the Cloud Functions emulator.
 *
 * Note: this must be called before this instance has been used to do any operations.
 *
 * @param host The emulator host (ex: localhost)
 * @param port The emulator port (ex: 5001)
 * @public
 */
function connectFunctionsEmulator$1(functionsInstance, host, port) {
    functionsInstance.emulatorOrigin = `http://${host}:${port}`;
}
/**
 * Returns a reference to the callable https trigger with the given name.
 * @param name - The name of the trigger.
 * @public
 */
function httpsCallable$1(functionsInstance, name, options) {
    return (data => {
        return call(functionsInstance, name, data, options || {});
    });
}
/**
 * Does an HTTP POST and returns the completed response.
 * @param url The url to post to.
 * @param body The JSON body of the post.
 * @param headers The HTTP headers to include in the request.
 * @return A Promise that will succeed when the request finishes.
 */
async function postJSON(url, body, headers, fetchImpl) {
    headers['Content-Type'] = 'application/json';
    let response;
    try {
        response = await fetchImpl(url, {
            method: 'POST',
            body: JSON.stringify(body),
            headers
        });
    }
    catch (e) {
        // This could be an unhandled error on the backend, or it could be a
        // network error. There's no way to know, since an unhandled error on the
        // backend will fail to set the proper CORS header, and thus will be
        // treated as a network error by fetch.
        return {
            status: 0,
            json: null
        };
    }
    let json = null;
    try {
        json = await response.json();
    }
    catch (e) {
        // If we fail to parse JSON, it will fail the same as an empty body.
    }
    return {
        status: response.status,
        json
    };
}
/**
 * Calls a callable function asynchronously and returns the result.
 * @param name The name of the callable trigger.
 * @param data The data to pass as params to the function.s
 */
async function call(functionsInstance, name, data, options) {
    const url = functionsInstance._url(name);
    // Encode any special types, such as dates, in the input data.
    data = encode(data);
    const body = { data };
    // Add a header for the authToken.
    const headers = {};
    const context = await functionsInstance.contextProvider.getContext();
    if (context.authToken) {
        headers['Authorization'] = 'Bearer ' + context.authToken;
    }
    if (context.messagingToken) {
        headers['Firebase-Instance-ID-Token'] = context.messagingToken;
    }
    if (context.appCheckToken !== null) {
        headers['X-Firebase-AppCheck'] = context.appCheckToken;
    }
    // Default timeout to 70s, but let the options override it.
    const timeout = options.timeout || 70000;
    const response = await Promise.race([
        postJSON(url, body, headers, functionsInstance.fetchImpl),
        failAfter(timeout),
        functionsInstance.cancelAllRequests
    ]);
    // If service was deleted, interrupted response throws an error.
    if (!response) {
        throw new FunctionsError('cancelled', 'Firebase Functions instance was deleted.');
    }
    // Check for an error status, regardless of http status.
    const error = _errorForResponse(response.status, response.json);
    if (error) {
        throw error;
    }
    if (!response.json) {
        throw new FunctionsError('internal', 'Response is not valid JSON object.');
    }
    let responseData = response.json.data;
    // TODO(klimt): For right now, allow "result" instead of "data", for
    // backwards compatibility.
    if (typeof responseData === 'undefined') {
        responseData = response.json.result;
    }
    if (typeof responseData === 'undefined') {
        // Consider the response malformed.
        throw new FunctionsError('internal', 'Response is missing data field.');
    }
    // Decode any special types, such as dates, in the returned data.
    const decodedData = decode(responseData);
    return { data: decodedData };
}

/**
 * @license
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const APP_CHECK_INTERNAL_NAME = 'app-check-internal';
function registerFunctions(fetchImpl) {
    const factory = (container, { instanceIdentifier: regionOrCustomDomain }) => {
        // Dependencies
        const app = container.getProvider('app').getImmediate();
        const authProvider = container.getProvider('auth-internal');
        const messagingProvider = container.getProvider('messaging-compat');
        const appCheckProvider = container.getProvider(APP_CHECK_INTERNAL_NAME);
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        return new FunctionsService(app, authProvider, messagingProvider, appCheckProvider, regionOrCustomDomain, fetchImpl);
    };
    _registerComponent(new Component(FUNCTIONS_TYPE, factory, "PUBLIC" /* PUBLIC */).setMultipleInstances(true));
}

const name = "@firebase/functions";
const version = "0.7.0-2021719182840";

/**
 * @license
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Returns a {@link Functions} instance for the given app.
 * @param app - The {@link @firebase/app#FirebaseApp} to use.
 * @param regionOrCustomDomain - one of:
 *   a) The region the callable functions are located in (ex: us-central1)
 *   b) A custom domain hosting the callable functions (ex: https://mydomain.com)
 * @public
 */
function getFunctions(app = getApp(), regionOrCustomDomain = DEFAULT_REGION) {
    // Dependencies
    const functionsProvider = _getProvider(getModularInstance(app), FUNCTIONS_TYPE);
    const functionsInstance = functionsProvider.getImmediate({
        identifier: regionOrCustomDomain
    });
    return functionsInstance;
}
/**
 * Modify this instance to communicate with the Cloud Functions emulator.
 *
 * Note: this must be called before this instance has been used to do any operations.
 *
 * @param host - The emulator host (ex: localhost)
 * @param port - The emulator port (ex: 5001)
 * @public
 */
function connectFunctionsEmulator(functionsInstance, host, port) {
    connectFunctionsEmulator$1(getModularInstance(functionsInstance), host, port);
}
/**
 * Returns a reference to the callable HTTPS trigger with the given name.
 * @param name - The name of the trigger.
 * @public
 */
function httpsCallable(functionsInstance, name, options) {
    return httpsCallable$1(getModularInstance(functionsInstance), name, options);
}

/**
 * Cloud Functions for Firebase
 *
 * @packageDocumentation
 */
registerFunctions(fetch.bind(self));
registerVersion(name, version);

export { connectFunctionsEmulator, getFunctions, httpsCallable };
//# sourceMappingURL=firebase-functions.js.map

redpajama_set_name: RedPajamaGithub


Research Associate in "Institute for Conflict Management", New Delhi, India. Ph.D. in "Madarsa Education in India, Pakistan and Bangladesh: A Comparative Study".
Abstract: The word 'madrasa' do generate a lot of curiosity and negative propaganda among scholars of international community. In most of the instances it is considered to be an institution of preaching hatred and violence. Moreover, the madrasas existing in Pakistan are considered to be factories producing religious extremists. But, strangely enough, the basic reason behind the emergence of madrasa- to seek knowledge as enshrined in the principals of Islam are not known. Therefore, fundamental objective or purpose of the study is to understand the changing pattern of madrasa and the role of government in Pakistan to 'modernise' it. The paper is also trying to understand the socio-political context of Pakistan under which the madrasas are operating. The study has been based on the research experience of the writer who has extensively studied the Madrasa Literature of Pakistan while writing her Doctoral thesis. The few core findings of the paper are the fact that over a considerable period of time, madrasas have evolved from an all encompassing educational institution to a centre of religious knowledge; the society of Pakistan to some extent has been segmented into western educated 'modern and fortunate' people versus madrasa educated 'traditional and less-fortunate' mass. Moreover, post 9/11, Pakistani Government did try to 'reform' the madrasa system but could not achieve much success due to shallow approach and non-compliance of various madrasa establishments.
1 Dr. Sanchita Bhattacharya is Research Associate in "Institute for Conflict Management", New Delhi, India. She has done Ph.D. in "Madarsa Education in India, Pakistan and Bangladesh: A Comparative Study" from School of International Studies (SIS), Jawaharlal Nehru University (JNU), New Delhi. She writes frequently on the subject of Political Islam, in various national and international journals. Moreover, her commentaries and articles are also published in East Asia Forum, Outlook India, New Age Islam etc. She can be reached at sanchita.bhat83@gmail.com.
i 'On June 19, 2003 the federal government signed a Memorandum of Understanding with the provinces of Federally Administered Tribal Areas (FATA), Federally Administered Northern Areas (FANA) and the Pakistan Occupied Kashmir (PoK) to reform 8,000 madrasas in next five years. Under this arrangement the MRP was launched' (Looney 2003: 268).


text:
Loni Love Says Single Black Women Should Take A Chance On Interracial Love [WATCH]
Despite the differences between herself and boyfriend James Welsh, Loni Love says he's perfect for her. "He's different, his culture's different…
Little Known Black History Fact: Whoopi Goldberg
Since the early '80s, Whoopi Goldberg has seemingly done it all. The award-winning comedian, actress and television host was born…
Loni Love And Ashley Stewart Have Collaborated On A Fashion Line For The Holidays
"Ashley Stewart's commitment to inspiring all women and especially African American women a company that invests in my sisters is…
Tamron Hall Shares A Sexy Email From Prince On Day His Memoir Is Released [WATCH]
We've always wondered if Tamron Hall and Prince were more than just friend and maybe today, we have somewhat of…
Wendy Williams On Meghan Markle: 'Nobody Feels Sorry For You'
Welp! It's obvious that Wendy Williams is not in the fan or sympathetic column when it comes to Meghan Markle and her royal woes.…
Mike From "Bachelor In Paradise" Asked Keke Palmer Out On Live TV [WATCH]
"Bachelor In Paradise" cast off Mike Johnson is back on the dating scene singing, "Keke, do you love me?"
Tamar Shades 'The Real' Cast, They Clap Back!
The ladies of The Real had a few things to get off of their chest during Wednesday's live taping of the show.…
How She Doin' – Wendy Williams Show Renewed Through 2022
If you're a fan of Wendy Williams, you already know that she's back with season 11 starting today. But, there's even…
Tamron Hall: "Just Because I Married A White Man Doesn't Mean I Don't Love Black Men"
Tthis week Tamron Hall's new self-titled syndicated talk show debuts on stations around the country (check local listings). But of…
Fantasia And Tamron Hall Link Up For Tamron Show Theme Song [LISTEN]
Tamron Hall has chosen Fantasia, to be the voice of her new TV chat show's theme song. Tamron Hall is…
Loni Love Quits Drinking To Prepare For Season 6 Of 'The Real'
Loni Love is going through a dry spell, but we're talking about alcohol, here. The 48-year-old comedian and The Real co-host announced her…
50 Cent On Wendy Williams And The Art Of The Clapback [WATCH]
50 Cent does not hold back! The "Power" star tells Access Hollywood exactly how he feels about Wendy Williams attending his Tycoon party…

redpajama_set_name: RedPajamaCommonCrawl


text:
Naysayers around Griner's release are actually a good sign
Brittney Griner on the plane that brought her back to the U.S. FSB/TASS photo.
When Brittney Griner was freed from Russian captivity three days ago, the basketball world rejoiced.
The U.S. government traded the WNBA star for convicted arms dealer Viktor Bout in a prisoner swap that concluded months of tedious talks between the two countries. Griner, convicted in August of possessing a small amount of hashish oil and a vape cartridge, had been sentenced to serve almost a decade in a Russian penal colony.
But though the trade was hailed in sports circles as a victory, others decried it. President Joe Biden was ridiculed as making the U.S. look "weak" by taking Griner, and he was criticized for not holding out for American hostage Paul Whelan to also be included in the deal.
Many of the critics were legislators, who also took aim at Griner's identity: a Black, queer woman who had joined her Phoenix Mercury teammates in not being in the arena during the national anthem, beginning after the 2020 murder of George Floyd in Minnesota.
And though the rhetoric itself is unfortunate, the fact that there was blow back in Griner's case is ultimately an encouraging sign.
Let's first acknowledge how monumental the trade was for the Olympian and All-Star: this was the first time a woman had been the focal trade piece in a national prisoner swap. And to top that, she is a member of three groups that are marginalized around the world in her race, her gender and her sexual orientation.
Almost 20 years ago, comedian Dave Chappelle made a joke that terrorists never take Black hostages because they have no trade value, while homophobia was still rampant in the U.S. So much has changed since then.
This past summer and fall, Iranian women began protesting violence and discrimination against women in that country, for refusing to wear hijabs. They not only haven't stopped, but have been joined by men.
At the World Cup in Qatar this month, protesters have disrupted events and defied rules prohibiting wearing the LGBTQ+ rainbow flag. It is clear that many traditionally-marginalized people on planet Earth are not willing to put up with discrimination any longer.
Griner's trade is a signal that she matters, so it is not surprising that those who do not want people like her to matter will speak out against her, and against her mattering. It is reminiscent of the way some social media trolls will insult women's basketball: they are upset that the athletes are getting the attention. It says everything about them, and nothing about the players they rail against.
Martin Luther King Jr.'s daughter Bernice King has pointed out repeatedly that although her father is loved and lauded now, he was "the most hated man in America" when he was an activist. Those that stand up to wrong, fight for change, and who are who they are unapologetically, will always get the hate, at least initially.
A Black, queer female athlete was a political prisoner, and her country negotiated her release. People across the world are continuing to fight – and put their lives at risk – to speak out against sexism, homophobia, and other forms of hate. It is important to look past the negative rhetoric in Griner's case and remember the big picture: the needle of progress is moving. We are finally starting to see change, in both big and small ways.
Griner played basketball today for the first time in 10 months. If we see her back on a WNBA court next season, which it sounds like we may, it is important to continue to keep that large view in mind: we need to keep fighting for change. Step by step, despite the pain that comes with it, we have to keep walking.
Tags: brittney griner
November Award For Table-Topping Kapoulas
NCAAW roundup: Tara VanDerveer, Aneesah Morrow the stars of the week
New partnership between Sheffield Sharks and LivingCare
The 2022 WNBA season highlighted the former player-to-coach pipeline


text:
I Had No Idea Smirnoff Vodka Originated in Bethel, CT
Suzy Garcia Published: March 20, 2018
Credit: Getty Images for New York Magazine
Did you know that a penniless immigrant from Russia went on to establish and bottle the world's number one selling brand of vodka from right here in Connecticut?
The Smirnoff Vodka distillery in Bethel was the very first domestic vodka distillery and was established soon after the repeal of prohibition in the US in 1934, according to Connecticut Magazine.
Rudolph Kunett left Russia in the wake of the revolution for New York and eventually settled in Connecticut. With knowledge of the trade from his family's plantation, and then making a connection with the Smirnoff family in Russia who was already in the distillery business, he introduced the spirit that had been a favorite in his homeland for generations. Prior to the introduction of the Smirnoff brand to Americans, vodka had not been produced in the states at all (legally).
Heublein Incorporated of Hartford purchased the rights to Smirnoff in 1939. Mr. Kunett resided in West Hartford until retiring in 1963 and moving to California. He passed away in 1979 at the age of 85, according to the New York Times. Raise your glass to Rudolph as he was a Nutmegger we can really be proud of!
Download the i95 Mobile App to Rock With Everything Live and Local
Read More Local Stories:
Parents in New Milford Reportedly Hire Lawyers Regarding School Walkout
Once Thriving Pleasure Beach Is Connecticut's Newest Ghost Town
Police: Putnam County Man Impersonating Officer Performs Traffic Stop
2 Brookfield Guys Launch Invention to Hold Drink + Phone at the Same Time
The Official Rules of the American Handshake:
Lou's Hilarious Commercial for Olive Garden's Meatball Pizza Bowl:


Interior design, decoration, furnishing a space, why do we do it? Functionality, aesthetics, lifestyles, culture and tradition all play a role. What happens when these are called into question? Homes, offices, transportation, hotels, are undergoing changes that fascinate designers, architects, engineers, and sociologists. How are these interpreted by the trade and at shows like Heimtextil, Domotex, imm cologne, Maison&Objet, and Paris Deco Off? Get inspired with the February edition!
Cologne — Trend areas at trade shows are about inspiration. We believe that if you do not walk away feeling inspired in some manner then that space has failed, even it is accurate in its design or lifestyle directions presented. Learn about our insights into the presentations at Heimtextil, imm cologne, Maison&Objet, and others to be reviewed throughout the month. In this gallery walk through the concept home of Todd Bracher for Das Haus.
Paris — A journey through the inspiration zone at Maison&Objet can be taken at face value, or one can contemplate the deeper meaning of the creations and understand some deep shifts in society. Elizabeth Leriche notes that, "Silence is the new philosopher's stone; disconnection is synonymous with liberation and silence is the new and luxurious material that is a source of creativity, respiration, and harmony." See the products of silence herein.
Frankfurt — Trendspot Retail was realized under the theme 'Make yourself at home' this year during Heimtextil, based on the trends found within the Theme Park. There are two cocoons each presenting a unique approach to retail staging and sensory experiences following the color combinations for 2017/2018. All of the products shown are available from exhibitors at the exhibition. Come in to explore the Discovery Shop here.
Frankfurt — The Capsule Shop displays retail potential with an elegant domestic atmosphere and traditional elements offset with contemporary accents. As an oasis of peace and quiet , the cocoon creates the antithesis of the fast-moving, high-tech world. A stylish opulence without ostentation, intermixed with some reinterpreted design classics, creates a sense of individuality with a touch of extravagance.
Frankfurt — The landscape of retail has changed. Today's retailer faces new challenges to remain relevant and competitive. What are focal points for sustainability in business as well as the environment? In the Heimtextil Theme Park one of the areas focused on retail, where attention was paid to materials as well as restoration. In this gallery subscribers can see how these ideas were visualized to inspire visitors to Hall 6.0.
Frankfurt — When one thinks of home textiles transportation is probably not the first thing to come to mind; however, textiles play a huge role in the interiors of cars, planes, trains, boats, and even space travel. Aside from the obvious—upholstery—fabrics and technical textiles are present beyond where the eye can see. Subscribers can view the modular and customizable XYT electric car on show and a carousel of fabrics.
Frankfurt — Work environments have undergone an enormous transformation since the beginning of the Dot Com era. More offices take on home-like atmospheres. In fact, more and more people work from home full-time or a couple days per week. Perhaps they are not even at home, but they are tapping into the office remotely. How will these lifestyle shifts catalyze change in interiors for 2017/2018?
Cologne — How does a trade body such as the Deutsches Tapeten-Institut support its members during a trade show that is large in scale and every exhibitor must fight to get the attention of the visitor? By recreating the Garden of Eden with Adam, Eve, the juicy apple, and the tempter of a snake. That's right, the association made an entire fantasy world entirely out of wallpaper, and that definitely got visitors to imm cologne to take notice.


Hi friends! I hope you are you all doing well! We have had better weeks. I'm not going to lie to you. I'm sick and hubby is sick. The boys need parent teacher conferences. The baby is... oh so very two. And we are having car issues. But next week will be better, right? Promise?
You know what helps on those weeks like this?? Super quick meals that everyone in the family will eat without complaining. This is a taco soup recipe that I got from my mother in law that I've made tiny changes to. It is so easy and fast! The kids LOVE this soup! It's perfect for during the week when you need to throw something together and run out the door to scouts, sports, or whatever you do.
1. Brown turkey in a large pot and drain the fat.
2. Open all the cans and dump ALL of them in (with liquid).
3. Season with taco seasoning. I usually use a whole packet or the equivalent of homemade seasoning.
4. Cook for about 20 mins to let the flavors meld.
5. Ladle into bowls and top with your favorite taco toppings.
LOVE easy recipes! So sorry to hear that you guys have been sick! I was down for a bit last week and it was MISERABLE! Get better soon!!!


text:
Fogasavai'i is a village on the island of Savai'i in Samoa. It is situated on the south coast of the island in the district of Satupa'itea and the electoral district of Salega 2. The population is 354.

References

Populated places in Satupa'itea

redpajama_set_name: RedPajamaWikipedia


For the first time in its 200 year history, Stowford Mill is getting ready to welcome its first residents. Once a bustling paper mill, this handsome piece of architecture was only accessed by its workforce, so lay relatively undiscovered in its peaceful rural setting. Burrington Estates undertook the transformation of the eight-acre site bounded by the River Erme into a collection of new homes, very close to everything Ivybridge has to offer.
On Saturday, January 26 from 11am-2pm, prospective buyers are invited to a special Off Plan Sales Event at estate agents Maitlands in Ivybridge. They will be able to see the latest visuals, speak to mortgage advisors and solicitors, and other experts who can support with schemes such as Help to Buy.
When its historic iron gates open for the first time in May, homeowners will be welcomed to contemporary residential, commercial and leisure spaces on the site. Existing buildings are being sensitively restored to their former glory, and new buildings include three, four and five bedroom homes, a later living community and luxury loft apartments. Quality craftsmanship and high build quality is key to this project's ethos.
Stowford Mill is an extension of the bustling market town of Ivybridge: a five minute stroll beside the river takes you to the town centre with attractions such as The Watermark, which hosts exciting community events throughout the year, as well as a newly upgraded cinema showing the latest blockbusters. Ivybridge Leisure Centre has a newly fitted gym, sauna and steam room, offering a great place to stay fit and active.
To book your attendance to this event or to learn more about one of the remaining properties, contact Maitlands on 01752 717710 or email ivybridge@maitlands.biz. Properties are available from £375,000.


text:
What font does 'Law & Order' use?
Jeopardy! host Alex Trebek: How long he's been hosting, retirement, cancer diagnosis, contract and possible replacements
White House Press Corps
For journalists covering Trump, the new reality at the White House
"There was a knock on our NBC News workspace door at the White House. I first assumed it was a colleague or a press aide coming by with an update. Instead, it was a White House official I'd never seen before with a forehead thermometer in his hand," writes NBC News' Shannon Pettypiece.


dont worry about your spelling just write a nice frist draft then go back and spell check.
I don't know whether you intended the spelling mistakes in your submission, but I think they do an excellent job of illustrating your point.
The advice to "just write" is one of the best bits of advice on writing I keep coming across. It's always possible to fix something that's written. But if there's nothing on the page, the is only a blank page.
So, I agree, with your advice to just write, and I thank you for the example you provided.
I sure didn't read that into the comments.
There is only one piece of advice, so no one is telling anyone that EVERYTHING they have ever done in writing is wrong.
Most (not all) practicing writers agree that writing is best when the creative side of the brain is working without reference to the picky editor side of the brain until the writing is done. THEN the editor can go to work.
Some (very few) practicing writers do enough work inside their heads before they put pen to paper or fingers to keyboards that they actually do the revisions internally and write a fairly clear first draft. Maybe that's what you do.
You may like to read books by other practicing writers who explain their processes. I think you will find that most do at least one free flowing draft.
That still doesn't mean you have to, or even should, do the same thing.
You sound hurt and angry. I'm sure no one meant to cause those feelings in you. So you might want to ask yourself where those feelings are coming from. Then ask yourself what you can take from the comments you read here, and what to leave.
I have always loved writing, but this page told me that everything I was doing was wrong. Thank you soo much!!


text:
West Loop, Near West Side, Pilsen
Pilsen's Largest Vacant Site Could Be Developed By The Resurrection Project
By Stephanie Lulay |&nbspSeptember 14, 2016 9:35am | Updated on September 14, 2016 10:34am
@slulay2
Ald. Danny Solis announced plans to rezone a massive Pilsen lot in an effort to block a developer's planned redevelopment of the property Tuesday.
dnainfo/Stephanie Lulay
PILSEN — After a zoning change, Pilsen's largest vacant site could still be developed into housing after all — affordable housing — by one of the city's largest affordable housing non-profits.
The Resurrection Project, a Pilsen-based housing non-profit, is interested in developing the 7.85-acre site between 16th and 18th streets and Newberry Avenue and Peoria Street, possibly in partnership with a private developer, confirmed Raul Raymundo, Resurrection Project CEO. The group has been interested in the site for years, he said.
"Are we interested in the site? Absolutely," said Raymundo, who also chairs the Pilsen Land Use Committee, which approves new development in the neighborhood. "And if we were so fortunate as to acquire it, we would make sure that not only 21 percent affordable housing would be done, but more than that."
Ald. Danny Solis (25th) confirmed at least part of any new plan for the site would include more than 21 percent affordable housing and would be less dense than the 500-unit project previously pitched by developer Property Markets Group.
Since, 2005, Solis and the land use committee has required a minimum of 21 percent of all new developments to be designated as affordable housing units. The rule applies to new developments of 10 or more units that seek zoning changes from the city or use city land or subsidies, but Solis has approved projects with less affordable housing on site when the developer offers another benefit to the community.
Solis' 21 percent mandate — which only applies to Pilsen, not other parts of the 25th Ward — is more than double the city's mandate requiring 10 percent of new developments to be affordable housing units. Developers can also skirt the city's rules by opting to make a payment to a city affordable housing fund.
Raymundo said Resurrection Project is working with Solis to ensure that whatever developer is chosen "does the right thing."
"Eventually that place we believe that it needs to get developed, but we want to make sure that whoever plans development for that site adheres to 21 percent [affordable housing] set aside for the community," Raymundo said. "As the community gets better, we want to make sure that there is an opportunity for residents to benefit."
A representative for The Midwest Jesuits, who have owned the site since 2009, declined to comment this week.
Developer Noah Gottlieb, representing developer New York-based developer Property Markets Group, also declined to comment.
In a feud over future development at the massive vacant Pilsen site, Solis moved to rezone the property to an industrial use this summer. The alderman first announced his intention to rezone the property in May, blocking the planned residential redevelopment by developer Property Markets Group.
At the time, Solis, a veteran alderman who serves as chairman of the Committee on Zoning, said the move would allow time for the community to develop the best plan for the site.
"Sometimes what a community needs or what a community wants isn't exactly what a developer is proposing," Solis said.
In response, Property Markets Group said they were "obviously disappointed in the decision."
"Our last proposal ... consisted of a public park connecting to the new Paseo, a large-scale art garden cultivated by local residents, bike and walking paths, and contained, on site, more affordable housing units then any privately funded project in the history of the City of Chicago, amongst other community benefits," the statement from New York-based Property Markets Group said.
While Pilsen needs more affordable housing, strict restrictions on development in Pilsen has led to no private affordable housing being created, the developer said.
Vincent Cook, representing The Midwest Jesuits said the zoning change was ""not the best use of that property."
Julio Paz of the Pilsen Land Use Committee said that the zoning change gave the committee time to find the best use for the land. The new plan will commence as "an entire community planning process," he said.
In May, Pilsen and University Village neighbors living near the site said they didn't want to see the property rezoned to an industrial use.
The move to rezone the property comes after developer Property Markets Group announced in April that it would still develop the property without a zoning change. Developer Noah Gottlieb said that they would still buy the site, and instead of 500 apartments, a smaller mixed-use project would be developed that meets the site's current zoning rules.
The developers came to that decision after the Pilsen Land Use Committee nixed their plan in February to build 500 apartments at the site. The sticking point that led the committee to deny the 500-unit project plan was Pilsen's stringent affordable housing mandate, which requires any development of eight or more units that requires a zoning change must provide 21 percent affordable housing on site.
In the case of the 500-unit development, Property Markets Group proposed developing 10 percent of affordable housing units on the site, Gottlieb confirmed.
Property Markets Group previously planned to develop 500 rental units on a vacant at 7.85-acre site between 16th and 18th streets and Newberry Avenue and Peoria Street in Pilsen. [PMG website]
In spring 2015, Property Markets Group revealed plans to develop 500 apartments on the vacant Pilsen property. The developer wanted a mix of one-, two- and three-bedroom units at the site.
In May 2015, Pilsen Alliance protested the Midwest Jesuits' planned sale of property in front of the Roman Catholic order's headquarters, calling the plan "gentrification on steroids."
Meanwhile, some University Village neighbors who live nearby are pushing for the long-vacant site to be developed soon. About 100 people have signed a petition in favor of developing the site.
Next in West Loop, Near West Side, Pilsen
FBI Vehicle Gets Broken Into In West Loop, But Nothing Gets Stolen
Affordable Housing Waiting List In Pilsen Just Got A Lot Shorter
Dine Under Airborne Mermaids, Twisting Aerialists This Month At Carnivale
Help Immigrants Learn English By Volunteering At McKinley Park
Pistol Whipping of Sisters In Chinatown Part Of Larger Crime Spree: Police
New Peoria St. Hotel Plan Would Add 5th Floor, Restaurant To Empty Building
'Get Out' Of Pilsen, Taggers Tell Filipino And White-Owned Businesses
West Loop »
What Is That Mysterious Orange Globe in Bartelme Park?
Twins Born At Roosevelt Red Line Station Have Names, Are Doing Well
Pilsen »
Historic Pilsen Bar Harbee Liquors Will Reopen in March, Owner Says


EMORY, Texas — Everyone recognizes the shiny blue trophies that are presented to each of the nine winners of regular-season Bassmaster Elite Series events.
Likewise, all fans of professional bass fishing instantly know the hulking trophy that is awarded every year to the Bassmaster Classic champion.
But there's one piece of B.A.S.S. hardware that isn't seen nearly as often.
Known as the Century Belt, it's only awarded to anglers who catch more than 100 pounds of bass during a four-day Elite Series event — and it could be making a rare appearance soon.
The third annual Toyota Bassmaster Texas Fest benefiting the Texas Parks and Wildlife Department is scheduled for May 2-6 on Lake Fork near Emory, Texas. That means some of the best bass anglers in the world will converge on a lake with a reputation for producing giant bass at just the right time on the calendar.
In 2014, the Toyota Texas Bass Classic (TTBC) — the predecessor to Texas Fest that included the top anglers from B.A.S.S. and the FLW Tour — was held on Lake Fork. Current Bassmaster Elite Series pro Keith Combs took first place with a gigantic winning weight of 110 pounds.
That was a three-day event that recorded the weights of only 15 fish.
Anglers will spend four days on the water at Texas Fest and record the weights of their 20 biggest fish. All fish will be weighed in the boat and immediately released.
In the 10 years TTBC was held and the two years since its transition to Toyota Bassmaster Texas Fest, the event has generated millions of dollars for TPWD's youth fishing and urban outreach programs.
The Elite Series was formed in 2006, and Century Belts have only been awarded at nine events (out of more than 100 total). No angler has earned one of the belts since the 2013 Elite Series event on Falcon Lake when Combs (111-5), Rick Clunn (105-6) and John Crews (103-13) all topped the 100-pound mark.
Many believe Century Belts could be claimed again at Texas Fest because Lake Fork — a 27,000-acre impoundment on the Sabine River — has been intensely managed for giant bass since it was impounded in 1980.
Through 2018, Texas Parks and Wildlife has stocked nearly 14 million Florida-strain largemouth — and the bass have flourished in habitat that includes vast areas of standing timber, hydrilla, milfoil and duckweed.
To help the fish reach exceptional sizes, TPWD implemented a slot limit that protects all bass that measure between 16 and 24 inches. Anglers can keep up to five bass per day, but only one of them can be over 24 inches.
Those management efforts have created a fishery that has produced 30 of the 50 largest bass ever caught in Texas, including the current state record of 18.18 pounds, which was in 1992 by Barry St. Clair.
The slot limit won't be a problem for the 75-angler Elite Series field since all bass will be immediately released — and the springtime conditions at Fork could lead to great things. The catch/weigh/release format made its debut at the first Toyota Texas Bass Classic, which was held on Lake Fork in 2007.
During that 2014 TTBC when Combs won with 110 pounds, he had one five-bass limit that weighed 42 pounds. That's a little more than 3 pounds shy of the all-time B.A.S.S. record for largest single-day, five-bass limit.
The full field of Elite Series anglers will fish Thursday and Friday, May 2-3. Anglers will then take a break from competition on Saturday, May 4, for a special Fan Appreciation Day with festivities, including Bassmaster University seminars, the Bassmaster Outdoors Expo and the annual Bassmaster High School All-American Fishing Team Tournament. A highlight of the Expo will be the Texas Parks and Wildlife Department Outdoor Adventure experience, including a catfish tank, wildlife viewing tent, fly casting and tying center, Texas State Fish Art exhibit, Toyota Sharelunker Trailer and many others.
The Top 35 Elite Series pros will resume competition on Sunday, May 5, and the Top 10 will compete on Championship Monday, May 6.
The tournament will feature a total payout of $1 million, with $100,000 going to the champion. A Toyota Tundra pickup truck will be awarded to the angler who weighs in the heaviest bass of the week.
The event will be covered in real time on Bassmaster LIVE, which streams on Bassmaster.com and the ESPN app, and it will be featured in a special episode of The Bassmasters television program to be aired later on ESPN2 and ESPN Classic.
In addition to the Lake Fork Chamber, the Wood County Industrial Commission, the Sabine River Authority, Quitman Economic Development Commission and Emory, TX Tourism are hosting the Texas Fest event.


text:
Barcelona X: The Amazing Sagrada Família Basilica
Aug10 by Ron and Ginger Warner
The Basílica i Temple Expiatori de la Sagrada Família – or simply La Sagrada Família (translation: Holy Family) – is a Roman Catholic church designed by Gaudí that, 130 years later, is still under construction. As shown below, it's big! Although parallels with Gothic
cathedrals of the Middle Ages are obvious, there is one major difference; in today's world, I can't imagine another such church ever being built. If things stay on schedule, it will have taken 144 years to reach completion. That makes this basilica the Last-of-the-Mohicans special – and is it ever! Gaudí's grand masterpiece is structurally innovative, wildly creative, incredibly bold, and unmistakably organic in architecture and decor. The interior is spectacular, and like nothing you have ever seen. Literally.
Before we explore this masterpiece by Gaudí, let me give you some history (ah … actually a bunch of history). Construction on the basilica started in 1882 with a Neo-gothic design by the architect Francisco de Paula del Villar y Lozano. However, due to disagreements,
the architect resigned and Antoni Gaudí took over in 1883. A few years later Gaudí proposed a more grand design, abandoning the Neo-gothic plan for something more monumental and innovative, both in structure and in construction. It would be a large church with a Latin-cross floor plan and soaring towers, and be immensely symbolic both architecturally and sculpturally, conveying teachings of the Gospels and Christian Church.
In 1914 Gaudí decided to concentrate exclusively on Sagrada Família; he undertook no other major work in the later years of his life. On a summer day in 1926, while taking his daily walk to church, he was struck by a passing tram and knocked unconscious. Assumed to be a beggar due to a lack of identity documents and shabby clothing, he did not receive immediate aid. Eventually transported to a hospital, he received rudimentary care. He was finally recognized the next day but died 2 days later at the age of 73. He had worked for 43 years on the temple. "It is not a disappointment that I will not be able to finish the temple. I will grow old, but others will come after me. What must be always preserved is the spirit of the work; its life will depend on the generations that transmit this spirit and bring it to life." A. Gaudí.
After Gaudí's death in 1926, the construction of Sagrada Família was continued by architects and craftsmen who had worked with him, following his plans and plaster models. I think it worth spending a little time to understand how novel Gaudí's design was (and continues to be). In his desire to overcome defects he saw in Gothic structural systems, he developed a new architecture based on organic and geometric forms of nature to create balanced and self-supporting structures. Nature often incorporates in its structures such geometrical forms as the ellipse, parabola and hyperbola, and Gaudí adapted these and – when using two together – their intersections to be integral structural forms of his architecture. An example of Gaudí copying from nature is shown below, comparing the structure of a plant pollen grain to windows in the Sagrada.
Gaudí rarely drew detailed plans of his works, instead preferring to create them as 3-dimensional scale models, as illustrated below and as shown incorporated in the
Sagrada (Note: Isn't that last picture, showing the interior, absolutely breathtaking??). Some of Gaudi's evolving models of La Sagrada are shown below. They show an evolution from a neo-Gothic structure to a model based on the parabola to the final design using
hyperbolas. The models are reconstructions, alas. At the beginning of the Spanish Civil War (1936), anarchists broke into La Sagrada, wrecked a crypt and chapel, and destroyed and burned Gaudí's studio. His drawings did not survive, but the mobs left behind many broken pieces of his original models which were painstakingly restored.
Gaudí also used the catenary arch; a catenary is the curve that a string or chain assumes under its own weight when supported only at its ends. Gravity gives it that shape. Flip it upside down, and it's a weight-bearing structure with only compression forces. In Gaudí's time it was used only in the construction of suspension bridges; Gaudí was the first to use it in common architecture. He would attach a drawing of the building floor plan to a ceiling, from which he would attach strings (representing columns, arches, walls and vaults) with bags of birdshot (for the weight of small building parts). He would then take a picture that, when inverted, showed the structure for columns and arches that he was looking for. Using this technique, Gaudí arrived at the revolutionary idea of using inclined columns that subsequently branched out like trees. The leaning columns better resist the perpendicular pressure that they experience, and the branches support a structure of intertwined hyperboloid vaults. Space is divided into small, independent and self-supporting modules without needing the buttresses required with the neo-Gothic style. Further, the hyperboloid vaults have an empty center, allowing natural light to enter, in contrast to Gothic vaults with their keystones that resulted in closed, dark cathedrals. Where Gothic vaults have ribs, the hyperboloid design allows the intersection between vaults to have holes, which Gaudí employed to give the impression of a starry sky. Further, Gaudí conceived the branching columns of the church to have not only a structural function but to represent a forest, a natural temple that invites prayer; and like sunlight filtering through leaves, to create a space of magical lighting conducive to intimacy and meditation. Isn't that picture on the left gorgeous? Wait 'til you see the Gaudí interior!
One last architectural point. To achieve greater stability and a slender and more harmonious effect, Gaudí designed all the branching columns to have a double-turn helicoidal shape (right turn and left turn) similar to those in the branches and trunks of
trees. The base of each column has a cross-section that is a polygon or star which, as it twists to the right and left, transforms into a circle higher up. Depending on the position of the column in the basilica and the weight load, the columns have different cross sections, as shown schematically in the last two pictures above.
OK, after talking about Gaudí and the bones of Sagrada Família, maybe now you want to actually see it? And I want to show it! But first let me give you the overview of this complex basilica. The Sagrada Família could be used to give a crash course on the Catholic religion, given the wealth of Christian symbols that Gaudí placed on the facades.
First of all, just look at the model to the left, and be amazed. That's a church? At this scale it almost looks like a Disney fairyland castle run amok. However, up close, surrounded by the cathedral's details, the structure is overwhelmingly, undeniably religious.
The basilica has three monumental entrances, each one representing one of the three crucial events of Christ's existence: his birth (Nativity facade); his Passion, Death and Resurrection (facing us in this picture); and his present and future Glory (facing to the right in this picture). The Sagrada has 18 towers, each with a special significance. The middle tower is dedicated to Jesus Christ; around it are four towers representing the Gospels. The tower above the apse, crowned by a star, represents the Virgin Mary, while the remaining 12 towers – 4 over each entrance – represent the Apostles. Christian symbols, as well as Modernista nods to nature, are present everywhere on and in the basilica, too numerous to mention but including the main symbols of the Old Testament.
We'll start at the current entrance and the oldest facade, the Nativity, begun in 1892 (when the Sagrada is finished, this will be a side entrance). This facade faces the rising sun, symbolic of the birth, life, and light of Jesus. It's decorated in a style I would call
"too busy". The facade's decoration includes over 100 plant species and an equal number of animals (!). It attempts to communicate and celebrate man's journey from creation through the old testament, then Christ's birth and youth, and at the highest niche, visible in the last two pictures above, Christ triumphantly crowning Mary. Starting at the bottom of the Nativity facade – you might find it helpful to refer back to the right 2 pictures above – this facade has 3 separate entrances each nestled inside a grand parabola (or portico), each portico representing one of the theological virtues of Hope, Faith and Charity. Two massive columns flanking the central portico rest either on a turtle or a tortoise, representing dominion over land and sea. The central and largest portico, Charity, has fabulous bronze double doors inspired by nature, full of metal leaves, flowers and insects, as shown below; perhaps suggesting that you are about to enter Gaudí's reverential forest (of columns) mentioned earlier. Note that the statuary surrounding the doors (the Adoration
of the Magi and the Adoration of the Shepherds) practically includes you in it as you enter (details shown below). The scene in the middle above the doorway celebrates Jesus' birth and the "Sagrada Família" – the holy family of Mary, Joseph and baby Jesus in the
manger. Arrayed just above the Holy Family is a chorus of young angels with angel
musicians flanking them (and the star of Bethlehem atop a central pillar between the windows). Above the angel choir is a depiction of the Annunciation, with the Archangel Gabriel announcing to Mary that she will be the mother of the Son of God. Finally, much higher than all of these decorations and at the apex of the Charity portico's parabola is the beginning of a spire, the Tree of Life, which at its base opens out to form a large and commanding niche showing Jesus Christ crowning Mary as Queen of Heaven, as shown below. Interestingly, Joseph is present in this Coronation scene – an
unusual detail. The Tree of Life sweeps upward, pointing towards the heavens with many symbols of Christianity and with doves of peace nesting in its branches. Among the Christian symbols is the pelican, based on an ancient legend that it will pierce its own breast with its beak to feed blood to its hungry babies, a symbol of Christ sacrificing himself for man.
Some details of the Nativity facade's Hope and Faith portals are shown below.
There's more to this side of the Sagrada Família than just that ornate Nativity entrance, as shown in the first picture below. There's a looooong extension to the left, with a very different architecture! Here geometry won over ornate story telling; there's still religious symbolism, but basically the windows are simply amazing, with each vertical level wonderfully different. Windows on the first two levels, shown below, are relatively
conventional; the next level is simply awesome. In the first picture below, there's a lot going on – plant statuary on the triangular roofs, interesting spiral columns, alpha and omega symbols, statues of religious figures – but mostly there's a fascinating array of
windows formed by the intersection of hyperbolic planes, as shown in the pictures above. The window glass is planar, but the surrounding structures show all kinds of energetic angles! Those angles remind me of the flying planes formed by ejecta when a water droplet falls onto flat water, shown in the last picture above. For me, the window array is wonderfully exciting.
Windows at the highest level are equally fascinating and are also formed largely by the
intersection of hyperbolic planes. They are so cool! Look at the intersections at the bottom of those pictures where several windows converge! Love it!
The side of the Sagrada Família to the right of the Nativity facade (shown obliquely in the first picture below) has no grand entrance and generally has a more conventional Gothic-like architecture; however, there are a lot of very interesting and unusual details, like the huge animals that can be seen slithering half-way down the side of the building.
The pictures below show details of these man-sized animals.
There are also plants hanging out here and there.
The left side of the Nativity facade is – or will be – the main entrance, the Glory facade. It will be the largest and most striking of the facades. Alas, it's under major construction and not much to see now. Ultimately the facade will represent how the soul navigates Death and the Final Judgment, avoids the pitfalls of Hell, and finds the eternal glory of God. Expect the Seven Deadly Sins, the Seven Heavenly Virtues, demons, idols, purgatory, etc.
Opposite the Nativity facade is the Passion facade, addressing Christ's death and resurrection. And oh my, is it different! The Nativity facade was built first because, as Gaudí put it, "If, instead of building this decorated, richly ornamented (Nativity) facade, we had started with the hard, bare and skeletal Passion facade, people would have rejected it." The Passion facade's 4 spires were designed by Gaudí, as were the lower bone-like archways. Gaudí intended the facade to be grim and terrifying, but with his (few) original plans destroyed in the Spanish Civil War, trustees had to piece together what they perceived as Gaudí's vision. Not surprisingly, what's being done has been controversial (in 2008, more than 100 members of Barcelona's art and architecture community protested its direction). The overall appearance of the facade is stark – and
contemporary. Details of some sculptures are shown below. This side of the Sagrada is
sooooooooooo different from the Nativity facade! But absolutely arresting. A few more pictures of this side of the Sagrada are shown below. I should point out that whereas the
Sagrada gives the impression that it is mostly gray or tan stone, it does have some fascinating color decorations – often fanciful, and typically on its upper levels and spires –
as shown above.
That covers what we could see of this fascinating basilica from the outside. It's amazing, yes? Designed in the early 1900's but avant-garde even today. Gaudí was amazing. And really you haven't seen anything yet! The interior is the mouth-gaping OMG part. My intention was to also show off the Sagrada interior in this post, but due to my enthusiasm the post is already too looooong! So you'll have to wait to be blown away. The next post will be the Sagrada interior; the picture to the left is just a small taste of what's to come. Don't miss it!
I'll close with a few pictures of the Sagrada exterior at night.
Stay tuned for the Sagrada Família interior, next post!
This entry was posted in Barcelona, Spain.
← Barcelona IX: Art Museums
Barcelona XI: Interior of the Amazing Sagrada Família →


E-mail Bruce G. Lisser, P.L.S.
Bruce is the principal-in-charge of surveying projects for Lisser & Associates, and the owner of the firm. He has extensive experience in planning and land surveying, and is responsible for survey coordination, mapping preparation, and legal descriptions for property acquisition. Bruce obtained his Professional Land Surveying License in 1985.
E-mail Kevin G. Lisser, L.S.I.T.
Kevin has been employed in the land surveying profession for 11 years. His area of expertise with Lisser & Associates includes boundary surveying, preparation of land descriptions, and topographical and construction surveying. He's been with the firm since 2014.
Merry has been with Lisser & Associates since 1999. Her prior employment and numerous years in the banking industry established the excellent customer service we provide our clients.


text:
Remember when…? – Lights
My grandfather was a mechanics by trade, but he was also a tech guy of his times. He had a movie camera and he would love to do stop animation. Yes, I saw one of his movies he made when I turned 1, meaning, more than half a century ago!
I understand why many old "home" movies had people squint when they looked toward the person filming. I remember how my grandpa had that set up with 16 lights, 8 on each side of his camera. It must have been quite heavy to hold as it was attached to the camera and not on stands. Grandpa would go around and film here and there. Those lights were so bright that it was really hard to look toward him (not even just at him).
Hot lights
Of course, we knew he was coming as the bright lights would precede him, but even if we had our eye closed, we could feel the heat of those lights. They were far from the cooler lamps we have now. Whenever he would get close to us, we felt like a wood stove was moving toward us. We really felt it.
Lost films
Over the years, grandpa had made many many films of us, at various gathering (often at Christmas), and a dozen of stop animations. He would usually create intros for his film with moving letters. That is at least, what I remember of the film of my first birthday. Too bad, all those have been lost. We are not sure where they went, but we suspect they were thrown out to the garbage, years after he passed away. What a loss!
What was your first encounter with technology? Did you have relatives who were interested in the latest gadgets? Share your stories in the comments below.


IDEAL has important implications for everyone who is concerned about research into complex and invasive interventions.
Please select the section that is most relevant to you.
Is your area of interest not represented above?
IDEAL addresses complex and difficult issues, and we don't expect to have covered all perspectives at once. We want to hear from anyone who feels that their area of interest is not represented in the list above.
More generally, if you have any questions or comments about your area of expertise or personal experience in this area, we also want to hear from you.
Please use the feedback form at the foot of each of these pages.