diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js
index 30e653731d..5c425d7a6e 100644
--- a/apps/remix-ide/src/app.js
+++ b/apps/remix-ide/src/app.js
@@ -3,6 +3,7 @@ import { RunTab, makeUdapp } from './app/udapp'
import { RemixEngine } from './remixEngine'
import { RemixAppManager } from './remixAppManager'
import { ThemeModule } from './app/tabs/theme-module'
+import { LocaleModule } from './app/tabs/locale-module'
import { NetworkModule } from './app/tabs/network-module'
import { Web3ProviderModule } from './app/tabs/web3-provider'
import { CompileAndRun } from './app/tabs/compile-and-run'
@@ -134,7 +135,10 @@ class AppComponent {
this.gistHandler = new GistHandler()
// ----------------- theme service ---------------------------------
this.themeModule = new ThemeModule()
+ // ----------------- locale service ---------------------------------
+ this.localeModule = new LocaleModule()
Registry.getInstance().put({ api: this.themeModule, name: 'themeModule' })
+ Registry.getInstance().put({ api: this.localeModule, name: 'localeModule' })
// ----------------- editor service ----------------------------
const editor = new Editor() // wrapper around ace editor
@@ -206,7 +210,7 @@ class AppComponent {
const configPlugin = new ConfigPlugin()
this.layout = new Layout()
-
+
const permissionHandler = new PermissionHandlerPlugin()
this.engine.register([
@@ -218,6 +222,7 @@ class AppComponent {
blockchain,
contentImport,
this.themeModule,
+ this.localeModule,
editor,
fileManager,
compilerMetadataGenerator,
@@ -332,7 +337,7 @@ class AppComponent {
async activate () {
const queryParams = new QueryParams()
const params = queryParams.get()
-
+
if (isElectron()) {
this.appManager.activatePlugin('remixd')
}
@@ -345,7 +350,7 @@ class AppComponent {
await this.appManager.activatePlugin(['layout'])
await this.appManager.activatePlugin(['notification'])
await this.appManager.activatePlugin(['editor'])
- await this.appManager.activatePlugin(['permissionhandler', 'theme', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
+ await this.appManager.activatePlugin(['permissionhandler', 'theme', 'locale', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await this.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs'])
await this.appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await this.appManager.activatePlugin(['home'])
diff --git a/apps/remix-ide/src/app/tabs/locale-module.js b/apps/remix-ide/src/app/tabs/locale-module.js
new file mode 100644
index 0000000000..9a2c1b3b04
--- /dev/null
+++ b/apps/remix-ide/src/app/tabs/locale-module.js
@@ -0,0 +1,75 @@
+import { Plugin } from '@remixproject/engine'
+import { EventEmitter } from 'events'
+import { QueryParams } from '@remix-project/remix-lib'
+import * as packageJson from '../../../../../package.json'
+import Registry from '../state/registry'
+import enUS from './locales/en-US'
+import zhCN from './locales/zh-CN'
+const _paq = window._paq = window._paq || []
+
+const locales = [
+ { name: 'en-US', messages: enUS },
+ { name: 'zh-CN', messages: zhCN },
+]
+
+const profile = {
+ name: 'locale',
+ events: ['localeChanged'],
+ methods: ['switchLocale', 'getLocales', 'currentLocale'],
+ version: packageJson.version,
+ kind: 'locale'
+}
+
+export class LocaleModule extends Plugin {
+ constructor () {
+ super(profile)
+ this.events = new EventEmitter()
+ this._deps = {
+ config: Registry.getInstance().get('config') && Registry.getInstance().get('config').api
+ }
+ this.locales = {}
+ locales.map((locale) => {
+ this.locales[locale.name.toLocaleLowerCase()] = locale
+ })
+ this._paq = _paq
+ let queryLocale = (new QueryParams()).get().locale
+ queryLocale = queryLocale && queryLocale.toLocaleLowerCase()
+ queryLocale = this.locales[queryLocale] ? queryLocale : null
+ let currentLocale = (this._deps.config && this._deps.config.get('settings/locale')) || null
+ currentLocale = currentLocale && currentLocale.toLocaleLowerCase()
+ currentLocale = this.locales[currentLocale] ? currentLocale : null
+ this.currentLocaleState = { queryLocale, currentLocale }
+ this.active = queryLocale || currentLocale || 'en-us'
+ this.forced = !!queryLocale
+ }
+
+ /** Return the active locale */
+ currentLocale () {
+ return this.locales[this.active]
+ }
+
+ /** Returns all locales as an array */
+ getLocales () {
+ return Object.keys(this.locales).map(key => this.locales[key])
+ }
+
+ /**
+ * Change the current locale
+ * @param {string} [localeName] - The name of the locale
+ */
+ switchLocale (localeName) {
+ localeName = localeName && localeName.toLocaleLowerCase()
+ if (localeName && !Object.keys(this.locales).includes(localeName)) {
+ throw new Error(`Locale ${localeName} doesn't exist`)
+ }
+ const next = localeName || this.active // Name
+ if (next === this.active) return // --> exit out of this method
+ _paq.push(['trackEvent', 'localeModule', 'switchTo', next])
+ const nextLocale = this.locales[next] // Locale
+ if (!this.forced) this._deps.config.set('settings/locale', next)
+
+ if (localeName) this.active = localeName
+ this.emit('localeChanged', nextLocale)
+ this.events.emit('localeChanged', nextLocale)
+ }
+}
diff --git a/apps/remix-ide/src/app/tabs/locales/en-US.js b/apps/remix-ide/src/app/tabs/locales/en-US.js
new file mode 100644
index 0000000000..16a276eb76
--- /dev/null
+++ b/apps/remix-ide/src/app/tabs/locales/en-US.js
@@ -0,0 +1,4 @@
+export default {
+ 'themes': 'Themes',
+ 'locales': 'Lanaguage',
+}
diff --git a/apps/remix-ide/src/app/tabs/locales/zh-CN.js b/apps/remix-ide/src/app/tabs/locales/zh-CN.js
new file mode 100644
index 0000000000..1015386167
--- /dev/null
+++ b/apps/remix-ide/src/app/tabs/locales/zh-CN.js
@@ -0,0 +1,4 @@
+export default {
+ 'themes': '主题',
+ 'locales': '语言',
+}
diff --git a/apps/remix-ide/src/app/tabs/settings-tab.tsx b/apps/remix-ide/src/app/tabs/settings-tab.tsx
index 8440ffbfa7..45e47fc2ac 100644
--- a/apps/remix-ide/src/app/tabs/settings-tab.tsx
+++ b/apps/remix-ide/src/app/tabs/settings-tab.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react' // eslint-disable-line
import { ViewPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json'
@@ -23,8 +24,8 @@ module.exports = class SettingsTab extends ViewPlugin {
config: any = {}
editor: any
private _deps: {
- themeModule: any // eslint-disable-line
-
+ themeModule: any
+ localeModule: any
}
element: HTMLDivElement
public useMatomoAnalytics: any
@@ -34,7 +35,8 @@ module.exports = class SettingsTab extends ViewPlugin {
this.config = config
this.editor = editor
this._deps = {
- themeModule: Registry.getInstance().get('themeModule').api
+ themeModule: Registry.getInstance().get('themeModule').api,
+ localeModule: Registry.getInstance().get('localeModule').api
}
this.element = document.createElement('div')
this.element.setAttribute('id', 'settingsTab')
@@ -46,7 +48,7 @@ module.exports = class SettingsTab extends ViewPlugin {
this.renderComponent()
}
- render() {
+ render() {
return
@@ -59,6 +61,7 @@ module.exports = class SettingsTab extends ViewPlugin {
_deps={state._deps}
useMatomoAnalytics={state.useMatomoAnalytics}
themeModule = {state._deps.themeModule}
+ localeModule={state._deps.localeModule}
/>
}
@@ -77,4 +80,4 @@ module.exports = class SettingsTab extends ViewPlugin {
...this
})
}
-}
\ No newline at end of file
+}
diff --git a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx
index 8d0aeec020..edcd4a837d 100644
--- a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx
+++ b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx
@@ -9,6 +9,7 @@ import AppDialogs from './components/modals/dialogs'
import DialogViewPlugin from './components/modals/dialogViewPlugin'
import { AppContext } from './context/context'
import { RemixUiVerticalIconsPanel } from '@remix-ui/vertical-icons-panel'
+import { IntlProvider } from 'react-intl'
interface IRemixAppUi {
app: any
@@ -17,6 +18,7 @@ interface IRemixAppUi {
const RemixApp = (props: IRemixAppUi) => {
const [appReady, setAppReady] = useState(false)
const [hideSidePanel, setHideSidePanel] = useState(false)
+ const [locale, setLocale] = useState<{ name:string; messages:any }>({ name:'', messages:{} });
const sidePanelRef = useRef(null)
useEffect(() => {
@@ -26,6 +28,7 @@ const RemixApp = (props: IRemixAppUi) => {
props.app.activate()
setListeners()
})
+ setLocale(props.app.localeModule.currentLocale())
}
if (props.app) {
activateApp()
@@ -48,6 +51,9 @@ const RemixApp = (props: IRemixAppUi) => {
setHideSidePanel(true)
}, 1000)
})
+ props.app.localeModule.events.on('localeChanged', (nextLocale) => {
+ setLocale(nextLocale)
+ })
}
const value = {
@@ -59,22 +65,24 @@ const RemixApp = (props: IRemixAppUi) => {
}
return (
-
-
-
+
+
+
+
-
-
{props.app.menuicons.render()}
-
{props.app.sidePanel.render()}
-
-
-
+
+
{props.app.menuicons.render()}
+
{props.app.sidePanel.render()}
+
+
+
+
-
-
{props.app.hiddenPanel.render()}
-
-
-
+
{props.app.hiddenPanel.render()}
+
+
+
+
)
}
diff --git a/libs/remix-ui/locale-module/.babelrc b/libs/remix-ui/locale-module/.babelrc
new file mode 100644
index 0000000000..ccae900be4
--- /dev/null
+++ b/libs/remix-ui/locale-module/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ [
+ "@nrwl/react/babel",
+ {
+ "runtime": "automatic",
+ "useBuiltIns": "usage"
+ }
+ ]
+ ],
+ "plugins": []
+}
diff --git a/libs/remix-ui/locale-module/.eslintrc.json b/libs/remix-ui/locale-module/.eslintrc.json
new file mode 100644
index 0000000000..50e59482cf
--- /dev/null
+++ b/libs/remix-ui/locale-module/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/libs/remix-ui/locale-module/README.md b/libs/remix-ui/locale-module/README.md
new file mode 100644
index 0000000000..affdd5db4e
--- /dev/null
+++ b/libs/remix-ui/locale-module/README.md
@@ -0,0 +1,7 @@
+# remix-ui-locale-module
+
+This library was generated with [Nx](https://nx.dev).
+
+## Running unit tests
+
+Run `nx test remix-ui-locale-module` to execute the unit tests via [Jest](https://jestjs.io).
diff --git a/libs/remix-ui/locale-module/src/index.ts b/libs/remix-ui/locale-module/src/index.ts
new file mode 100644
index 0000000000..fdda78b342
--- /dev/null
+++ b/libs/remix-ui/locale-module/src/index.ts
@@ -0,0 +1,2 @@
+export * from './lib/remix-ui-locale-module';
+export * from '../types/locale-module'
diff --git a/libs/remix-ui/locale-module/src/lib/remix-ui-locale-module.module.css b/libs/remix-ui/locale-module/src/lib/remix-ui-locale-module.module.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/libs/remix-ui/locale-module/src/lib/remix-ui-locale-module.tsx b/libs/remix-ui/locale-module/src/lib/remix-ui-locale-module.tsx
new file mode 100644
index 0000000000..2f8fa256f0
--- /dev/null
+++ b/libs/remix-ui/locale-module/src/lib/remix-ui-locale-module.tsx
@@ -0,0 +1,56 @@
+import React, { useEffect, useState } from 'react';
+import { FormattedMessage } from 'react-intl'
+import { LocaleModule } from '../../types/locale-module';
+import './remix-ui-locale-module.module.css';
+
+export interface RemixUiLocaleModuleProps {
+ localeModule: LocaleModule;
+}
+
+export function RemixUiLocaleModule({ localeModule }: RemixUiLocaleModuleProps) {
+ const [localeName, setLocaleName] = useState('')
+
+ useEffect(() => {
+ localeModule.switchLocale()
+ }, [localeName, localeModule])
+
+ return (
+
+
+
+
+ {localeModule.getLocales()
+ ? localeModule.getLocales().map((locale, idx) => (
+
+ {
+ localeModule.switchLocale(locale.name);
+ setLocaleName(locale.name);
+ }}
+ className="align-middle custom-control-input"
+ name="locale"
+ id={locale.name}
+ data-id={`settingsTabLocale${locale.name}`}
+ checked={localeModule.active === locale.name.toLocaleLowerCase()}
+ />
+
+
+ ))
+ : null}
+
+
+
+ )
+}
+
+export default RemixUiLocaleModule;
diff --git a/libs/remix-ui/locale-module/tsconfig.json b/libs/remix-ui/locale-module/tsconfig.json
new file mode 100644
index 0000000000..8bd701c578
--- /dev/null
+++ b/libs/remix-ui/locale-module/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../../../tsconfig.base.json",
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "allowJs": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.lib.json"
+ }
+ ]
+}
diff --git a/libs/remix-ui/locale-module/tsconfig.lib.json b/libs/remix-ui/locale-module/tsconfig.lib.json
new file mode 100644
index 0000000000..b560bc4dec
--- /dev/null
+++ b/libs/remix-ui/locale-module/tsconfig.lib.json
@@ -0,0 +1,13 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../dist/out-tsc",
+ "types": ["node"]
+ },
+ "files": [
+ "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
+ "../../../node_modules/@nrwl/react/typings/image.d.ts"
+ ],
+ "exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
+ "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
+}
diff --git a/libs/remix-ui/locale-module/types/locale-module.ts b/libs/remix-ui/locale-module/types/locale-module.ts
new file mode 100644
index 0000000000..535d6864e0
--- /dev/null
+++ b/libs/remix-ui/locale-module/types/locale-module.ts
@@ -0,0 +1,29 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { Plugin } from "@remixproject/engine/lib/abstract";
+import { EventEmitter } from "events";
+export interface LocaleModule extends Plugin
{
+ currentLocaleState: Record;
+ new(): any;
+ events: EventEmitter;
+ _deps: {
+ config: any;
+ };
+ _paq: any
+ element: HTMLDivElement;
+ locales: {[key: string]: Locale};
+ active: string;
+ forced: boolean;
+ render(): HTMLDivElement;
+ renderComponent(): void;
+ /** Return the active locale */
+ currentLocale(): Locale;
+ /** Returns all locales as an array */
+ getLocales(): Locale[];
+ /**
+ * Change the current locale
+ * @param {string} [localeName] - The name of the locale
+ */
+ switchLocale(localeName?: string): void;
+}
+
+interface Locale { name: string, messages: any }
diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
index 2de3ecd67b..09a9fd4302 100644
--- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
+++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
@@ -8,6 +8,7 @@ import { ethereumVM, generateContractMetadat, personal, textWrapEventAction, use
import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer'
import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
import { RemixUiThemeModule, ThemeModule} from '@remix-ui/theme-module'
+import { RemixUiLocaleModule, LocaleModule} from '@remix-ui/locale-module'
/* eslint-disable-next-line */
export interface RemixUiSettingsProps {
@@ -16,6 +17,7 @@ export interface RemixUiSettingsProps {
_deps: any,
useMatomoAnalytics: boolean
themeModule: ThemeModule
+ localeModule: LocaleModule
}
export const RemixUiSettings = (props: RemixUiSettingsProps) => {
@@ -346,12 +348,13 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
return (
{state.message ? : null}
- {generalConfig()}
+ {generalConfig()}
{token('gist')}
{token('etherscan')}
{swarmSettings()}
{ipfsSettings()}
+
)
}
diff --git a/libs/remix-ui/theme-module/src/lib/remix-ui-theme-module.tsx b/libs/remix-ui/theme-module/src/lib/remix-ui-theme-module.tsx
index 077da4edba..b2f3d8df1f 100644
--- a/libs/remix-ui/theme-module/src/lib/remix-ui-theme-module.tsx
+++ b/libs/remix-ui/theme-module/src/lib/remix-ui-theme-module.tsx
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useEffect, useState } from 'react';
+import { FormattedMessage } from 'react-intl'
import { ThemeModule } from '../../types/theme-module';
import './remix-ui-theme-module.module.css';
@@ -18,7 +19,7 @@ export function RemixUiThemeModule({ themeModule }: RemixUiThemeModuleProps) {
return (
-
Themes
+
{themeModule.getThemes()
? themeModule.getThemes().map((theme, idx) => (
diff --git a/nx.json b/nx.json
index c6fca5f4ad..5a34120f4c 100644
--- a/nx.json
+++ b/nx.json
@@ -169,6 +169,9 @@
},
"remix-ui-permission-handler": {
"tags": []
+ },
+ "remix-ui-locale-module": {
+ "tags": []
}
},
"targetDependencies": {
diff --git a/package.json b/package.json
index 478fe06031..27a082bc22 100644
--- a/package.json
+++ b/package.json
@@ -196,6 +196,7 @@
"react-bootstrap": "^1.6.4",
"react-dom": "^17.0.2",
"react-draggable": "^4.4.4",
+ "react-intl": "^6.0.4",
"react-tabs": "^3.2.2",
"regenerator-runtime": "0.13.7",
"rss-parser": "^3.12.0",
diff --git a/tsconfig.base.json b/tsconfig.base.json
index 409590c800..90d2773d72 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -87,7 +87,8 @@
"@remix-ui/run-tab": ["libs/remix-ui/run-tab/src/index.ts"],
"@remix-ui/permission-handler": [
"libs/remix-ui/permission-handler/src/index.ts"
- ]
+ ],
+ "@remix-ui/locale-module": ["libs/remix-ui/locale-module/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]
diff --git a/workspace.json b/workspace.json
index 7ead3dd32b..c3b8682f16 100644
--- a/workspace.json
+++ b/workspace.json
@@ -1253,6 +1253,21 @@
}
}
}
+ },
+ "remix-ui-locale-module": {
+ "root": "libs/remix-ui/locale-module",
+ "sourceRoot": "libs/remix-ui/locale-module/src",
+ "projectType": "library",
+ "architect": {
+ "lint": {
+ "builder": "@nrwl/linter:eslint",
+ "options": {
+ "lintFilePatterns": [
+ "libs/remix-ui/locale-module/**/*.{ts,tsx,js,jsx}"
+ ]
+ }
+ }
+ }
}
},
"cli": {
diff --git a/yarn.lock b/yarn.lock
index 6139c5e6c5..e5721bb7c4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2297,6 +2297,76 @@
resolved "https://registry.yarnpkg.com/@f/svg-namespace/-/svg-namespace-1.0.1.tgz#f6f1a5ce5d3971a4ade91a11d22d4c459acd375f"
integrity sha512-GQVBgTMtsxdOEKkgMNqiSJwBXpfDJgnMnWkpu/jv526piA6na7AjvKb+5fPkd42Ig5Aa2Dc5BVUrwF7R2nXhYw==
+"@formatjs/ecma402-abstract@1.11.7":
+ version "1.11.7"
+ resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.7.tgz#47f1a854f679f813d9baa1ee55adae94880ec706"
+ integrity sha512-uNaok4XWMJBtPZk/veTDamFCm5HeWJUk2jwoVfH5/+wenQ60QHjH6T3UQ0GOOCz9jpKmed7vqOri7xSf//Dt7g==
+ dependencies:
+ "@formatjs/intl-localematcher" "0.2.28"
+ tslib "2.4.0"
+
+"@formatjs/fast-memoize@1.2.4":
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-1.2.4.tgz#4b5ddce9eb7803ff0bd4052387672151a8b7f8a0"
+ integrity sha512-9ARYoLR8AEzXvj2nYrOVHY/h1dDMDWGTnKDLXSISF1uoPakSmfcZuSqjiqZX2wRkEUimPxdwTu/agyozBtZRHA==
+ dependencies:
+ tslib "2.4.0"
+
+"@formatjs/icu-messageformat-parser@2.1.3":
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.3.tgz#d228ac26f22630689a1263e83192227f1d085bd3"
+ integrity sha512-hsdAn1dXcujW/G8DHw0iiIy7357pw10yOulCrL6xrQOKJAxT7m7EgpG0Hm1OW9xqaLEzqWyE/jA2AGVnOCaCQw==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ "@formatjs/icu-skeleton-parser" "1.3.9"
+ tslib "2.4.0"
+
+"@formatjs/icu-skeleton-parser@1.3.9":
+ version "1.3.9"
+ resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.9.tgz#149badc16ffd15dd928f8047ae21aa9136e0ea73"
+ integrity sha512-s9THwwhiiSzbGSk73FP6Ur2MBwEj1vfgYDHKa5FiXGQMfYzdRdRvyH1dgqNgSFJPB6PM3DKtkloJLjpqpSDNUg==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ tslib "2.4.0"
+
+"@formatjs/intl-displaynames@6.0.2":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.0.2.tgz#f6349b5c75fd9ecc7c77c7e73101daee5dc69e3a"
+ integrity sha512-h9Id/6vbSHpARHKMVsjWag3KMZJpop9s67CZTd+AMxhjHb5xDG2b5rlSRJKx/UdIDQ+GzESK7a4fv32yylG3cw==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ "@formatjs/intl-localematcher" "0.2.28"
+ tslib "2.4.0"
+
+"@formatjs/intl-listformat@7.0.2":
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.0.2.tgz#c07d370c9171dfc86c163addbfcb08f67ae26215"
+ integrity sha512-K+HXrYIvEcAH/dS8XXnSHQYC/z4w0eHjPlDx43HOoDY87/xV7rpHxFVXWXTgwLYC6iAPUO72Y/AaT9iq873juw==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ "@formatjs/intl-localematcher" "0.2.28"
+ tslib "2.4.0"
+
+"@formatjs/intl-localematcher@0.2.28":
+ version "0.2.28"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.2.28.tgz#412ea7fefbfc7ed33cd6b43aa304fc14d816e564"
+ integrity sha512-FLsc6Gifs1np/8HnCn/7Q+lHMmenrD5fuDhRT82yj0gi9O19kfaFwjQUw1gZsyILuRyT93GuzdifHj7TKRhBcw==
+ dependencies:
+ tslib "2.4.0"
+
+"@formatjs/intl@2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.3.0.tgz#848edf81c95d608757662b3feada0eb2dacc5424"
+ integrity sha512-mE8zGqP+Flrd8tS3AsdvSucnblqwR5gsGM4Bd5711abkabrz52F2TDrU88rVvVfCdHV4dFHFYEmUBVZZ4pATtg==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ "@formatjs/fast-memoize" "1.2.4"
+ "@formatjs/icu-messageformat-parser" "2.1.3"
+ "@formatjs/intl-displaynames" "6.0.2"
+ "@formatjs/intl-listformat" "7.0.2"
+ intl-messageformat "10.1.0"
+ tslib "2.4.0"
+
"@fortawesome/fontawesome-free@^5.8.1":
version "5.15.4"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5"
@@ -4178,7 +4248,7 @@
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.9.tgz#1cfb6d60ef3822c589f18e70f8b12f9a28ce8724"
integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==
-"@types/hoist-non-react-statics@^3.3.0":
+"@types/hoist-non-react-statics@^3.3.0", "@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==
@@ -4393,6 +4463,15 @@
"@types/scheduler" "*"
csstype "^3.0.2"
+"@types/react@16 || 17 || 18":
+ version "18.0.14"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.14.tgz#e016616ffff51dba01b04945610fe3671fdbe06d"
+ integrity sha512-x4gGuASSiWmo0xjDLpm5mPb52syZHJx02VKbqUKdLmKtAwIh63XClGsiTI1K6DO5q7ox4xAsQrU+Gl3+gGXF9Q==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
"@types/readable-stream@^2.3.11":
version "2.3.13"
resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.13.tgz#46451c1b87cb61010e420ac02a76cfc1b2c2089a"
@@ -9550,7 +9629,7 @@ ent@~2.2.0:
resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
-entities@^2.0.0:
+entities@^2.0.0, entities@^2.0.3:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
@@ -12648,6 +12727,16 @@ interpret@^1.0.0, interpret@^1.4.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
+intl-messageformat@10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.1.0.tgz#ffbbcbf1068af8466ad5497f78c30c3d96ef5505"
+ integrity sha512-diGMDv9Zo2Mggf6AkJszq/BIR5+rarkwcr4g5JGgREwbwAHY9hR/dYd8FbIgQx2RTxhJsABfAWCiENFLbaTZjg==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ "@formatjs/fast-memoize" "1.2.4"
+ "@formatjs/icu-messageformat-parser" "2.1.3"
+ tslib "2.4.0"
+
intro.js@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/intro.js/-/intro.js-4.3.0.tgz#39d072e638eae9c8491e225b8565ad63b6aaf1f7"
@@ -19224,6 +19313,22 @@ react-draggable@^4.4.4:
clsx "^1.1.1"
prop-types "^15.6.0"
+react-intl@^6.0.4:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.0.4.tgz#635d7639aa7b70e837c75796535cf1d534016acf"
+ integrity sha512-eBIP4QuFOdr67+ZmNOA7WGzJ6dj0qgsGQbx3phzcel2B0kVLvfojTJuvYiFuLgbZTrRJMjHwYJZO5zsmibsfug==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.11.7"
+ "@formatjs/icu-messageformat-parser" "2.1.3"
+ "@formatjs/intl" "2.3.0"
+ "@formatjs/intl-displaynames" "6.0.2"
+ "@formatjs/intl-listformat" "7.0.2"
+ "@types/hoist-non-react-statics" "^3.3.1"
+ "@types/react" "16 || 17 || 18"
+ hoist-non-react-statics "^3.3.2"
+ intl-messageformat "10.1.0"
+ tslib "2.4.0"
+
react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -20202,6 +20307,14 @@ rollup@1.31.1:
"@types/node" "*"
acorn "^7.1.0"
+rss-parser@^3.12.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/rss-parser/-/rss-parser-3.12.0.tgz#b8888699ea46304a74363fbd8144671b2997984c"
+ integrity sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==
+ dependencies:
+ entities "^2.0.3"
+ xml2js "^0.4.19"
+
rsvp@^4.8.4:
version "4.8.5"
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
@@ -20332,7 +20445,7 @@ sax@0.5.x:
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
-sax@~1.2.4:
+sax@>=0.6.0, sax@~1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -22394,6 +22507,11 @@ tslib@2.1.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
+tslib@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -24086,6 +24204,19 @@ xml-name-validator@^3.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+xml2js@^0.4.19:
+ version "0.4.23"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
+ integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
+ dependencies:
+ sax ">=0.6.0"
+ xmlbuilder "~11.0.0"
+
+xmlbuilder@~11.0.0:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
+ integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"