mirror of
				https://github.com/elyby/accounts-frontend.git
				synced 2025-05-31 14:11:58 +05:30 
			
		
		
		
	Upgrade to intl@^3.0.0
This commit is contained in:
		@@ -17,3 +17,4 @@ module.file_ext=.jsx
 | 
			
		||||
module.file_ext=.css
 | 
			
		||||
module.file_ext=.scss
 | 
			
		||||
module.ignore_non_literal_requires=true
 | 
			
		||||
esproposal.optional_chaining=enable
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,8 @@ module.exports = {
 | 
			
		||||
        '@babel/plugin-syntax-dynamic-import',
 | 
			
		||||
        '@babel/plugin-proposal-function-bind',
 | 
			
		||||
        '@babel/plugin-proposal-class-properties',
 | 
			
		||||
        '@babel/plugin-proposal-optional-chaining',
 | 
			
		||||
        '@babel/plugin-proposal-nullish-coalescing-operator',
 | 
			
		||||
        [
 | 
			
		||||
            '@babel/plugin-transform-runtime',
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								flow-typed/npm/react-intl_v2.x.x.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								flow-typed/npm/react-intl_v2.x.x.js
									
									
									
									
										vendored
									
									
								
							@@ -42,7 +42,9 @@ declare module "react-intl" {
 | 
			
		||||
  declare type $npm$ReactIntl$IntlFormat = {
 | 
			
		||||
    formatDate: (value: any, options?: Object) => string,
 | 
			
		||||
    formatTime: (value: any, options?: Object) => string,
 | 
			
		||||
    formatRelative: (value: any, options?: Object) => string,
 | 
			
		||||
    formatRelativeTime: (value: number, options?: $npm$ReactIntl$RelativeFormatOptions & {
 | 
			
		||||
      format: string
 | 
			
		||||
    }) => string,
 | 
			
		||||
    formatNumber: (value: any, options?: Object) => string,
 | 
			
		||||
    formatPlural: (value: any, options?: Object) => string,
 | 
			
		||||
    formatMessage: (
 | 
			
		||||
@@ -77,8 +79,9 @@ declare module "react-intl" {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  declare type $npm$ReactIntl$RelativeFormatOptions = {
 | 
			
		||||
    style?: "best fit" | "numeric",
 | 
			
		||||
    units?: "second" | "minute" | "hour" | "day" | "month" | "year"
 | 
			
		||||
    numeric?: "auto" | "always",
 | 
			
		||||
    style?: "short" | "narrow" | "numeric",
 | 
			
		||||
    unit?: "second" | "minute" | "hour" | "day" | "month" | "year"
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  declare type $npm$ReactIntl$NumberFormatOptions = {
 | 
			
		||||
@@ -161,6 +164,15 @@ declare module "react-intl" {
 | 
			
		||||
    $Diff<React$ElementConfig<Component>, InjectIntlVoidProps>
 | 
			
		||||
  >;
 | 
			
		||||
 | 
			
		||||
  declare type IntlCache = any;
 | 
			
		||||
 | 
			
		||||
  declare function createIntlCache(): IntlCache;
 | 
			
		||||
 | 
			
		||||
  declare function createIntl(options: {
 | 
			
		||||
    locale: string,
 | 
			
		||||
    messages?: {[key: string]: string}
 | 
			
		||||
  }, cache?: IntlCache): IntlShape;
 | 
			
		||||
 | 
			
		||||
  declare function formatMessage(
 | 
			
		||||
    messageDescriptor: $npm$ReactIntl$MessageDescriptor,
 | 
			
		||||
    values?: Object
 | 
			
		||||
@@ -177,11 +189,10 @@ declare module "react-intl" {
 | 
			
		||||
    value: any,
 | 
			
		||||
    options?: $npm$ReactIntl$DateTimeFormatOptions & { format: string }
 | 
			
		||||
  ): string;
 | 
			
		||||
  declare function formatRelative(
 | 
			
		||||
    value: any,
 | 
			
		||||
  declare function formatRelativeTime(
 | 
			
		||||
    value: number, // delta
 | 
			
		||||
    options?: $npm$ReactIntl$RelativeFormatOptions & {
 | 
			
		||||
      format: string,
 | 
			
		||||
      now: any
 | 
			
		||||
      format: string
 | 
			
		||||
    }
 | 
			
		||||
  ): string;
 | 
			
		||||
  declare function formatNumber(
 | 
			
		||||
@@ -223,12 +234,11 @@ declare module "react-intl" {
 | 
			
		||||
      children?: (formattedDate: string) => React$Node
 | 
			
		||||
    }
 | 
			
		||||
  > {}
 | 
			
		||||
  declare class FormattedRelative extends React$Component<
 | 
			
		||||
  declare class FormattedRelativeTime extends React$Component<
 | 
			
		||||
    $npm$ReactIntl$RelativeFormatOptions & {
 | 
			
		||||
      value: $npm$ReactIntl$DateParseable,
 | 
			
		||||
      value: number, // delta
 | 
			
		||||
      format?: string,
 | 
			
		||||
      updateInterval?: number,
 | 
			
		||||
      initialNow?: $npm$ReactIntl$DateParseable,
 | 
			
		||||
      updateIntervalInSeconds?: number,
 | 
			
		||||
      children?: (formattedDate: string) => React$Node
 | 
			
		||||
    }
 | 
			
		||||
  > {}
 | 
			
		||||
@@ -257,6 +267,12 @@ declare module "react-intl" {
 | 
			
		||||
      initialNow?: $npm$ReactIntl$DateParseable
 | 
			
		||||
    }
 | 
			
		||||
  > {}
 | 
			
		||||
  declare class RawIntlProvider extends React$Component<
 | 
			
		||||
    {|
 | 
			
		||||
      children?: React$Node,
 | 
			
		||||
      value?: IntlShape
 | 
			
		||||
    |}
 | 
			
		||||
  > {}
 | 
			
		||||
  declare type IntlShape = $npm$ReactIntl$IntlShape;
 | 
			
		||||
  declare type MessageDescriptor = $npm$ReactIntl$MessageDescriptor;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							@@ -39,9 +39,12 @@
 | 
			
		||||
    "build:install": "yarn install",
 | 
			
		||||
    "build:webpack": "NODE_PATH=./src webpack --colors -p --bail",
 | 
			
		||||
    "build:quiet": "yarn run clean && yarn run build:webpack --quiet",
 | 
			
		||||
    "build:dll": "node ./scripts/build-dll.js"
 | 
			
		||||
    "build:dll": "node ./scripts/build-dll.js",
 | 
			
		||||
    "build:serve": "http-server --proxy https://dev.account.ely.by ./dist"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@formatjs/intl-pluralrules": "^1.3.2",
 | 
			
		||||
    "@formatjs/intl-relativetimeformat": "^4.4.1",
 | 
			
		||||
    "@hot-loader/react-dom": "^16.11.0",
 | 
			
		||||
    "classnames": "^2.2.6",
 | 
			
		||||
    "copy-to-clipboard": "^3.0.8",
 | 
			
		||||
@@ -56,7 +59,7 @@
 | 
			
		||||
    "react-dom": "^16.11.0",
 | 
			
		||||
    "react-helmet": "^5.0.0",
 | 
			
		||||
    "react-hot-loader": "^4.12.16",
 | 
			
		||||
    "react-intl": "^2.7.2",
 | 
			
		||||
    "react-intl": "^3.4.0",
 | 
			
		||||
    "react-motion": "^0.5.0",
 | 
			
		||||
    "react-redux": "^7.1.3",
 | 
			
		||||
    "react-router-dom": "^5.1.2",
 | 
			
		||||
@@ -82,7 +85,7 @@
 | 
			
		||||
    "@babel/plugin-proposal-function-sent": "^7.7.0",
 | 
			
		||||
    "@babel/plugin-proposal-json-strings": "^7.0.0",
 | 
			
		||||
    "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
 | 
			
		||||
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
 | 
			
		||||
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4",
 | 
			
		||||
    "@babel/plugin-proposal-numeric-separator": "^7.0.0",
 | 
			
		||||
    "@babel/plugin-proposal-optional-chaining": "^7.6.0",
 | 
			
		||||
    "@babel/plugin-proposal-pipeline-operator": "^7.5.0",
 | 
			
		||||
@@ -96,7 +99,7 @@
 | 
			
		||||
    "@babel/runtime-corejs3": "^7.7.2",
 | 
			
		||||
    "babel-eslint": "^10.0.3",
 | 
			
		||||
    "babel-loader": "^8.0.0",
 | 
			
		||||
    "babel-plugin-react-intl": "^2.0.0",
 | 
			
		||||
    "babel-plugin-react-intl": "^5.1.1",
 | 
			
		||||
    "core-js": "3.4.0",
 | 
			
		||||
    "csp-webpack-plugin": "^2.0.2",
 | 
			
		||||
    "css-loader": "^3.2.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,32 @@
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
// @flow
 | 
			
		||||
import type { Node } from 'react';
 | 
			
		||||
import type { IntlShape } from 'react-intl';
 | 
			
		||||
import React, { useState, useEffect } from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { RawIntlProvider } from 'react-intl';
 | 
			
		||||
import i18n from 'services/i18n';
 | 
			
		||||
 | 
			
		||||
import { IntlProvider as OrigIntlProvider } from 'react-intl';
 | 
			
		||||
type OwnProps = {|
 | 
			
		||||
  children: Node
 | 
			
		||||
|};
 | 
			
		||||
 | 
			
		||||
class IntlProvider extends Component {
 | 
			
		||||
    static displayName = 'IntlProvider';
 | 
			
		||||
    static propTypes = {
 | 
			
		||||
        locale: PropTypes.string,
 | 
			
		||||
        messages: PropTypes.objectOf(PropTypes.string),
 | 
			
		||||
        children: PropTypes.element
 | 
			
		||||
    };
 | 
			
		||||
type Props = {
 | 
			
		||||
  ...OwnProps,
 | 
			
		||||
  locale: string
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        return (
 | 
			
		||||
            <OrigIntlProvider locale="en" {...this.props} />
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
function IntlProvider({ children, locale }: Props) {
 | 
			
		||||
    const [intl, setIntl] = useState<IntlShape>(i18n.getIntl());
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        (async () => {
 | 
			
		||||
            setIntl(await i18n.changeLocale(locale));
 | 
			
		||||
        })();
 | 
			
		||||
    }, [locale]);
 | 
			
		||||
 | 
			
		||||
    return <RawIntlProvider value={intl}>{children}</RawIntlProvider>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
 | 
			
		||||
export default connect(({i18n}) => i18n)(IntlProvider);
 | 
			
		||||
export default connect<Props, OwnProps, _, _, _, _>(({ i18n }) => i18n)(
 | 
			
		||||
    IntlProvider
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,22 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import i18n from 'services/i18n';
 | 
			
		||||
import captcha from 'services/captcha';
 | 
			
		||||
 | 
			
		||||
export const SET_LOCALE = 'i18n:setLocale';
 | 
			
		||||
export function setLocale(desiredLocale: string) {
 | 
			
		||||
    return async (dispatch: (action: Object) => any) => {
 | 
			
		||||
        const { locale, messages } = await i18n.require(i18n.detectLanguage(desiredLocale));
 | 
			
		||||
        dispatch(_setLocale(locale, messages));
 | 
			
		||||
    return async (dispatch: (action: Object) => any): Promise<string> => {
 | 
			
		||||
        const locale = i18n.detectLanguage(desiredLocale);
 | 
			
		||||
 | 
			
		||||
        // TODO: probably should be moved from here, because it is a side effect
 | 
			
		||||
        captcha.setLang(locale);
 | 
			
		||||
        dispatch(_setLocale(locale));
 | 
			
		||||
 | 
			
		||||
        return locale;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _setLocale(locale: string, messages: { [string]: string }) {
 | 
			
		||||
function _setLocale(locale: string) {
 | 
			
		||||
    return {
 | 
			
		||||
        type: SET_LOCALE,
 | 
			
		||||
        payload: {
 | 
			
		||||
            locale,
 | 
			
		||||
            messages,
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,18 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import i18n from 'services/i18n';
 | 
			
		||||
 | 
			
		||||
import { SET_LOCALE } from './actions';
 | 
			
		||||
 | 
			
		||||
export default function(state = {}, {type, payload}) {
 | 
			
		||||
type State = { locale: string };
 | 
			
		||||
 | 
			
		||||
const defaultState = {
 | 
			
		||||
    locale: i18n.detectLanguage()
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default function(
 | 
			
		||||
    state: State = defaultState,
 | 
			
		||||
    { type, payload }: { type: string, payload: State }
 | 
			
		||||
): State {
 | 
			
		||||
    if (type === SET_LOCALE) {
 | 
			
		||||
        return payload;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import type { IntlShape } from 'react-intl';
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
import { FormattedMessage as Message, intlShape } from 'react-intl';
 | 
			
		||||
import { FormattedMessage as Message, injectIntl } from 'react-intl';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { changeLang } from 'components/user/actions';
 | 
			
		||||
@@ -36,6 +37,7 @@ type OwnProps = {|
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    ...OwnProps,
 | 
			
		||||
    intl: IntlShape,
 | 
			
		||||
    selectedLocale: string,
 | 
			
		||||
    changeLang: (lang: string) => void,
 | 
			
		||||
};
 | 
			
		||||
@@ -44,10 +46,6 @@ class LanguageSwitcher extends Component<Props, {
 | 
			
		||||
    filter: string,
 | 
			
		||||
    filteredLangs: LocalesMap,
 | 
			
		||||
}> {
 | 
			
		||||
    static contextTypes = {
 | 
			
		||||
        intl: intlShape,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    state = {
 | 
			
		||||
        filter: '',
 | 
			
		||||
        filteredLangs: this.props.langs,
 | 
			
		||||
@@ -59,7 +57,7 @@ class LanguageSwitcher extends Component<Props, {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        const { selectedLocale, onClose } = this.props;
 | 
			
		||||
        const { selectedLocale, onClose, intl } = this.props;
 | 
			
		||||
        const { filteredLangs } = this.state;
 | 
			
		||||
 | 
			
		||||
        return (
 | 
			
		||||
@@ -79,7 +77,7 @@ class LanguageSwitcher extends Component<Props, {
 | 
			
		||||
                                    formStyles.lightTextField,
 | 
			
		||||
                                    formStyles.greenTextField,
 | 
			
		||||
                                )}
 | 
			
		||||
                                placeholder={this.context.intl.formatMessage(messages.startTyping)}
 | 
			
		||||
                                placeholder={intl.formatMessage(messages.startTyping)}
 | 
			
		||||
                                onChange={this.onFilterUpdate}
 | 
			
		||||
                                onKeyPress={this.onFilterKeyPress()}
 | 
			
		||||
                                autoFocus
 | 
			
		||||
@@ -161,8 +159,10 @@ class LanguageSwitcher extends Component<Props, {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect<Props, OwnProps, _, _, _, _>((state) => ({
 | 
			
		||||
    selectedLocale: state.i18n.locale,
 | 
			
		||||
}), {
 | 
			
		||||
    changeLang,
 | 
			
		||||
})(LanguageSwitcher);
 | 
			
		||||
export default injectIntl(
 | 
			
		||||
    connect<Props, OwnProps, _, _, _, _>((state) => ({
 | 
			
		||||
        selectedLocale: state.i18n.locale,
 | 
			
		||||
    }), {
 | 
			
		||||
        changeLang,
 | 
			
		||||
    })(LanguageSwitcher)
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,12 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import { FormattedMessage as Message, FormattedRelative as Relative } from 'react-intl';
 | 
			
		||||
import { FormattedMessage as Message } from 'react-intl';
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
import Helmet from 'react-helmet';
 | 
			
		||||
import { ChangeLanguageLink } from 'components/languageSwitcher';
 | 
			
		||||
import { RelativeTime } from 'components/ui';
 | 
			
		||||
 | 
			
		||||
import ProfileField from './ProfileField';
 | 
			
		||||
import styles from './profile.scss';
 | 
			
		||||
import profileForm from './profileForm.scss';
 | 
			
		||||
@@ -85,7 +87,7 @@ class Profile extends Component<Props> {
 | 
			
		||||
                                link="/profile/change-password"
 | 
			
		||||
                                label={<Message {...messages.password} />}
 | 
			
		||||
                                value={<Message {...messages.changedAt} values={{
 | 
			
		||||
                                    at: (<Relative value={user.passwordChangedAt * 1000} updateInterval={1000} />)
 | 
			
		||||
                                    at: (<RelativeTime timestamp={user.passwordChangedAt * 1000} />),
 | 
			
		||||
                                }} />}
 | 
			
		||||
                            />
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								src/components/ui/RelativeTime.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/components/ui/RelativeTime.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { FormattedRelativeTime } from 'react-intl';
 | 
			
		||||
import { selectUnit } from '@formatjs/intl-utils';
 | 
			
		||||
 | 
			
		||||
function RelativeTime({timestamp}: {timestamp: number}) {
 | 
			
		||||
    const {unit, value}: {unit: any, value: number} = selectUnit(timestamp);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <FormattedRelativeTime
 | 
			
		||||
            value={value}
 | 
			
		||||
            unit={unit}
 | 
			
		||||
            numeric="auto"
 | 
			
		||||
            updateIntervalInSeconds={['seconds', 'minute', 'hour'].includes(unit) ? 1 : undefined}
 | 
			
		||||
        />
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default RelativeTime;
 | 
			
		||||
@@ -1,13 +1,10 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import type { MessageDescriptor } from 'react-intl';
 | 
			
		||||
import type { Element } from 'react';
 | 
			
		||||
import { Component } from 'react';
 | 
			
		||||
import { intlShape } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
export default class FormComponent<P, S = void> extends Component<P, S> {
 | 
			
		||||
    static contextTypes = {
 | 
			
		||||
        intl: intlShape,
 | 
			
		||||
    };
 | 
			
		||||
import i18n from 'services/i18n';
 | 
			
		||||
 | 
			
		||||
class FormComponent<P, S = void> extends Component<P, S> {
 | 
			
		||||
    /**
 | 
			
		||||
     * Formats message resolving intl translations
 | 
			
		||||
     *
 | 
			
		||||
@@ -15,16 +12,16 @@ export default class FormComponent<P, S = void> extends Component<P, S> {
 | 
			
		||||
     *
 | 
			
		||||
     * @return {string}
 | 
			
		||||
     */
 | 
			
		||||
    formatMessage(message: string | MessageDescriptor): string {
 | 
			
		||||
        if (message && message.id) {
 | 
			
		||||
            if (this.context && this.context.intl) {
 | 
			
		||||
                message = this.context.intl.formatMessage(message);
 | 
			
		||||
            } else {
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
    formatMessage(message: string | MessageDescriptor | Element<any>): string | Element<any> {
 | 
			
		||||
        if (typeof message === 'string') {
 | 
			
		||||
            return message;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ((message: any): string);
 | 
			
		||||
        if (message && message.id) {
 | 
			
		||||
            return i18n.getIntl().formatMessage(message);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ((message: any): Element<any>);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -40,3 +37,5 @@ export default class FormComponent<P, S = void> extends Component<P, S> {
 | 
			
		||||
    onFormInvalid() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default FormComponent;
 | 
			
		||||
 
 | 
			
		||||
@@ -37,3 +37,5 @@ export const SKIN_DARK: Skin = 'dark';
 | 
			
		||||
export const SKIN_LIGHT: Skin = 'light';
 | 
			
		||||
 | 
			
		||||
export const skins: Array<Skin> = [SKIN_DARK, SKIN_LIGHT];
 | 
			
		||||
 | 
			
		||||
export {default as RelativeTime} from './RelativeTime';
 | 
			
		||||
 
 | 
			
		||||
@@ -40,13 +40,16 @@ export function setUser(payload: $Shape<User>) {
 | 
			
		||||
export const CHANGE_LANG = 'USER_CHANGE_LANG';
 | 
			
		||||
export function changeLang(lang: string) {
 | 
			
		||||
    return (dispatch: Dispatch, getState: () => State) => dispatch(setLocale(lang))
 | 
			
		||||
        .then((lang) => {
 | 
			
		||||
        .then((lang: string) => {
 | 
			
		||||
            const { id, isGuest, lang: oldLang } = getState().user;
 | 
			
		||||
 | 
			
		||||
            if (oldLang === lang) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            !isGuest && changeLangEndpoint(((id: any): number), lang); // hack to tell Flow that it's defined
 | 
			
		||||
            if (!isGuest && id) {
 | 
			
		||||
                changeLangEndpoint(id, lang);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            dispatch({
 | 
			
		||||
                type: CHANGE_LANG,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import loader from 'services/loader';
 | 
			
		||||
import logger from 'services/logger';
 | 
			
		||||
import font from 'services/font';
 | 
			
		||||
import history, { browserHistory } from 'services/history';
 | 
			
		||||
import i18n from 'services/i18n';
 | 
			
		||||
import { loadScript, debounce } from 'functions';
 | 
			
		||||
 | 
			
		||||
import App from './App';
 | 
			
		||||
@@ -28,7 +29,8 @@ authFlow.setStore(store);
 | 
			
		||||
 | 
			
		||||
Promise.all([
 | 
			
		||||
    userFactory(store),
 | 
			
		||||
    font.load(['Roboto', 'Roboto Condensed'])
 | 
			
		||||
    font.load(['Roboto', 'Roboto Condensed']),
 | 
			
		||||
    i18n.ensureIntl(), // ensure, that intl is polyfilled before any rendering
 | 
			
		||||
]).then(() => {
 | 
			
		||||
    ReactDOM.render(
 | 
			
		||||
        <App store={store} browserHistory={browserHistory} />,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
import { FormattedMessage as Message, FormattedRelative as Relative } from 'react-intl';
 | 
			
		||||
import { FormattedMessage as Message } from 'react-intl';
 | 
			
		||||
import { RelativeTime } from 'components/ui';
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import messages from './errorsDict.intl.json';
 | 
			
		||||
@@ -76,7 +77,7 @@ const errorsMap = {
 | 
			
		||||
    'error.recently_sent_message': (props) => (
 | 
			
		||||
        <Message {...messages.emailFrequency} values={{
 | 
			
		||||
            // for msLeft @see AuthError.jsx
 | 
			
		||||
            time: <Relative value={props.msLeft} updateInterval={1000} />
 | 
			
		||||
            time: <RelativeTime value={props.msLeft} />
 | 
			
		||||
        }} />
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import locales from 'i18n/index.json';
 | 
			
		||||
 | 
			
		||||
import { addLocaleData } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
const SUPPORTED_LANGUAGES = Object.keys(locales);
 | 
			
		||||
const DEFAULT_LANGUAGE = 'en';
 | 
			
		||||
 | 
			
		||||
const needPolyfill = !window.Intl;
 | 
			
		||||
 | 
			
		||||
function getUserLanguages(userSelectedLang: string): Array<string> {
 | 
			
		||||
    return [userSelectedLang]
 | 
			
		||||
        .concat(navigator.languages || [])
 | 
			
		||||
        .concat(navigator.language || []);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function detectLanguage(
 | 
			
		||||
    userLanguages: Array<string>,
 | 
			
		||||
    availableLanguages: Array<string>,
 | 
			
		||||
    defaultLanguage: string,
 | 
			
		||||
): string {
 | 
			
		||||
    return userLanguages
 | 
			
		||||
        .map((lang) => lang.split('-').shift().toLowerCase())
 | 
			
		||||
        .find((lang) => availableLanguages.indexOf(lang) !== -1) || defaultLanguage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    detectLanguage(lang: string): string {
 | 
			
		||||
        return detectLanguage(getUserLanguages(lang), SUPPORTED_LANGUAGES, DEFAULT_LANGUAGE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    require(locale: string): Promise<{
 | 
			
		||||
        locale: string;
 | 
			
		||||
        messages: { [string]: string };
 | 
			
		||||
    }> {
 | 
			
		||||
        const promises: Array<Promise<any>> = [
 | 
			
		||||
            import(/* webpackChunkName: "locale-[request]" */`react-intl/locale-data/${locale}.js`),
 | 
			
		||||
            import(/* webpackChunkName: "locale-[request]" */`i18n/${locale}.json`),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        if (needPolyfill) {
 | 
			
		||||
            promises.push(import(/* webpackChunkName: "intl-polyfill" */'intl'));
 | 
			
		||||
            promises.push(import(/* webpackChunkName: "intl-polyfill-[request]" */`intl/locale-data/jsonp/${locale}.js`));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Promise.all(promises)
 | 
			
		||||
            .then(([localeData, {default: messages}]) => {
 | 
			
		||||
                addLocaleData(localeData);
 | 
			
		||||
 | 
			
		||||
                return {locale, messages};
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										85
									
								
								src/services/i18n/i18n.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/services/i18n/i18n.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
// @flow
 | 
			
		||||
import type {IntlShape} from 'react-intl';
 | 
			
		||||
import {createIntl, createIntlCache} from 'react-intl';
 | 
			
		||||
import captcha from 'services/captcha';
 | 
			
		||||
import locales from 'i18n/index.json';
 | 
			
		||||
 | 
			
		||||
import intlPolyfill from './intlPolyfill';
 | 
			
		||||
 | 
			
		||||
const SUPPORTED_LANGUAGES = Object.keys(locales);
 | 
			
		||||
const DEFAULT_LANGUAGE = 'en';
 | 
			
		||||
 | 
			
		||||
function getBrowserPreferredLanguages(): string[] {
 | 
			
		||||
    return []
 | 
			
		||||
        .concat(navigator.languages || [])
 | 
			
		||||
        .concat(navigator.language || []);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function detectLanguage(
 | 
			
		||||
    userLanguages: string[],
 | 
			
		||||
    availableLanguages: string[],
 | 
			
		||||
    defaultLanguage: string,
 | 
			
		||||
): string {
 | 
			
		||||
    return userLanguages
 | 
			
		||||
        .map((lang) => lang.split('-').shift().toLowerCase())
 | 
			
		||||
        .find((lang) => availableLanguages.indexOf(lang) !== -1) || defaultLanguage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const cache = createIntlCache();
 | 
			
		||||
 | 
			
		||||
let intl: IntlShape;
 | 
			
		||||
 | 
			
		||||
class I18N {
 | 
			
		||||
    detectLanguage(lang: string): string {
 | 
			
		||||
        return detectLanguage(
 | 
			
		||||
            [lang].concat(getBrowserPreferredLanguages()).filter((item) => !!item),
 | 
			
		||||
            SUPPORTED_LANGUAGES,
 | 
			
		||||
            DEFAULT_LANGUAGE
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getIntl(): IntlShape {
 | 
			
		||||
        if (!intl) {
 | 
			
		||||
            intl = createIntl({
 | 
			
		||||
                locale: 'en',
 | 
			
		||||
                messages: {}
 | 
			
		||||
            }, cache);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return intl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async changeLocale(locale: string = DEFAULT_LANGUAGE): Promise<IntlShape> {
 | 
			
		||||
        const { messages } = await this.require(locale);
 | 
			
		||||
 | 
			
		||||
        captcha.setLang(locale);
 | 
			
		||||
 | 
			
		||||
        intl = createIntl({
 | 
			
		||||
            locale,
 | 
			
		||||
            messages
 | 
			
		||||
        }, cache);
 | 
			
		||||
 | 
			
		||||
        return intl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async ensureIntl() {
 | 
			
		||||
        await intlPolyfill('en');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async require(locale: string): Promise<{
 | 
			
		||||
        locale: string;
 | 
			
		||||
        messages: { [string]: string };
 | 
			
		||||
    }> {
 | 
			
		||||
        const [{default: messages}] = await Promise.all([
 | 
			
		||||
            import(/* webpackChunkName: "locale-[request]" */`i18n/${locale}.json`),
 | 
			
		||||
            intlPolyfill(locale)
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            locale,
 | 
			
		||||
            messages
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new I18N();
 | 
			
		||||
							
								
								
									
										2
									
								
								src/services/i18n/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/services/i18n/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
// @flow
 | 
			
		||||
export { default } from './i18n';
 | 
			
		||||
							
								
								
									
										100
									
								
								src/services/i18n/intlPolyfill.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/services/i18n/intlPolyfill.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
 | 
			
		||||
// @flow
 | 
			
		||||
import logger from 'services/logger';
 | 
			
		||||
 | 
			
		||||
const needs = {
 | 
			
		||||
    intl: !window.Intl,
 | 
			
		||||
    plural: !window?.Intl?.PluralRules,
 | 
			
		||||
    relative: !window?.Intl?.RelativeTimeFormat
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * All modern browsers currently do support all required Intl APIs,
 | 
			
		||||
 * for the outdated browsers we will polyfill this api on demand
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
async function polyfill(locale: string): Promise<void> {
 | 
			
		||||
    const promises = [];
 | 
			
		||||
 | 
			
		||||
    if (!needs.intl
 | 
			
		||||
      && Intl.DateTimeFormat.supportedLocalesOf([locale]).length === 0
 | 
			
		||||
    ) {
 | 
			
		||||
        // fallback to polyfill in case, when browser does not support locale we need
 | 
			
		||||
        needs.intl = true;
 | 
			
		||||
        needs.plural = true;
 | 
			
		||||
        needs.relative = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (needs.intl) {
 | 
			
		||||
        promises.push(polyfillIntl(locale));
 | 
			
		||||
    } else {
 | 
			
		||||
        if (needs.plural) {
 | 
			
		||||
            promises.push(polyfillPlural(locale));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (needs.relative) {
 | 
			
		||||
            promises.push(polyfillRelative(locale));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        await Promise.all(promises);
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        logger.warn('Error loading intl polyfills', {
 | 
			
		||||
            error
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function polyfillIntl(locale: string): Promise<void> {
 | 
			
		||||
    // do not rely on tests provided by polyfill implementation
 | 
			
		||||
    // forcibly apply polyfill, because if this function was called
 | 
			
		||||
    // this means that browser does not support some of locales
 | 
			
		||||
    const {default: Intl} = await import(
 | 
			
		||||
        /* webpackChunkName: "intl" */
 | 
			
		||||
        'intl'
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    window.Intl = Intl;
 | 
			
		||||
 | 
			
		||||
    // MUST be loaded in series with the main polyfill
 | 
			
		||||
    await Promise.all([
 | 
			
		||||
        import(
 | 
			
		||||
            // WARNING: .js extension is required for proper function of ContextReplacementPlugin
 | 
			
		||||
            /* webpackChunkName: "intl-[request]" */
 | 
			
		||||
            `intl/locale-data/jsonp/${locale}.js`
 | 
			
		||||
        ),
 | 
			
		||||
        polyfillPlural(locale),
 | 
			
		||||
        polyfillRelative(locale),
 | 
			
		||||
    ]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function polyfillPlural(locale: string): Promise<void> {
 | 
			
		||||
    await import(
 | 
			
		||||
        /* webpackChunkName: "intl-pluralrules" */
 | 
			
		||||
        '@formatjs/intl-pluralrules/polyfill'
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // MUST be loaded in series with the main polyfill
 | 
			
		||||
    await import(
 | 
			
		||||
        // WARNING: .js extension is required for proper function of ContextReplacementPlugin
 | 
			
		||||
        /* webpackChunkName: "intl-pluralrules-[request]" */
 | 
			
		||||
        `@formatjs/intl-pluralrules/dist/locale-data/${locale}.js`
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function polyfillRelative(locale: string): Promise<void> {
 | 
			
		||||
    await import(
 | 
			
		||||
        /* webpackChunkName: "intl-relativetimeformat" */
 | 
			
		||||
        '@formatjs/intl-relativetimeformat/polyfill'
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // MUST be loaded in series with the main polyfill
 | 
			
		||||
    await import(
 | 
			
		||||
        // WARNING: .js extension is required for proper function of ContextReplacementPlugin
 | 
			
		||||
        /* webpackChunkName: "intl-relativetimeformat-[request]" */
 | 
			
		||||
        `@formatjs/intl-relativetimeformat/dist/locale-data/${locale}.js`
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default polyfill;
 | 
			
		||||
@@ -57,7 +57,7 @@ const webpackConfig = {
 | 
			
		||||
        modules: [rootPath, 'node_modules'],
 | 
			
		||||
        extensions: ['.js', '.jsx', '.json'],
 | 
			
		||||
        alias: {
 | 
			
		||||
            'react-dom': '@hot-loader/react-dom'
 | 
			
		||||
            'react-dom': isProduction ? 'react-dom' : '@hot-loader/react-dom'
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -137,10 +137,10 @@ const webpackConfig = {
 | 
			
		||||
            }
 | 
			
		||||
        ),
 | 
			
		||||
        // restrict webpack import context, to create chunks only for supported locales
 | 
			
		||||
        // @see services/i18n.js
 | 
			
		||||
        // @see services/i18n/intlPolyfill.js
 | 
			
		||||
        new webpack.ContextReplacementPlugin(
 | 
			
		||||
            /locale-data/,
 | 
			
		||||
            new RegExp(`/(${SUPPORTED_LANGUAGES.join('|')})\\.js`)
 | 
			
		||||
            new RegExp(`/(${SUPPORTED_LANGUAGES.join('|')})\\.js$`)
 | 
			
		||||
        ),
 | 
			
		||||
        // @see components/i18n/localeFlags.js
 | 
			
		||||
        new webpack.ContextReplacementPlugin(
 | 
			
		||||
@@ -264,7 +264,10 @@ if (isProduction) {
 | 
			
		||||
        splitChunks: {
 | 
			
		||||
            cacheGroups: {
 | 
			
		||||
                vendor: {
 | 
			
		||||
                    test: (m) => String(m.context).includes('node_modules') && !String(m.context).includes('flag-icon-css'),
 | 
			
		||||
                    test: (m) => String(m.context).includes('node_modules')
 | 
			
		||||
                      // icons and intl with relateed polyfills are allowed
 | 
			
		||||
                      // to be splitted to other chunks
 | 
			
		||||
                      && !/\/(flag-icon-css|intl|@formatjs)\//.test(String(m.context)),
 | 
			
		||||
                    name: 'vendors',
 | 
			
		||||
                    chunks: 'all',
 | 
			
		||||
                },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										234
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -32,7 +32,7 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/highlight" "^7.0.0"
 | 
			
		||||
 | 
			
		||||
"@babel/core@^7.7.2":
 | 
			
		||||
"@babel/core@^7.6.2", "@babel/core@^7.7.2":
 | 
			
		||||
  version "7.7.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91"
 | 
			
		||||
  integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==
 | 
			
		||||
@@ -374,16 +374,16 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489"
 | 
			
		||||
  integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==
 | 
			
		||||
 | 
			
		||||
"@babel/parser@^7.1.0", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2":
 | 
			
		||||
  version "7.7.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.3.tgz#5fad457c2529de476a248f75b0f090b3060af043"
 | 
			
		||||
  integrity sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==
 | 
			
		||||
 | 
			
		||||
"@babel/parser@^7.4.4", "@babel/parser@^7.4.5":
 | 
			
		||||
  version "7.4.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872"
 | 
			
		||||
  integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==
 | 
			
		||||
 | 
			
		||||
"@babel/parser@^7.7.0", "@babel/parser@^7.7.2":
 | 
			
		||||
  version "7.7.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.3.tgz#5fad457c2529de476a248f75b0f090b3060af043"
 | 
			
		||||
  integrity sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==
 | 
			
		||||
 | 
			
		||||
"@babel/plugin-proposal-async-generator-functions@^7.7.0":
 | 
			
		||||
  version "7.7.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.0.tgz#83ef2d6044496b4c15d8b4904e2219e6dccc6971"
 | 
			
		||||
@@ -475,7 +475,7 @@
 | 
			
		||||
    "@babel/helper-plugin-utils" "^7.0.0"
 | 
			
		||||
    "@babel/plugin-syntax-logical-assignment-operators" "^7.2.0"
 | 
			
		||||
 | 
			
		||||
"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0":
 | 
			
		||||
"@babel/plugin-proposal-nullish-coalescing-operator@^7.4.4":
 | 
			
		||||
  version "7.4.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz#41c360d59481d88e0ce3a3f837df10121a769b39"
 | 
			
		||||
  integrity sha512-Amph7Epui1Dh/xxUxS2+K22/MUi6+6JVTvy3P58tja3B6yKTSjwwx0/d83rF7551D6PVSSoplQb8GCwqec7HRw==
 | 
			
		||||
@@ -1177,6 +1177,15 @@
 | 
			
		||||
    lodash "^4.17.10"
 | 
			
		||||
    to-fast-properties "^2.0.0"
 | 
			
		||||
 | 
			
		||||
"@babel/types@^7.3.0", "@babel/types@^7.7.0", "@babel/types@^7.7.1", "@babel/types@^7.7.2":
 | 
			
		||||
  version "7.7.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7"
 | 
			
		||||
  integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    esutils "^2.0.2"
 | 
			
		||||
    lodash "^4.17.13"
 | 
			
		||||
    to-fast-properties "^2.0.0"
 | 
			
		||||
 | 
			
		||||
"@babel/types@^7.4.4":
 | 
			
		||||
  version "7.4.4"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
 | 
			
		||||
@@ -1186,15 +1195,6 @@
 | 
			
		||||
    lodash "^4.17.11"
 | 
			
		||||
    to-fast-properties "^2.0.0"
 | 
			
		||||
 | 
			
		||||
"@babel/types@^7.7.0", "@babel/types@^7.7.1", "@babel/types@^7.7.2":
 | 
			
		||||
  version "7.7.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7"
 | 
			
		||||
  integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    esutils "^2.0.2"
 | 
			
		||||
    lodash "^4.17.13"
 | 
			
		||||
    to-fast-properties "^2.0.0"
 | 
			
		||||
 | 
			
		||||
"@cypress/listr-verbose-renderer@0.4.1":
 | 
			
		||||
  version "0.4.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a"
 | 
			
		||||
@@ -1213,6 +1213,39 @@
 | 
			
		||||
    debug "^3.1.0"
 | 
			
		||||
    lodash.once "^4.1.1"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-pluralrules@^1.3.2":
 | 
			
		||||
  version "1.3.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-1.3.2.tgz#10b4d09526739d2146ef5e05c8540db3343862c7"
 | 
			
		||||
  integrity sha512-ZPHR7c4dEQ+7Y2pav2p55xfB8fbNMdr8iUqiH+T1FcXWDBE3ISlp/qU0fii97P4Co4dRXA6LCpfcdVcfQzzSmw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/intl-utils" "^1.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-relativetimeformat@^4.2.1":
 | 
			
		||||
  version "4.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-4.4.0.tgz#8de1d25457cd34531c87f3fa4c7d381606f010ed"
 | 
			
		||||
  integrity sha512-8lXOWWvoIPJR8Ak1uywE/gajBmHppfIg6a1o/fyd3t6NV7Qe+PVj7SJ5SgyRUcK3xQVA6AXpDJ7LCyjo5iOD8g==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/intl-utils" "^1.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-relativetimeformat@^4.4.1":
 | 
			
		||||
  version "4.4.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-4.4.1.tgz#2277daba93462781d126abfe071f3aa66c247a19"
 | 
			
		||||
  integrity sha512-VOc/uvZy1qmw7ssBMumNdinDg3Hvzbvmiqaaz8SMr+znYXd1D6Ogd2JsaskSrr3/bJOscEN5W4wNHFl1McfffQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/intl-utils" "^1.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-unified-numberformat@^2.1.0":
 | 
			
		||||
  version "2.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-2.1.0.tgz#0b8ef3bc3ebbafb40a65f09606a3fc414f1a392a"
 | 
			
		||||
  integrity sha512-0zL5DKRe4KiaupyiwT8ckTmE1aPlb2fsR0deMGN4QVlkdCxsCDMrLykrLyrhBa9fthTDaGR4Qh+bALk/sa4Vcg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/intl-utils" "^1.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-utils@^1.4.0":
 | 
			
		||||
  version "1.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-1.4.0.tgz#b59fdf78bbae9f99c500a298bf73b1945f5991f1"
 | 
			
		||||
  integrity sha512-z5HyJumGzORM+5SpvkAlp/hu0AHDeZcUNKSmj9NjS7kWxOGZMuAdS3X1K5XiE0j5I8r8s8SIaz0IQOdMA1WFeA==
 | 
			
		||||
 | 
			
		||||
"@hot-loader/react-dom@^16.11.0":
 | 
			
		||||
  version "16.11.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.11.0.tgz#c0b483923b289db5431516f56ee2a69448ebf9bd"
 | 
			
		||||
@@ -1268,6 +1301,39 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
 | 
			
		||||
  integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
 | 
			
		||||
 | 
			
		||||
"@types/babel__core@^7.1.2":
 | 
			
		||||
  version "7.1.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30"
 | 
			
		||||
  integrity sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/parser" "^7.1.0"
 | 
			
		||||
    "@babel/types" "^7.0.0"
 | 
			
		||||
    "@types/babel__generator" "*"
 | 
			
		||||
    "@types/babel__template" "*"
 | 
			
		||||
    "@types/babel__traverse" "*"
 | 
			
		||||
 | 
			
		||||
"@types/babel__generator@*":
 | 
			
		||||
  version "7.6.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.0.tgz#f1ec1c104d1bb463556ecb724018ab788d0c172a"
 | 
			
		||||
  integrity sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/types" "^7.0.0"
 | 
			
		||||
 | 
			
		||||
"@types/babel__template@*":
 | 
			
		||||
  version "7.0.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307"
 | 
			
		||||
  integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/parser" "^7.1.0"
 | 
			
		||||
    "@babel/types" "^7.0.0"
 | 
			
		||||
 | 
			
		||||
"@types/babel__traverse@*":
 | 
			
		||||
  version "7.0.7"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.7.tgz#2496e9ff56196cc1429c72034e07eab6121b6f3f"
 | 
			
		||||
  integrity sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/types" "^7.3.0"
 | 
			
		||||
 | 
			
		||||
"@types/events@*":
 | 
			
		||||
  version "3.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
 | 
			
		||||
@@ -1282,6 +1348,19 @@
 | 
			
		||||
    "@types/minimatch" "*"
 | 
			
		||||
    "@types/node" "*"
 | 
			
		||||
 | 
			
		||||
"@types/hoist-non-react-statics@^3.3.1":
 | 
			
		||||
  version "3.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
 | 
			
		||||
  integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/react" "*"
 | 
			
		||||
    hoist-non-react-statics "^3.3.0"
 | 
			
		||||
 | 
			
		||||
"@types/invariant@^2.2.30":
 | 
			
		||||
  version "2.2.30"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.30.tgz#20efa342807606ada5483731a8137cb1561e5fe9"
 | 
			
		||||
  integrity sha512-98fB+yo7imSD2F7PF7GIpELNgtLNgo5wjivu0W5V4jx+KVVJxo6p/qN4zdzSTBWy4/sN3pPyXwnhRSD28QX+ag==
 | 
			
		||||
 | 
			
		||||
"@types/minimatch@*":
 | 
			
		||||
  version "3.0.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
 | 
			
		||||
@@ -1302,7 +1381,7 @@
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
 | 
			
		||||
  integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
 | 
			
		||||
 | 
			
		||||
"@types/react@^15.0.0 || ^16.0.0":
 | 
			
		||||
"@types/react@*", "@types/react@^15.0.0 || ^16.0.0":
 | 
			
		||||
  version "16.9.11"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.11.tgz#70e0b7ad79058a7842f25ccf2999807076ada120"
 | 
			
		||||
  integrity sha512-UBT4GZ3PokTXSWmdgC/GeCGEJXE5ofWyibCcecRLUVN2ZBpXQGVgQGtG2foS7CrTKFKlQVVswLvf7Js6XA/CVQ==
 | 
			
		||||
@@ -1310,6 +1389,11 @@
 | 
			
		||||
    "@types/prop-types" "*"
 | 
			
		||||
    csstype "^2.2.0"
 | 
			
		||||
 | 
			
		||||
"@types/schema-utils@^1.0.0":
 | 
			
		||||
  version "1.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/schema-utils/-/schema-utils-1.0.0.tgz#295d36f01e2cb8bc3207ca1d9a68e210db6b40cb"
 | 
			
		||||
  integrity sha512-YesPanU1+WCigC/Aj1Mga8UCOjHIfMNHZ3zzDsUY7lI8GlKnh/Kv2QwJOQ+jNQ36Ru7IfzSedlG14hppYaN13A==
 | 
			
		||||
 | 
			
		||||
"@types/sizzle@2.3.2":
 | 
			
		||||
  version "2.3.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
 | 
			
		||||
@@ -1982,22 +2066,18 @@ babel-plugin-dynamic-import-node@^2.3.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    object.assign "^4.1.0"
 | 
			
		||||
 | 
			
		||||
babel-plugin-react-intl@^2.0.0:
 | 
			
		||||
  version "2.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-2.4.0.tgz#292fca8030603a9e0476973290836aa0c7da17e2"
 | 
			
		||||
  integrity sha512-r67nOQdpKxPtDFiJHquTt9dBG0xOlBk1u3rForULNrDXvTzg5RRHbB7RLqqMWOvqfP2znTo0C+e/PLnPKt+JXA==
 | 
			
		||||
babel-plugin-react-intl@^5.1.1:
 | 
			
		||||
  version "5.1.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-5.1.1.tgz#3c3d8af13aeb7b50c6470fc3d7abe9bdbae9f6da"
 | 
			
		||||
  integrity sha512-kkghFOjjssYRiVPxwV/6q4WFhpkYw2LnpQAuvqHHDvPbOH2bcAz2U+GXy+W7pzSwH2FPnqegCbzJ4nPogVRGwg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    babel-runtime "^6.2.0"
 | 
			
		||||
    intl-messageformat-parser "^1.2.0"
 | 
			
		||||
    mkdirp "^0.5.1"
 | 
			
		||||
 | 
			
		||||
babel-runtime@^6.2.0:
 | 
			
		||||
  version "6.26.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
 | 
			
		||||
  integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
 | 
			
		||||
  dependencies:
 | 
			
		||||
    core-js "^2.4.0"
 | 
			
		||||
    regenerator-runtime "^0.11.0"
 | 
			
		||||
    "@babel/core" "^7.6.2"
 | 
			
		||||
    "@babel/helper-plugin-utils" "^7.0.0"
 | 
			
		||||
    "@types/babel__core" "^7.1.2"
 | 
			
		||||
    "@types/schema-utils" "^1.0.0"
 | 
			
		||||
    fs-extra "^8.0.1"
 | 
			
		||||
    intl-messageformat-parser "^3.2.2"
 | 
			
		||||
    schema-utils "^2.2.0"
 | 
			
		||||
 | 
			
		||||
backo2@1.0.2:
 | 
			
		||||
  version "1.0.2"
 | 
			
		||||
@@ -3030,11 +3110,6 @@ core-js@^1.0.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
 | 
			
		||||
  integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
 | 
			
		||||
 | 
			
		||||
core-js@^2.4.0:
 | 
			
		||||
  version "2.6.9"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
 | 
			
		||||
  integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
 | 
			
		||||
 | 
			
		||||
core-util-is@1.0.2, core-util-is@~1.0.0:
 | 
			
		||||
  version "1.0.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
 | 
			
		||||
@@ -4781,6 +4856,15 @@ fs-extra@^7.0.1:
 | 
			
		||||
    jsonfile "^4.0.0"
 | 
			
		||||
    universalify "^0.1.0"
 | 
			
		||||
 | 
			
		||||
fs-extra@^8.0.1:
 | 
			
		||||
  version "8.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
 | 
			
		||||
  integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    graceful-fs "^4.2.0"
 | 
			
		||||
    jsonfile "^4.0.0"
 | 
			
		||||
    universalify "^0.1.0"
 | 
			
		||||
 | 
			
		||||
fs-minipass@^1.2.5:
 | 
			
		||||
  version "1.2.6"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
 | 
			
		||||
@@ -5086,6 +5170,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
 | 
			
		||||
  integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
 | 
			
		||||
 | 
			
		||||
graceful-fs@^4.2.0:
 | 
			
		||||
  version "4.2.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
 | 
			
		||||
  integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
 | 
			
		||||
 | 
			
		||||
greedy-interval-packer@1.2.0:
 | 
			
		||||
  version "1.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/greedy-interval-packer/-/greedy-interval-packer-1.2.0.tgz#d6da11f3661bb797812da78a1ea510678a2a8739"
 | 
			
		||||
@@ -5685,29 +5774,28 @@ interpret@1.2.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
 | 
			
		||||
  integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
 | 
			
		||||
 | 
			
		||||
intl-format-cache@^2.0.5:
 | 
			
		||||
  version "2.2.9"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-2.2.9.tgz#fb560de20c549cda20b569cf1ffb6dc62b5b93b4"
 | 
			
		||||
  integrity sha512-Zv/u8wRpekckv0cLkwpVdABYST4hZNTDaX7reFetrYTJwxExR2VyTqQm+l0WmL0Qo8Mjb9Tf33qnfj0T7pjxdQ==
 | 
			
		||||
intl-format-cache@^4.2.3, intl-format-cache@^4.2.5:
 | 
			
		||||
  version "4.2.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-4.2.5.tgz#6319f5707cdc766ab5c196990a6e55b0df9cc70f"
 | 
			
		||||
  integrity sha512-xvvog/4HTVhJIg5dexcs6Ji/ROlolCgtz3std23bLEmucoGPrUVrYQPTcBWR314NM9khm4JSrdOamv9SEtvCUg==
 | 
			
		||||
 | 
			
		||||
intl-messageformat-parser@1.4.0, intl-messageformat-parser@^1.2.0:
 | 
			
		||||
  version "1.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
 | 
			
		||||
  integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU=
 | 
			
		||||
intl-locales-supported@^1.6.0:
 | 
			
		||||
  version "1.8.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-locales-supported/-/intl-locales-supported-1.8.0.tgz#cfec56f5ac8cbb828bd5ce3155c4392555cd5c5c"
 | 
			
		||||
  integrity sha512-y1K5NaNM/WjwZcRy4TtRZ4kR8TCXfoPlX2MFbFGWqqYBD0jPG8liX/cU8aBzk2j5+bu1W6ztlLtOfCPAEwQc3A==
 | 
			
		||||
 | 
			
		||||
intl-messageformat@^2.0.0, intl-messageformat@^2.1.0:
 | 
			
		||||
  version "2.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc"
 | 
			
		||||
  integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=
 | 
			
		||||
intl-messageformat-parser@^3.2.2:
 | 
			
		||||
  version "3.2.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-3.2.2.tgz#28cacc80a53823a28b5ecaf16b3b35d0a1d5f9d2"
 | 
			
		||||
  integrity sha512-ax9639ST77YimAddTH/0Q9qhXuYS8ZVsoqOZinqnS90MbXaNuIq+KIdifaIndwI+lMEv3o+qNaGycXYvlh17rw==
 | 
			
		||||
 | 
			
		||||
intl-messageformat@^7.3.3:
 | 
			
		||||
  version "7.5.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-7.5.0.tgz#53582b6e911d4f41434e9d897b4789d2a2b2ff8e"
 | 
			
		||||
  integrity sha512-s08OFUbRVUPTiXS8OOP06OhfehM1K4ughymhOazY4OhQMO+RiY4bnmsqRgYe7XorETg7mZnwJX1M34sJrzKoOA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    intl-messageformat-parser "1.4.0"
 | 
			
		||||
 | 
			
		||||
intl-relativeformat@^2.1.0:
 | 
			
		||||
  version "2.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.2.0.tgz#6aca95d019ec8d30b6c5653b6629f9983ea5b6c5"
 | 
			
		||||
  integrity sha512-4bV/7kSKaPEmu6ArxXf9xjv1ny74Zkwuey8Pm01NH4zggPP7JHwg2STk8Y3JdspCKRDriwIyLRfEXnj2ZLr4Bw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    intl-messageformat "^2.0.0"
 | 
			
		||||
    intl-format-cache "^4.2.5"
 | 
			
		||||
    intl-messageformat-parser "^3.2.2"
 | 
			
		||||
 | 
			
		||||
intl@^1.2.5:
 | 
			
		||||
  version "1.2.5"
 | 
			
		||||
@@ -8787,16 +8875,22 @@ react-hot-loader@^4.12.16:
 | 
			
		||||
    shallowequal "^1.1.0"
 | 
			
		||||
    source-map "^0.7.3"
 | 
			
		||||
 | 
			
		||||
react-intl@^2.7.2:
 | 
			
		||||
  version "2.9.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.9.0.tgz#c97c5d17d4718f1575fdbd5a769f96018a3b1843"
 | 
			
		||||
  integrity sha512-27jnDlb/d2A7mSJwrbOBnUgD+rPep+abmoJE511Tf8BnoONIAUehy/U1zZCHGO17mnOwMWxqN4qC0nW11cD6rA==
 | 
			
		||||
react-intl@^3.4.0:
 | 
			
		||||
  version "3.4.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-3.4.0.tgz#25986ac75b3c0073c0a7bce31ab2cb1b8bbf421c"
 | 
			
		||||
  integrity sha512-pW+z0ngVtPzICQeBrvoxk/YOotjFjVMvqxf/q0hjfM4CLvzIWJW/7MQcOz8ujD0Agf146mYOUv0//a9JM4H6Tg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/intl-relativetimeformat" "^4.2.1"
 | 
			
		||||
    "@formatjs/intl-unified-numberformat" "^2.1.0"
 | 
			
		||||
    "@types/hoist-non-react-statics" "^3.3.1"
 | 
			
		||||
    "@types/invariant" "^2.2.30"
 | 
			
		||||
    hoist-non-react-statics "^3.3.0"
 | 
			
		||||
    intl-format-cache "^2.0.5"
 | 
			
		||||
    intl-messageformat "^2.1.0"
 | 
			
		||||
    intl-relativeformat "^2.1.0"
 | 
			
		||||
    intl-format-cache "^4.2.3"
 | 
			
		||||
    intl-locales-supported "^1.6.0"
 | 
			
		||||
    intl-messageformat "^7.3.3"
 | 
			
		||||
    intl-messageformat-parser "^3.2.2"
 | 
			
		||||
    invariant "^2.1.1"
 | 
			
		||||
    shallow-equal "^1.1.0"
 | 
			
		||||
 | 
			
		||||
react-is@^16.10.2, react-is@^16.9.0:
 | 
			
		||||
  version "16.11.0"
 | 
			
		||||
@@ -9090,11 +9184,6 @@ regenerate@^1.4.0:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
 | 
			
		||||
  integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
 | 
			
		||||
 | 
			
		||||
regenerator-runtime@^0.11.0:
 | 
			
		||||
  version "0.11.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
 | 
			
		||||
  integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
 | 
			
		||||
 | 
			
		||||
regenerator-runtime@^0.12.0:
 | 
			
		||||
  version "0.12.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
 | 
			
		||||
@@ -9511,7 +9600,7 @@ schema-utils@^1.0.0:
 | 
			
		||||
    ajv-errors "^1.0.0"
 | 
			
		||||
    ajv-keywords "^3.1.0"
 | 
			
		||||
 | 
			
		||||
schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.1.0, schema-utils@^2.4.1:
 | 
			
		||||
schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.1.0, schema-utils@^2.2.0, schema-utils@^2.4.1:
 | 
			
		||||
  version "2.5.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.5.0.tgz#8f254f618d402cc80257486213c8970edfd7c22f"
 | 
			
		||||
  integrity sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==
 | 
			
		||||
@@ -9656,6 +9745,11 @@ shallow-clone@^3.0.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    kind-of "^6.0.2"
 | 
			
		||||
 | 
			
		||||
shallow-equal@^1.1.0:
 | 
			
		||||
  version "1.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.0.tgz#fd828d2029ff4e19569db7e19e535e94e2d1f5cc"
 | 
			
		||||
  integrity sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==
 | 
			
		||||
 | 
			
		||||
shallowequal@^1.0.1, shallowequal@^1.1.0:
 | 
			
		||||
  version "1.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user