diff --git a/package.json b/package.json index 742c441..368f72b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "scripts": { "start": "webpack-dev-server --mode=development --progress --colors", "lint": "eslint ./src", - "i18n:collect": "node --experimental-modules ./scripts/i18n-collect.mjs", + "i18n:collect": "./scripts/i18n-collect/index.js", "build": "rm -rf dist/ && webpack --mode=production --progress --colors", "i18n:pull": "cd ./scripts && ../node_modules/.bin/babel-node --presets es2015,stage-0 i18n-onesky.js pull" }, @@ -32,20 +32,24 @@ "@babel/plugin-proposal-export-default-from": "^7.2.0", "@babel/preset-env": "^7.3.4", "@babel/preset-react": "^7.0.0", - "@eoleo/image-size-loader": "^1.0.0", "babel-eslint": "^6.0.0", "babel-loader": "^8.0.5", - "babel-plugin-react-intl": "^3.0.1", "babel-preset-react-hot": "^1.0.5", "eslint": "^3.1.1", "eslint-plugin-react": "^6.0.0", + "extended-translations-loader": "file:webpack-utils/extended-translations-loader", "file-loader": "^3.0.1", "html-webpack-plugin": "^3.2.0", + "i18n-collect": "file:scripts/i18n-collect", "intl-json-loader": "file:./webpack-utils/intl-json-loader", + "json-loader": "^0.5.7", "prop-types": "^15.7.2", - "scripts": "file:scripts", + "text2png-loader": "file:./webpack-utils/text2png-loader", "webpack": "^4.29.6", "webpack-cli": "^3.3.0", "webpack-dev-server": "^3.2.1" + }, + "engines": { + "node": ">=7.6.0" } } diff --git a/scripts/i18n-collect.mjs b/scripts/i18n-collect.mjs deleted file mode 100644 index c8359d6..0000000 --- a/scripts/i18n-collect.mjs +++ /dev/null @@ -1,191 +0,0 @@ -/* eslint-env node */ -/* eslint-disable no-console */ -import fs from 'fs'; -import path from 'path'; -import glob from 'glob'; -import mkdirp from 'mkdirp'; -import chalk from 'chalk'; -import prompt from 'prompt'; - -// https://stackoverflow.com/a/50052194/5184751 -const __dirname = path.dirname(new URL(import.meta.url).pathname); // eslint-disable-line - -const MESSAGES_PATTERN = path.resolve(__dirname, '../dist/messages/**/*.json'); -const LANG_DIR = path.resolve(__dirname, '../src/i18n'); -const DEFAULT_LOCALE = 'en'; -const SUPPORTED_LANGS = Object.keys(JSON.parse(fs.readFileSync(path.join(LANG_DIR, 'index.json')))); - -/** - * Aggregates the default messages that were extracted from the app's - * React components via the React Intl Babel plugin. An error will be thrown if - * there are messages in different components that use the same `id`. The result - * is a flat collection of `id: message` pairs for the app's default locale. - */ -let idToFileMap = {}; -let duplicateIds = []; -const collectedMessages = glob.sync(MESSAGES_PATTERN) - .map((filename) => [filename, JSON.parse(fs.readFileSync(filename, 'utf8'))]) - .reduce((collection, [file, descriptors]) => { - descriptors.forEach(({id, defaultMessage}) => { - if (collection.hasOwnProperty(id)) { - duplicateIds.push(id); - } - - collection[id] = defaultMessage; - idToFileMap[id] = (idToFileMap[id] || []).concat(file); - }); - - return collection; - }, {}); - -if (duplicateIds.length) { - console.log('\nFound duplicated ids:'); - duplicateIds.forEach((id) => console.log(`${chalk.yellow(id)}:\n - ${idToFileMap[id].join('\n - ')}\n`)); - console.log(chalk.red('Please correct the errors above to proceed further!')); - - process.exit(0); -} - -duplicateIds = null; -idToFileMap = null; - -/** - * Making a diff with the previous DEFAULT_LOCALE version - */ -const defaultMessagesPath = `${LANG_DIR}/${DEFAULT_LOCALE}.json`; -let keysToUpdate = []; -let keysToAdd = []; -let keysToRemove = []; -const keysToRename = []; -const isNotMarked = (value) => value.slice(0, 2) !== '--'; - -const prevMessages = readJSON(defaultMessagesPath); -const prevMessagesMap = Object.entries(prevMessages).reduce((acc, [key, value]) => { - if (acc[value]) { - acc[value].push(key); - } else { - acc[value] = [key]; - } - - return acc; -}, {}); -keysToAdd = Object.keys(collectedMessages).filter((key) => !prevMessages[key]); -keysToRemove = Object.keys(prevMessages).filter((key) => !collectedMessages[key]).filter(isNotMarked); -keysToUpdate = Object.entries(prevMessages).reduce((acc, [key, message]) => - acc.concat(collectedMessages[key] && collectedMessages[key] !== message ? key : []) -, []); - -// detect keys to rename, mutating keysToAdd and keysToRemove -[].concat(keysToAdd).forEach((toKey) => { - const keys = prevMessagesMap[collectedMessages[toKey]] || []; - const fromKey = keys.find((fromKey) => keysToRemove.indexOf(fromKey) > -1); - - if (fromKey) { - keysToRename.push([fromKey, toKey]); - - keysToRemove.splice(keysToRemove.indexOf(fromKey), 1); - keysToAdd.splice(keysToAdd.indexOf(toKey), 1); - } -}); - -if (!keysToAdd.length && !keysToRemove.length && !keysToUpdate.length && !keysToRename.length) { - console.log(chalk.green('Everything is up to date!')); - process.exit(); -} - -console.log(chalk.magenta(`The diff relative to default locale (${DEFAULT_LOCALE}) is:`)); - -if (keysToRemove.length) { - console.log('The following keys will be removed:'); - console.log([chalk.red('\n - '), keysToRemove.join(chalk.red('\n - ')), '\n'].join('')); -} - -if (keysToAdd.length) { - console.log('The following keys will be added:'); - console.log([chalk.green('\n + '), keysToAdd.join(chalk.green('\n + ')), '\n'].join('')); -} - -if (keysToUpdate.length) { - console.log('The following keys will be updated:'); - console.log([chalk.yellow('\n @ '), keysToUpdate.join(chalk.yellow('\n @ ')), '\n'].join('')); -} - -if (keysToRename.length) { - console.log('The following keys will be renamed:\n'); - console.log(keysToRename.reduce((str, pair) => - [str, pair[0], chalk.yellow(' -> '), pair[1], '\n'].join('') - , '')); -} - -prompt.start(); -prompt.get({ - properties: { - apply: { - description: 'Apply changes? [Y/n]', - pattern: /^y|n$/i, - message: 'Please enter "y" or "n"', - default: 'y', - before: (value) => value.toLowerCase() === 'y' - } - } -}, (err, resp) => { - console.log('\n'); - - if (err || !resp.apply) { - return console.log(chalk.red('Aborted')); - } - - buildLocales(); - - console.log(chalk.green('All locales was successfuly built')); -}); - - -function buildLocales() { - mkdirp.sync(LANG_DIR); - - SUPPORTED_LANGS.map((lang) => { - const destPath = `${LANG_DIR}/${lang}.json`; - const newMessages = readJSON(destPath); - - keysToRename.forEach(([fromKey, toKey]) => { - newMessages[toKey] = newMessages[fromKey]; - delete newMessages[fromKey]; - }); - keysToRemove.forEach((key) => { - delete newMessages[key]; - }); - keysToUpdate.forEach((key) => { - newMessages[`--${key}`] = newMessages[key]; - newMessages[key] = collectedMessages[key]; - }); - keysToAdd.forEach((key) => { - newMessages[key] = collectedMessages[key]; - }); - - const sortedKeys = Object.keys(newMessages).sort((key1, key2) => { - key1 = key1.replace(/^\-+/, ''); - key2 = key2.replace(/^\-+/, ''); - - return key1 < key2 || !isNotMarked(key1) ? -1 : 1; - }); - - const sortedNewMessages = sortedKeys.reduce((acc, key) => { - acc[key] = newMessages[key]; - - return acc; - }, {}); - - fs.writeFileSync(destPath, JSON.stringify(sortedNewMessages, null, 4) + '\n'); - }); -} - -function readJSON(destPath) { - try { - return JSON.parse(fs.readFileSync(destPath, 'utf8')); - } catch (err) { - console.log(chalk.yellow(`Can not read ${destPath}. The new file will be created.`), `(${err.message})`); - } - - return {}; -} diff --git a/scripts/i18n-collect/index.js b/scripts/i18n-collect/index.js new file mode 100755 index 0000000..1d0301c --- /dev/null +++ b/scripts/i18n-collect/index.js @@ -0,0 +1,57 @@ +#!/usr/bin/env node + +/* eslint-env node */ +/* eslint-disable no-console */ + +const os = require('os'); +const fs = require('fs'); +const path = require('path'); +const glob = require('glob'); +const sortKeys = require('sort-keys'); + +const DEFAULT_LOCALE = 'en'; +const INDEX_FILE_NAME = 'index'; + +const ROOT_PATH = path.resolve(__dirname, '../../src'); +const LANG_DIR = path.join(ROOT_PATH, 'i18n'); +const MESSAGES_PATTERN = path.join(ROOT_PATH, '**/*.intl.json'); +const TARGET_FILE = path.join(LANG_DIR, `${DEFAULT_LOCALE}.json`); + +const messages = glob.sync(MESSAGES_PATTERN) + .map((filename) => [filename, JSON.parse(fs.readFileSync(filename, 'utf8'))]) + .reduce((collection, [filename, descriptors]) => { + const prefix = path.dirname(filename) + .replace(ROOT_PATH, '') + .replace(/^\/|\/$/g, '') + .replace(/\//g, '.'); + for (const id in descriptors) { + // noinspection JSUnfilteredForInLoop + const key = `${prefix}.${id}`; + // noinspection JSUnfilteredForInLoop + const descriptor = descriptors[id]; + if (typeof descriptor === 'object') { + const { defaultMessage } = descriptor; + collection[key] = defaultMessage; + } else { + collection[key] = descriptor; + } + } + + return collection; + }, {}); + +fs.writeFileSync(TARGET_FILE, JSON.stringify(sortKeys(messages), null, 4) + os.EOL); +const messagesIds = Object.keys(messages); +glob.sync(path.join(LANG_DIR, `!(${DEFAULT_LOCALE}|${INDEX_FILE_NAME}).json`)) + .map((filename) => [filename, JSON.parse(fs.readFileSync(filename, 'utf8'))]) + .forEach(([filename, translatedMessages]) => { + const translatedMessagesIds = Object.keys(translatedMessages); + messagesIds.filter((id) => !translatedMessagesIds.includes(id)).forEach((newKey) => { + translatedMessages[newKey] = messages[newKey]; + }); + translatedMessagesIds.filter((id) => !messagesIds.includes(id)).forEach((removedKey) => { + Reflect.deleteProperty(translatedMessages, removedKey); + }); + + fs.writeFileSync(filename, JSON.stringify(sortKeys(translatedMessages), null, 4) + os.EOL); + }); diff --git a/scripts/i18n-collect/package.json b/scripts/i18n-collect/package.json new file mode 100644 index 0000000..e501d71 --- /dev/null +++ b/scripts/i18n-collect/package.json @@ -0,0 +1,9 @@ +{ + "name": "i18n-collect", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "glob": "^7.1.3", + "sort-keys": "^3.0.0" + } +} diff --git a/scripts/package.json b/scripts/package.json deleted file mode 100644 index 9fa1d3b..0000000 --- a/scripts/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "scripts", - "version": "1.0.0", - "description": "", - "main": "i18n-build.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "chalk": "^1.1.3", - "glob": "^7.1.3", - "mkdirp": "^0.5.1", - "prompt": "^1.0.0" - } -} diff --git a/src/App.js b/src/App.js index 74e00b7..ac9671b 100644 --- a/src/App.js +++ b/src/App.js @@ -44,8 +44,8 @@ export default function App({type, payload = {}}) { locale = DEFAULT_LANGUAGE; } - const messages = require(`i18n/${locale}.json`); - const Email = require(`emails/${type}/index`).default; + const { default: messages } = require(`!extended-translations-loader!i18n/${locale}.json`); + const { default: Email } = require(`emails/${type}/index`); return ( diff --git a/src/components/blocks/code/messages.intl.json b/src/components/blocks/code/messages.intl.json index 30adb83..69cfd5d 100644 --- a/src/components/blocks/code/messages.intl.json +++ b/src/components/blocks/code/messages.intl.json @@ -1,4 +1,4 @@ { "or": "or", - "pass_code_in_field": "Use this code in an entry field of our site:" + "pass_code_in_field": "Insert this code into form field of our site:" } diff --git a/src/components/layout/footer/Footer.js b/src/components/layout/footer/Footer.js index 256b9f1..6040ba7 100644 --- a/src/components/layout/footer/Footer.js +++ b/src/components/layout/footer/Footer.js @@ -1,11 +1,11 @@ import React from 'react'; -import { FormattedMessage as Message } from 'react-intl'; +import { FormattedMessage as Message, FormattedHTMLMessage as HTMLMessage } from 'react-intl'; import { Table } from 'components/table'; -import { BitmapText } from 'components/text'; import styles from './styles'; import messages from './messages.intl.json'; +import logoImg from './images/logo.png'; export default function Footer() { return ( @@ -21,7 +21,8 @@ export default function Footer() { - + Ely.by + diff --git a/src/components/layout/footer/images/logo.png b/src/components/layout/footer/images/logo.png new file mode 100644 index 0000000..6db068f Binary files /dev/null and b/src/components/layout/footer/images/logo.png differ diff --git a/src/components/layout/footer/messages.intl.json b/src/components/layout/footer/messages.intl.json index 92eed43..ba1a07d 100644 --- a/src/components/layout/footer/messages.intl.json +++ b/src/components/layout/footer/messages.intl.json @@ -1,5 +1,10 @@ { - "footer": "You have received this message, because this E‑mail was set during registration at the {serviceLink} service. If it wasn't you just delete the message please.", + "footer": "You have received this message, because this E‑mail was entered during registration at the {serviceLink} service. If that wasn't you, please just ignore this message.", "service_name": "Accounts Ely.by", - "footer_logo_alt": "Ely.by - Alternative Minecraft services" + "alternativeMinecraftServices": { + "type": "text2png", + "defaultMessage": "Alternative Minecraft services", + "size": 13, + "color": "#7a7a7a" + } } diff --git a/src/components/layout/footer/styles.js b/src/components/layout/footer/styles.js index 606ab50..632fd85 100644 --- a/src/components/layout/footer/styles.js +++ b/src/components/layout/footer/styles.js @@ -18,7 +18,7 @@ export default { borderBottom: '1px dashed #7A7A7A' }, footerLogo: { - verticalAlign: 'middle', - padding: '0 30px' + padding: '0 30px', + textAlign: 'center' } }; diff --git a/src/components/text/BitmapText.js b/src/components/text/BitmapText.js deleted file mode 100644 index 9611ee5..0000000 --- a/src/components/text/BitmapText.js +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { FormattedMessage as Message } from 'react-intl'; - -export function BitmapText(props) { - const parts = props.message.id.split('.'); - - if (parts[0] !== 'emails' && parts[0] !== 'components') { - throw new Error('Only src/emails and src/components subdirectories supported for now'); - } - - const fileName = parts.pop(); - const componentPath = parts.slice(1).join('/'); - - let src; - let size; - try { - try { - src = require(`emails/${componentPath}/images/${props.intl.locale}/${fileName}.png`); - // TODO: we can improve this loader in future by adding an option to disable file emitting - // because this thing is handled by url-loader - size = require(`image-size-loader!emails/${componentPath}/images/${props.intl.locale}/${fileName}.png`); - } catch (err) { // fallback to default locale - src = require(`emails/${componentPath}/images/${props.intl.defaultLocale}/${fileName}.png`); - size = require(`image-size-loader!emails/${componentPath}/images/${props.intl.defaultLocale}/${fileName}.png`); - } - } catch (err) { // try components - try { - src = require(`components/${componentPath}/images/${props.intl.locale}/${fileName}.png`); - size = require(`image-size-loader!components/${componentPath}/images/${props.intl.locale}/${fileName}.png`); - } catch (err) { // fallback to default locale - src = require(`components/${componentPath}/images/${props.intl.defaultLocale}/${fileName}.png`); - size = require(`image-size-loader!components/${componentPath}/images/${props.intl.defaultLocale}/${fileName}.png`); - } - } - - const width = props.retina ? size.width / 2 : size.width; - const height = props.retina ? size.height / 2 : size.height; - - return ( - {(message) => - {message} - } - ); -} - -BitmapText.propTypes = { - message: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.shape({ - id: PropTypes.string - }) - ]).isRequired, - style: PropTypes.object, // eslint-disable-line react/forbid-prop-types - retina: PropTypes.bool -}; - -BitmapText.defaultProps = { - retina: true, - style: { - verticalAlign: 'middle' - } -}; - -import { injectIntl, intlShape } from 'react-intl'; - -BitmapText.propTypes.intl = intlShape; - -export default injectIntl(BitmapText); diff --git a/src/components/text/index.js b/src/components/text/index.js deleted file mode 100644 index 0a8572b..0000000 --- a/src/components/text/index.js +++ /dev/null @@ -1 +0,0 @@ -export BitmapText from './BitmapText'; diff --git a/src/emails/forgotPassword/ForgotPassword.js b/src/emails/forgotPassword/ForgotPassword.js index aea87cf..e4532e8 100644 --- a/src/emails/forgotPassword/ForgotPassword.js +++ b/src/emails/forgotPassword/ForgotPassword.js @@ -1,11 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage as Message } from 'react-intl'; +import { FormattedMessage as Message, FormattedHTMLMessage as HTMLMessage } from 'react-intl'; import { Userbar, Header, Content, Footer } from 'components/layout'; import { Table } from 'components/table'; import { Code } from 'components/blocks'; -import { BitmapText } from 'components/text'; import { lightViolet } from 'components/ui/colors'; import styles from './styles'; @@ -17,7 +16,7 @@ export default function ForgotPassword({username, link, code}) {
+ } /> @@ -32,7 +31,7 @@ export default function ForgotPassword({username, link, code}) { + } /> diff --git a/src/emails/forgotPassword/messages.intl.json b/src/emails/forgotPassword/messages.intl.json index 8070325..1c239af 100644 --- a/src/emails/forgotPassword/messages.intl.json +++ b/src/emails/forgotPassword/messages.intl.json @@ -1,5 +1,15 @@ { - "forgot_the_password_image": "Forgot the password?", - "shit_happens": "Oops, this happens. If you wish to continue changing the password, you should enter the following code on the website. If you didn't start this process, just delete this email to be sure – this code may be used to steal your password.", - "continue_image": "Continue" + "forgot_the_password_image": { + "type": "text2png", + "defaultMessage": "Forgot the password?", + "size": 32, + "color": "#fff" + }, + "shit_happens": "Oops, this happens. If you wish to continue changing the password, you should enter the following code on the website. If you haven't requested password recovery, just ignore this email. Without this code no-one will be able to steal your password.", + "continue_image": { + "type": "text2png", + "defaultMessage": "Continue", + "size": 18, + "color": "#fff" + } } diff --git a/src/emails/register/Register.js b/src/emails/register/Register.js index 8041fb7..a6100f1 100644 --- a/src/emails/register/Register.js +++ b/src/emails/register/Register.js @@ -1,11 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage as Message } from 'react-intl'; +import { FormattedMessage as Message, FormattedHTMLMessage as HTMLMessage } from 'react-intl'; import { Userbar, Header, Content, Footer } from 'components/layout'; import { Table } from 'components/table'; import { blue } from 'components/ui/colors'; -import { BitmapText } from 'components/text'; import { Code } from 'components/blocks'; import styles from './styles'; @@ -21,7 +20,7 @@ export default function Register({username, link, code}) {
+ } /> @@ -36,7 +35,7 @@ export default function Register({username, link, code}) { + } /> @@ -45,7 +44,7 @@ export default function Register({username, link, code}) { ...styles.contentCenterCell, ...styles.whatsNextText }}> - + @@ -59,7 +58,7 @@ export default function Register({username, link, code}) { }} /> - +
- +
- +
- +
diff --git a/src/emails/register/messages.intl.json b/src/emails/register/messages.intl.json index 44e39d2..8cadf52 100644 --- a/src/emails/register/messages.intl.json +++ b/src/emails/register/messages.intl.json @@ -1,12 +1,42 @@ { - "welcome_image": "Welcome to Ely.by", - "we_glad_to_see_you": "We glad to see you among the users of Ely.by. You almost reached the final point, it remains only to confirm your E-mail address.For doing it, please push a button under the text.", - "confirm_email_image": "Confirm E‑mail", - "whats_next_image": "What's the next?", - "choose_you_skin_image": "Choose your skin", + "welcome_image": { + "type": "text2png", + "defaultMessage": "Welcome to Ely.by", + "size": 32, + "color": "#fff" + }, + "we_glad_to_see_you": "We glad to see you among the users of Ely.by. You almost reached the final point, it remains only to confirm your E-mail address. Please push the button bellow to continue.", + "confirm_email_image": { + "type": "text2png", + "defaultMessage": "Confirm E‑mail", + "size": 18, + "color": "#fff" + }, + "whats_next_image": { + "type": "text2png", + "defaultMessage": "What's the next?", + "size": 32, + "color": "#444" + }, + "choose_you_skin_image": { + "type": "text2png", + "defaultMessage": "Choose your skin", + "size": 24, + "color": "#6b5a8d" + }, "choose_you_skin_text": "In Ely.by's catalog you can find great diversity of skins, which are ready to be put up.", - "install_our_patch_image": "Install our patch in the game", - "install_our_patch_text": "You should install our patch to make the Ely.by's skin system working. You can find it at 'Load' section.", - "use_tlauncher_image": "Use TLauncher", - "use_tlauncher_text": "It is much easier, when you use right tool for right purpose. TLauncher is one of the best alternative launchers for the Minecraft, that also has installed Ely.by's support system." + "install_our_patch_image": { + "type": "text2png", + "defaultMessage": "Install our patch in the game", + "size": 24, + "color": "#df864a" + }, + "install_our_patch_text": "You should install our patch to make the Ely.by's skin system working. You can find it in 'Load' section on our site.", + "useTLLauncher": { + "type": "text2png", + "defaultMessage": "Use TL launcher", + "size": 24, + "color": "#28555b" + }, + "useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support." } diff --git a/src/i18n/be.json b/src/i18n/be.json index 61e0ac7..595d59a 100644 --- a/src/i18n/be.json +++ b/src/i18n/be.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "ці", "components.blocks.code.pass_code_in_field": "Пазнач гэты код у поле ўводу на сайце:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Ты атрымаў гэты ліст, бо гэты E‑mail быў пазначаны пры рэгістрацыі на сэрвісе {serviceLink}. Калі гэта быў не ты, то проста выдалі гэты ліст.", - "components.layout.footer.footer_logo_alt": "Ely.by - Альтэрнатыўныя сэрвісы Minecraft", "components.layout.footer.service_name": "Акаўнты Ely.by", "components.layout.header.hello_username": "Прывітанне, {username}", "emails.forgotPassword.continue_image": "Працягуць", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Пацвердзіць E‑mail", "emails.register.install_our_patch_image": "Устанаві наш патч у гульню", "emails.register.install_our_patch_text": "Для таго, каб сістема скіноў Ely.by працавала, табе патрэбна ўстанавіць наш патч. Знайсці яго можна ў раздзеле загрузак на сайце.", - "emails.register.use_tlauncher_image": "Выкарыстоўвай TLauncher", - "emails.register.use_tlauncher_text": "Усё значна лягчэй, калі ты выкарыстоўваеш правільную прыладу для сваёй задачы. TLauncher з'яўляецца лепшым альтэрнатыўным лаунчарам для Minecraft, які таксама мае ўбудаваную падтрымку Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Мы рады бачыць цябе ў шэрагах карыстальнікаў праекту Ely.by. Ты ўжо амаль у мэты, засталося толькі пацвердзіць свой E‑mail адрас. Каб зрабіць гэта, калі ласка, націсні на кнопку, якая знаходзіцца ніжэй.", "emails.register.welcome_image": "Сардэчна запрашаем на Ely.by", "emails.register.whats_next_image": "Што далей?" diff --git a/src/i18n/el.json b/src/i18n/el.json index 66a1d9c..ba99857 100644 --- a/src/i18n/el.json +++ b/src/i18n/el.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "ή", "components.blocks.code.pass_code_in_field": "Πληκτρολογήστε αυτόν το κωδικό στο κενό στην ιστοσελίδα:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Λάβατε αυτό το μήνυμα, γιατί αυτό το E‑mail είχε εισαχθεί για την δημιουργία λογαριασμού στην υπηρεσία {serviceLink}. Αν δεν ήσασταν εσείς παρακαλώ αγνοείστε αυτό το μήνυμα.", - "components.layout.footer.footer_logo_alt": "Ely.by - Alternative Minecraft services", "components.layout.footer.service_name": "Λογαριασμός Ely.by", "components.layout.header.hello_username": "Γεια {username}", "emails.forgotPassword.continue_image": "Συνέχεια", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Επιβεβαίωση E‑mail", "emails.register.install_our_patch_image": "Κάνε αναβάθμιση μέσα στο παιχνίδι", "emails.register.install_our_patch_text": "Θα ήταν καλύτερα να κατέβαζες την καινούργια αναβάθμιση για να κάνει το συστημα να δουλέψει. Μπορείς να το βρείς στην κατηγορία 'φόρτιση' στην ιστοσελίδα.", - "emails.register.use_tlauncher_image": "Χρησιμοποίησε το TLauncher", - "emails.register.use_tlauncher_text": "Είναι πολύ ποιο εύκολο όταν χρησιμοποιείς το σωστό εργαλείο για την σωστή χρήση. Το TLauncher είναι​ το καλύτερο εναλλακτικό launcher για το Minecraft, το οποίο υποστηρίζει το σύστημα Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Χαιρόμαστε που βρίσκεσαι ανάμεσα στους χρήστες του Ely.by. Έμεινε μόνο ένα ακόμη πράγμα, να επιβιώσεις την διεύθυνση ηλεκτρονικού ταχυδρομείου. Παρακαλώ πατήστε το κουμπί παρακάτω για να συνεχίσεις.", "emails.register.welcome_image": "Καλωσορίσατε στο Ely.by", "emails.register.whats_next_image": "Τι έχει μετά;" diff --git a/src/i18n/en.json b/src/i18n/en.json index 33244e3..61053e7 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "or", "components.blocks.code.pass_code_in_field": "Insert this code into form field of our site:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "You have received this message, because this E‑mail was entered during registration at the {serviceLink} service. If that wasn't you, please just ignore this message.", - "components.layout.footer.footer_logo_alt": "Ely.by - Alternative Minecraft services", "components.layout.footer.service_name": "Accounts Ely.by", "components.layout.header.hello_username": "Hello, {username}", "emails.forgotPassword.continue_image": "Continue", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Confirm E‑mail", "emails.register.install_our_patch_image": "Install our patch in the game", "emails.register.install_our_patch_text": "You should install our patch to make the Ely.by's skin system working. You can find it in 'Load' section on our site.", - "emails.register.use_tlauncher_image": "Use TLauncher", - "emails.register.use_tlauncher_text": "It is much easier, when you use right tool for the right purpose. TLauncher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "We glad to see you among the users of Ely.by. You almost reached the final point, it remains only to confirm your E-mail address. Please push the button bellow to continue.", "emails.register.welcome_image": "Welcome to Ely.by", "emails.register.whats_next_image": "What's the next?" diff --git a/src/i18n/fil.json b/src/i18n/fil.json index 1482770..1607cd7 100644 --- a/src/i18n/fil.json +++ b/src/i18n/fil.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "o", "components.blocks.code.pass_code_in_field": "Isingit ang code sa form field ng aming site:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Natanggap mo ang mensaheng ito, dahil ito E-mail ay naipasok tuwing registration sa {serviceLink} serbisyo. kung hindi ikaw yung wag mo nalang pansinin tong message.", - "components.layout.footer.footer_logo_alt": "Ely.by - Alternatibong Minecraft na Serbisyo", "components.layout.footer.service_name": "Accounts Ely.by", "components.layout.header.hello_username": "Kamusta, {username}\n", "emails.forgotPassword.continue_image": "Continue", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Kumpirmahin ang E-mail", "emails.register.install_our_patch_image": "I-install ang aming patch sa laro", "emails.register.install_our_patch_text": "Dapat mong i-install ang aming patch upang gumawa ng balat sistema ng pagtatrabaho sa Ely.by ni. Maaari mong mahanap ito sa seksyon ng 'I-load ang' sa aming site.", - "emails.register.use_tlauncher_image": "Gamitin mo ang Tlauncher", - "emails.register.use_tlauncher_text": "Ito ay lubhang mas madaling, kapag ginamit mo tamang tool para sa tamang layunin. TLauncher ay isa sa mga pinakamahusay na alternatibong launcher para sa Minecraft, na mayroon ding Ely.by sistema ng suporta.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Kami ay natutuwa na nakikita mo sa gitna ng mga gumagamit ng mga Ely.by. Halos umabot sa panghuling punto, ito ay nananatiling lamang upang kumpirmahin ang iyong E-mail address. Mangyaring itulak ang pindutan ng bellow upang magpatuloy.", "emails.register.welcome_image": "Maligayang pagdating sa Ely.by", "emails.register.whats_next_image": "Ano ang susunod?" diff --git a/src/i18n/fr.json b/src/i18n/fr.json index 3f94df0..41a5c3b 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "ou", "components.blocks.code.pass_code_in_field": "Insérez ce code dans le champ de formulaire de notre site:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Vous avez reçu ce message, car cet e-mail a été saisi lors de l'inscription au service des {serviceLink}. Si ce n'était pas vous, ignorez ce message.", - "components.layout.footer.footer_logo_alt": "Ely.by - Services alternatifs de Minecraft", "components.layout.footer.service_name": "Comptes Ely.by", "components.layout.header.hello_username": "Bonjour {username},", "emails.forgotPassword.continue_image": "Continuer", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Confirmez votre E-mail", "emails.register.install_our_patch_image": "Installez notre application dans le jeu", "emails.register.install_our_patch_text": "Vous devrez installer notre application pour faire fonctionner le système de skin Ely.by. Vous pouvez le trouver dans la section 'Télécharger' sur notre site.", - "emails.register.use_tlauncher_image": "Utiliser TLauncher", - "emails.register.use_tlauncher_text": "C'est beaucoup plus facile, lorsque vous utilisez l'outil approprié pour le bon but. TLauncher est l'un des meilleurs launchers pour Minecraft, qui dispose également du support de notre système de skins Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Nous sommes heureux de vous voir parmi les utilisateurs de Ely.by. Vous avez presque atteint le dernier point, il ne vous reste qu'à confirmer votre adresse E-mail. Appuyez sur le bouton ci-dessous pour continuer.", "emails.register.welcome_image": "Bienvenue sur Ely.by", "emails.register.whats_next_image": "C'est quoi après?" diff --git a/src/i18n/id.json b/src/i18n/id.json index 7d1fe0c..0fa7889 100644 --- a/src/i18n/id.json +++ b/src/i18n/id.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "atau", "components.blocks.code.pass_code_in_field": "Masukkan kode ini kedalam bagian formulir situs kami:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Anda telah menerima pesan ini, karena E-mail ini dimasukkan saat pendaftaran di layanan {serviceLink}. Jika itu bukan anda, mohon abaikan saja pesan ini.", - "components.layout.footer.footer_logo_alt": "Ely.by - Layanan Minecraft Alternatif", "components.layout.footer.service_name": "Akun Ely.by", "components.layout.header.hello_username": "Halo, {username}", "emails.forgotPassword.continue_image": "Lanjutkan", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Konfirmasi E-mail", "emails.register.install_our_patch_image": "Pasang patch kami didalam game", "emails.register.install_our_patch_text": "Anda harus memasang patch kami agar sistem skin Ely.by dapat bekerja. Anda bisa menemukannya pada bagian \"Unduhan\" di situs kami.", - "emails.register.use_tlauncher_image": "Gunakan TLauncher", - "emails.register.use_tlauncher_text": "Akan jauhlebih mudah saat anda menggunakan alat yang benar untuk tujuan yang benar. TLauncher adalah salah satu dari peluncur Minecraft alternatif terbaik, yang juga memiliki dukungan sistem Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Kami senang melihat Anda di antara pengguna Ely.by. Anda hampir mencapai titik akhir, hanya tinggal untuk mengkonfirmasi alamat E-mail Anda. Tolong tekan tombol di bawah untuk melanjutkan.", "emails.register.welcome_image": "Selamat datang di Ely.by", "emails.register.whats_next_image": "Selanjutnya apa?" diff --git a/src/i18n/lt.json b/src/i18n/lt.json index f2e60a8..9d117c5 100644 --- a/src/i18n/lt.json +++ b/src/i18n/lt.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "arba", "components.blocks.code.pass_code_in_field": "Įterpkite šį kodą į mūsų svetainės formos lauką:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Jūs gavote šį pranešimą, nes šis elektroninis paštas buvo įvestas registruojant {serviceLink} tarnybą. Jei tai nebuvo jūsų, tiesiog ignoruokite šį pranešimą.", - "components.layout.footer.footer_logo_alt": "Ely.by - Alternatyvios Minecraft paslaugos", "components.layout.footer.service_name": "Paskyros Ely.by", "components.layout.header.hello_username": "Sveiki, {username}", "emails.forgotPassword.continue_image": "Tęsti", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Patvirtinti el. paštą", "emails.register.install_our_patch_image": "Įdiekite mūsų pleistrą žaidime", "emails.register.install_our_patch_text": "Turėtumėte įdiegti mūsų pleistrą, kad veiktų Ely.by apvalkalų sistema. Tai galite rasti mūsų svetainėje esančioje skiltyje \"Įkelti\".", - "emails.register.use_tlauncher_image": "Naudoti TLauncher", - "emails.register.use_tlauncher_text": "Tai daug lengviau, kai naudojate teisingą priemonę tinkamam tikslui. TLauncher yra viena iš geriausių Minecraft alternatyvių paleidiklių, kuri taip pat turi Ely.by sistemos palaikymą.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Mielai matome jus tarp Ely.by naudotojų. Jūs beveik pasiekėte paskutinį tašką, lieka tik patvirtinti savo el. pašto adresą. Jei norite tęsti, spauskite žemiau esantį mygtuką.", "emails.register.welcome_image": "Sveiki atvykę į Ely.by", "emails.register.whats_next_image": "Kas toliau?" diff --git a/src/i18n/pl.json b/src/i18n/pl.json index 26e09b9..91b6cd8 100644 --- a/src/i18n/pl.json +++ b/src/i18n/pl.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "lub", "components.blocks.code.pass_code_in_field": "Wprowadź ten kod w polu formularza na naszej stronie", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Otrzymałeś tę wiadomość, ponieważ ten E-mail został wprowadzony podczas rejestracji w usłudze {serviceLink}. Jeśli to nie ty, po prostu zignoruj ​​tę wiadomość.", - "components.layout.footer.footer_logo_alt": "Ely.by - Alternatywne usługi Minecraft", "components.layout.footer.service_name": "Kont Ely.by", "components.layout.header.hello_username": "Cześć, {username}", "emails.forgotPassword.continue_image": "Dalej", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Potwierdź adres E-mail", "emails.register.install_our_patch_image": "Zainstaluj nasz patch w grze", "emails.register.install_our_patch_text": "Powinieneś zainstalować nasz patch, by nasz system Ely.by działał poprawnie. Można znaleźć go w zakładce \"załaduj\" na naszej stronie.", - "emails.register.use_tlauncher_image": "Użyj TLauncher", - "emails.register.use_tlauncher_text": "Jest to dużo łatwiejsze, gdy używasz właściwego narzędzia do właściwego celu. TLauncher jest jednym z najlepszych alternatywnych launcherów dla Minecraft'a, który również obsługuje system Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Cieszymy się widząc Ciebie pośród użytkowników Ely.by. Już prawie dotarłeś do końca, lecz pozostało Ci jedynie potwierdzić Twój adres E-mail. Naciśnij przycisk poniżej, by kontynuować.", "emails.register.welcome_image": "Witamy na Ely.by", "emails.register.whats_next_image": "Co dalej?" diff --git a/src/i18n/pt.json b/src/i18n/pt.json index 8a04787..8589d9e 100644 --- a/src/i18n/pt.json +++ b/src/i18n/pt.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "ou", "components.blocks.code.pass_code_in_field": "Insira esse código no campo de formulário do nosso site:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Você recebeu essa mensagem porque este E-mail foi digitado durante o registro no serviço {serviceLink}. Se não foi você, apenas ignore esta mensagem.", - "components.layout.footer.footer_logo_alt": "Ely.by - Serviço de Minecraft alternativo", "components.layout.footer.service_name": "Contas Ely.by", "components.layout.header.hello_username": "Olá, {username}", "emails.forgotPassword.continue_image": "Continuar", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Confirmar E-mail", "emails.register.install_our_patch_image": "Instale nosso patch no jogo", "emails.register.install_our_patch_text": "Você deve instalar o nosso patch para fazer o sistema de skins Ely.by funcionar. Você pode encontrá-lo na seção 'carregar' no nosso site.", - "emails.register.use_tlauncher_image": "Use o TLauncher", - "emails.register.use_tlauncher_text": "É muito fácil quando você usa a ferramenta correta para o motivo correto. O TLauncher é uma das melhores alternativas de launchers para Minecraft, e também tem o suporte do sistema Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Estamos felizes de ver você entre os usuários do Ely.by. Você está quase no final, falta apenas confirmar o endereço de E-mail. Por favor, aperte o botão abaixo para continuar.", "emails.register.welcome_image": "Bem-vindo ao Ely.by", "emails.register.whats_next_image": "O que é o próximo a se fazer?" diff --git a/src/i18n/ro.json b/src/i18n/ro.json index 07a620e..8f6d8f3 100644 --- a/src/i18n/ro.json +++ b/src/i18n/ro.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "sau", "components.blocks.code.pass_code_in_field": "Insereaza acest cod in formularul de pe site-ul nostru:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Ai primit acest mesaj deoarece acest E-mail a fost introdus intr-o inregistrare la serviciul {serviceLink}. Daca nu ati fost dvs., va rugam sa ingnorati acest mesaj.", - "components.layout.footer.footer_logo_alt": "Ely.by - Servicii Minecraft Alternative", "components.layout.footer.service_name": "Conturi Ely.by", "components.layout.header.hello_username": "Bună ziua, {username}", "emails.forgotPassword.continue_image": "Continua", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Confirma E-mail-ul", "emails.register.install_our_patch_image": "Instaleaza pachetul nostru in joc", "emails.register.install_our_patch_text": "Ar trebui sa instalezi pachetul nostru pentru a sistemul de skinuri Ely.by sa functioneze. Poti sa il gasesti in sectiunea \"Incarca\" de pe site-ul nostru.", - "emails.register.use_tlauncher_image": "Foloseste TLauncher", - "emails.register.use_tlauncher_text": "Este mult mai usor, cand folosesti unealta buna pentru un motiv bun. TLauncher e unul dintre cele mai bune lansatoare alternative pentru Minecraft, care are si suport pentru sistem Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Ne bucurăm să vă vedem printre utilizatorii Ely.by. Aproape ați ajuns la punctul final, rămâne doar pentru a vă confirma adresa de E-mail. Apăsați butonul de mai jos pentru a continua.", "emails.register.welcome_image": "Bun venit pe Ely.by", "emails.register.whats_next_image": "Ce urmeaza?" diff --git a/src/i18n/ru.json b/src/i18n/ru.json index 966b314..05e53c8 100644 --- a/src/i18n/ru.json +++ b/src/i18n/ru.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "или", "components.blocks.code.pass_code_in_field": "Укажи этот код в поле ввода на сайте:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Ты получил это письмо, т.к. этот E‑mail был указан при регистрации на сервисе {serviceLink}. Если это был не ты, то просто удали это письмо.", - "components.layout.footer.footer_logo_alt": "Ely.by - Альтернативные сервисы Minecraft", "components.layout.footer.service_name": "Аккаунты Ely.by", "components.layout.header.hello_username": "Привет, {username}", "emails.forgotPassword.continue_image": "Продолжить", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Подтвердить E‑mail", "emails.register.install_our_patch_image": "Установи наш патч в игру", "emails.register.install_our_patch_text": "Для того, чтобы система скинов Ely.by работала, тебе нужно установить наш патч. Найти его можно в разделе загрузок на сайте.", - "emails.register.use_tlauncher_image": "Используй TLauncher", - "emails.register.use_tlauncher_text": "Всё гораздо проще, когда ты используешь правильный инструмент для своей задачи. TLauncher является лучшим альтернативным лаунчером для Minecraft, который также имеет встроенную поддержку Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Мы рады видеть тебя в рядах пользователей проекта Ely.by. Ты уже почти у цели, осталось лишь подтвердить свой E‑mail адрес. Чтобы сделать это, пожалуйста, нажми на кнопку, которая расположена ниже.", "emails.register.welcome_image": "Добро пожаловать на Ely.by", "emails.register.whats_next_image": "Что дальше?" diff --git a/src/i18n/sl.json b/src/i18n/sl.json index c95d164..d47aeb9 100644 --- a/src/i18n/sl.json +++ b/src/i18n/sl.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "ali", "components.blocks.code.pass_code_in_field": "Vnesi to kodo v polje na naši spletni strani:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "To sporočilo ste prejeli, ker je bil ta E-mail vnesen med registracijo {serviceLink} storitve. Če to niste bili vi, prosim ignorirajte to sporočilo.", - "components.layout.footer.footer_logo_alt": "Ely.by - Alternativne storitve za Minecraft", "components.layout.footer.service_name": "Računi Ely.by", "components.layout.header.hello_username": "Pozdravljen, {username}", "emails.forgotPassword.continue_image": "Nadaljuj", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Potrdi E-mail", "emails.register.install_our_patch_image": "Namesti maš dodatek v igro", "emails.register.install_our_patch_text": "Če hočeš, da sistem za skin deluje, moraš namestiti dodatek Ely.by. Najdeš ga lahko na poglavju 'Naloži' na naši strani.", - "emails.register.use_tlauncher_image": "Uporabi TLauncher", - "emails.register.use_tlauncher_text": "Veliko lažje je, če uporabljaš prava orodja za prave stvari. TLauncher je eden najboljših alternativnih zaganjalnikov za igro Minecraft. Kar je še bolje, pa je, da podpira Ely.by skin sistem.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Srečni smo, da te lahko najdemo med uporabniki Ely.by. Edino, kar ti preostane do tvojega računa je potrditev E-maila. Prosim pritisni gumb spodaj za nadaljevanje.", "emails.register.welcome_image": "Dobrodošel na Ely.by", "emails.register.whats_next_image": "Kaj sledi?" diff --git a/src/i18n/uk.json b/src/i18n/uk.json index 9b1b1dc..d952a5d 100644 --- a/src/i18n/uk.json +++ b/src/i18n/uk.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "або", "components.blocks.code.pass_code_in_field": "Введи цей код в форму на сайті:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Ти отримав цей лист, тому що твій E-mail було вказано при реєстрації на сервісі {serviceLink}. Якщо це був не ти, то просто видали цей лист.", - "components.layout.footer.footer_logo_alt": "Ely.by - Альтернативні сервіси Minecraft", "components.layout.footer.service_name": "Акаунти Ely.by", "components.layout.header.hello_username": "Привіт, {username}", "emails.forgotPassword.continue_image": "Продовжити", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Підтвердити E-mail", "emails.register.install_our_patch_image": "Встанови наш патч в гру", "emails.register.install_our_patch_text": "Для того, щоб система скінів Ely.by працювала, тобі потрібно встановити наш патч. Знайти його можна в розділі завантажень на сайті.", - "emails.register.use_tlauncher_image": "Використовуй TLauncher", - "emails.register.use_tlauncher_text": "Все набагато простіше, коли ти використовуєш правильний інструмент для своєї задачі. TLauncher є кращим альтернативним лаунчером для Minecraft, який також має вбудовану підтримку Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Ми раді бачити тебе в рядах користувачів проекту Ely.by. Ти вже майже у мети, залишилося лише підтвердити свою E-mail адресу. Щоб зробити це, будь ласка, натисни на кнопку, яка розташована нижче.", "emails.register.welcome_image": "Ласкаво просимо до Ely.by", "emails.register.whats_next_image": "Що далі?" diff --git a/src/i18n/vi.json b/src/i18n/vi.json index 5e3822e..bef945c 100644 --- a/src/i18n/vi.json +++ b/src/i18n/vi.json @@ -1,8 +1,8 @@ { "components.blocks.code.or": "hoặc", "components.blocks.code.pass_code_in_field": "Chèn mã này vào mẫu của trang chúng tôi:", + "components.layout.footer.alternativeMinecraftServices": "Alternative Minecraft services", "components.layout.footer.footer": "Bạn đã nhận được tin nhắn này, bởi vì địa chỉ E-mail này đã được nhập trong quá trình đăng ký tại dịch vụ {serviceLink}. Nếu đó không phải bạn, vui lòng bỏ qua tin nhắn.", - "components.layout.footer.footer_logo_alt": "Ely.by - Dịch vụ Minecraft luân hồi", "components.layout.footer.service_name": "Tài khoản Ely.by", "components.layout.header.hello_username": "Xin chào, {username}", "emails.forgotPassword.continue_image": "Tiếp tục", @@ -13,8 +13,8 @@ "emails.register.confirm_email_image": "Xác nhận E-mail", "emails.register.install_our_patch_image": "Cài đặt bản vá của chúng tôi trong game", "emails.register.install_our_patch_text": "Bạn nên cài đặt bản vá của chúng tôi để làm hệ thống skin của Ely.by hoạt động. Bạn có thể tìm thấy nó trong phần 'Tải' trên trang của chúng tôi.", - "emails.register.use_tlauncher_image": "Dùng TLauncher", - "emails.register.use_tlauncher_text": "Nó sẽ rất dễ hơn, khi mà bạn dùng công cụ đúng cho mục đích đúng. TLauncher là một trong những trình khởi động thay thế tốt nhất cho Minecraft, cũng được hỗ trợ bởi hệ thống Ely.by.", + "emails.register.useTLLauncher": "Use TL launcher", + "emails.register.useTLLauncherText": "It is much easier, when you use right tool for the right purpose. The TL launcher is one of the best alternative launchers for the Minecraft, that also has Ely.by system support.", "emails.register.we_glad_to_see_you": "Chúng tôi rất vui vì bạn chọn Ely.by. Bạn đã gần đạt được điểm cuối cùng, bước còn lại là chỉ cần xác nhận E-mail của bạn. Vui lòng nhấn nút bên dưới để tiếp tục.", "emails.register.welcome_image": "Chào mừng tới Ely.by", "emails.register.whats_next_image": "Làm gì tiếp theo?" diff --git a/webpack-utils/extended-translations-loader/RobotoCondensed-Regular.ttf b/webpack-utils/extended-translations-loader/RobotoCondensed-Regular.ttf new file mode 100644 index 0000000..9a1418d Binary files /dev/null and b/webpack-utils/extended-translations-loader/RobotoCondensed-Regular.ttf differ diff --git a/webpack-utils/extended-translations-loader/index.js b/webpack-utils/extended-translations-loader/index.js new file mode 100644 index 0000000..4e467ce --- /dev/null +++ b/webpack-utils/extended-translations-loader/index.js @@ -0,0 +1,120 @@ +/* eslint-env node */ + +const fs = require('fs'); +const path = require('path'); +const glob = require('glob'); +const { stringify } = require('qs'); + +const localFontPath = path.join(__dirname, 'RobotoCondensed-Regular.ttf'); +const localFontName = 'RobotoCondensed'; +const scale = 2; + +module.exports = async function(content) { + this.cacheable && this.cacheable(); + + const callback = this.async(); + + const { publicPath } = this._compiler.options.output; + const ROOT_PATH = path.join(this.rootContext, 'src'); + const localeName = path.basename(this.resourcePath, `.${this.resourcePath.split('.').pop()}`); + + const renderText2Png = (key, { text, size, color }) => new Promise((resolve, reject) => { + if (!text || !size || !color) { + reject(new Error('text, size and color params are required')); + return; + } + + const fileName = `${key.replace(/\./g, '_')}_${localeName}.png`; + const args = { + localFontPath, + localFontName, + text, + color, + font: `${size * scale}px RobotoCondensed`, // eslint-disable-line generator-star-spacing + }; + const renderTextRequest = `text2png-loader?${stringify(args)}!`; + const emitFileRequest = `image-size-loader?name=assets${path.sep}${fileName}?[hash]!${renderTextRequest}`; + this.loadModule(emitFileRequest, (err, module) => { + if (err) { + reject(err); + return; + } + + global.__webpack_public_path__ = publicPath; // eslint-disable-line camelcase + const { src, width, height } = this.exec(module, fileName); + Reflect.deleteProperty(global, '__webpack_public_path__'); + + const targetWidth = Math.ceil(width / scale); + const targetHeight = Math.ceil(height / scale); + + resolve(`${text}`); + }); + }); + + const examine = (key, value) => new Promise((resolve, reject) => { + const pathParts = key.split('.'); + const id = pathParts.pop(); + const pattern = path.join(ROOT_PATH, pathParts.join('/'), '*.intl.json'); + // glob always uses linux separators + glob(pattern.replace(/\\/g, '/'), (err, matches) => { + if (err) { + reject(err); + return; + } + + if (matches.length === 0) { + this.emitWarning(`Unable to find corresponding intl file for ${key} key`); + resolve(value); + return; + } + + for (const path of matches) { + const json = JSON.parse(fs.readFileSync(path)); + const descriptor = json[id]; + if (!descriptor) { + continue; + } + + this.addDependency(path); + + if (typeof descriptor === 'string') { + resolve(value); + continue; + } + + if (typeof descriptor !== 'object') { + this.emitWarning('Unknown value type'); + continue; + } + + const { type } = descriptor; + if (type !== 'text2png') { + this.emitWarning(`Unsupported object key type "${type}"`); + continue; + } + + renderText2Png(key, { + ...descriptor, + text: value, + }).then(resolve).catch(reject); + + return; + } + + resolve(value); + }); + }); + + const json = JSON.parse(content); + const result = JSON.stringify(await Object.keys(json).reduce(async (translationsPromise, key) => { + const translations = await translationsPromise; + translations[key] = await examine(key, json[key]); + + return translations; + }, Promise.resolve({}))); + + callback(null, ` + import { defineMessages } from 'react-intl'; + export default defineMessages(${result}); + `); +}; diff --git a/webpack-utils/extended-translations-loader/package.json b/webpack-utils/extended-translations-loader/package.json new file mode 100644 index 0000000..752846b --- /dev/null +++ b/webpack-utils/extended-translations-loader/package.json @@ -0,0 +1,13 @@ +{ + "name": "extended-translations-loader", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "@lesechos/image-size-loader": "file:./../image-size-loader", + "glob": "^7.1.4", + "loader-utils": "^1.2.3", + "text2png-loader": "file:./../text2png-loader", + "tmp": "^0.0.33", + "qs": "^6.0.0" + } +} diff --git a/webpack-utils/image-size-loader/index.js b/webpack-utils/image-size-loader/index.js new file mode 100644 index 0000000..da94934 --- /dev/null +++ b/webpack-utils/image-size-loader/index.js @@ -0,0 +1,108 @@ +/* eslint-disable multiline-ternary */ +const path = require('path'); +const fs = require('fs'); + +const sizeOf = require('image-size'); +const loaderUtils = require('loader-utils'); +const validateOptions = require('schema-utils'); + +const schema = require('./options.json'); + +function imageToString(image) { + return ` + module.exports = { + src: ${image.src}, + width: ${JSON.stringify(image.width)}, + height: ${JSON.stringify(image.height)}, + bytes: ${JSON.stringify(image.bytes)}, + type: ${JSON.stringify(image.type)}, + }; + // For requires from CSS when used with webpack css-loader, + // outputting an Object doesn't make sense, + // So overriding the toString method to output just the URL + module.exports.toString = function() { + return ${image.src}; + }; + `; +} + +module.exports = function(content) { + if (!this.emitFile) { + throw new Error('File Loader\n\nemitFile is required from module system'); + } + + const options = loaderUtils.getOptions(this) || {}; + + validateOptions(schema, options, 'File Loader'); + + const context = options.context || this.rootContext || (this.options && this.options.context); + + const url = loaderUtils.interpolateName(this, options.name, { + context, + content, + regExp: options.regExp, + }); + + let image; + if (this.resourcePath) { + image = sizeOf(this.resourcePath); + image.bytes = fs.statSync(this.resourcePath).size; + } else { + image = sizeOf(content); + image.bytes = content.byteLength; + } + + let outputPath = url; + + if (options.outputPath) { + if (typeof options.outputPath === 'function') { + outputPath = options.outputPath(url); + } else { + outputPath = path.posix.join(options.outputPath, url); + } + } + + if (options.useRelativePath) { + const filePath = this.resourcePath; + + const issuer = options.context ? context : this._module && this._module.issuer && this._module.issuer.context; + + const relativeUrl = issuer && path + .relative(issuer, filePath) + .split(path.sep) + .join('/'); + + const relativePath = relativeUrl && `${path.dirname(relativeUrl)}/`; + // eslint-disable-next-line no-bitwise + if (~relativePath.indexOf('../')) { + outputPath = path.posix.join(outputPath, relativePath, url); + } else { + outputPath = path.posix.join(relativePath, url); + } + } + + let publicPath = `__webpack_public_path__ + ${JSON.stringify(outputPath)}`; + + if (options.publicPath) { + if (typeof options.publicPath === 'function') { + publicPath = options.publicPath(url); + } else if (options.publicPath.endsWith('/')) { + publicPath = options.publicPath + url; + } else { + publicPath = `${options.publicPath}/${url}`; + } + + publicPath = JSON.stringify(publicPath); + } + + image.src = publicPath; + + // eslint-disable-next-line no-undefined + if (options.emitFile === undefined || options.emitFile) { + this.emitFile(outputPath, content); + } + + return imageToString(image); +}; + +module.exports.raw = true; diff --git a/webpack-utils/image-size-loader/options.json b/webpack-utils/image-size-loader/options.json new file mode 100644 index 0000000..bab6fd5 --- /dev/null +++ b/webpack-utils/image-size-loader/options.json @@ -0,0 +1,19 @@ +{ + "type": "object", + "properties": { + "name": {}, + "regExp": {}, + "context": { + "type": "string" + }, + "publicPath": {}, + "outputPath": {}, + "useRelativePath": { + "type": "boolean" + }, + "emitFile": { + "type": "boolean" + } + }, + "additionalProperties": true +} \ No newline at end of file diff --git a/webpack-utils/image-size-loader/package.json b/webpack-utils/image-size-loader/package.json new file mode 100644 index 0000000..bf1ce9b --- /dev/null +++ b/webpack-utils/image-size-loader/package.json @@ -0,0 +1,13 @@ +{ + "name": "@lesechos/image-size-loader", + "version": "1.0.0", + "main": "index.js", + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" + }, + "dependencies": { + "image-size": "^0.6.3", + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + } +} diff --git a/webpack-utils/intl-json-loader/index.js b/webpack-utils/intl-json-loader/index.js index 09a1a23..d988a0b 100644 --- a/webpack-utils/intl-json-loader/index.js +++ b/webpack-utils/intl-json-loader/index.js @@ -10,16 +10,25 @@ module.exports = function(input) { const json = JSON.parse(input); const result = JSON.stringify(Object.keys(json).reduce((translations, key) => { - translations[key] = { - id: `${moduleId}.${key}`, - defaultMessage: json[key], - }; + const value = json[key]; + const id = `${moduleId}.${key}`; + if (typeof value === 'object') { + translations[key] = { + ...value, + id, + }; + } else { + translations[key] = { + id, + defaultMessage: value, + }; + } return translations; }, {})); return ` import { defineMessages } from 'react-intl'; - export default defineMessages(${result}) + export default defineMessages(${result}); `; }; diff --git a/webpack-utils/text2png-loader/index.js b/webpack-utils/text2png-loader/index.js new file mode 100644 index 0000000..e7aed02 --- /dev/null +++ b/webpack-utils/text2png-loader/index.js @@ -0,0 +1,16 @@ +/* eslint-env node */ + +const { getOptions } = require('loader-utils'); +const text2png = require('text2png'); + +module.exports = function() { + this.cacheable && this.cacheable(); + + const { text, ...options } = getOptions(this); + if (!text) { + this.emitError('The text param is required'); + return ''; + } + + return text2png(text, options); +}; diff --git a/webpack-utils/text2png-loader/package.json b/webpack-utils/text2png-loader/package.json new file mode 100644 index 0000000..b22e959 --- /dev/null +++ b/webpack-utils/text2png-loader/package.json @@ -0,0 +1,9 @@ +{ + "name": "text2png-loader", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "text2png": "^2.1.0", + "loader-utils": "^1.2.3" + } +} diff --git a/webpack.config.js b/webpack.config.js index 028c5ec..f726b26 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,8 +2,11 @@ const path = require('path'); +const { ContextReplacementPlugin } = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); +const SUPPORTED_LANGUAGES = Object.keys(require('./src/i18n/index.json')); + module.exports = (env, { mode = 'development' }) => { const isProduction = mode === 'production'; @@ -33,7 +36,7 @@ module.exports = (env, { mode = 'development' }) => { resolveLoader: { alias: { - 'image-size-loader': path.join(__dirname, 'node_modules/@eoleo/image-size-loader/dist/cjs.js'), + 'image-size-loader': path.join(__dirname, 'node_modules/@lesechos/image-size-loader/index.js'), }, }, @@ -46,6 +49,9 @@ module.exports = (env, { mode = 'development' }) => { }, plugins: [ + new ContextReplacementPlugin( + /i18n/, new RegExp(`/(${SUPPORTED_LANGUAGES.join('|')})\\.json`) + ), new HtmlWebpackPlugin({ template: 'src/index.ejs', favicon: 'src/favicon.ico', @@ -87,11 +93,6 @@ module.exports = (env, { mode = 'development' }) => { plugins: [ '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-export-default-from', - // TODO: by unknown reasons react-intl plugins isn't working. - // investigate later - ['react-intl', { - messagesDir: path.join(__dirname, 'dist/messages/'), - }], ], }, }, @@ -104,12 +105,20 @@ module.exports = (env, { mode = 'development' }) => { name: 'assets/[name]-[folder].[ext]?[hash]', }, }, + // The explicit declaration of the json loader allows us to disable the built-in + // webpack 4 loader for json, which interferes with the work of text2png-loader + { + test: /\.json$/, + exclude: /\.intl\.json$/, + loader: 'json-loader', + type: 'javascript/auto', + }, { test: /\.intl\.json$/, loader: 'intl-json-loader', type: 'javascript/auto', }, - ] + ], }, }; }; diff --git a/yarn.lock b/yarn.lock index 0c401df..2780534 100644 --- a/yarn.lock +++ b/yarn.lock @@ -652,13 +652,6 @@ "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/runtime@^7.0.0": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.4.tgz#73d12ba819e365fcf7fd152aed56d6df97d21c83" - integrity sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g== - dependencies: - regenerator-runtime "^0.12.0" - "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" @@ -692,10 +685,8 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" -"@eoleo/image-size-loader@^1.0.0": +"@lesechos/image-size-loader@file:./webpack-utils/image-size-loader": version "1.0.0" - resolved "https://registry.yarnpkg.com/@eoleo/image-size-loader/-/image-size-loader-1.0.0.tgz#f63d781cbd0863a925429631bf9013a6266b2046" - integrity sha512-5ltMAAxQQyw95uF1dW9HJ9r727hhdDkS6uEClKS9Rgqwn7dYDAKjoCM1/zIvydbz9h7MbjFWKwRKyCmASXZryw== dependencies: image-size "^0.6.3" loader-utils "^1.1.0" @@ -1076,16 +1067,6 @@ async@^1.5.2: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= -async@~0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= - -async@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" - integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k= - atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -1128,15 +1109,6 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-react-intl@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-3.0.1.tgz#4abc7fff04a7bbbb7034aec0a675713f2e52181c" - integrity sha512-FqnEO+Tq7kJVUPKsSG3s5jaHi3pAC4RUR11IrscvjsfkOApLP2DtzNo6dtQ+tX+OzEzJx7cUms8aCw5BFyW5xg== - dependencies: - "@babel/runtime" "^7.0.0" - intl-messageformat-parser "^1.2.0" - mkdirp "^0.5.1" - babel-plugin-react-transform@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-2.0.2.tgz#515bbfa996893981142d90b1f9b1635de2995109" @@ -1480,6 +1452,14 @@ caniuse-lite@^1.0.30000948: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000949.tgz#8cbc6d2f141bc32362f7467b45a2dcae8e64c84b" integrity sha512-jIF/jphmuJ7oAWmfYO0qAxRAvCa0zNquALO6Ykfe6qo8qwh882Cgcs+OWmm21L3x6nu4TVLFeEZ9/q6VuKCfSg== +canvas@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.4.1.tgz#d3b40efc7c281006ca0ff9cc854aaa8b82abec7a" + integrity sha512-SaFomFqDuuuSTScTHQ7nXc5ea71Ieb8ctvwXjR7vzLsBMfp3euTv2xsTY70zIoC5r4sSQZYXv6tiHiORJ4y1vg== + dependencies: + nan "^2.12.1" + node-pre-gyp "^0.11.0" + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1612,16 +1592,6 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -colors@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= - -colors@^1.1.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" - integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== - commander@2.17.x: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -1827,11 +1797,6 @@ css-what@2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== -cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= - cyclist@~0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" @@ -1892,11 +1857,6 @@ deep-equal@^1.0.1: resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= -deep-equal@~0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" - integrity sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0= - deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -2498,6 +2458,16 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +"extended-translations-loader@file:webpack-utils/extended-translations-loader": + version "1.0.0" + dependencies: + "@lesechos/image-size-loader" "file:../../.cache/yarn/v4/npm-extended-translations-loader-1.0.0-cce5d179-7eca-4a0d-9cb7-e40895c28e2e-1557440986048/node_modules/image-size-loader" + glob "^7.1.4" + loader-utils "^1.2.3" + qs "^6.0.0" + text2png-loader "file:../../.cache/yarn/v4/npm-extended-translations-loader-1.0.0-cce5d179-7eca-4a0d-9cb7-e40895c28e2e-1557440986048/node_modules/text2png-loader" + tmp "^0.0.33" + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -2512,11 +2482,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -eyes@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= - fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -2767,7 +2732,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.1.3: +glob@^7.0.0, glob@^7.0.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -2779,6 +2744,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.3, glob@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -3037,10 +3014,11 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -i@0.3.x: - version "0.3.6" - resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" - integrity sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0= +"i18n-collect@file:scripts/i18n-collect": + version "1.0.0" + dependencies: + glob "^7.1.3" + sort-keys "^3.0.0" iconv-lite@0.4.23: version "0.4.23" @@ -3164,7 +3142,7 @@ intl-format-cache@^2.0.5: "intl-json-loader@file:./webpack-utils/intl-json-loader": version "1.0.0" -intl-messageformat-parser@1.4.0, intl-messageformat-parser@^1.2.0: +intl-messageformat-parser@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075" integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU= @@ -3368,6 +3346,11 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-plain-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.0.0.tgz#7fd1a7f1b69e160cde9181d2313f445c68aa2679" + integrity sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ== + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -3436,11 +3419,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@0.1.x: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - js-levenshtein@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" @@ -3474,6 +3452,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= +json-loader@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== + json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -3589,7 +3572,7 @@ loader-utils@^0.2.16: json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.2, loader-utils@^1.1.0: +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== @@ -3845,7 +3828,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.x, mkdirp@0.x.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -3892,10 +3875,10 @@ mute-stream@0.0.5: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= -mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +nan@^2.12.1: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== nan@^2.9.2: version "2.13.1" @@ -3924,11 +3907,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -ncp@1.0.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" - integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= - needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" @@ -4015,6 +3993,22 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" +node-pre-gyp@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" + integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + node-releases@^1.1.10: version "1.1.11" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.11.tgz#9a0841a4b0d92b7d5141ed179e764f42ad22724a" @@ -4209,7 +4203,7 @@ os-locale@^3.0.0: lcid "^2.0.0" mem "^4.0.0" -os-tmpdir@^1.0.0: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -4394,16 +4388,6 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkginfo@0.3.x: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" - integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE= - -pkginfo@0.x.x: - version "0.4.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" - integrity sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8= - pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" @@ -4466,18 +4450,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -prompt@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe" - integrity sha1-jlcSPDlquYiJf7Mn/Trtw+c15P4= - dependencies: - colors "^1.1.2" - pkginfo "0.x.x" - read "1.0.x" - revalidator "0.1.x" - utile "0.3.x" - winston "2.1.x" - prop-types@^15.5.4, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -4557,6 +4529,11 @@ qs@6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +qs@^6.0.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -4674,13 +4651,6 @@ react@^16.8.4: prop-types "^15.6.2" scheduler "^0.13.4" -read@1.0.x: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= - dependencies: - mute-stream "~0.0.4" - "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -4755,11 +4725,6 @@ regenerator-runtime@^0.11.0: 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" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== - regenerator-transform@^0.13.4: version "0.13.4" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.4.tgz#18f6763cf1382c69c36df76c6ce122cc694284fb" @@ -4908,12 +4873,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -revalidator@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" - integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs= - -rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -4986,14 +4946,6 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -"scripts@file:scripts": - version "1.0.0" - dependencies: - chalk "^1.1.3" - glob "^7.1.3" - mkdirp "^0.5.1" - prompt "^1.0.0" - select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -5182,6 +5134,13 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" +sort-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-3.0.0.tgz#fa751737e3da363ef80632d4fd78e324d661fe9a" + integrity sha512-77XUKMiZN5LvQXZ9sgWfJza19AvYIDwaDGwGiULM+B5XYru8Z90Oh06JvqDlJczvjjYvssrV0aK1GI6+YXvn5A== + dependencies: + is-plain-obj "^2.0.0" + source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -5275,11 +5234,6 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - stackframe@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" @@ -5472,6 +5426,20 @@ text-table@~0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +"text2png-loader@file:./webpack-utils/text2png-loader": + version "1.0.0" + dependencies: + loader-utils "^1.2.3" + text2png "^2.1.0" + +text2png@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/text2png/-/text2png-2.1.0.tgz#789fae490663c1062aa0e6d70d4657710bd67191" + integrity sha512-nk6ccBTNdwRcCGGgYpCOmi17J+tk23r03qcVClb9EgvH5wXdXMfLF01khfeJWT2yfWSkbeNBOzPfkZUeljgRpg== + dependencies: + canvas "^2.0.1" + commander "^2.19.0" + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -5497,6 +5465,13 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -5727,18 +5702,6 @@ utila@^0.4.0, utila@~0.4: resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= -utile@0.3.x: - version "0.3.0" - resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" - integrity sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo= - dependencies: - async "~0.9.0" - deep-equal "~0.2.1" - i "0.3.x" - mkdirp "0.x.x" - ncp "1.0.x" - rimraf "2.x.x" - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -5923,19 +5886,6 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -winston@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e" - integrity sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4= - dependencies: - async "~1.0.0" - colors "1.0.x" - cycle "1.0.x" - eyes "0.1.x" - isstream "0.1.x" - pkginfo "0.3.x" - stack-trace "0.0.x" - wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"