From 17ae4512e19baaefae7af50fea37bcaa9573be51 Mon Sep 17 00:00:00 2001 From: 1aerostorm Date: Sun, 10 Sep 2023 18:25:50 +0000 Subject: [PATCH] NFT UI --- app/ResolveRoute.js | 4 +- app/components/all.scss | 1 + app/components/modules/Header.jsx | 18 +- .../modules/nft/CreateNFTCollection.jsx | 361 ++++++++++++++++++ .../modules/nft/CreateNFTCollection.scss | 34 ++ app/components/modules/nft/NFTCollections.jsx | 94 +++++ app/components/modules/nft/NFTTokens.jsx | 47 +++ app/components/pages/UserProfile.jsx | 31 +- app/locales/en.json | 27 ++ app/locales/ru-RU.json | 27 ++ app/redux/FetchDataSaga.js | 16 + package.json | 2 +- yarn.lock | 53 +-- 13 files changed, 675 insertions(+), 40 deletions(-) create mode 100644 app/components/modules/nft/CreateNFTCollection.jsx create mode 100644 app/components/modules/nft/CreateNFTCollection.scss create mode 100644 app/components/modules/nft/NFTCollections.jsx create mode 100644 app/components/modules/nft/NFTTokens.jsx diff --git a/app/ResolveRoute.js b/app/ResolveRoute.js index fd9ec96..5607b12 100644 --- a/app/ResolveRoute.js +++ b/app/ResolveRoute.js @@ -1,9 +1,9 @@ export const routeRegex = { UserProfile1: /^\/(@[\w\.\d-]+)\/?$/, - UserProfile2: /^\/(@[\w\.\d-]+)\/(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|filled-orders|permissions|created|password|witness|settings)\/??(?:&?[^=&]*=[^=&]*)*$/, + UserProfile2: /^\/(@[\w\.\d-]+)\/(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|nft|nft-collections|filled-orders|permissions|created|password|witness|settings)\/??(?:&?[^=&]*=[^=&]*)*$/, UserProfile3: /^\/(@[\w\.\d-]+)\/[\w\.\d-]+/, UserAssetEndPoints: /^\/(@[\w\.\d-]+)\/assets\/([\w\d.-]+)\/(update|transfer)$/, - UserEndPoints: /^(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|filled-orders|permissions|created|password|witness|settings)$/, + UserEndPoints: /^(transfers|assets|create-asset|invites|curation-rewards|author-rewards|donates-from|donates-to|nft|nft-collections|filled-orders|permissions|created|password|witness|settings)$/, WorkerSort: /^\/workers\/([\w\d\-]+)\/?($|\?)/, WorkerSearchByAuthor: /^\/workers\/([\w\d\-]+)\/(\@[\w\d.-]+)\/?($|\?)/, WorkerRequest: /^\/workers\/([\w\d\-]+)\/(\@[\w\d.-]+)\/([\w\d-]+)\/?($|\?)/, diff --git a/app/components/all.scss b/app/components/all.scss index d85eb42..30d6e92 100644 --- a/app/components/all.scss +++ b/app/components/all.scss @@ -67,6 +67,7 @@ @import "./modules/Powerdown.scss"; @import "./modules/QuickBuy.scss"; @import "./modules/Modals"; +@import "./modules/nft/CreateNFTCollection"; // pages @import "./pages/Exchanges"; diff --git a/app/components/modules/Header.jsx b/app/components/modules/Header.jsx index 12bfd41..f61adfb 100644 --- a/app/components/modules/Header.jsx +++ b/app/components/modules/Header.jsx @@ -91,20 +91,20 @@ class Header extends React.Component { const name = acct_meta ? normalizeProfile(acct_meta.toJS()).name : null; const user_title = name ? `${name} (@${user_name})` : user_name; page_title = user_title; - if(route.params[1] === "curation-rewards"){ + if (route.params[1] === "curation-rewards"){ page_title = tt('header_jsx.curation_rewards_by') + " " + user_title; - } - if(route.params[1] === "author-rewards"){ + } else if (route.params[1] === "author-rewards"){ page_title = tt('header_jsx.author_rewards_by') + " " + user_title; - } - if(route.params[1] === "donates-from"){ + } else if (route.params[1] === "donates-from"){ page_title = tt('header_jsx.donates_from') + " " + user_title; - } - if(route.params[1] === "donates-to"){ + } else if (route.params[1] === "donates-to"){ page_title = tt('header_jsx.donates_to') + " " + user_title; - } - if(route.params[1] === "recent-replies"){ + } else if (route.params[1] === "recent-replies"){ page_title = tt('header_jsx.replies_to') + " " + user_title; + } else if (route.params[1] === "nft"){ + page_title = tt('header_jsx.nft_tokens') + " " + user_title + } else if (route.params[1] === "nft-collections"){ + page_title = tt('header_jsx.nft_collections') + " " + user_title } } else if (route.page === 'ConvertAssetsPage') { page_title = tt('g.convert_assets') diff --git a/app/components/modules/nft/CreateNFTCollection.jsx b/app/components/modules/nft/CreateNFTCollection.jsx new file mode 100644 index 0000000..eff2064 --- /dev/null +++ b/app/components/modules/nft/CreateNFTCollection.jsx @@ -0,0 +1,361 @@ +import React, { Component, } from 'react' +import tt from 'counterpart' +import { connect, } from 'react-redux' +import CloseButton from 'react-foundation-components/lib/global/close-button' +import { Formik, Form, Field, ErrorMessage, } from 'formik' + +import Expandable from 'app/components/elements/Expandable' +import LoadingIndicator from 'app/components/elements/LoadingIndicator' +import transaction from 'app/redux/Transaction' + +const UINT32_MAX = '4294967295' + +class CreateNFTCollection extends Component { + state = { + collection: { + name: '', + title: '', + json_metadata: '{}', + max_token_count: UINT32_MAX, + infinity: true + } + } + + validate = (values) => { + const errors = {} + const { title, name } = values + if (!title.length) { + errors.title = tt('g.required') + } + if (name.length < 3) { + errors.name = tt('assets_jsx.symbol_too_short') + } else { + const parts = name.split('.') + if (parts[0] == 'GOLOS' || parts[0] == 'GBG' || parts[0] == 'GESTS') { + errors.name = tt('assets_jsx.top_symbol_not_your') + } else if (parts.length == 2 && parts[1].length < 3) { + errors.name = tt('assets_jsx.subsymbol_too_short') + } + } + let meta = values.json_metadata + try { + meta = JSON.parse(meta) + if (Array.isArray(meta)) throw new Error('JSON is array') + } catch (err) { + console.error('json_metadata', err) + errors.json_metadata = tt('create_nft_collection_jsx.json_wrong') + meta = null + } + if (meta) { + const noFields = [] + if (!('title' in meta)) noFields.push('title') + if (values.image && !('image' in meta)) noFields.push('image') + if (values.description && !('description' in meta)) noFields.push('description') + if (noFields.length) { + errors.json_metadata = tt('create_nft_collection_jsx.json_no_fields') + errors.json_metadata += noFields.join(', ') + '. ' + } + } + return errors + } + + setSubmitting = (submitting) => { + this.setState({ submitting }) + } + + _onSubmit = async (values) => { + this.setSubmitting(true) + const { currentUser } = this.props + const username = currentUser.get('username') + await this.props.createCollection(values.name, values.json_metadata, values.max_token_count, currentUser, () => { + this.props.fetchState() + this.props.onClose() + this.setSubmitting(false) + }, (err) => { + console.error(err) + this.setSubmitting(false) + }) + } + + _renderSubmittingIndicator = () => { + const { submitting } = this.state + + return submitting ? + + : null + } + + onNameChange = (e, values, setFieldValue) => { + let newName = '' + let hasDot + for (let i = 0; i < e.target.value.length; ++i) { + const c = e.target.value[i] + if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c !== '.') { + continue + } + if (c == '.') { + if (i < 3 || hasDot) { + continue + } + hasDot = true + } + newName += c.toUpperCase() + } + setFieldValue('name', newName) + } + + updateJSONMetadata = (values, setFieldValue, currentVals, force = false) => { + let { json_metadata } = values + try { + json_metadata = JSON.parse(json_metadata) + if (Array.isArray(json_metadata)) { + json_metadata = {} + } + } catch (err) { + console.error('updateJSONMetadata', err) + if (!force) { + return + } + json_metadata = {} + } + + const title = currentVals.title || values.title + json_metadata.title = title || '' + + const description = currentVals.description || values.description + if (description) { + json_metadata.description = description + } + + const image = currentVals.image || values.image + if (image) { + json_metadata.image = image + } + + setFieldValue('json_metadata', JSON.stringify(json_metadata, null, 2)) + } + + onTitleChange = (e, values, setFieldValue) => { + const title = e.target.value + setFieldValue('title', title) + this.updateJSONMetadata(values, setFieldValue, { title }) + } + + onDescriptionChange = (e, values, setFieldValue) => { + const description = e.target.value + setFieldValue('description', description) + this.updateJSONMetadata(values, setFieldValue, { description }) + } + + onImageChange = (e, values, setFieldValue) => { + const image = e.target.value + setFieldValue('image', image) + this.updateJSONMetadata(values, setFieldValue, { image }) + } + + onImageBlur = (e) => { + e.preventDefault() + this.setState({ + showImage: true + }) + } + + onMaxTokenCountChange = (e, setFieldValue) => { + let maxTokenCount = '' + for (let i = 0; i < e.target.value.length; ++i) { + const c = e.target.value[i] + if (c < '0' || c > '9') { + continue + } + maxTokenCount += c + } + if (maxTokenCount === UINT32_MAX) { + setFieldValue('infinity', true) + } + setFieldValue('max_token_count', maxTokenCount) + } + + onInfinityChange = (e, values, setFieldValue) => { + if (!values.infinity) { + setFieldValue('max_token_count', UINT32_MAX) + setFieldValue('infinity', !values.infinity) + } else { + setFieldValue('max_token_count', '') + setFieldValue('infinity', !values.infinity) + } + } + + restoreJson = (e, values, setFieldValue) => { + e.preventDefault() + this.updateJSONMetadata(values, setFieldValue, {}, true) + } + + fixJson = (e, values, setFieldValue) => { + e.preventDefault() + this.updateJSONMetadata(values, setFieldValue, {}) + } + + render() { + const { onClose, } = this.props; + const { submitting, showImage } = this.state + + return (
+ +

+ {tt('create_nft_collection_jsx.title')} +

+ + {({ + handleSubmit, isValid, values, errors, touched, setFieldValue, handleChange, + }) => { + return ( +
+
+
+ {tt('create_nft_collection_jsx.name')} +
+ this.onNameChange(e, values, setFieldValue)} /> +
+
+
+ {tt('create_nft_collection_jsx.coll_title') + '*'} +
+ this.onTitleChange(e, values, setFieldValue)} /> +
+ {!errors.name && } +
+ +
+
+ {tt('create_nft_collection_jsx.coll_descr')} + {' '} + {tt('create_nft_collection_jsx.not_required')} +
+
+
+
+ this.onDescriptionChange(e, values, setFieldValue)} /> +
+ +
+
+
+ {tt('create_nft_collection_jsx.image')} + {' '} + {tt('create_nft_collection_jsx.not_required')} +
+
+
+
+ this.onImageChange(e, values, setFieldValue)} /> + +
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+ + {(touched.json_metadata && errors.json_metadata) ? + (errors.json_metadata === tt('create_nft_collection_jsx.json_wrong') ? + this.restoreJson(e, values, setFieldValue)}>{tt('create_nft_collection_jsx.restore_json')} : + this.fixJson(e, values, setFieldValue)}>{tt('create_nft_collection_jsx.json_fix')}) + : null} +
+
+
+ {tt('create_nft_collection_jsx.token_count')} +
+
+
+
+ this.onMaxTokenCountChange(e, setFieldValue)} + /> +
+
+
+
+ +
+
+
+
+
+ + + {this._renderSubmittingIndicator()} +
+
+
+ )}}
+
) + } +} + +export default connect( + // mapStateToProps + (state, ownProps) => { + const {locationBeforeTransitions: {pathname}} = state.routing; + let currentUser = ownProps.currentUser || state.user.getIn(['current']) + if (!currentUser) { + const currentUserNameFromRoute = pathname.split(`/`)[1].substring(1); + currentUser = Map({username: currentUserNameFromRoute}); + } + const currentAccount = currentUser && state.global.getIn(['accounts', currentUser.get('username')]); + return { ...ownProps, currentUser, currentAccount, }; + }, + + dispatch => ({ + createCollection: ( + name, json_metadata, max_token_count, currentUser, successCallback, errorCallback + ) => { + const username = currentUser.get('username') + let json = JSON.parse(json_metadata) + json = JSON.stringify(json) + const operation = { + creator: username, + name, + json_metadata: json, + max_token_count: parseInt(max_token_count) + } + + dispatch(transaction.actions.broadcastOperation({ + type: 'nft_collection', + username, + operation, + successCallback, + errorCallback + })) + } + }) +)(CreateNFTCollection) diff --git a/app/components/modules/nft/CreateNFTCollection.scss b/app/components/modules/nft/CreateNFTCollection.scss new file mode 100644 index 0000000..3db9e28 --- /dev/null +++ b/app/components/modules/nft/CreateNFTCollection.scss @@ -0,0 +1,34 @@ +.CreateNFTCollection { + .column { + padding-left: 0rem; + padding-right: 0rem; + } + .padding-left { + padding-left: 0.75rem; + } + .image-preview { + max-width: 150px; + height: 40px; + margin-left: 0.75rem; + border: none; + } + .json_metadata { + min-width: 100%; + min-height: 120px; + font-family: monospace; + } + .json-error { + margin-bottom: 0px; + } + .Expandable { + margin-bottom: 0px; + padding-bottom: 0px; + width: 100%; + .Expander { + margin-bottom: 0px; + h5 { + font-size: 1rem; + } + } + } +} diff --git a/app/components/modules/nft/NFTCollections.jsx b/app/components/modules/nft/NFTCollections.jsx new file mode 100644 index 0000000..e7d4172 --- /dev/null +++ b/app/components/modules/nft/NFTCollections.jsx @@ -0,0 +1,94 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import {connect} from 'react-redux'; +import { Link } from 'react-router'; +import tt from 'counterpart'; +import { Asset } from 'golos-lib-js/lib/utils'; +import Reveal from 'react-foundation-components/lib/global/reveal'; + +import DialogManager from 'app/components/elements/common/DialogManager'; +import Icon from 'app/components/elements/Icon'; +import LoadingIndicator from 'app/components/elements/LoadingIndicator' +import CreateNFTCollection from 'app/components/modules/nft/CreateNFTCollection' +import g from 'app/redux/GlobalReducer' +import user from 'app/redux/User' + +class NFTCollections extends Component { + state = {} + + constructor() { + super() + } + + showCreate = (e) => { + e.preventDefault() + this.setState({ + showCreate: true, + }) + } + + hideCreate = () => { + this.setState({ + showCreate: false, + }) + } + + render() { + const { account, isMyAccount, nft_collections, fetchState } = this.props + const accountName = account.get('name') + + const collections = nft_collections ? nft_collections.toJS() : null + + let items + if (!collections) { + items = + } else if (!collections.length) { + if (isMyAccount) { + items = {tt('nft_collections_jsx.not_yet')} + } else { + items = {tt('nft_collections_jsx.not_yet2') + accountName + tt('nft_collections_jsx.not_yet3')} + } + } else { + items = JSON.stringify(collections) + } + + const { showCreate } = this.state + + return (
+
+
+

{tt('g.nft_collections')}

+ {isMyAccount && + {tt('nft_collections_jsx.create')} + } +
+
+
+
+ {items} +
+
+ + + + +
) + } +} + +export default connect( + (state, ownProps) => { + return {...ownProps, + nft_collections: state.global.get('nft_collections') + } + }, + dispatch => ({ + fetchState: () => { + const pathname = window.location.pathname + dispatch({type: 'FETCH_STATE', payload: {pathname}}) + } + }) +)(NFTCollections) diff --git a/app/components/modules/nft/NFTTokens.jsx b/app/components/modules/nft/NFTTokens.jsx new file mode 100644 index 0000000..5350c75 --- /dev/null +++ b/app/components/modules/nft/NFTTokens.jsx @@ -0,0 +1,47 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import {connect} from 'react-redux'; +import { Link } from 'react-router'; +import tt from 'counterpart'; +import { Asset } from 'golos-lib-js/lib/utils'; + +import g from 'app/redux/GlobalReducer' +import user from 'app/redux/User'; +import DialogManager from 'app/components/elements/common/DialogManager'; +import Icon from 'app/components/elements/Icon'; + +class NFTTokens extends Component { + state = {} + + constructor() { + super() + } + + render() { + const { account, isMyAccount } = this.props + const accountName = account.name + return (
+
+
+

{this.state.show_full_list ? tt('assets_jsx.all_assets') : tt('assets_jsx.my_assets')}

+ + {tt('filled_orders_jsx.quick_convert')} + + {isMyAccount && + {tt('assets_jsx.create_btn')} + } +
+
+
) + } +} + +export default connect( + (state, ownProps) => { + return {...ownProps, + nft_tokens: state.global.get('nft_tokens') + } + }, + dispatch => ({ + }) +)(NFTTokens) diff --git a/app/components/pages/UserProfile.jsx b/app/components/pages/UserProfile.jsx index 14c99c1..282516d 100644 --- a/app/components/pages/UserProfile.jsx +++ b/app/components/pages/UserProfile.jsx @@ -14,6 +14,8 @@ import CreateAsset from 'app/components/modules/uia/CreateAsset'; import Assets from 'app/components/modules/uia/Assets'; import UpdateAsset from 'app/components/modules/uia/UpdateAsset'; import TransferAsset from 'app/components/modules/uia/TransferAsset'; +import NFTCollections from 'app/components/modules/nft/NFTCollections' +import NFTTokens from 'app/components/modules/nft/NFTTokens' import Invites from 'app/components/elements/Invites'; import PasswordReset from 'app/components/elements/PasswordReset'; import UserWallet from 'app/components/modules/UserWallet'; @@ -246,8 +248,15 @@ export default class UserProfile extends React.Component {
; - } - else if( section === 'curation-rewards' ) { + } else if( section === 'nft-collections' ) { + tab_content =
+ +
+ } else if( section === 'nft' ) { + tab_content =
+ +
+ } else if( section === 'curation-rewards' ) { rewardsClass = 'active'; tab_content = {tt('g.assets')} +
+ } + > + + {tt('g.nft')} + + + +
{isMyAccount ? {tt('navigation.market2')} : null} diff --git a/app/locales/en.json b/app/locales/en.json index d0d9054..618d1a5 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -133,6 +133,9 @@ "reset_password": "Password reset", "invites": "Invite checks", "assets": "UIA assets", + "nft": "NFT", + "nft_tokens": "NFT-tokens", + "nft_collections": "NFT-collections", "help_wallet": "Wallet functions", "phone": "phone", "post": "Post", @@ -715,6 +718,28 @@ "no_way_error": "If you set at leas one of these fields, you should also set at least 1 withdrawal method or Details field.", "no_to_error": "If you set withdraw via transfer with memo, please also set, to which account to transfer." }, + "nft_collections_jsx": { + "not_yet": "You haven't any own NFT-token collections.", + "not_yet2": "", + "not_yet3": " haven't any own NFT-token collections.", + "create": "Create collection" + }, + "create_nft_collection_jsx": { + "title": "Create NFT collection", + "name": "Token name", + "coll_title": "Title", + "coll_descr": "Description", + "image": "Image URL", + "json_metadata": "JSON metadata", + "json_wrong": "Wrong JSON. ", + "not_required": "(not required)", + "token_count": "Max token count", + "infinity": "Infinity", + "create": "Create", + "restore_json": "Restore default", + "json_no_fields": "In JSON missing fields: ", + "json_fix": "Add missing fields" + }, "invites_jsx": { "create_invite": "Create new invite check", "create_invite_info": "Cheques (invite codes) are a universal tool for transferring of GOLOS tokens to other people outside the blockchain. There are two ways to redeem the code: transfer its balance to your account or register a new account using it.", @@ -918,6 +943,8 @@ "author_rewards_by": "Author rewards by", "donates_from": "Donates from", "donates_to": "Donates to", + "nft_tokens": "NFT-tokens", + "nft_collections": "NFT-collections, created by", "replies_to": "Replies to", "comments_by": "Comments by" }, diff --git a/app/locales/ru-RU.json b/app/locales/ru-RU.json index d4a29b1..6733a94 100644 --- a/app/locales/ru-RU.json +++ b/app/locales/ru-RU.json @@ -242,6 +242,9 @@ "reset_password": "Сброс пароля", "invites": "Инвайт-чеки", "assets": "Активы UIA", + "nft": "NFT", + "nft_tokens": "Токены NFT", + "nft_collections": "Коллекции NFT", "help_wallet": "Функции кошелька", "phone": "телефон", "post": "Пост", @@ -501,6 +504,8 @@ "author_rewards_by": "Автор награжден", "donates_from": "Донаты, отправленные", "donates_to": "Донаты, полученные", + "nft_tokens": "NFT-токены", + "nft_collections": "NFT-коллекции, созданные", "replies_to": "Ответы на", "comments_by": "Комментарии" }, @@ -1053,6 +1058,28 @@ "no_way_error": "Если вы заполнили одно из полей, то вы должны указать хотя бы один способ вывода или заполнить Дополнительно.", "no_to_error": "Если вы указали вывод через перевод с заметкой, то укажите, куда переводить." }, + "nft_collections_jsx": { + "not_yet": "У вас нет своих собственных коллекций NFT-токенов.", + "not_yet2": "У ", + "not_yet3": " нет своих собственных коллекций NFT-токенов.", + "create": "Создать коллекцию" + }, + "create_nft_collection_jsx": { + "title": "Создать коллекцию NFT", + "name": "Имя токена", + "coll_title": "Название", + "coll_descr": "Описание", + "image": "Ссылка на изображение", + "json_metadata": "JSON-метаданные", + "json_wrong": "Некорректный JSON. ", + "not_required": "(не обязательно)", + "token_count": "Количество токенов", + "infinity": "Бесконечное", + "create": "Создать", + "restore_json": "Вернуть по умолчанию", + "json_no_fields": "В JSON не хватает полей: ", + "json_fix": "Добавить недостающее" + }, "invites_jsx": { "create_invite": "Создание чека", "create_invite_info": "Чеки (инвайт-коды) — инструмент для передачи токенов другим людям вне блокчейна. Использовать чек можно двумя способами: перевести его баланс на аккаунт (форма для этого ниже) или зарегистрировать с его помощью новый аккаунт.", diff --git a/app/redux/FetchDataSaga.js b/app/redux/FetchDataSaga.js index 6c48c16..6a56e22 100644 --- a/app/redux/FetchDataSaga.js +++ b/app/redux/FetchDataSaga.js @@ -78,6 +78,8 @@ export function* fetchState(location_change_action) { state.current_route = location state.content = {} state.assets = {} + state.nft_collections = [] + state.nft_tokens = [] state.worker_requests = {} state.accounts = {} state.witnesses = {} @@ -124,6 +126,20 @@ export function* fetchState(location_change_action) { state.cprops = yield call([api, api.getChainPropertiesAsync]) break + case 'nft-collections': + state.nft_collections = (yield call([api, api.getNftCollectionsAsync], { + creator: uname + })) + + state.cprops = yield call([api, api.getChainPropertiesAsync]) + break + + case 'nft': + state.nft_tokens = (yield call([api, api.getNftTokensAsync], { + owner: uname + })) + break + case 'invites': state.cprops = yield call([api, api.getChainPropertiesAsync]) break diff --git a/package.json b/package.json index 4aa7f8c..95faadd 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "foundation-sites": "^6.4.3", "fs-extra": "^10.0.1", "git-rev-sync": "^3.0.2", - "golos-lib-js": "^0.9.53", + "golos-lib-js": "^0.9.56", "history": "^2.0.0-rc2", "immutable": "^3.8.2", "intl": "^1.2.5", diff --git a/yarn.lock b/yarn.lock index ddbc36f..ecd2f83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2185,14 +2185,15 @@ assert@^1.4.1: util "0.10.3" assert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" - integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== dependencies: - es6-object-assign "^1.1.0" - is-nan "^1.2.1" - object-is "^1.0.1" - util "^0.12.0" + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" assertion-error@^1.1.0: version "1.1.0" @@ -2970,9 +2971,9 @@ core-js@^2.4.0, core-js@^2.5.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.17.3: - version "3.30.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.30.0.tgz#64ac6f83bc7a49fd42807327051701d4b1478dea" - integrity sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg== + version "3.32.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.2.tgz#172fb5949ef468f93b4be7841af6ab1f21992db7" + integrity sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ== core-js@^3.19.1, core-js@^3.6.0, core-js@^3.8.3: version "3.25.0" @@ -3605,11 +3606,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es6-object-assign@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" - integrity sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw== - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -4204,10 +4200,10 @@ globule@^1.0.0: lodash "^4.17.21" minimatch "~3.0.2" -golos-lib-js@^0.9.53: - version "0.9.53" - resolved "https://registry.yarnpkg.com/golos-lib-js/-/golos-lib-js-0.9.53.tgz#8469e0cfb5b0183bb0b161279ceb059907e5251e" - integrity sha512-ipjFLKOXhhI31JuQzYsgZtZbFJQem15PRwU0OG+ocnQtUHB1CsU02GGJV0la3gL+K2KvHZdmKqd8XzGx8jgA4g== +golos-lib-js@^0.9.56: + version "0.9.56" + resolved "https://registry.yarnpkg.com/golos-lib-js/-/golos-lib-js-0.9.56.tgz#3dfe8c0658fba2f50976ef49103ddc3f34109c19" + integrity sha512-h9ay0q2AuHiYL8aFXsCGoEFe6ojHt67FHMv8W6oWbqayl44JlRuuEysfE1MZQiiLwzBDFOO1SNMAtv5sE0bRcg== dependencies: abort-controller "^3.0.0" assert "^2.0.0" @@ -4849,7 +4845,7 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== -is-nan@^1.2.1: +is-nan@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== @@ -6073,7 +6069,7 @@ object-inspect@^1.12.2: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -object-is@^1.0.1: +object-is@^1.0.1, object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -7242,11 +7238,16 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -8148,7 +8149,7 @@ util@0.10.3: safe-buffer "^5.1.2" which-typed-array "^1.1.2" -util@^0.12.0: +util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -8531,9 +8532,9 @@ ws@^5.2.0: async-limiter "~1.0.0" ws@^8.2.3: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + version "8.14.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.1.tgz#4b9586b4f70f9e6534c7bb1d3dc0baa8b8cf01e0" + integrity sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A== ws@^8.4.2: version "8.11.0"