From f1b125cc4d342e76285da441e78d021be7d0f867 Mon Sep 17 00:00:00 2001
From: Pavel <14926950+prichodko@users.noreply.github.com>
Date: Wed, 23 Feb 2022 15:03:14 +0100
Subject: [PATCH] Update packages to @status-im (#223)
* Downgrade to yarn v1
* Rename status-communities to status-core
* Rename chat-sdk to status-react
* Rename packages in examples
* Update readme
* Remove changelog
* Add extensions recommendations
* Update gitignore
* Rename package imports
---
.eslintrc.json | 48 +
.github/workflows/ci.yml | 20 +
.gitignore | 74 +
.vscode/extensions.json | 3 +
.vscode/settings.json | 3 +
LICENSE-APACHE-v2 | 202 +
LICENSE-MIT | 21 +
README.md | 1 +
package.json | 19 +
packages/preview-proxy/package.json | 16 +
packages/preview-proxy/src/index.js | 59 +
packages/react-chat-example/.eslintrc.json | 41 +
packages/react-chat-example/.mocharc.json | 6 +
packages/react-chat-example/.prettierignore | 2 +
packages/react-chat-example/README.md | 13 +
packages/react-chat-example/package.json | 71 +
packages/react-chat-example/src/_redirects | 1 +
packages/react-chat-example/src/index.html | 14 +
packages/react-chat-example/src/index.tsx | 136 +
packages/react-chat-example/tsconfig.json | 47 +
.../react-chat-example/tsconfig.tsbuildinfo | 1 +
packages/react-chat-example/webpack.config.js | 88 +
.../react-group-chat-example/.eslintrc.json | 41 +
.../react-group-chat-example/.mocharc.json | 6 +
.../react-group-chat-example/.prettierignore | 2 +
packages/react-group-chat-example/README.md | 1 +
.../react-group-chat-example/package.json | 71 +
.../react-group-chat-example/src/_redirects | 1 +
.../react-group-chat-example/src/index.html | 14 +
.../react-group-chat-example/src/index.tsx | 135 +
.../react-group-chat-example/tsconfig.json | 47 +
.../tsconfig.tsbuildinfo | 1 +
.../webpack.config.js | 88 +
packages/status-core/.eslintrc.json | 42 +
packages/status-core/.mocharc.json | 6 +
packages/status-core/.prettierignore | 2 +
packages/status-core/README.md | 1 +
packages/status-core/buf.gen.yaml | 6 +
packages/status-core/buf.yaml | 9 +
packages/status-core/package.json | 67 +
.../proto/communities/v1/chat_identity.proto | 55 +
.../proto/communities/v1/chat_message.proto | 105 +
.../proto/communities/v1/communities.proto | 80 +
.../proto/communities/v1/emoji_reaction.proto | 39 +
.../proto/communities/v1/enums.proto | 25 +
.../v1/membership_update_message.proto | 45 +
.../proto/communities/v1/status_update.proto | 32 +
.../v1/application_metadata_message.proto | 50 +
packages/status-core/src/chat.ts | 85 +
packages/status-core/src/community.spec.ts | 42 +
packages/status-core/src/community.ts | 92 +
packages/status-core/src/contacts.ts | 169 +
packages/status-core/src/contentTopic.ts | 22 +
packages/status-core/src/encryption.spec.ts | 24 +
packages/status-core/src/encryption.ts | 15 +
packages/status-core/src/groupChats.ts | 459 +
packages/status-core/src/identity.ts | 39 +
packages/status-core/src/index.ts | 18 +
packages/status-core/src/messenger.spec.ts | 178 +
packages/status-core/src/messenger.ts | 268 +
.../src/proto/communities/v1/chat_identity.ts | 532 +
.../src/proto/communities/v1/chat_message.ts | 1105 ++
.../src/proto/communities/v1/communities.ts | 1768 ++++
.../proto/communities/v1/emoji_reaction.ts | 328 +
.../src/proto/communities/v1/enums.ts | 125 +
.../v1/membership_update_message.ts | 436 +
.../src/proto/communities/v1/status_update.ts | 212 +
.../status/v1/application_metadata_message.ts | 409 +
packages/status-core/src/topics.ts | 46 +
packages/status-core/src/utils.ts | 57 +
.../src/wire/application_metadata_message.ts | 75 +
.../status-core/src/wire/chat_identity.ts | 51 +
.../status-core/src/wire/chat_message.spec.ts | 78 +
packages/status-core/src/wire/chat_message.ts | 226 +
.../status-core/src/wire/community_chat.ts | 59 +
.../src/wire/community_description.ts | 101 +
.../src/wire/membership_update_message.ts | 201 +
.../status-core/src/wire/status_update.ts | 49 +
packages/status-core/tsconfig.json | 51 +
packages/status-react/.eslintrc.json | 42 +
packages/status-react/.mocharc.json | 6 +
packages/status-react/.prettierignore | 2 +
packages/status-react/README.md | 1 +
packages/status-react/buf.gen.yaml | 6 +
packages/status-react/buf.yaml | 5 +
packages/status-react/package.json | 69 +
.../ActivityCenter/ActivityButton.tsx | 116 +
.../ActivityCenter/ActivityCenter.tsx | 189 +
.../ActivityCenter/ActivityMessage.tsx | 386 +
.../src/components/Buttons/BackButton.tsx | 31 +
.../src/components/Buttons/DownloadButton.tsx | 84 +
.../src/components/Buttons/buttonStyle.ts | 59 +
.../src/components/Channels/Channel.tsx | 211 +
.../src/components/Channels/ChannelIcon.tsx | 54 +
.../src/components/Channels/Channels.tsx | 164 +
.../src/components/Channels/EmptyChannel.tsx | 129 +
.../src/components/Chat/ChatBody.tsx | 182 +
.../src/components/Chat/ChatCreation.tsx | 387 +
.../src/components/Chat/ChatInput.tsx | 562 +
.../components/Chat/ChatMessageContent.tsx | 233 +
.../src/components/Chat/ChatTopbar.tsx | 209 +
.../src/components/Chat/EmojiPicker.tsx | 41 +
.../status-react/src/components/Community.tsx | 38 +
.../src/components/CommunityChat.tsx | 67 +
.../src/components/CommunityChatRoom.tsx | 104 +
.../src/components/CommunityIdentity.tsx | 84 +
.../src/components/Form/ChannelMenu.tsx | 193 +
.../src/components/Form/ContactMenu.tsx | 163 +
.../src/components/Form/CopyInput.tsx | 30 +
.../src/components/Form/DropdownMenu.tsx | 94 +
.../src/components/Form/ImageMenu.tsx | 42 +
.../src/components/Form/LoginInstructions.tsx | 93 +
.../src/components/Form/MessageMenu.tsx | 119 +
.../src/components/Form/MuteMenu.tsx | 64 +
.../src/components/Form/NameError.tsx | 44 +
.../src/components/Form/PasteInput.tsx | 40 +
.../src/components/Form/TokenRequirement.tsx | 131 +
.../src/components/Form/Tooltip.tsx | 51 +
.../src/components/Form/inputStyles.ts | 93 +
.../src/components/Icons/ActivityIcon.tsx | 24 +
.../src/components/Icons/AddContactIcon.tsx | 37 +
.../src/components/Icons/AddIcon.tsx | 22 +
.../src/components/Icons/AddMemberIcon.tsx | 39 +
.../src/components/Icons/BlockIcon.tsx | 41 +
.../src/components/Icons/ChainIcon.tsx | 30 +
.../src/components/Icons/ChatIcon.tsx | 38 +
.../src/components/Icons/CheckIcon.tsx | 35 +
.../src/components/Icons/ClearIcon.tsx | 66 +
.../src/components/Icons/ClearIconFull.tsx | 35 +
.../src/components/Icons/CoinbaseLogo.tsx | 50 +
.../src/components/Icons/ColorChatIcon.tsx | 148 +
.../src/components/Icons/CommunityIcon.tsx | 43 +
.../src/components/Icons/CopyIcon.tsx | 31 +
.../src/components/Icons/CreateIcon.tsx | 27 +
.../src/components/Icons/CrossIcon.tsx | 35 +
.../src/components/Icons/DeleteIcon.tsx | 38 +
.../src/components/Icons/DownloadIcon.tsx | 27 +
.../src/components/Icons/EditIcon.tsx | 34 +
.../src/components/Icons/EmojiIcon.tsx | 46 +
.../src/components/Icons/EthereumLogo.tsx | 38 +
.../src/components/Icons/GifIcon.tsx | 46 +
.../src/components/Icons/GroupIcon.tsx | 32 +
.../src/components/Icons/HideIcon.tsx | 24 +
.../src/components/Icons/LeftIcon.tsx | 34 +
.../src/components/Icons/LoadingIcon.tsx | 44 +
.../src/components/Icons/LogoutIcon.tsx | 21 +
.../src/components/Icons/MarkerdaoLogo.tsx | 33 +
.../src/components/Icons/MembersIcon.tsx | 26 +
.../src/components/Icons/MembersSmallIcon.tsx | 36 +
.../src/components/Icons/MetamaskLogo.tsx | 217 +
.../src/components/Icons/MobileIcon.tsx | 25 +
.../src/components/Icons/MoreIcon.tsx | 24 +
.../src/components/Icons/MuteIcon.tsx | 31 +
.../src/components/Icons/MutedIcon.tsx | 22 +
.../src/components/Icons/NextIcon.tsx | 28 +
.../src/components/Icons/PictureIcon.tsx | 30 +
.../src/components/Icons/PinIcon.tsx | 41 +
.../src/components/Icons/ProfileIcon.tsx | 37 +
.../src/components/Icons/QuoteIcon.tsx | 37 +
.../src/components/Icons/ReactionIcon.tsx | 51 +
.../src/components/Icons/ReadIcon.tsx | 43 +
.../src/components/Icons/ReadMessageIcon.tsx | 33 +
.../components/Icons/ReplyActivityIcon.tsx | 19 +
.../src/components/Icons/ReplyIcon.tsx | 34 +
.../src/components/Icons/ScanIcon.tsx | 40 +
.../src/components/Icons/ShowIcon.tsx | 27 +
.../src/components/Icons/StatusIcon.tsx | 24 +
.../src/components/Icons/StatusLogo.tsx | 41 +
.../src/components/Icons/StickerIcon.tsx | 38 +
.../src/components/Icons/TipIcon.tsx | 38 +
.../src/components/Icons/UntrustworthIcon.tsx | 28 +
.../src/components/Icons/UserIcon.tsx | 38 +
.../components/Icons/WalletConnectLogo.tsx | 35 +
.../src/components/Icons/WarningIcon.tsx | 47 +
.../src/components/Members/Member.tsx | 125 +
.../src/components/Members/Members.tsx | 43 +
.../src/components/Members/MembersList.tsx | 132 +
.../src/components/Members/UserLogo.tsx | 132 +
.../src/components/Messages/MessageQuote.tsx | 67 +
.../components/Messages/MessageReactions.tsx | 83 +
.../src/components/Messages/MessagesList.tsx | 107 +
.../src/components/Messages/Styles.tsx | 156 +
.../src/components/Messages/UiMessage.tsx | 163 +
.../src/components/Modals/AgreementModal.tsx | 156 +
.../src/components/Modals/CoinbaseModal.tsx | 18 +
.../src/components/Modals/CommunityModal.tsx | 76 +
.../src/components/Modals/ConnectModal.tsx | 32 +
.../src/components/Modals/EditModal.tsx | 164 +
.../src/components/Modals/LeavingModal.tsx | 48 +
.../src/components/Modals/LinkModal.tsx | 48 +
.../src/components/Modals/LogoutModal.tsx | 100 +
.../src/components/Modals/Modal.tsx | 112 +
.../src/components/Modals/ModalStyle.tsx | 85 +
.../src/components/Modals/PictureModal.tsx | 31 +
.../components/Modals/ProfileFoundModal.tsx | 129 +
.../src/components/Modals/ProfileModal.tsx | 416 +
.../src/components/Modals/SizeLimitModal.tsx | 19 +
.../src/components/Modals/StatusModal.tsx | 89 +
.../components/Modals/UserCreationModal.tsx | 213 +
.../Modals/UserCreationStartModal.tsx | 26 +
.../components/Modals/WalletConnectModal.tsx | 19 +
.../src/components/Modals/WalletModal.tsx | 164 +
.../components/NarrowMode/NarrowChannels.tsx | 18 +
.../components/NarrowMode/NarrowMembers.tsx | 28 +
.../components/NarrowMode/NarrowTopbar.tsx | 59 +
.../components/Reactions/ReactionButton.tsx | 90 +
.../components/Reactions/ReactionPicker.tsx | 108 +
.../src/components/Reactions/Reactions.tsx | 89 +
.../src/components/SearchBlock.tsx | 78 +
.../components/Skeleton/CommunitySkeleton.tsx | 29 +
.../src/components/Skeleton/Loading.tsx | 37 +
.../components/Skeleton/LoadingSkeleton.tsx | 55 +
.../components/Skeleton/MessageSkeleton.tsx | 58 +
.../src/components/Skeleton/Skeleton.tsx | 46 +
packages/status-react/src/components/Text.tsx | 11 +
.../components/ToastMessages/ToastMessage.tsx | 128 +
.../ToastMessages/ToastMessageList.tsx | 29 +
.../components/UserCreation/UserCreation.tsx | 45 +
.../UserCreation/UserCreationButtons.tsx | 85 +
.../src/contexts/chatStateProvider.tsx | 25 +
.../src/contexts/configProvider.tsx | 24 +
.../src/contexts/fetchMetadataProvider.tsx | 23 +
.../src/contexts/identityProvider.tsx | 79 +
.../src/contexts/messengerProvider.tsx | 50 +
.../src/contexts/modalProvider.tsx | 63 +
.../src/contexts/narrowProvider.tsx | 29 +
.../src/contexts/scrollProvider.tsx | 70 +
.../src/contexts/toastProvider.tsx | 26 +
.../src/groupChatComponents/GroupChat.tsx | 58 +
.../GroupChat/GroupChatBody.tsx | 182 +
.../src/groupChatComponents/GroupChatRoom.tsx | 90 +
.../GroupMembers/GroupMembers.tsx | 49 +
.../src/hooks/messenger/useChannelsReducer.ts | 79 +
.../src/hooks/messenger/useContacts.ts | 126 +
.../src/hooks/messenger/useGroupChats.ts | 132 +
.../src/hooks/messenger/useLoadPrevDay.ts | 70 +
.../src/hooks/messenger/useMessages.ts | 93 +
.../src/hooks/messenger/useMessenger.ts | 358 +
.../src/hooks/messenger/useNotifications.ts | 24 +
.../status-react/src/hooks/useActivities.ts | 115 +
.../src/hooks/useChatScrollHandle.ts | 55 +
.../status-react/src/hooks/useClickOutside.ts | 23 +
.../src/hooks/useClickPosition.ts | 30 +
.../status-react/src/hooks/useContextMenu.ts | 27 +
.../status-react/src/hooks/useNameError.tsx | 40 +
.../status-react/src/hooks/useRefBreak.ts | 26 +
packages/status-react/src/hooks/useReply.ts | 6 +
packages/status-react/src/index.ts | 6 +
packages/status-react/src/models/Activity.ts | 49 +
.../status-react/src/models/ChannelData.ts | 15 +
.../status-react/src/models/ChatMessage.ts | 56 +
.../status-react/src/models/CommunityData.ts | 8 +
packages/status-react/src/models/Contact.ts | 13 +
packages/status-react/src/models/Metadata.ts | 5 +
packages/status-react/src/models/Toast.ts | 6 +
.../status-react/src/styles/GlobalStyle.tsx | 159 +
packages/status-react/src/styles/themes.ts | 107 +
.../status-react/src/utils/binarySetInsert.ts | 21 +
packages/status-react/src/utils/copy.ts | 5 +
packages/status-react/src/utils/copyImg.ts | 18 +
.../status-react/src/utils/createCommunity.ts | 22 +
.../status-react/src/utils/createMessenger.ts | 38 +
.../status-react/src/utils/downloadImg.ts | 10 +
packages/status-react/src/utils/equalDate.ts | 7 +
.../status-react/src/utils/identityStorage.ts | 79 +
packages/status-react/src/utils/index.ts | 12 +
packages/status-react/src/utils/paste.ts | 9 +
.../status-react/src/utils/reduceString.ts | 9 +
.../status-react/src/utils/uintToImgUrl.ts | 4 +
packages/status-react/tsconfig.json | 48 +
yarn.lock | 9025 +++++++++++++++++
271 files changed, 31652 insertions(+)
create mode 100644 .eslintrc.json
create mode 100644 .github/workflows/ci.yml
create mode 100644 .gitignore
create mode 100644 .vscode/extensions.json
create mode 100644 .vscode/settings.json
create mode 100644 LICENSE-APACHE-v2
create mode 100644 LICENSE-MIT
create mode 100644 README.md
create mode 100644 package.json
create mode 100644 packages/preview-proxy/package.json
create mode 100644 packages/preview-proxy/src/index.js
create mode 100644 packages/react-chat-example/.eslintrc.json
create mode 100644 packages/react-chat-example/.mocharc.json
create mode 100644 packages/react-chat-example/.prettierignore
create mode 100644 packages/react-chat-example/README.md
create mode 100644 packages/react-chat-example/package.json
create mode 100644 packages/react-chat-example/src/_redirects
create mode 100644 packages/react-chat-example/src/index.html
create mode 100644 packages/react-chat-example/src/index.tsx
create mode 100644 packages/react-chat-example/tsconfig.json
create mode 100644 packages/react-chat-example/tsconfig.tsbuildinfo
create mode 100644 packages/react-chat-example/webpack.config.js
create mode 100644 packages/react-group-chat-example/.eslintrc.json
create mode 100644 packages/react-group-chat-example/.mocharc.json
create mode 100644 packages/react-group-chat-example/.prettierignore
create mode 100644 packages/react-group-chat-example/README.md
create mode 100644 packages/react-group-chat-example/package.json
create mode 100644 packages/react-group-chat-example/src/_redirects
create mode 100644 packages/react-group-chat-example/src/index.html
create mode 100644 packages/react-group-chat-example/src/index.tsx
create mode 100644 packages/react-group-chat-example/tsconfig.json
create mode 100644 packages/react-group-chat-example/tsconfig.tsbuildinfo
create mode 100644 packages/react-group-chat-example/webpack.config.js
create mode 100644 packages/status-core/.eslintrc.json
create mode 100644 packages/status-core/.mocharc.json
create mode 100644 packages/status-core/.prettierignore
create mode 100644 packages/status-core/README.md
create mode 100644 packages/status-core/buf.gen.yaml
create mode 100644 packages/status-core/buf.yaml
create mode 100644 packages/status-core/package.json
create mode 100644 packages/status-core/proto/communities/v1/chat_identity.proto
create mode 100644 packages/status-core/proto/communities/v1/chat_message.proto
create mode 100644 packages/status-core/proto/communities/v1/communities.proto
create mode 100644 packages/status-core/proto/communities/v1/emoji_reaction.proto
create mode 100644 packages/status-core/proto/communities/v1/enums.proto
create mode 100644 packages/status-core/proto/communities/v1/membership_update_message.proto
create mode 100644 packages/status-core/proto/communities/v1/status_update.proto
create mode 100644 packages/status-core/proto/status/v1/application_metadata_message.proto
create mode 100644 packages/status-core/src/chat.ts
create mode 100644 packages/status-core/src/community.spec.ts
create mode 100644 packages/status-core/src/community.ts
create mode 100644 packages/status-core/src/contacts.ts
create mode 100644 packages/status-core/src/contentTopic.ts
create mode 100644 packages/status-core/src/encryption.spec.ts
create mode 100644 packages/status-core/src/encryption.ts
create mode 100644 packages/status-core/src/groupChats.ts
create mode 100644 packages/status-core/src/identity.ts
create mode 100644 packages/status-core/src/index.ts
create mode 100644 packages/status-core/src/messenger.spec.ts
create mode 100644 packages/status-core/src/messenger.ts
create mode 100644 packages/status-core/src/proto/communities/v1/chat_identity.ts
create mode 100644 packages/status-core/src/proto/communities/v1/chat_message.ts
create mode 100644 packages/status-core/src/proto/communities/v1/communities.ts
create mode 100644 packages/status-core/src/proto/communities/v1/emoji_reaction.ts
create mode 100644 packages/status-core/src/proto/communities/v1/enums.ts
create mode 100644 packages/status-core/src/proto/communities/v1/membership_update_message.ts
create mode 100644 packages/status-core/src/proto/communities/v1/status_update.ts
create mode 100644 packages/status-core/src/proto/status/v1/application_metadata_message.ts
create mode 100644 packages/status-core/src/topics.ts
create mode 100644 packages/status-core/src/utils.ts
create mode 100644 packages/status-core/src/wire/application_metadata_message.ts
create mode 100644 packages/status-core/src/wire/chat_identity.ts
create mode 100644 packages/status-core/src/wire/chat_message.spec.ts
create mode 100644 packages/status-core/src/wire/chat_message.ts
create mode 100644 packages/status-core/src/wire/community_chat.ts
create mode 100644 packages/status-core/src/wire/community_description.ts
create mode 100644 packages/status-core/src/wire/membership_update_message.ts
create mode 100644 packages/status-core/src/wire/status_update.ts
create mode 100644 packages/status-core/tsconfig.json
create mode 100644 packages/status-react/.eslintrc.json
create mode 100644 packages/status-react/.mocharc.json
create mode 100644 packages/status-react/.prettierignore
create mode 100644 packages/status-react/README.md
create mode 100644 packages/status-react/buf.gen.yaml
create mode 100644 packages/status-react/buf.yaml
create mode 100644 packages/status-react/package.json
create mode 100644 packages/status-react/src/components/ActivityCenter/ActivityButton.tsx
create mode 100644 packages/status-react/src/components/ActivityCenter/ActivityCenter.tsx
create mode 100644 packages/status-react/src/components/ActivityCenter/ActivityMessage.tsx
create mode 100644 packages/status-react/src/components/Buttons/BackButton.tsx
create mode 100644 packages/status-react/src/components/Buttons/DownloadButton.tsx
create mode 100644 packages/status-react/src/components/Buttons/buttonStyle.ts
create mode 100644 packages/status-react/src/components/Channels/Channel.tsx
create mode 100644 packages/status-react/src/components/Channels/ChannelIcon.tsx
create mode 100644 packages/status-react/src/components/Channels/Channels.tsx
create mode 100644 packages/status-react/src/components/Channels/EmptyChannel.tsx
create mode 100644 packages/status-react/src/components/Chat/ChatBody.tsx
create mode 100644 packages/status-react/src/components/Chat/ChatCreation.tsx
create mode 100644 packages/status-react/src/components/Chat/ChatInput.tsx
create mode 100644 packages/status-react/src/components/Chat/ChatMessageContent.tsx
create mode 100644 packages/status-react/src/components/Chat/ChatTopbar.tsx
create mode 100644 packages/status-react/src/components/Chat/EmojiPicker.tsx
create mode 100644 packages/status-react/src/components/Community.tsx
create mode 100644 packages/status-react/src/components/CommunityChat.tsx
create mode 100644 packages/status-react/src/components/CommunityChatRoom.tsx
create mode 100644 packages/status-react/src/components/CommunityIdentity.tsx
create mode 100644 packages/status-react/src/components/Form/ChannelMenu.tsx
create mode 100644 packages/status-react/src/components/Form/ContactMenu.tsx
create mode 100644 packages/status-react/src/components/Form/CopyInput.tsx
create mode 100644 packages/status-react/src/components/Form/DropdownMenu.tsx
create mode 100644 packages/status-react/src/components/Form/ImageMenu.tsx
create mode 100644 packages/status-react/src/components/Form/LoginInstructions.tsx
create mode 100644 packages/status-react/src/components/Form/MessageMenu.tsx
create mode 100644 packages/status-react/src/components/Form/MuteMenu.tsx
create mode 100644 packages/status-react/src/components/Form/NameError.tsx
create mode 100644 packages/status-react/src/components/Form/PasteInput.tsx
create mode 100644 packages/status-react/src/components/Form/TokenRequirement.tsx
create mode 100644 packages/status-react/src/components/Form/Tooltip.tsx
create mode 100644 packages/status-react/src/components/Form/inputStyles.ts
create mode 100644 packages/status-react/src/components/Icons/ActivityIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/AddContactIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/AddIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/AddMemberIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/BlockIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ChainIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ChatIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/CheckIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ClearIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ClearIconFull.tsx
create mode 100644 packages/status-react/src/components/Icons/CoinbaseLogo.tsx
create mode 100644 packages/status-react/src/components/Icons/ColorChatIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/CommunityIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/CopyIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/CreateIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/CrossIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/DeleteIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/DownloadIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/EditIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/EmojiIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/EthereumLogo.tsx
create mode 100644 packages/status-react/src/components/Icons/GifIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/GroupIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/HideIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/LeftIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/LoadingIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/LogoutIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/MarkerdaoLogo.tsx
create mode 100644 packages/status-react/src/components/Icons/MembersIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/MembersSmallIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/MetamaskLogo.tsx
create mode 100644 packages/status-react/src/components/Icons/MobileIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/MoreIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/MuteIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/MutedIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/NextIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/PictureIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/PinIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ProfileIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/QuoteIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ReactionIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ReadIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ReadMessageIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ReplyActivityIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ReplyIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ScanIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/ShowIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/StatusIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/StatusLogo.tsx
create mode 100644 packages/status-react/src/components/Icons/StickerIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/TipIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/UntrustworthIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/UserIcon.tsx
create mode 100644 packages/status-react/src/components/Icons/WalletConnectLogo.tsx
create mode 100644 packages/status-react/src/components/Icons/WarningIcon.tsx
create mode 100644 packages/status-react/src/components/Members/Member.tsx
create mode 100644 packages/status-react/src/components/Members/Members.tsx
create mode 100644 packages/status-react/src/components/Members/MembersList.tsx
create mode 100644 packages/status-react/src/components/Members/UserLogo.tsx
create mode 100644 packages/status-react/src/components/Messages/MessageQuote.tsx
create mode 100644 packages/status-react/src/components/Messages/MessageReactions.tsx
create mode 100644 packages/status-react/src/components/Messages/MessagesList.tsx
create mode 100644 packages/status-react/src/components/Messages/Styles.tsx
create mode 100644 packages/status-react/src/components/Messages/UiMessage.tsx
create mode 100644 packages/status-react/src/components/Modals/AgreementModal.tsx
create mode 100644 packages/status-react/src/components/Modals/CoinbaseModal.tsx
create mode 100644 packages/status-react/src/components/Modals/CommunityModal.tsx
create mode 100644 packages/status-react/src/components/Modals/ConnectModal.tsx
create mode 100644 packages/status-react/src/components/Modals/EditModal.tsx
create mode 100644 packages/status-react/src/components/Modals/LeavingModal.tsx
create mode 100644 packages/status-react/src/components/Modals/LinkModal.tsx
create mode 100644 packages/status-react/src/components/Modals/LogoutModal.tsx
create mode 100644 packages/status-react/src/components/Modals/Modal.tsx
create mode 100644 packages/status-react/src/components/Modals/ModalStyle.tsx
create mode 100644 packages/status-react/src/components/Modals/PictureModal.tsx
create mode 100644 packages/status-react/src/components/Modals/ProfileFoundModal.tsx
create mode 100644 packages/status-react/src/components/Modals/ProfileModal.tsx
create mode 100644 packages/status-react/src/components/Modals/SizeLimitModal.tsx
create mode 100644 packages/status-react/src/components/Modals/StatusModal.tsx
create mode 100644 packages/status-react/src/components/Modals/UserCreationModal.tsx
create mode 100644 packages/status-react/src/components/Modals/UserCreationStartModal.tsx
create mode 100644 packages/status-react/src/components/Modals/WalletConnectModal.tsx
create mode 100644 packages/status-react/src/components/Modals/WalletModal.tsx
create mode 100644 packages/status-react/src/components/NarrowMode/NarrowChannels.tsx
create mode 100644 packages/status-react/src/components/NarrowMode/NarrowMembers.tsx
create mode 100644 packages/status-react/src/components/NarrowMode/NarrowTopbar.tsx
create mode 100644 packages/status-react/src/components/Reactions/ReactionButton.tsx
create mode 100644 packages/status-react/src/components/Reactions/ReactionPicker.tsx
create mode 100644 packages/status-react/src/components/Reactions/Reactions.tsx
create mode 100644 packages/status-react/src/components/SearchBlock.tsx
create mode 100644 packages/status-react/src/components/Skeleton/CommunitySkeleton.tsx
create mode 100644 packages/status-react/src/components/Skeleton/Loading.tsx
create mode 100644 packages/status-react/src/components/Skeleton/LoadingSkeleton.tsx
create mode 100644 packages/status-react/src/components/Skeleton/MessageSkeleton.tsx
create mode 100644 packages/status-react/src/components/Skeleton/Skeleton.tsx
create mode 100644 packages/status-react/src/components/Text.tsx
create mode 100644 packages/status-react/src/components/ToastMessages/ToastMessage.tsx
create mode 100644 packages/status-react/src/components/ToastMessages/ToastMessageList.tsx
create mode 100644 packages/status-react/src/components/UserCreation/UserCreation.tsx
create mode 100644 packages/status-react/src/components/UserCreation/UserCreationButtons.tsx
create mode 100644 packages/status-react/src/contexts/chatStateProvider.tsx
create mode 100644 packages/status-react/src/contexts/configProvider.tsx
create mode 100644 packages/status-react/src/contexts/fetchMetadataProvider.tsx
create mode 100644 packages/status-react/src/contexts/identityProvider.tsx
create mode 100644 packages/status-react/src/contexts/messengerProvider.tsx
create mode 100644 packages/status-react/src/contexts/modalProvider.tsx
create mode 100644 packages/status-react/src/contexts/narrowProvider.tsx
create mode 100644 packages/status-react/src/contexts/scrollProvider.tsx
create mode 100644 packages/status-react/src/contexts/toastProvider.tsx
create mode 100644 packages/status-react/src/groupChatComponents/GroupChat.tsx
create mode 100644 packages/status-react/src/groupChatComponents/GroupChat/GroupChatBody.tsx
create mode 100644 packages/status-react/src/groupChatComponents/GroupChatRoom.tsx
create mode 100644 packages/status-react/src/groupChatComponents/GroupMembers/GroupMembers.tsx
create mode 100644 packages/status-react/src/hooks/messenger/useChannelsReducer.ts
create mode 100644 packages/status-react/src/hooks/messenger/useContacts.ts
create mode 100644 packages/status-react/src/hooks/messenger/useGroupChats.ts
create mode 100644 packages/status-react/src/hooks/messenger/useLoadPrevDay.ts
create mode 100644 packages/status-react/src/hooks/messenger/useMessages.ts
create mode 100644 packages/status-react/src/hooks/messenger/useMessenger.ts
create mode 100644 packages/status-react/src/hooks/messenger/useNotifications.ts
create mode 100644 packages/status-react/src/hooks/useActivities.ts
create mode 100644 packages/status-react/src/hooks/useChatScrollHandle.ts
create mode 100644 packages/status-react/src/hooks/useClickOutside.ts
create mode 100644 packages/status-react/src/hooks/useClickPosition.ts
create mode 100644 packages/status-react/src/hooks/useContextMenu.ts
create mode 100644 packages/status-react/src/hooks/useNameError.tsx
create mode 100644 packages/status-react/src/hooks/useRefBreak.ts
create mode 100644 packages/status-react/src/hooks/useReply.ts
create mode 100644 packages/status-react/src/index.ts
create mode 100644 packages/status-react/src/models/Activity.ts
create mode 100644 packages/status-react/src/models/ChannelData.ts
create mode 100644 packages/status-react/src/models/ChatMessage.ts
create mode 100644 packages/status-react/src/models/CommunityData.ts
create mode 100644 packages/status-react/src/models/Contact.ts
create mode 100644 packages/status-react/src/models/Metadata.ts
create mode 100644 packages/status-react/src/models/Toast.ts
create mode 100644 packages/status-react/src/styles/GlobalStyle.tsx
create mode 100644 packages/status-react/src/styles/themes.ts
create mode 100644 packages/status-react/src/utils/binarySetInsert.ts
create mode 100644 packages/status-react/src/utils/copy.ts
create mode 100644 packages/status-react/src/utils/copyImg.ts
create mode 100644 packages/status-react/src/utils/createCommunity.ts
create mode 100644 packages/status-react/src/utils/createMessenger.ts
create mode 100644 packages/status-react/src/utils/downloadImg.ts
create mode 100644 packages/status-react/src/utils/equalDate.ts
create mode 100644 packages/status-react/src/utils/identityStorage.ts
create mode 100644 packages/status-react/src/utils/index.ts
create mode 100644 packages/status-react/src/utils/paste.ts
create mode 100644 packages/status-react/src/utils/reduceString.ts
create mode 100644 packages/status-react/src/utils/uintToImgUrl.ts
create mode 100644 packages/status-react/tsconfig.json
create mode 100644 yarn.lock
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..d68fe3ed
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,48 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": { "project": "./tsconfig.json" },
+ "env": {
+ "es6": true,
+ "node": true,
+ "mocha": true,
+ "browser": true
+ },
+ "ignorePatterns": ["node_modules", "build", "coverage", "proto"],
+ "plugins": ["import", "eslint-comments", "functional"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:eslint-comments/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:import/typescript",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "globals": { "BigInt": true, "console": true, "WebAssembly": true },
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["error"],
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "eslint-comments/disable-enable-pair": [
+ "error",
+ { "allowWholeFile": true }
+ ],
+ "eslint-comments/no-unused-disable": "error",
+ "import/order": [
+ "error",
+ { "newlines-between": "always", "alphabetize": { "order": "asc" } }
+ ],
+ "no-constant-condition": ["error", { "checkLoops": false }],
+ "sort-imports": [
+ "error",
+ { "ignoreDeclarationSort": true, "ignoreCase": true }
+ ]
+ },
+ "overrides": [
+ {
+ "files": ["*.spec.ts", "**/test_utils/*.ts"],
+ "rules": {
+ "@typescript-eslint/no-non-null-assertion": "off"
+ }
+ }
+ ]
+}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..0cf607e3
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,20 @@
+name: CI
+
+on:
+ pull_request:
+ push:
+ branches:
+ - main
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup node 16
+ uses: actions/setup-node@v1
+ with:
+ node-version: 16.x
+ - run: yarn install --frozen-lockfile
+ - run: yarn build
+ - run: DEBUG=communities:test* yarn test
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..0b5f7c1c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,74 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.DS_Store
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Build output
+dist
+*.tsbuildinfo
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.parcel-cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+
+# Serverless directories
+.serverless/
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..d7df89c9
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..55712c19
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "typescript.tsdk": "node_modules/typescript/lib"
+}
\ No newline at end of file
diff --git a/LICENSE-APACHE-v2 b/LICENSE-APACHE-v2
new file mode 100644
index 00000000..318c8b10
--- /dev/null
+++ b/LICENSE-APACHE-v2
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2018 Status Research & Development GmbH
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 00000000..68faab7b
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2021 Status Research & Development GmbH
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..611f6def
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# Status Communities for the Web
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..d38f5ff6
--- /dev/null
+++ b/package.json
@@ -0,0 +1,19 @@
+{
+ "private": true,
+ "workspaces": [
+ "packages/*"
+ ],
+ "keywords": [],
+ "scripts": {
+ "fix": "run-s 'fix:*' && wsrun -e -c -s fix",
+ "fix:prettier": "prettier \"./*.json\" --write",
+ "build": "wsrun -e -c -s build",
+ "test": "wsrun -e -c -s test"
+ },
+ "devDependencies": {
+ "npm-run-all": "^4.1.5",
+ "prettier": "^2.3.2",
+ "wsrun": "^5.2.4"
+ },
+ "packageManager": "yarn@1.22.17"
+}
diff --git a/packages/preview-proxy/package.json b/packages/preview-proxy/package.json
new file mode 100644
index 00000000..2fc12487
--- /dev/null
+++ b/packages/preview-proxy/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@waku/preview-proxy",
+ "version": "0.1.0",
+ "main": "index.js",
+ "license": "MIT",
+ "type": "module",
+ "dependencies": {
+ "node-fetch": "^2.6.0"
+ },
+ "scripts": {
+ "start": "yarn node src/index.js",
+ "fix": "",
+ "build": "",
+ "test": ""
+ }
+}
diff --git a/packages/preview-proxy/src/index.js b/packages/preview-proxy/src/index.js
new file mode 100644
index 00000000..94496f59
--- /dev/null
+++ b/packages/preview-proxy/src/index.js
@@ -0,0 +1,59 @@
+import fetch from 'node-fetch'
+import https from 'https'
+import fs from 'fs'
+
+const regEx = new RegExp(/meta +(property|content)="(.+?)" +(property|content)="(.+?)"/g);
+
+async function listener(req, res){
+ const origin = req?.headers?.origin
+ res.statusCode = 200
+ res.setHeader('Content-Type', 'application/json')
+ if (origin === 'https://0.0.0.0:8080' || origin === 'https://localhost:8080' || origin === 'https://127.0.0.1:8080') {
+ res.setHeader('Access-Control-Allow-Origin', origin);
+ }
+ res.setHeader('Access-Control-Allow-Methods', 'POST');
+ res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
+ const requestBody = await new Promise((resolve) => {
+ if (req.method == 'POST') {
+ let body = '';
+ req.on('data', function (data) {
+ body += data;
+ if (body.length > 1e6)
+ req.connection.destroy();
+ });
+ req.on('end', function () {
+ try {
+ resolve(JSON.parse(body))
+ } catch {
+ resolve({})
+ }
+ });
+ } else {
+ resolve({})
+ }
+ })
+ const obj = {}
+ if ('site' in requestBody) {
+ try {
+ const response = await fetch(requestBody['site'])
+ const body = await response.text()
+ for (const match of body.matchAll(regEx)) {
+ if (match[1] === 'property') {
+ obj[match[2]] = match[4]
+ } else {
+ obj[match[4]] = match[2]
+ }
+ }
+ } catch {
+ }
+ }
+ res.end(JSON.stringify(obj));
+}
+
+const options = {
+ key: fs.readFileSync('../../../cert/CA/localhost/localhost.decrypted.key'),
+ cert: fs.readFileSync('../../../cert/CA/localhost/localhost.crt')
+}
+
+const server = https.createServer(options, listener);
+server.listen(3000, () => console.log('server running at port 3000'));
\ No newline at end of file
diff --git a/packages/react-chat-example/.eslintrc.json b/packages/react-chat-example/.eslintrc.json
new file mode 100644
index 00000000..b8a87ffa
--- /dev/null
+++ b/packages/react-chat-example/.eslintrc.json
@@ -0,0 +1,41 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": { "project": "./tsconfig.json" },
+ "env": { "es6": true },
+ "ignorePatterns": ["node_modules", "dist", "coverage", "proto"],
+ "plugins": ["import", "eslint-comments", "functional"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:eslint-comments/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:import/typescript",
+ "prettier"
+ ],
+ "globals": { "BigInt": true, "console": true, "WebAssembly": true },
+ "rules": {
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "eslint-comments/disable-enable-pair": [
+ "error",
+ { "allowWholeFile": true }
+ ],
+ "eslint-comments/no-unused-disable": "error",
+ "import/order": [
+ "error",
+ { "newlines-between": "always", "alphabetize": { "order": "asc" } }
+ ],
+ "no-constant-condition": ["error", { "checkLoops": false }],
+ "sort-imports": [
+ "error",
+ { "ignoreDeclarationSort": true, "ignoreCase": true }
+ ]
+ },
+ "overrides": [
+ {
+ "files": ["*.spec.ts", "**/test_utils/*.ts"],
+ "rules": {
+ "@typescript-eslint/no-non-null-assertion": "off"
+ }
+ }
+ ]
+}
diff --git a/packages/react-chat-example/.mocharc.json b/packages/react-chat-example/.mocharc.json
new file mode 100644
index 00000000..b65763d3
--- /dev/null
+++ b/packages/react-chat-example/.mocharc.json
@@ -0,0 +1,6 @@
+{
+ "extension": ["ts"],
+ "spec": "src/**/*.spec.ts",
+ "require": "ts-node/register",
+ "exit": true
+}
diff --git a/packages/react-chat-example/.prettierignore b/packages/react-chat-example/.prettierignore
new file mode 100644
index 00000000..996c3a37
--- /dev/null
+++ b/packages/react-chat-example/.prettierignore
@@ -0,0 +1,2 @@
+# package.json is formatted by package managers, so we ignore it here
+package.json
diff --git a/packages/react-chat-example/README.md b/packages/react-chat-example/README.md
new file mode 100644
index 00000000..d9fa0d1b
--- /dev/null
+++ b/packages/react-chat-example/README.md
@@ -0,0 +1,13 @@
+#React chat example
+
+##How to run example
+
+ 1. First you need to `yarn && yarn build` in main repo folder
+ 2. set two environment libraries
+ ENV and COMMUNITY_KEY
+
+ `export ENV=test` to use waku test fleet
+ `export ENV=prod` to use waku prod fleet
+ `export COMMUNITY_KEY=0x038ff8c6539ff268e024d07534a362ef69f7b13b056fcf19177fb6282b4d547bc8` to set a key to community
+
+ 3. run `yarn start` in `packages/react-chat-example` folder.
\ No newline at end of file
diff --git a/packages/react-chat-example/package.json b/packages/react-chat-example/package.json
new file mode 100644
index 00000000..e21a4455
--- /dev/null
+++ b/packages/react-chat-example/package.json
@@ -0,0 +1,71 @@
+{
+ "name": "@waku/react-chat-sdk-example",
+ "main": "index.js",
+ "version": "0.1.0",
+ "repository": "https://github.com/status-im/wakuconnect-chat-sdk/",
+ "license": "MIT OR Apache-2.0",
+ "packageManager": "yarn@3.0.1",
+ "scripts": {
+ "clean:all": "yarn clean && rimraf node_modules/",
+ "clean": "rimraf dist/",
+ "build": "rm -rf dist && webpack --mode=production --env ENV=production",
+ "start": "webpack serve --mode=development --env ENV=$ENV COMMUNITY_KEY=$COMMUNITY_KEY --https",
+ "fix": "run-s 'fix:*'",
+ "fix:prettier": "prettier './{src,test}/**/*.{ts,tsx}' \"./*.json\" --write",
+ "fix:lint": "eslint './{src,test}/**/*.{ts,tsx}' --fix",
+ "test": "run-s 'test:*'",
+ "test:lint": "eslint './{src,test}/**/*.{ts,tsx}'",
+ "test:prettier": "prettier './{src,test}/**/*.{ts,tsx}' \"./*.json\" --list-different"
+ },
+ "dependencies": {
+ "@status-im/react": "^0.0.0",
+ "assert": "^2.0.0",
+ "browserify-zlib": "^0.2.0",
+ "buffer": "^6.0.3",
+ "crypto-browserify": "^3.12.0",
+ "https-browserify": "^1.0.0",
+ "process": "^0.11.10",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "react-router-dom": "^5.2.0",
+ "stream-browserify": "^3.0.0",
+ "stream-http": "^3.2.0",
+ "styled-components": "^5.3.1"
+ },
+ "devDependencies": {
+ "@testing-library/react-hooks": "^7.0.1",
+ "@types/chai": "^4.2.21",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^16.4.12",
+ "@types/react": "^17.0.15",
+ "@types/react-dom": "^17.0.9",
+ "@types/react-router": "^5.1.16",
+ "@types/react-router-dom": "^5.1.8",
+ "@types/styled-components": "^5.1.12",
+ "@typescript-eslint/eslint-plugin": "^4.29.0",
+ "@typescript-eslint/parser": "^4.29.0",
+ "chai": "^4.3.4",
+ "css-loader": "^6.3.0",
+ "esbuild-loader": "^2.15.1",
+ "eslint": "^7.32.0",
+ "eslint-plugin-hooks": "^0.2.0",
+ "eslint-plugin-react": "^7.24.0",
+ "file-loader": "^6.2.0",
+ "fork-ts-checker-webpack-plugin": "^6.3.1",
+ "html-webpack-plugin": "^5.3.2",
+ "jsdom": "^16.7.0",
+ "jsdom-global": "^3.0.2",
+ "mocha": "^9.0.3",
+ "npm-run-all": "^4.1.5",
+ "prettier": "^2.3.2",
+ "rimraf": "^3.0.2",
+ "source-map-loader": "^3.0.0",
+ "style-loader": "^3.3.0",
+ "ts-loader": "^9.2.5",
+ "ts-node": "^10.1.0",
+ "typescript": "^4.3.5",
+ "webpack": "^5.48.0",
+ "webpack-cli": "^4.7.2",
+ "webpack-dev-server": "^3.11.2"
+ }
+}
diff --git a/packages/react-chat-example/src/_redirects b/packages/react-chat-example/src/_redirects
new file mode 100644
index 00000000..ad37e2c2
--- /dev/null
+++ b/packages/react-chat-example/src/_redirects
@@ -0,0 +1 @@
+/* /index.html 200
diff --git a/packages/react-chat-example/src/index.html b/packages/react-chat-example/src/index.html
new file mode 100644
index 00000000..8bc17f8e
--- /dev/null
+++ b/packages/react-chat-example/src/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Waku Connect Chat
+
+
+
+
+
+
+
diff --git a/packages/react-chat-example/src/index.tsx b/packages/react-chat-example/src/index.tsx
new file mode 100644
index 00000000..71d13474
--- /dev/null
+++ b/packages/react-chat-example/src/index.tsx
@@ -0,0 +1,136 @@
+import { CommunityChat, darkTheme, lightTheme } from "@waku/react-chat-sdk";
+import React, { useRef, useState } from "react";
+import ReactDOM from "react-dom";
+import styled from "styled-components";
+
+const fetchMetadata = async (link: string) => {
+ const response = await fetch("https://localhost:3000", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ site: link }),
+ });
+ const body = await response.text();
+ const parsedBody = JSON.parse(body);
+ if (
+ "og:image" in parsedBody &&
+ "og:site_name" in parsedBody &&
+ "og:title" in parsedBody
+ ) {
+ return JSON.parse(body);
+ }
+};
+
+function DragDiv() {
+ const [x, setX] = useState(0);
+ const [y, setY] = useState(0);
+ const [width, setWidth] = useState(window.innerWidth - 50);
+ const [height, setHeight] = useState(window.innerHeight - 50);
+ const [showChat, setShowChat] = useState(true);
+ const ref = useRef(null);
+ const moved = useRef(false);
+ const setting = useRef("");
+
+ const [theme, setTheme] = useState(true);
+
+ const onMouseMove = (e: MouseEvent) => {
+ if (setting.current === "position") {
+ e.preventDefault();
+ setX(e.x - 20);
+ setY(e.y - 20);
+ }
+ if (setting.current === "size") {
+ setWidth(e.x - x);
+ setHeight(e.y - y);
+ e.preventDefault();
+ }
+ moved.current = true;
+ };
+
+ const onMouseUp = () => {
+ document.removeEventListener("mousemove", onMouseMove);
+ document.removeEventListener("mouseup", onMouseUp);
+ if (!moved.current) [setShowChat((prev) => !prev)];
+ moved.current = false;
+ };
+
+ return (
+ <>
+
+
+ {
+ setting.current = "position";
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+ }}
+ />
+
+
+
+ {showChat && (
+ {
+ setting.current = "size";
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+ }}
+ >
+ )}
+
+ >
+ );
+}
+
+const FloatingDiv = styled.div`
+ height: calc(100% - 50px);
+ border: 1px solid black;
+
+ &.hide {
+ display: none;
+ }
+`;
+
+const SizeSet = styled.div`
+ margin-left: auto;
+ margin-right: 0px;
+ width: 10px;
+ height: 10px;
+ background-color: light-grey;
+ border: 1px solid;
+`;
+
+const Bubble = styled.div`
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ background-color: lightblue;
+ border: 1px solid;
+`;
+
+const Drag = styled.div`
+ position: absolute;
+ min-width: 375px;
+`;
+
+ReactDOM.render(
+
+
+
,
+ document.getElementById("root")
+);
diff --git a/packages/react-chat-example/tsconfig.json b/packages/react-chat-example/tsconfig.json
new file mode 100644
index 00000000..cee3d03f
--- /dev/null
+++ b/packages/react-chat-example/tsconfig.json
@@ -0,0 +1,47 @@
+{
+ "compilerOptions": {
+ "target": "es6",
+ "outDir": "dist",
+ "jsx": "react",
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "declaration": true,
+ "sourceMap": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "composite": true,
+ "strict": true /* Enable all strict type-checking options. */,
+
+ /* Strict Type-Checking Options */
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "strictPropertyInitialization": true,
+ "noImplicitThis": true,
+ "alwaysStrict": true,
+
+ /* Additional Checks */
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": false /* to set at a later stage */,
+ "noFallthroughCasesInSwitch": true,
+ "forceConsistentCasingInFileNames": true,
+
+ /* Debugging Options */
+ "traceResolution": false,
+ "listEmittedFiles": false,
+ "listFiles": false,
+ "pretty": true,
+
+ // Due to broken types in indirect dependencies
+ "skipLibCheck": true,
+ "typeRoots": [
+ "./node_modules/@types",
+ "./src/types",
+ "../../node_modules/@types"
+ ]
+ },
+ "include": ["src"],
+ "types": ["mocha"],
+ "compileOnSave": false
+}
diff --git a/packages/react-chat-example/tsconfig.tsbuildinfo b/packages/react-chat-example/tsconfig.tsbuildinfo
new file mode 100644
index 00000000..bf848bfa
--- /dev/null
+++ b/packages/react-chat-example/tsconfig.tsbuildinfo
@@ -0,0 +1 @@
+{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es6.d.ts","../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/@types/react/global.d.ts","../../node_modules/csstype/index.d.ts","../../node_modules/@types/prop-types/index.d.ts","../../node_modules/@types/scheduler/tracing.d.ts","../../node_modules/@types/react/index.d.ts","../../node_modules/@types/react-dom/index.d.ts","./src/index.tsx","../../node_modules/@types/chai/index.d.ts","../../node_modules/@types/ms/index.d.ts","../../node_modules/@types/debug/index.d.ts","../../node_modules/@types/eslint/helpers.d.ts","../../node_modules/@types/eslint/lib/rules/index.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/eslint/index.d.ts","../../node_modules/@types/eslint-scope/index.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/globals.global.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/@types/minimatch/index.d.ts","../../node_modules/@types/glob/index.d.ts","../../node_modules/@types/history/DOMUtils.d.ts","../../node_modules/@types/history/createBrowserHistory.d.ts","../../node_modules/@types/history/createHashHistory.d.ts","../../node_modules/@types/history/createMemoryHistory.d.ts","../../node_modules/@types/history/LocationUtils.d.ts","../../node_modules/@types/history/PathUtils.d.ts","../../node_modules/@types/history/index.d.ts","../../node_modules/@types/hoist-non-react-statics/index.d.ts","../../node_modules/@types/html-minifier-terser/index.d.ts","../../node_modules/@types/istanbul-lib-coverage/index.d.ts","../../node_modules/@types/istanbul-lib-report/index.d.ts","../../node_modules/@types/istanbul-reports/index.d.ts","../../node_modules/@types/json5/index.d.ts","../../node_modules/@types/keyv/index.d.ts","../../node_modules/@types/long/index.d.ts","../../node_modules/@types/mocha/index.d.ts","../../node_modules/@types/object-hash/index.d.ts","../../node_modules/@types/parse-json/index.d.ts","../../node_modules/@types/prettier/index.d.ts","../../node_modules/@types/react-router/index.d.ts","../../node_modules/@types/react-router-dom/index.d.ts","../../node_modules/@types/react-test-renderer/index.d.ts","../../node_modules/@types/responselike/index.d.ts","../../node_modules/@types/retry/index.d.ts","../../node_modules/@types/scheduler/index.d.ts","../../node_modules/@types/secp256k1/index.d.ts","../../node_modules/@types/styled-components/index.d.ts","../../node_modules/@types/yargs-parser/index.d.ts","../../node_modules/@types/yargs/index.d.ts"],"fileInfos":["721cec59c3fef87aaf480047d821fb758b3ec9482c4129a54631e6e25e432a31",{"version":"aa9fb4c70f369237c2f45f9d969c9a59e0eae9a192962eb48581fe864aa609db","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","e6b724280c694a9f588847f754198fb96c43d805f065c3a5b28bbc9594541c84","e21c071ca3e1b4a815d5f04a7475adcaeea5d64367e840dd0154096d705c3940",{"version":"e54c8715a4954cfdc66cd69489f2b725c09ebf37492dbd91cff0a1688b1159e8","affectsGlobalScope":true},{"version":"e34eb9339171ec45da2801c1967e4d378bd61a1dceaa1b1b4e1b6d28cb9ca962","affectsGlobalScope":true},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true},{"version":"51b8b27c21c066bf877646e320bf6a722b80d1ade65e686923cd9d4494aef1ca","affectsGlobalScope":true},{"version":"43fb1d932e4966a39a41b464a12a81899d9ae5f2c829063f5571b6b87e6d2f9c","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"2c8c5ee58f30e7c944e04ab1fb5506fdbb4dd507c9efa6972cf4b91cec90c503","affectsGlobalScope":true},{"version":"2bb4b3927299434052b37851a47bf5c39764f2ba88a888a107b32262e9292b7c","affectsGlobalScope":true},{"version":"810627a82ac06fb5166da5ada4159c4ec11978dfbb0805fe804c86406dab8357","affectsGlobalScope":true},{"version":"62d80405c46c3f4c527ee657ae9d43fda65a0bf582292429aea1e69144a522a6","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"75ec0bdd727d887f1b79ed6619412ea72ba3c81d92d0787ccb64bab18d261f14","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"12a310447c5d23c7d0d5ca2af606e3bd08afda69100166730ab92c62999ebb9d","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"df9c8a72ca8b0ed62f5470b41208a0587f0f73f0a7db28e5a1272cf92537518e","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"93544ca2f26a48716c1b6c5091842cad63129daac422dfa4bc52460465f22bb1","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"1b3fe904465430e030c93239a348f05e1be80640d91f2f004c3512c2c2c89f34","affectsGlobalScope":true},{"version":"7435b75fdf3509622e79622dbe5091cf4b09688410ee2034e4fc17d0c99d0862","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"9f1817f7c3f02f6d56e0f403b927e90bb133f371dcebc36fa7d6d208ef6899da","affectsGlobalScope":true},{"version":"4632665b87204bb1caa8b44d165bce0c50dfab177df5b561b345a567cabacf9a","affectsGlobalScope":true},{"version":"ecf78e637f710f340ec08d5d92b3f31b134a46a4fcf2e758690d8c46ce62cba6","affectsGlobalScope":true},"5b1d4ebd62d975c7d3826202f8fac290bac0bae6e04d9e84d1707d7047e108df","f7b46d22a307739c145e5fddf537818038fdfffd580d79ed717f4d4d37249380","f5a8b384f182b3851cec3596ccc96cb7464f8d3469f48c74bf2befb782a19de5",{"version":"7b4a3453c60663af7f58636bf4673bfcc540d83ce1c41b816a5cc2e924009880","affectsGlobalScope":true},"b4dfafe583b829a382edccbe32303535d0785f0c02ba7f04418e2a81de97af8a",{"version":"93a64c8d9db6a210880af441b80af0c05130faf026d293ffb6beb398e2693224","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"0c9d1fd5b43d5e88c277f7f53cffc87778190f2f9a1f57743559421f04fc730b","affectsGlobalScope":true},"6a9c5127096b35264eb7cd21b2417bfc1d42cceca9ba4ce2bb0c3410b7816042","78828b06c0d3b586954015e9ebde5480b009e166c71244763bda328ec0920f41",{"version":"64d4b35c5456adf258d2cf56c341e203a073253f229ef3208fc0d5020253b241","affectsGlobalScope":true},"0133ebdd17a823ae56861948870cde4dac18dd8818ab641039c85bbb720429e0","0359682c54e487c4cab2b53b2b4d35cc8dea4d9914bc6abcdb5701f8b8e745a4","7d7c8ef7d48a035142c07dae60545ecc0e4af4c337742760cb09726f2f8e31db","e300bf65972ac08167a72787e19d1b43c285c5424707194d0ba64422f6b02c77","82772e5d55062a042a2715a555d347275a663940926fc785705eb082010cb9f6","0d5a2ee1fdfa82740e0103389b9efd6bfe145a20018a2da3c02b89666181f4d9","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"92d63add669d18ebc349efbacd88966d6f2ccdddfb1b880b2db98ae3aa7bf7c4","affectsGlobalScope":true},"ccc94049a9841fe47abe5baef6be9a38fc6228807974ae675fb15dc22531b4be",{"version":"658a70ff0b4d8298739566835c4b324a9ecef1676a2cd1fabfb5660a821d38ef","affectsGlobalScope":true},"43978f18d1165eea81040bc9bfac1a551717f5cc9bd0f13b31bf490c5fcdc75f","afc6e96061af46bcff47246158caee7e056f5288783f2d83d6858cd25be1c565",{"version":"c3ad91d23259b68e10a9bef08c5f9fa1d19f27ef740ac9af98ed226b030c09c6","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","38643f040239c18923ef39b5e1fe2651eaa8a633d2e371d48ae7e951ec55a923","260aad3a6bd3fc510b7f97cfb05859bfc045ce185f8c2b4d73ddb9c43b0eb3c0","cb428529763c6c8e38e42db2a39f333ffcc6d3aab396b24ac84b22da752c1de0","ad4b60488fb1e562bf375dac9299815f7028bf667d9b5887b2d01d501b7d1ddd","246341c3a7a2638cf830d690e69de1e6085a102c6a30596435b050e6ac86c11a","6972fca26f6e9bd56197568d4379f99071a90766e06b4fcb5920a0130a9202be",{"version":"4a2628e95962c8ab756121faa3ac2ed348112ff7a87b5c286dd2cc3326546b4c","affectsGlobalScope":true},"ccded627c1c57aa9e021aea914c3197899e7335fdc65426a6d61a8e65e751c00","2fa7fb7be51fa9924ebef6bd61d290c91bfebb93de00fd4949d836e68668a9de","f2f0941f8d09218dfabd1b89ee9b4fb4a193568deb9b44c13a08ac5a386d81ae","b287b810b5035d5685f1df6e1e418f1ca452a3ed4f59fd5cc081dbf2045f0d9b","4b9a003b5c556c96784132945bb41c655ea11273b1917f5c8d0c154dd5fd20dd","62a00c9cc0c78d9f282dcd7b0a7776aefe220106c3bc327e259e5f6484c6f556",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"f3e8bcce378a26bc672fce0ec05affabbbbfa18493b76f24c39136dea87100d0","abc1c425b2ad6720433f40f1877abfa4223f0f3dd486c9c28c492179ca183cb6","cd4854d38f4eb5592afd98ab95ca17389a7dfe38013d9079e802d739bdbcc939","94eed4cc2f5f658d5e229ff1ccd38860bddf4233e347bf78edd2154dee1f2b99",{"version":"e51bee3200733b1f58818b5a9ea90fcd61c5b8afa3a0378391991f3696826a65","affectsGlobalScope":true},"9f1069b9e2c051737b1f9b4f1baf50e4a63385a6a89c32235549ae87fc3d5492","ee18f2da7a037c6ceeb112a084e485aead9ea166980bf433474559eac1b46553","e70339a3d63f806c43f24250c42aa0000093923457b0ed7dfc10e0ac910ebca9","0acbf26bf958f9e80c1ffa587b74749d2697b75b484062d36e103c137c562bc3","2c20a91799640fc6bf027056fd56e5b8db5c427c1cc016bdb04cde5c9a0603b9","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff",{"version":"806ef4cac3b3d9fa4a48d849c8e084d7c72fcd7b16d76e06049a9ed742ff79c0","affectsGlobalScope":true},"a279435e7813d1f061c0cab6ab77b1b9377e8d96851e5ed4a76a1ce6eb6e628f","c33a6ea7147af60d8e98f1ac127047f4b0d4e2ce28b8f08ff3de07ca7cc00637",{"version":"b42b47e17b8ece2424ae8039feb944c2e3ba4b262986aebd582e51efbdca93dc","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","2408611d9b4146e35d1dbd1f443ccd8e187c74614a54b80300728277529dbf11","998a3de5237518c0b3ac00a11b3b4417affb008aa20aedee52f3fdae3cb86151","3accc1301749459bba2d1ba0084fdf399e5471508300956a3a2a1a8f4bc35f2e","b810390059fc34122556c644f586e7a2b4598ded8afe5ba70bb82fc2e50577b1","ba9de5c5823e06ee3314f959c138cdaf4477d3a1a0769f0d24e62911020e8088","c3db860bcaaaeb3bbc23f353bbda1f8ab82756c8d5e973bebb3953cb09ea68f2","235a53595bd20b0b0eeb1a29cb2887c67c48375e92f03749b2488fbd46d0b1a0","bc09393cd4cd13f69cf1366d4236fbae5359bb550f0de4e15767e9a91d63dfb1","9c266243b01545e11d2733a55ad02b4c00ecdbda99c561cd1674f96e89cdc958","c71155c05fc76ff948a4759abc1cb9feec036509f500174bc18dad4c7827a60c",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"ba229259c8b01c6733dc6a3e7b2ae3e2b76e502bb640a1691238a4c9cae5cfed","8841e2aa774b89bd23302dede20663306dc1b9902431ac64b24be8b8d0e3f649","725b884357ba84171341a8e4cc08edf11417854fd069842ca6d22afb2e340e45",{"version":"271cde49dfd9b398ccc91bb3aaa43854cf76f4d14e10fed91cbac649aa6cbc63","affectsGlobalScope":true},"2bcecd31f1b4281710c666843fc55133a0ee25b143e59f35f49c62e168123f4b","a6273756fa05f794b64fe1aff45f4371d444f51ed0257f9364a8b25f3501915d","2374e4ddc628bd0af8ce7578621f1b9d08ab183f4dbacb8749eabb1a85018196","25d91fb9ed77a828cc6c7a863236fb712dafcd52f816eec481bd0c1f589f4404","4cd14cea22eed1bfb0dc76183e56989f897ac5b14c0e2a819e5162eafdcfe243","ab35d08aa06a7615f06dad04db7e88f27d623220f05de68a94f16d5d22e6aaea","bfe1b52cf71aea9bf8815810cc5d9490fa9617313e3d3c2ee3809a28b80d0bb4","70b34c8420d6226ed565d55f47fe04912d0ca0ad128825c5a06e018a3498db32","de18acda71730bac52f4b256ce7511bb56cc21f6f114c59c46782eff2f632857","7eb06594824ada538b1d8b48c3925a83e7db792f47a081a62cf3e5c4e23cf0ee","029769d13d9917e3284cb2356ed28a6576e8b07ae6a06ee1e672518adf21a102","c5a14bdeb170e0e67fb4200c54e0e02fd0ec94aca894c212c9d43c2916891542","82169f198ffdfc787fba368ccfad2b2d8ef3712f3c696df94ac13f6884bbbe2d","e8465811693dfe4e96ef2b3dffda539d6edfe896961b7af37b44db2c0e48532b",{"version":"e8bf92aabac2b11e1bf60a0161039cd6f5f0cd9713863ca2289dd7b10eddece8","affectsGlobalScope":true},"a84c95e04a7387764e5c9f03a1bb1083ffa1166254a517398524630e918f8627","2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b","29651525db5579157e617c77e869af8bfdc1130f5d811c1f759ad35b7bafc8ef","f8116d99ea6244e8b1492a9229b5d7e46e66f3fa21691d356ff173f03a14b6c9","341f07a69f65cbae19fc6ccf3c7ffe432365606d473d64d9be3d358ee2e86070","60aaac5fb1858fbd4c4eb40e01706eb227eed9eca5c665564bd146971280dbd3","3cfb0cb51cc2c2e1b313d7c4df04dbf7e5bda0a133c6b309bf6af77cf614b971","58a3914b1cce4560d9ad6eee2b716caaa030eda0a90b21ca2457ea9e2783eaa3","74b0245c42990ed8a849df955db3f4362c81b13f799ebc981b7bec2d5b414a57","3dce33e7eb25594863b8e615f14a45ab98190d85953436750644212d8a18c066",{"version":"fccaceadff070fd2caf21495a48c42444c28412556537a199cf1e57e30f70bf0","affectsGlobalScope":true},"f7e133b20ee2669b6c0e5d7f0cd510868c57cd64b283e68c7f598e30ce9d76d2","d9f5e2cb6bce0d05a252e991b33e051f6385299b0dd18d842fc863b59173a18e"],"options":{"composite":true,"declaration":true,"declarationMap":false,"esModuleInterop":true,"inlineSourceMap":false,"jsx":2,"module":1,"noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":false,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":false,"strict":true,"strictNullChecks":true,"strictPropertyInitialization":true,"target":2},"fileIdsList":[[103],[52,103],[57,58,103],[54,55,56,57,103],[58,103],[75,103,110,111],[103,119],[103,113,119],[103,114,115,116,117,118],[48,103],[103,122],[103,122,123],[75,103,110],[60,103],[63,103],[64,69,103],[65,75,76,83,92,102,103],[65,66,75,83,103],[67,103],[68,69,76,84,103],[69,92,99,103],[70,72,75,83,103],[71,103],[72,73,103],[74,75,103],[75,103],[75,76,77,92,102,103],[75,76,77,92,103],[78,83,92,102,103],[75,76,78,79,83,92,99,102,103],[78,80,92,99,102,103],[60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109],[75,81,103],[82,102,103],[72,75,83,92,103],[84,103],[85,103],[63,86,103],[87,101,103,107],[88,103],[89,103],[75,90,103],[90,91,103,105],[75,92,93,94,103],[92,94,103],[92,93,103],[95,103],[96,103],[75,97,98,103],[97,98,103],[69,83,99,103],[100,103],[83,101,103],[64,78,89,102,103],[69,103],[92,103,104],[103,105],[103,106],[64,69,75,77,86,92,102,103,105,107],[92,103,108],[48,103,119,132],[48,103,119],[44,45,46,47,103],[78,92,103,110],[103,110],[45,48,103,120],[103,140],[48,49,103]],"referencedMap":[[51,1],[53,2],[59,3],[54,1],[58,4],[55,5],[57,1],[112,6],[113,1],[117,7],[118,7],[114,8],[115,8],[116,8],[119,9],[120,10],[121,1],[122,1],[123,11],[124,12],[56,1],[125,1],[126,13],[127,1],[111,1],[128,1],[52,1],[60,14],[61,14],[63,15],[64,16],[65,17],[66,18],[67,19],[68,20],[69,21],[70,22],[71,23],[72,24],[73,24],[74,25],[75,26],[76,27],[77,28],[62,1],[109,1],[78,29],[79,30],[80,31],[110,32],[81,33],[82,34],[83,35],[84,36],[85,37],[86,38],[87,39],[88,40],[89,41],[90,42],[91,43],[92,44],[94,45],[93,46],[95,47],[96,48],[97,49],[98,50],[99,51],[100,52],[101,53],[102,54],[103,55],[104,56],[105,57],[106,58],[107,59],[108,60],[129,1],[130,1],[131,1],[46,1],[49,10],[133,61],[132,62],[134,10],[44,1],[48,63],[135,64],[136,1],[137,1],[47,1],[138,65],[139,66],[140,1],[141,67],[45,1],[9,1],[10,1],[14,1],[13,1],[3,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[4,1],[5,1],[26,1],[23,1],[24,1],[25,1],[27,1],[28,1],[29,1],[6,1],[30,1],[31,1],[32,1],[33,1],[7,1],[34,1],[35,1],[36,1],[37,1],[8,1],[42,1],[38,1],[39,1],[40,1],[41,1],[2,1],[1,1],[43,1],[12,1],[11,1],[50,68]],"exportedModulesMap":[[51,1],[53,2],[59,3],[54,1],[58,4],[55,5],[57,1],[112,6],[113,1],[117,7],[118,7],[114,8],[115,8],[116,8],[119,9],[120,10],[121,1],[122,1],[123,11],[124,12],[56,1],[125,1],[126,13],[127,1],[111,1],[128,1],[52,1],[60,14],[61,14],[63,15],[64,16],[65,17],[66,18],[67,19],[68,20],[69,21],[70,22],[71,23],[72,24],[73,24],[74,25],[75,26],[76,27],[77,28],[62,1],[109,1],[78,29],[79,30],[80,31],[110,32],[81,33],[82,34],[83,35],[84,36],[85,37],[86,38],[87,39],[88,40],[89,41],[90,42],[91,43],[92,44],[94,45],[93,46],[95,47],[96,48],[97,49],[98,50],[99,51],[100,52],[101,53],[102,54],[103,55],[104,56],[105,57],[106,58],[107,59],[108,60],[129,1],[130,1],[131,1],[46,1],[49,10],[133,61],[132,62],[134,10],[44,1],[48,63],[135,64],[136,1],[137,1],[47,1],[138,65],[139,66],[140,1],[141,67],[45,1],[9,1],[10,1],[14,1],[13,1],[3,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[4,1],[5,1],[26,1],[23,1],[24,1],[25,1],[27,1],[28,1],[29,1],[6,1],[30,1],[31,1],[32,1],[33,1],[7,1],[34,1],[35,1],[36,1],[37,1],[8,1],[42,1],[38,1],[39,1],[40,1],[41,1],[2,1],[1,1],[43,1],[12,1],[11,1]],"semanticDiagnosticsPerFile":[51,53,59,54,58,55,57,112,113,117,118,114,115,116,119,120,121,122,123,124,56,125,126,127,111,128,52,60,61,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,62,109,78,79,80,110,81,82,83,84,85,86,87,88,89,90,91,92,94,93,95,96,97,98,99,100,101,102,103,104,105,106,107,108,129,130,131,46,49,133,132,134,44,48,135,136,137,47,138,139,140,141,45,9,10,14,13,3,15,16,17,18,19,20,21,22,4,5,26,23,24,25,27,28,29,6,30,31,32,33,7,34,35,36,37,8,42,38,39,40,41,2,1,43,12,11,[50,[{"file":"./src/index.tsx","start":85,"length":25,"messageText":"Cannot find module '@waku/react-chat-sdk' or its corresponding type declarations.","category":1,"code":2307}]]]},"version":"4.4.3"}
diff --git a/packages/react-chat-example/webpack.config.js b/packages/react-chat-example/webpack.config.js
new file mode 100644
index 00000000..4500adf3
--- /dev/null
+++ b/packages/react-chat-example/webpack.config.js
@@ -0,0 +1,88 @@
+const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
+const webpack = require('webpack');
+const { ESBuildMinifyPlugin } = require('esbuild-loader');
+
+module.exports = env => {
+ const environment = env.ENV || 'development';
+ const communityKey = env.COMMUNITY_KEY || '';
+
+ return {
+ entry: './src/index.tsx',
+ output: {
+ filename: 'index.[fullhash].js',
+ path: path.join(__dirname, 'dist'),
+ publicPath: '/',
+ },
+ devtool: 'source-map',
+ resolve: {
+ extensions: ['.ts', '.tsx', '.js', '.json'],
+ fallback: {
+ buffer: require.resolve('buffer/'),
+ crypto: require.resolve('crypto-browserify'),
+ stream: require.resolve('stream-browserify'),
+ assert: require.resolve('assert/'),
+ http: require.resolve('stream-http'),
+ https: require.resolve('https-browserify'),
+ zlib: require.resolve('browserify-zlib')
+ },
+ },
+ module: {
+ rules: [
+ {
+ test: /\.tsx?$/,
+ loader: 'esbuild-loader',
+ exclude: /node_modules/,
+ options: {
+ loader: 'tsx',
+ target: 'es2020',
+ },
+ },
+ {
+ enforce: 'pre',
+ test: /\.js$/,
+ exclude: /node_modules/,
+ loader: 'source-map-loader',
+ },
+ {
+ test: /\.(png|svg|jpg|gif|woff|woff2|eot|ttf|otf|ico)$/,
+ use: ['file-loader'],
+ },
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ ],
+ },
+ optimization: {
+ minimizer: [
+ new ESBuildMinifyPlugin({
+ target: 'es2020',
+ }),
+ ],
+ },
+ plugins: [
+ new ForkTsCheckerWebpackPlugin(),
+ new HtmlWebpackPlugin({
+ template: 'src/index.html',
+ }),
+ new webpack.DefinePlugin({
+ 'process.env.ENV': JSON.stringify(environment),
+ 'process.env.COMMUNITY_KEY': JSON.stringify(communityKey),
+ }),
+ new webpack.ProvidePlugin({
+ process: 'process/browser.js',
+ Buffer: ['buffer', 'Buffer'],
+ }),
+ ],
+ devServer: {
+ historyApiFallback: true,
+ host: '0.0.0.0',
+ stats: 'errors-only',
+ overlay: true,
+ hot: true,
+ },
+ stats: 'minimal',
+ };
+};
diff --git a/packages/react-group-chat-example/.eslintrc.json b/packages/react-group-chat-example/.eslintrc.json
new file mode 100644
index 00000000..b8a87ffa
--- /dev/null
+++ b/packages/react-group-chat-example/.eslintrc.json
@@ -0,0 +1,41 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": { "project": "./tsconfig.json" },
+ "env": { "es6": true },
+ "ignorePatterns": ["node_modules", "dist", "coverage", "proto"],
+ "plugins": ["import", "eslint-comments", "functional"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:eslint-comments/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:import/typescript",
+ "prettier"
+ ],
+ "globals": { "BigInt": true, "console": true, "WebAssembly": true },
+ "rules": {
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "eslint-comments/disable-enable-pair": [
+ "error",
+ { "allowWholeFile": true }
+ ],
+ "eslint-comments/no-unused-disable": "error",
+ "import/order": [
+ "error",
+ { "newlines-between": "always", "alphabetize": { "order": "asc" } }
+ ],
+ "no-constant-condition": ["error", { "checkLoops": false }],
+ "sort-imports": [
+ "error",
+ { "ignoreDeclarationSort": true, "ignoreCase": true }
+ ]
+ },
+ "overrides": [
+ {
+ "files": ["*.spec.ts", "**/test_utils/*.ts"],
+ "rules": {
+ "@typescript-eslint/no-non-null-assertion": "off"
+ }
+ }
+ ]
+}
diff --git a/packages/react-group-chat-example/.mocharc.json b/packages/react-group-chat-example/.mocharc.json
new file mode 100644
index 00000000..b65763d3
--- /dev/null
+++ b/packages/react-group-chat-example/.mocharc.json
@@ -0,0 +1,6 @@
+{
+ "extension": ["ts"],
+ "spec": "src/**/*.spec.ts",
+ "require": "ts-node/register",
+ "exit": true
+}
diff --git a/packages/react-group-chat-example/.prettierignore b/packages/react-group-chat-example/.prettierignore
new file mode 100644
index 00000000..996c3a37
--- /dev/null
+++ b/packages/react-group-chat-example/.prettierignore
@@ -0,0 +1,2 @@
+# package.json is formatted by package managers, so we ignore it here
+package.json
diff --git a/packages/react-group-chat-example/README.md b/packages/react-group-chat-example/README.md
new file mode 100644
index 00000000..539a1696
--- /dev/null
+++ b/packages/react-group-chat-example/README.md
@@ -0,0 +1 @@
+#React chat example
\ No newline at end of file
diff --git a/packages/react-group-chat-example/package.json b/packages/react-group-chat-example/package.json
new file mode 100644
index 00000000..f9dfcbe5
--- /dev/null
+++ b/packages/react-group-chat-example/package.json
@@ -0,0 +1,71 @@
+{
+ "name": "@waku/react-group-chat-sdk-example",
+ "main": "index.js",
+ "version": "0.1.0",
+ "repository": "https://github.com/status-im/wakuconnect-chat-sdk/",
+ "license": "MIT OR Apache-2.0",
+ "packageManager": "yarn@3.0.1",
+ "scripts": {
+ "clean:all": "yarn clean && rimraf node_modules/",
+ "clean": "rimraf dist/",
+ "build": "rm -rf dist && webpack --mode=production --env ENV=production",
+ "start": "webpack serve --mode=development --env ENV=$ENV COMMUNITY_KEY=$COMMUNITY_KEY --https",
+ "fix": "run-s 'fix:*'",
+ "fix:prettier": "prettier './{src,test}/**/*.{ts,tsx}' \"./*.json\" --write",
+ "fix:lint": "eslint './{src,test}/**/*.{ts,tsx}' --fix",
+ "test": "run-s 'test:*'",
+ "test:lint": "eslint './{src,test}/**/*.{ts,tsx}'",
+ "test:prettier": "prettier './{src,test}/**/*.{ts,tsx}' \"./*.json\" --list-different"
+ },
+ "dependencies": {
+ "@status-im/react": "^0.0.0",
+ "assert": "^2.0.0",
+ "browserify-zlib": "^0.2.0",
+ "buffer": "^6.0.3",
+ "crypto-browserify": "^3.12.0",
+ "https-browserify": "^1.0.0",
+ "process": "^0.11.10",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "react-router-dom": "^5.2.0",
+ "stream-browserify": "^3.0.0",
+ "stream-http": "^3.2.0",
+ "styled-components": "^5.3.1"
+ },
+ "devDependencies": {
+ "@testing-library/react-hooks": "^7.0.1",
+ "@types/chai": "^4.2.21",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^16.4.12",
+ "@types/react": "^17.0.15",
+ "@types/react-dom": "^17.0.9",
+ "@types/react-router": "^5.1.16",
+ "@types/react-router-dom": "^5.1.8",
+ "@types/styled-components": "^5.1.12",
+ "@typescript-eslint/eslint-plugin": "^4.29.0",
+ "@typescript-eslint/parser": "^4.29.0",
+ "chai": "^4.3.4",
+ "css-loader": "^6.3.0",
+ "esbuild-loader": "^2.15.1",
+ "eslint": "^7.32.0",
+ "eslint-plugin-hooks": "^0.2.0",
+ "eslint-plugin-react": "^7.24.0",
+ "file-loader": "^6.2.0",
+ "fork-ts-checker-webpack-plugin": "^6.3.1",
+ "html-webpack-plugin": "^5.3.2",
+ "jsdom": "^16.7.0",
+ "jsdom-global": "^3.0.2",
+ "mocha": "^9.0.3",
+ "npm-run-all": "^4.1.5",
+ "prettier": "^2.3.2",
+ "rimraf": "^3.0.2",
+ "source-map-loader": "^3.0.0",
+ "style-loader": "^3.3.0",
+ "ts-loader": "^9.2.5",
+ "ts-node": "^10.1.0",
+ "typescript": "^4.3.5",
+ "webpack": "^5.48.0",
+ "webpack-cli": "^4.7.2",
+ "webpack-dev-server": "^3.11.2"
+ }
+}
diff --git a/packages/react-group-chat-example/src/_redirects b/packages/react-group-chat-example/src/_redirects
new file mode 100644
index 00000000..ad37e2c2
--- /dev/null
+++ b/packages/react-group-chat-example/src/_redirects
@@ -0,0 +1 @@
+/* /index.html 200
diff --git a/packages/react-group-chat-example/src/index.html b/packages/react-group-chat-example/src/index.html
new file mode 100644
index 00000000..9a13586c
--- /dev/null
+++ b/packages/react-group-chat-example/src/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Waku Connect group chat
+
+
+
+
+
+
+
diff --git a/packages/react-group-chat-example/src/index.tsx b/packages/react-group-chat-example/src/index.tsx
new file mode 100644
index 00000000..35953b1a
--- /dev/null
+++ b/packages/react-group-chat-example/src/index.tsx
@@ -0,0 +1,135 @@
+import { darkTheme, GroupChat, lightTheme } from "@waku/react-chat-sdk";
+import React, { useRef, useState } from "react";
+import ReactDOM from "react-dom";
+import styled from "styled-components";
+
+const fetchMetadata = async (link: string) => {
+ const response = await fetch("https://localhost:3000", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ site: link }),
+ });
+ const body = await response.text();
+ const parsedBody = JSON.parse(body);
+ if (
+ "og:image" in parsedBody &&
+ "og:site_name" in parsedBody &&
+ "og:title" in parsedBody
+ ) {
+ return JSON.parse(body);
+ }
+};
+
+function DragDiv() {
+ const [x, setX] = useState(0);
+ const [y, setY] = useState(0);
+ const [width, setWidth] = useState(window.innerWidth - 50);
+ const [height, setHeight] = useState(window.innerHeight - 50);
+ const [showChat, setShowChat] = useState(true);
+ const ref = useRef(null);
+ const moved = useRef(false);
+ const setting = useRef("");
+
+ const [theme, setTheme] = useState(true);
+
+ const onMouseMove = (e: MouseEvent) => {
+ if (setting.current === "position") {
+ e.preventDefault();
+ setX(e.x - 20);
+ setY(e.y - 20);
+ }
+ if (setting.current === "size") {
+ setWidth(e.x - x);
+ setHeight(e.y - y);
+ e.preventDefault();
+ }
+ moved.current = true;
+ };
+
+ const onMouseUp = () => {
+ document.removeEventListener("mousemove", onMouseMove);
+ document.removeEventListener("mouseup", onMouseUp);
+ if (!moved.current) [setShowChat((prev) => !prev)];
+ moved.current = false;
+ };
+
+ return (
+ <>
+
+
+ {
+ setting.current = "position";
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+ }}
+ />
+
+
+
+ {showChat && (
+ {
+ setting.current = "size";
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+ }}
+ >
+ )}
+
+ >
+ );
+}
+
+const FloatingDiv = styled.div`
+ height: calc(100% - 50px);
+ border: 1px solid black;
+
+ &.hide {
+ display: none;
+ }
+`;
+
+const SizeSet = styled.div`
+ margin-left: auto;
+ margin-right: 0px;
+ width: 10px;
+ height: 10px;
+ background-color: light-grey;
+ border: 1px solid;
+`;
+
+const Bubble = styled.div`
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ background-color: lightblue;
+ border: 1px solid;
+`;
+
+const Drag = styled.div`
+ position: absolute;
+ min-width: 375px;
+`;
+
+ReactDOM.render(
+
+
+
,
+ document.getElementById("root")
+);
diff --git a/packages/react-group-chat-example/tsconfig.json b/packages/react-group-chat-example/tsconfig.json
new file mode 100644
index 00000000..cee3d03f
--- /dev/null
+++ b/packages/react-group-chat-example/tsconfig.json
@@ -0,0 +1,47 @@
+{
+ "compilerOptions": {
+ "target": "es6",
+ "outDir": "dist",
+ "jsx": "react",
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "declaration": true,
+ "sourceMap": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "composite": true,
+ "strict": true /* Enable all strict type-checking options. */,
+
+ /* Strict Type-Checking Options */
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "strictPropertyInitialization": true,
+ "noImplicitThis": true,
+ "alwaysStrict": true,
+
+ /* Additional Checks */
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": false /* to set at a later stage */,
+ "noFallthroughCasesInSwitch": true,
+ "forceConsistentCasingInFileNames": true,
+
+ /* Debugging Options */
+ "traceResolution": false,
+ "listEmittedFiles": false,
+ "listFiles": false,
+ "pretty": true,
+
+ // Due to broken types in indirect dependencies
+ "skipLibCheck": true,
+ "typeRoots": [
+ "./node_modules/@types",
+ "./src/types",
+ "../../node_modules/@types"
+ ]
+ },
+ "include": ["src"],
+ "types": ["mocha"],
+ "compileOnSave": false
+}
diff --git a/packages/react-group-chat-example/tsconfig.tsbuildinfo b/packages/react-group-chat-example/tsconfig.tsbuildinfo
new file mode 100644
index 00000000..bf848bfa
--- /dev/null
+++ b/packages/react-group-chat-example/tsconfig.tsbuildinfo
@@ -0,0 +1 @@
+{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es6.d.ts","../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/@types/react/global.d.ts","../../node_modules/csstype/index.d.ts","../../node_modules/@types/prop-types/index.d.ts","../../node_modules/@types/scheduler/tracing.d.ts","../../node_modules/@types/react/index.d.ts","../../node_modules/@types/react-dom/index.d.ts","./src/index.tsx","../../node_modules/@types/chai/index.d.ts","../../node_modules/@types/ms/index.d.ts","../../node_modules/@types/debug/index.d.ts","../../node_modules/@types/eslint/helpers.d.ts","../../node_modules/@types/eslint/lib/rules/index.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/estree/index.d.ts","../../node_modules/@types/eslint/index.d.ts","../../node_modules/@types/eslint-scope/index.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/globals.global.d.ts","../../node_modules/@types/node/index.d.ts","../../node_modules/@types/minimatch/index.d.ts","../../node_modules/@types/glob/index.d.ts","../../node_modules/@types/history/DOMUtils.d.ts","../../node_modules/@types/history/createBrowserHistory.d.ts","../../node_modules/@types/history/createHashHistory.d.ts","../../node_modules/@types/history/createMemoryHistory.d.ts","../../node_modules/@types/history/LocationUtils.d.ts","../../node_modules/@types/history/PathUtils.d.ts","../../node_modules/@types/history/index.d.ts","../../node_modules/@types/hoist-non-react-statics/index.d.ts","../../node_modules/@types/html-minifier-terser/index.d.ts","../../node_modules/@types/istanbul-lib-coverage/index.d.ts","../../node_modules/@types/istanbul-lib-report/index.d.ts","../../node_modules/@types/istanbul-reports/index.d.ts","../../node_modules/@types/json5/index.d.ts","../../node_modules/@types/keyv/index.d.ts","../../node_modules/@types/long/index.d.ts","../../node_modules/@types/mocha/index.d.ts","../../node_modules/@types/object-hash/index.d.ts","../../node_modules/@types/parse-json/index.d.ts","../../node_modules/@types/prettier/index.d.ts","../../node_modules/@types/react-router/index.d.ts","../../node_modules/@types/react-router-dom/index.d.ts","../../node_modules/@types/react-test-renderer/index.d.ts","../../node_modules/@types/responselike/index.d.ts","../../node_modules/@types/retry/index.d.ts","../../node_modules/@types/scheduler/index.d.ts","../../node_modules/@types/secp256k1/index.d.ts","../../node_modules/@types/styled-components/index.d.ts","../../node_modules/@types/yargs-parser/index.d.ts","../../node_modules/@types/yargs/index.d.ts"],"fileInfos":["721cec59c3fef87aaf480047d821fb758b3ec9482c4129a54631e6e25e432a31",{"version":"aa9fb4c70f369237c2f45f9d969c9a59e0eae9a192962eb48581fe864aa609db","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","e6b724280c694a9f588847f754198fb96c43d805f065c3a5b28bbc9594541c84","e21c071ca3e1b4a815d5f04a7475adcaeea5d64367e840dd0154096d705c3940",{"version":"e54c8715a4954cfdc66cd69489f2b725c09ebf37492dbd91cff0a1688b1159e8","affectsGlobalScope":true},{"version":"e34eb9339171ec45da2801c1967e4d378bd61a1dceaa1b1b4e1b6d28cb9ca962","affectsGlobalScope":true},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true},{"version":"51b8b27c21c066bf877646e320bf6a722b80d1ade65e686923cd9d4494aef1ca","affectsGlobalScope":true},{"version":"43fb1d932e4966a39a41b464a12a81899d9ae5f2c829063f5571b6b87e6d2f9c","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"2c8c5ee58f30e7c944e04ab1fb5506fdbb4dd507c9efa6972cf4b91cec90c503","affectsGlobalScope":true},{"version":"2bb4b3927299434052b37851a47bf5c39764f2ba88a888a107b32262e9292b7c","affectsGlobalScope":true},{"version":"810627a82ac06fb5166da5ada4159c4ec11978dfbb0805fe804c86406dab8357","affectsGlobalScope":true},{"version":"62d80405c46c3f4c527ee657ae9d43fda65a0bf582292429aea1e69144a522a6","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"75ec0bdd727d887f1b79ed6619412ea72ba3c81d92d0787ccb64bab18d261f14","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"12a310447c5d23c7d0d5ca2af606e3bd08afda69100166730ab92c62999ebb9d","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"df9c8a72ca8b0ed62f5470b41208a0587f0f73f0a7db28e5a1272cf92537518e","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"93544ca2f26a48716c1b6c5091842cad63129daac422dfa4bc52460465f22bb1","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"1b3fe904465430e030c93239a348f05e1be80640d91f2f004c3512c2c2c89f34","affectsGlobalScope":true},{"version":"7435b75fdf3509622e79622dbe5091cf4b09688410ee2034e4fc17d0c99d0862","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"9f1817f7c3f02f6d56e0f403b927e90bb133f371dcebc36fa7d6d208ef6899da","affectsGlobalScope":true},{"version":"4632665b87204bb1caa8b44d165bce0c50dfab177df5b561b345a567cabacf9a","affectsGlobalScope":true},{"version":"ecf78e637f710f340ec08d5d92b3f31b134a46a4fcf2e758690d8c46ce62cba6","affectsGlobalScope":true},"5b1d4ebd62d975c7d3826202f8fac290bac0bae6e04d9e84d1707d7047e108df","f7b46d22a307739c145e5fddf537818038fdfffd580d79ed717f4d4d37249380","f5a8b384f182b3851cec3596ccc96cb7464f8d3469f48c74bf2befb782a19de5",{"version":"7b4a3453c60663af7f58636bf4673bfcc540d83ce1c41b816a5cc2e924009880","affectsGlobalScope":true},"b4dfafe583b829a382edccbe32303535d0785f0c02ba7f04418e2a81de97af8a",{"version":"93a64c8d9db6a210880af441b80af0c05130faf026d293ffb6beb398e2693224","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"},{"version":"0c9d1fd5b43d5e88c277f7f53cffc87778190f2f9a1f57743559421f04fc730b","affectsGlobalScope":true},"6a9c5127096b35264eb7cd21b2417bfc1d42cceca9ba4ce2bb0c3410b7816042","78828b06c0d3b586954015e9ebde5480b009e166c71244763bda328ec0920f41",{"version":"64d4b35c5456adf258d2cf56c341e203a073253f229ef3208fc0d5020253b241","affectsGlobalScope":true},"0133ebdd17a823ae56861948870cde4dac18dd8818ab641039c85bbb720429e0","0359682c54e487c4cab2b53b2b4d35cc8dea4d9914bc6abcdb5701f8b8e745a4","7d7c8ef7d48a035142c07dae60545ecc0e4af4c337742760cb09726f2f8e31db","e300bf65972ac08167a72787e19d1b43c285c5424707194d0ba64422f6b02c77","82772e5d55062a042a2715a555d347275a663940926fc785705eb082010cb9f6","0d5a2ee1fdfa82740e0103389b9efd6bfe145a20018a2da3c02b89666181f4d9","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"92d63add669d18ebc349efbacd88966d6f2ccdddfb1b880b2db98ae3aa7bf7c4","affectsGlobalScope":true},"ccc94049a9841fe47abe5baef6be9a38fc6228807974ae675fb15dc22531b4be",{"version":"658a70ff0b4d8298739566835c4b324a9ecef1676a2cd1fabfb5660a821d38ef","affectsGlobalScope":true},"43978f18d1165eea81040bc9bfac1a551717f5cc9bd0f13b31bf490c5fcdc75f","afc6e96061af46bcff47246158caee7e056f5288783f2d83d6858cd25be1c565",{"version":"c3ad91d23259b68e10a9bef08c5f9fa1d19f27ef740ac9af98ed226b030c09c6","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","38643f040239c18923ef39b5e1fe2651eaa8a633d2e371d48ae7e951ec55a923","260aad3a6bd3fc510b7f97cfb05859bfc045ce185f8c2b4d73ddb9c43b0eb3c0","cb428529763c6c8e38e42db2a39f333ffcc6d3aab396b24ac84b22da752c1de0","ad4b60488fb1e562bf375dac9299815f7028bf667d9b5887b2d01d501b7d1ddd","246341c3a7a2638cf830d690e69de1e6085a102c6a30596435b050e6ac86c11a","6972fca26f6e9bd56197568d4379f99071a90766e06b4fcb5920a0130a9202be",{"version":"4a2628e95962c8ab756121faa3ac2ed348112ff7a87b5c286dd2cc3326546b4c","affectsGlobalScope":true},"ccded627c1c57aa9e021aea914c3197899e7335fdc65426a6d61a8e65e751c00","2fa7fb7be51fa9924ebef6bd61d290c91bfebb93de00fd4949d836e68668a9de","f2f0941f8d09218dfabd1b89ee9b4fb4a193568deb9b44c13a08ac5a386d81ae","b287b810b5035d5685f1df6e1e418f1ca452a3ed4f59fd5cc081dbf2045f0d9b","4b9a003b5c556c96784132945bb41c655ea11273b1917f5c8d0c154dd5fd20dd","62a00c9cc0c78d9f282dcd7b0a7776aefe220106c3bc327e259e5f6484c6f556",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"f3e8bcce378a26bc672fce0ec05affabbbbfa18493b76f24c39136dea87100d0","abc1c425b2ad6720433f40f1877abfa4223f0f3dd486c9c28c492179ca183cb6","cd4854d38f4eb5592afd98ab95ca17389a7dfe38013d9079e802d739bdbcc939","94eed4cc2f5f658d5e229ff1ccd38860bddf4233e347bf78edd2154dee1f2b99",{"version":"e51bee3200733b1f58818b5a9ea90fcd61c5b8afa3a0378391991f3696826a65","affectsGlobalScope":true},"9f1069b9e2c051737b1f9b4f1baf50e4a63385a6a89c32235549ae87fc3d5492","ee18f2da7a037c6ceeb112a084e485aead9ea166980bf433474559eac1b46553","e70339a3d63f806c43f24250c42aa0000093923457b0ed7dfc10e0ac910ebca9","0acbf26bf958f9e80c1ffa587b74749d2697b75b484062d36e103c137c562bc3","2c20a91799640fc6bf027056fd56e5b8db5c427c1cc016bdb04cde5c9a0603b9","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff",{"version":"806ef4cac3b3d9fa4a48d849c8e084d7c72fcd7b16d76e06049a9ed742ff79c0","affectsGlobalScope":true},"a279435e7813d1f061c0cab6ab77b1b9377e8d96851e5ed4a76a1ce6eb6e628f","c33a6ea7147af60d8e98f1ac127047f4b0d4e2ce28b8f08ff3de07ca7cc00637",{"version":"b42b47e17b8ece2424ae8039feb944c2e3ba4b262986aebd582e51efbdca93dc","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","2408611d9b4146e35d1dbd1f443ccd8e187c74614a54b80300728277529dbf11","998a3de5237518c0b3ac00a11b3b4417affb008aa20aedee52f3fdae3cb86151","3accc1301749459bba2d1ba0084fdf399e5471508300956a3a2a1a8f4bc35f2e","b810390059fc34122556c644f586e7a2b4598ded8afe5ba70bb82fc2e50577b1","ba9de5c5823e06ee3314f959c138cdaf4477d3a1a0769f0d24e62911020e8088","c3db860bcaaaeb3bbc23f353bbda1f8ab82756c8d5e973bebb3953cb09ea68f2","235a53595bd20b0b0eeb1a29cb2887c67c48375e92f03749b2488fbd46d0b1a0","bc09393cd4cd13f69cf1366d4236fbae5359bb550f0de4e15767e9a91d63dfb1","9c266243b01545e11d2733a55ad02b4c00ecdbda99c561cd1674f96e89cdc958","c71155c05fc76ff948a4759abc1cb9feec036509f500174bc18dad4c7827a60c",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"ba229259c8b01c6733dc6a3e7b2ae3e2b76e502bb640a1691238a4c9cae5cfed","8841e2aa774b89bd23302dede20663306dc1b9902431ac64b24be8b8d0e3f649","725b884357ba84171341a8e4cc08edf11417854fd069842ca6d22afb2e340e45",{"version":"271cde49dfd9b398ccc91bb3aaa43854cf76f4d14e10fed91cbac649aa6cbc63","affectsGlobalScope":true},"2bcecd31f1b4281710c666843fc55133a0ee25b143e59f35f49c62e168123f4b","a6273756fa05f794b64fe1aff45f4371d444f51ed0257f9364a8b25f3501915d","2374e4ddc628bd0af8ce7578621f1b9d08ab183f4dbacb8749eabb1a85018196","25d91fb9ed77a828cc6c7a863236fb712dafcd52f816eec481bd0c1f589f4404","4cd14cea22eed1bfb0dc76183e56989f897ac5b14c0e2a819e5162eafdcfe243","ab35d08aa06a7615f06dad04db7e88f27d623220f05de68a94f16d5d22e6aaea","bfe1b52cf71aea9bf8815810cc5d9490fa9617313e3d3c2ee3809a28b80d0bb4","70b34c8420d6226ed565d55f47fe04912d0ca0ad128825c5a06e018a3498db32","de18acda71730bac52f4b256ce7511bb56cc21f6f114c59c46782eff2f632857","7eb06594824ada538b1d8b48c3925a83e7db792f47a081a62cf3e5c4e23cf0ee","029769d13d9917e3284cb2356ed28a6576e8b07ae6a06ee1e672518adf21a102","c5a14bdeb170e0e67fb4200c54e0e02fd0ec94aca894c212c9d43c2916891542","82169f198ffdfc787fba368ccfad2b2d8ef3712f3c696df94ac13f6884bbbe2d","e8465811693dfe4e96ef2b3dffda539d6edfe896961b7af37b44db2c0e48532b",{"version":"e8bf92aabac2b11e1bf60a0161039cd6f5f0cd9713863ca2289dd7b10eddece8","affectsGlobalScope":true},"a84c95e04a7387764e5c9f03a1bb1083ffa1166254a517398524630e918f8627","2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b","29651525db5579157e617c77e869af8bfdc1130f5d811c1f759ad35b7bafc8ef","f8116d99ea6244e8b1492a9229b5d7e46e66f3fa21691d356ff173f03a14b6c9","341f07a69f65cbae19fc6ccf3c7ffe432365606d473d64d9be3d358ee2e86070","60aaac5fb1858fbd4c4eb40e01706eb227eed9eca5c665564bd146971280dbd3","3cfb0cb51cc2c2e1b313d7c4df04dbf7e5bda0a133c6b309bf6af77cf614b971","58a3914b1cce4560d9ad6eee2b716caaa030eda0a90b21ca2457ea9e2783eaa3","74b0245c42990ed8a849df955db3f4362c81b13f799ebc981b7bec2d5b414a57","3dce33e7eb25594863b8e615f14a45ab98190d85953436750644212d8a18c066",{"version":"fccaceadff070fd2caf21495a48c42444c28412556537a199cf1e57e30f70bf0","affectsGlobalScope":true},"f7e133b20ee2669b6c0e5d7f0cd510868c57cd64b283e68c7f598e30ce9d76d2","d9f5e2cb6bce0d05a252e991b33e051f6385299b0dd18d842fc863b59173a18e"],"options":{"composite":true,"declaration":true,"declarationMap":false,"esModuleInterop":true,"inlineSourceMap":false,"jsx":2,"module":1,"noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":false,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":false,"strict":true,"strictNullChecks":true,"strictPropertyInitialization":true,"target":2},"fileIdsList":[[103],[52,103],[57,58,103],[54,55,56,57,103],[58,103],[75,103,110,111],[103,119],[103,113,119],[103,114,115,116,117,118],[48,103],[103,122],[103,122,123],[75,103,110],[60,103],[63,103],[64,69,103],[65,75,76,83,92,102,103],[65,66,75,83,103],[67,103],[68,69,76,84,103],[69,92,99,103],[70,72,75,83,103],[71,103],[72,73,103],[74,75,103],[75,103],[75,76,77,92,102,103],[75,76,77,92,103],[78,83,92,102,103],[75,76,78,79,83,92,99,102,103],[78,80,92,99,102,103],[60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109],[75,81,103],[82,102,103],[72,75,83,92,103],[84,103],[85,103],[63,86,103],[87,101,103,107],[88,103],[89,103],[75,90,103],[90,91,103,105],[75,92,93,94,103],[92,94,103],[92,93,103],[95,103],[96,103],[75,97,98,103],[97,98,103],[69,83,99,103],[100,103],[83,101,103],[64,78,89,102,103],[69,103],[92,103,104],[103,105],[103,106],[64,69,75,77,86,92,102,103,105,107],[92,103,108],[48,103,119,132],[48,103,119],[44,45,46,47,103],[78,92,103,110],[103,110],[45,48,103,120],[103,140],[48,49,103]],"referencedMap":[[51,1],[53,2],[59,3],[54,1],[58,4],[55,5],[57,1],[112,6],[113,1],[117,7],[118,7],[114,8],[115,8],[116,8],[119,9],[120,10],[121,1],[122,1],[123,11],[124,12],[56,1],[125,1],[126,13],[127,1],[111,1],[128,1],[52,1],[60,14],[61,14],[63,15],[64,16],[65,17],[66,18],[67,19],[68,20],[69,21],[70,22],[71,23],[72,24],[73,24],[74,25],[75,26],[76,27],[77,28],[62,1],[109,1],[78,29],[79,30],[80,31],[110,32],[81,33],[82,34],[83,35],[84,36],[85,37],[86,38],[87,39],[88,40],[89,41],[90,42],[91,43],[92,44],[94,45],[93,46],[95,47],[96,48],[97,49],[98,50],[99,51],[100,52],[101,53],[102,54],[103,55],[104,56],[105,57],[106,58],[107,59],[108,60],[129,1],[130,1],[131,1],[46,1],[49,10],[133,61],[132,62],[134,10],[44,1],[48,63],[135,64],[136,1],[137,1],[47,1],[138,65],[139,66],[140,1],[141,67],[45,1],[9,1],[10,1],[14,1],[13,1],[3,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[4,1],[5,1],[26,1],[23,1],[24,1],[25,1],[27,1],[28,1],[29,1],[6,1],[30,1],[31,1],[32,1],[33,1],[7,1],[34,1],[35,1],[36,1],[37,1],[8,1],[42,1],[38,1],[39,1],[40,1],[41,1],[2,1],[1,1],[43,1],[12,1],[11,1],[50,68]],"exportedModulesMap":[[51,1],[53,2],[59,3],[54,1],[58,4],[55,5],[57,1],[112,6],[113,1],[117,7],[118,7],[114,8],[115,8],[116,8],[119,9],[120,10],[121,1],[122,1],[123,11],[124,12],[56,1],[125,1],[126,13],[127,1],[111,1],[128,1],[52,1],[60,14],[61,14],[63,15],[64,16],[65,17],[66,18],[67,19],[68,20],[69,21],[70,22],[71,23],[72,24],[73,24],[74,25],[75,26],[76,27],[77,28],[62,1],[109,1],[78,29],[79,30],[80,31],[110,32],[81,33],[82,34],[83,35],[84,36],[85,37],[86,38],[87,39],[88,40],[89,41],[90,42],[91,43],[92,44],[94,45],[93,46],[95,47],[96,48],[97,49],[98,50],[99,51],[100,52],[101,53],[102,54],[103,55],[104,56],[105,57],[106,58],[107,59],[108,60],[129,1],[130,1],[131,1],[46,1],[49,10],[133,61],[132,62],[134,10],[44,1],[48,63],[135,64],[136,1],[137,1],[47,1],[138,65],[139,66],[140,1],[141,67],[45,1],[9,1],[10,1],[14,1],[13,1],[3,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[4,1],[5,1],[26,1],[23,1],[24,1],[25,1],[27,1],[28,1],[29,1],[6,1],[30,1],[31,1],[32,1],[33,1],[7,1],[34,1],[35,1],[36,1],[37,1],[8,1],[42,1],[38,1],[39,1],[40,1],[41,1],[2,1],[1,1],[43,1],[12,1],[11,1]],"semanticDiagnosticsPerFile":[51,53,59,54,58,55,57,112,113,117,118,114,115,116,119,120,121,122,123,124,56,125,126,127,111,128,52,60,61,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,62,109,78,79,80,110,81,82,83,84,85,86,87,88,89,90,91,92,94,93,95,96,97,98,99,100,101,102,103,104,105,106,107,108,129,130,131,46,49,133,132,134,44,48,135,136,137,47,138,139,140,141,45,9,10,14,13,3,15,16,17,18,19,20,21,22,4,5,26,23,24,25,27,28,29,6,30,31,32,33,7,34,35,36,37,8,42,38,39,40,41,2,1,43,12,11,[50,[{"file":"./src/index.tsx","start":85,"length":25,"messageText":"Cannot find module '@waku/react-chat-sdk' or its corresponding type declarations.","category":1,"code":2307}]]]},"version":"4.4.3"}
diff --git a/packages/react-group-chat-example/webpack.config.js b/packages/react-group-chat-example/webpack.config.js
new file mode 100644
index 00000000..4500adf3
--- /dev/null
+++ b/packages/react-group-chat-example/webpack.config.js
@@ -0,0 +1,88 @@
+const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
+const webpack = require('webpack');
+const { ESBuildMinifyPlugin } = require('esbuild-loader');
+
+module.exports = env => {
+ const environment = env.ENV || 'development';
+ const communityKey = env.COMMUNITY_KEY || '';
+
+ return {
+ entry: './src/index.tsx',
+ output: {
+ filename: 'index.[fullhash].js',
+ path: path.join(__dirname, 'dist'),
+ publicPath: '/',
+ },
+ devtool: 'source-map',
+ resolve: {
+ extensions: ['.ts', '.tsx', '.js', '.json'],
+ fallback: {
+ buffer: require.resolve('buffer/'),
+ crypto: require.resolve('crypto-browserify'),
+ stream: require.resolve('stream-browserify'),
+ assert: require.resolve('assert/'),
+ http: require.resolve('stream-http'),
+ https: require.resolve('https-browserify'),
+ zlib: require.resolve('browserify-zlib')
+ },
+ },
+ module: {
+ rules: [
+ {
+ test: /\.tsx?$/,
+ loader: 'esbuild-loader',
+ exclude: /node_modules/,
+ options: {
+ loader: 'tsx',
+ target: 'es2020',
+ },
+ },
+ {
+ enforce: 'pre',
+ test: /\.js$/,
+ exclude: /node_modules/,
+ loader: 'source-map-loader',
+ },
+ {
+ test: /\.(png|svg|jpg|gif|woff|woff2|eot|ttf|otf|ico)$/,
+ use: ['file-loader'],
+ },
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ ],
+ },
+ optimization: {
+ minimizer: [
+ new ESBuildMinifyPlugin({
+ target: 'es2020',
+ }),
+ ],
+ },
+ plugins: [
+ new ForkTsCheckerWebpackPlugin(),
+ new HtmlWebpackPlugin({
+ template: 'src/index.html',
+ }),
+ new webpack.DefinePlugin({
+ 'process.env.ENV': JSON.stringify(environment),
+ 'process.env.COMMUNITY_KEY': JSON.stringify(communityKey),
+ }),
+ new webpack.ProvidePlugin({
+ process: 'process/browser.js',
+ Buffer: ['buffer', 'Buffer'],
+ }),
+ ],
+ devServer: {
+ historyApiFallback: true,
+ host: '0.0.0.0',
+ stats: 'errors-only',
+ overlay: true,
+ hot: true,
+ },
+ stats: 'minimal',
+ };
+};
diff --git a/packages/status-core/.eslintrc.json b/packages/status-core/.eslintrc.json
new file mode 100644
index 00000000..f0d0dc9b
--- /dev/null
+++ b/packages/status-core/.eslintrc.json
@@ -0,0 +1,42 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": { "project": "./tsconfig.json" },
+ "env": { "es6": true },
+ "ignorePatterns": ["node_modules", "dist", "coverage", "proto"],
+ "plugins": ["import", "eslint-comments", "functional"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:eslint-comments/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:import/typescript",
+ "prettier"
+ ],
+ "globals": { "BigInt": true, "console": true, "WebAssembly": true },
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["error"],
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "eslint-comments/disable-enable-pair": [
+ "error",
+ { "allowWholeFile": true }
+ ],
+ "eslint-comments/no-unused-disable": "error",
+ "import/order": [
+ "error",
+ { "newlines-between": "always", "alphabetize": { "order": "asc" } }
+ ],
+ "no-constant-condition": ["error", { "checkLoops": false }],
+ "sort-imports": [
+ "error",
+ { "ignoreDeclarationSort": true, "ignoreCase": true }
+ ]
+ },
+ "overrides": [
+ {
+ "files": ["*.spec.ts", "**/test_utils/*.ts"],
+ "rules": {
+ "@typescript-eslint/no-non-null-assertion": "off"
+ }
+ }
+ ]
+}
diff --git a/packages/status-core/.mocharc.json b/packages/status-core/.mocharc.json
new file mode 100644
index 00000000..b65763d3
--- /dev/null
+++ b/packages/status-core/.mocharc.json
@@ -0,0 +1,6 @@
+{
+ "extension": ["ts"],
+ "spec": "src/**/*.spec.ts",
+ "require": "ts-node/register",
+ "exit": true
+}
diff --git a/packages/status-core/.prettierignore b/packages/status-core/.prettierignore
new file mode 100644
index 00000000..996c3a37
--- /dev/null
+++ b/packages/status-core/.prettierignore
@@ -0,0 +1,2 @@
+# package.json is formatted by package managers, so we ignore it here
+package.json
diff --git a/packages/status-core/README.md b/packages/status-core/README.md
new file mode 100644
index 00000000..693b3bc1
--- /dev/null
+++ b/packages/status-core/README.md
@@ -0,0 +1 @@
+# `status-core`
diff --git a/packages/status-core/buf.gen.yaml b/packages/status-core/buf.gen.yaml
new file mode 100644
index 00000000..40edf963
--- /dev/null
+++ b/packages/status-core/buf.gen.yaml
@@ -0,0 +1,6 @@
+version: v1beta1
+
+plugins:
+ - name: ts_proto
+ out: ./src/proto
+ opt: grpc_js,esModuleInterop=true
diff --git a/packages/status-core/buf.yaml b/packages/status-core/buf.yaml
new file mode 100644
index 00000000..c6a09b81
--- /dev/null
+++ b/packages/status-core/buf.yaml
@@ -0,0 +1,9 @@
+version: v1beta1
+
+build:
+ roots:
+ - ./proto
+lint:
+ except:
+ - ENUM_ZERO_VALUE_SUFFIX
+ - ENUM_VALUE_PREFIX
diff --git a/packages/status-core/package.json b/packages/status-core/package.json
new file mode 100644
index 00000000..dd1cba56
--- /dev/null
+++ b/packages/status-core/package.json
@@ -0,0 +1,67 @@
+{
+ "name": "@status-im/core",
+ "version": "0.0.0",
+ "license": "MIT OR Apache-2.0",
+ "repository": {
+ "url": "https://github.com/status-im/status-web.git",
+ "directory": "packages/status-core",
+ "type": "git"
+ },
+ "bugs": {
+ "url": "https://github.com/status-im/status-web/issues"
+ },
+ "main": "dist/cjs/src/index.js",
+ "module": "dist/esm/src/index.js",
+ "types": "dist/esm/src/index.d.ts",
+ "scripts": {
+ "build": "run-s 'build:*'",
+ "build:esm": "tsc --module es2020 --target es2017 --outDir dist/esm",
+ "build:cjs": "tsc --outDir dist/cjs",
+ "fix": "run-s 'fix:*'",
+ "fix:prettier": "prettier \"src/**/*.ts\" \"./*.json\" --write",
+ "fix:lint": "eslint src --ext .ts --fix",
+ "test": "run-s 'test:*'",
+ "test:lint": "eslint src --ext .ts",
+ "test:prettier": "prettier \"src/**/*.ts\" \"./*.json\" --list-different",
+ "test:unit": "mocha",
+ "proto": "run-s 'proto:*'",
+ "proto:lint": "buf lint",
+ "proto:build": "buf generate"
+ },
+ "devDependencies": {
+ "@types/bn.js": "^5.1.0",
+ "@types/chai": "^4.2.22",
+ "@types/elliptic": "^6.4.14",
+ "@types/mocha": "^9.0.0",
+ "@types/pbkdf2": "^3.1.0",
+ "@types/secp256k1": "^4.0.3",
+ "@types/uuid": "^8.3.3",
+ "@typescript-eslint/eslint-plugin": "^4.31.1",
+ "@typescript-eslint/parser": "^4.31.1",
+ "chai": "^4.3.4",
+ "eslint": "^7.32.0",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-import-resolver-node": "^0.3.6",
+ "eslint-plugin-eslint-comments": "^3.2.0",
+ "eslint-plugin-functional": "^3.7.0",
+ "eslint-plugin-import": "^2.24.2",
+ "mocha": "^9.1.1",
+ "npm-run-all": "^4.1.5",
+ "prettier": "^2.4.0",
+ "ts-node": "^10.2.1",
+ "ts-proto": "^1.83.0",
+ "typescript": "^4.4.3"
+ },
+ "dependencies": {
+ "bn.js": "^5.2.0",
+ "buffer": "^6.0.3",
+ "ecies-geth": "^1.5.3",
+ "elliptic": "^6.5.4",
+ "js-sha3": "^0.8.0",
+ "js-waku": "^0.16.0",
+ "pbkdf2": "^3.1.2",
+ "protobufjs": "^6.11.2",
+ "secp256k1": "^4.0.2",
+ "uuid": "^8.3.2"
+ }
+}
diff --git a/packages/status-core/proto/communities/v1/chat_identity.proto b/packages/status-core/proto/communities/v1/chat_identity.proto
new file mode 100644
index 00000000..314fb1b1
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/chat_identity.proto
@@ -0,0 +1,55 @@
+syntax = "proto3";
+
+package communities.v1;
+
+import "communities/v1/enums.proto";
+
+// ChatIdentity represents the user defined identity associated with their public chat key
+message ChatIdentity {
+ // Lamport timestamp of the message
+ uint64 clock = 1;
+
+ // ens_name is the valid ENS name associated with the chat key
+ string ens_name = 2;
+
+ // images is a string indexed mapping of images associated with an identity
+ map images = 3;
+
+ // display name is the user set identity, valid only for organisations
+ string display_name = 4;
+
+ // description is the user set description, valid only for organisations
+ string description = 5;
+
+ string color = 6;
+
+ string emoji = 7;
+}
+
+// ProfileImage represents data associated with a user's profile image
+message IdentityImage {
+
+ // payload is a context based payload for the profile image data,
+ // context is determined by the `source_type`
+ bytes payload = 1;
+
+ // source_type signals the image payload source
+ SourceType source_type = 2;
+
+ // image_type signals the image type and method of parsing the payload
+ ImageType image_type =3;
+
+ // SourceType are the predefined types of image source allowed
+ enum SourceType {
+ UNKNOWN_SOURCE_TYPE = 0;
+
+ // RAW_PAYLOAD image byte data
+ RAW_PAYLOAD = 1;
+
+ // ENS_AVATAR uses the ENS record's resolver get-text-data.avatar data
+ // The `payload` field will be ignored if ENS_AVATAR is selected
+ // The application will read and parse the ENS avatar data as image payload data, URLs will be ignored
+ // The parent `ChatMessageIdentity` must have a valid `ens_name` set
+ ENS_AVATAR = 2;
+ }
+}
diff --git a/packages/status-core/proto/communities/v1/chat_message.proto b/packages/status-core/proto/communities/v1/chat_message.proto
new file mode 100644
index 00000000..20d467cb
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/chat_message.proto
@@ -0,0 +1,105 @@
+syntax = "proto3";
+
+package communities.v1;
+
+import "communities/v1/enums.proto";
+
+message StickerMessage {
+ string hash = 1;
+ int32 pack = 2;
+}
+
+message ImageMessage {
+ bytes payload = 1;
+ ImageType type = 2;
+}
+
+message AudioMessage {
+ bytes payload = 1;
+ AudioType type = 2;
+ uint64 duration_ms = 3;
+ enum AudioType {
+ AUDIO_TYPE_UNKNOWN_UNSPECIFIED = 0;
+ AUDIO_TYPE_AAC = 1;
+ AUDIO_TYPE_AMR = 2;
+ }
+}
+
+message EditMessage {
+ uint64 clock = 1;
+ // Text of the message
+ string text = 2;
+
+ string chat_id = 3;
+ string message_id = 4;
+
+ // Grant for community edit messages
+ bytes grant = 5;
+
+ // The type of message (public/one-to-one/private-group-chat)
+ MessageType message_type = 6;
+}
+
+message DeleteMessage {
+ uint64 clock = 1;
+
+ string chat_id = 2;
+ string message_id = 3;
+
+ // Grant for community delete messages
+ bytes grant = 4;
+
+ // The type of message (public/one-to-one/private-group-chat)
+ MessageType message_type = 5;
+}
+
+
+message ChatMessage {
+ // Lamport timestamp of the chat message
+ uint64 clock = 1;
+ // Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
+ // so that we don't rely on it
+ uint64 timestamp = 2;
+ // Text of the message
+ string text = 3;
+ // Id of the message that we are replying to
+ string response_to = 4;
+ // Ens name of the sender
+ string ens_name = 5;
+ // Chat id, this field is symmetric for public-chats and private group chats,
+ // but asymmetric in case of one-to-ones, as the sender will use the chat-id
+ // of the received, while the receiver will use the chat-id of the sender.
+ // Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
+ string chat_id = 6;
+
+ // The type of message (public/one-to-one/private-group-chat)
+ MessageType message_type = 7;
+ // The type of the content of the message
+ ContentType content_type = 8;
+
+ oneof payload {
+ StickerMessage sticker = 9;
+ ImageMessage image = 10;
+ AudioMessage audio = 11;
+ bytes community = 12;
+ }
+
+ // Grant for community chat messages
+ optional bytes grant = 13;
+
+ enum ContentType {
+ CONTENT_TYPE_UNKNOWN_UNSPECIFIED = 0;
+ CONTENT_TYPE_TEXT_PLAIN = 1;
+ CONTENT_TYPE_STICKER = 2;
+ CONTENT_TYPE_STATUS = 3;
+ CONTENT_TYPE_EMOJI = 4;
+ CONTENT_TYPE_TRANSACTION_COMMAND = 5;
+ // Only local
+ CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP = 6;
+ CONTENT_TYPE_IMAGE = 7;
+ CONTENT_TYPE_AUDIO = 8;
+ CONTENT_TYPE_COMMUNITY = 9;
+ // Only local
+ CONTENT_TYPE_SYSTEM_MESSAGE_GAP = 10;
+ }
+}
diff --git a/packages/status-core/proto/communities/v1/communities.proto b/packages/status-core/proto/communities/v1/communities.proto
new file mode 100644
index 00000000..48badc95
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/communities.proto
@@ -0,0 +1,80 @@
+syntax = "proto3";
+
+package communities.v1;
+
+import "communities/v1/chat_identity.proto";
+
+message Grant {
+ bytes community_id = 1;
+ bytes member_id = 2;
+ string chat_id = 3;
+ uint64 clock = 4;
+}
+
+message CommunityMember {
+ enum Roles {
+ UNKNOWN_ROLE = 0;
+ ROLE_ALL = 1;
+ ROLE_MANAGE_USERS = 2;
+ }
+ repeated Roles roles = 1;
+}
+
+message CommunityPermissions {
+ enum Access {
+ UNKNOWN_ACCESS = 0;
+ NO_MEMBERSHIP = 1;
+ INVITATION_ONLY = 2;
+ ON_REQUEST = 3;
+ }
+
+ bool ens_only = 1;
+ // https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md is a candidate for the algorithm to be used in case we want to have private communityal chats, lighter than pairwise encryption using the DR, less secure, but more efficient for large number of participants
+ bool private = 2;
+ Access access = 3;
+}
+
+message CommunityDescription {
+ uint64 clock = 1;
+ map members = 2;
+ CommunityPermissions permissions = 3;
+ ChatIdentity identity = 5;
+ map chats = 6;
+ repeated string ban_list = 7;
+ map categories = 8;
+}
+
+message CommunityChat {
+ map members = 1;
+ CommunityPermissions permissions = 2;
+ ChatIdentity identity = 3;
+ string category_id = 4;
+ int32 position = 5;
+}
+
+message CommunityCategory {
+ string category_id = 1;
+ string name = 2;
+ int32 position = 3;
+}
+
+message CommunityInvitation {
+ bytes community_description = 1;
+ bytes grant = 2;
+ string chat_id = 3;
+ bytes public_key = 4;
+}
+
+message CommunityRequestToJoin {
+ uint64 clock = 1;
+ string ens_name = 2;
+ string chat_id = 3;
+ bytes community_id = 4;
+}
+
+message CommunityRequestToJoinResponse {
+ uint64 clock = 1;
+ CommunityDescription community = 2;
+ bool accepted = 3;
+ bytes grant = 4;
+}
diff --git a/packages/status-core/proto/communities/v1/emoji_reaction.proto b/packages/status-core/proto/communities/v1/emoji_reaction.proto
new file mode 100644
index 00000000..98726f25
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/emoji_reaction.proto
@@ -0,0 +1,39 @@
+syntax = "proto3";
+
+package communities.v1;
+
+import "communities/v1/enums.proto";
+
+message EmojiReaction {
+ // clock Lamport timestamp of the chat message
+ uint64 clock = 1;
+
+ // chat_id the ID of the chat the message belongs to, for query efficiency the chat_id is stored in the db even though the
+ // target message also stores the chat_id
+ string chat_id = 2;
+
+ // message_id the ID of the target message that the user wishes to react to
+ string message_id = 3;
+
+ // message_type is (somewhat confusingly) the ID of the type of chat the message belongs to
+ MessageType message_type = 4;
+
+ // type the ID of the emoji the user wishes to react with
+ Type type = 5;
+
+ enum Type {
+ UNKNOWN_EMOJI_REACTION_TYPE = 0;
+ LOVE = 1;
+ THUMBS_UP = 2;
+ THUMBS_DOWN = 3;
+ LAUGH = 4;
+ SAD = 5;
+ ANGRY = 6;
+ }
+
+ // whether this is a rectraction of a previously sent emoji
+ bool retracted = 6;
+
+ // Grant for organisation chat messages
+ bytes grant = 7;
+}
\ No newline at end of file
diff --git a/packages/status-core/proto/communities/v1/enums.proto b/packages/status-core/proto/communities/v1/enums.proto
new file mode 100644
index 00000000..b8af60b1
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/enums.proto
@@ -0,0 +1,25 @@
+syntax = "proto3";
+
+package communities.v1;
+
+enum MessageType {
+ MESSAGE_TYPE_UNKNOWN_UNSPECIFIED = 0;
+ MESSAGE_TYPE_ONE_TO_ONE = 1;
+ MESSAGE_TYPE_MESSAGE_TYPE_PUBLIC_GROUP = 2;
+ MESSAGE_TYPE_PRIVATE_GROUP = 3;
+ // Only local
+ MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP = 4;
+ MESSAGE_TYPE_COMMUNITY_CHAT = 5;
+ // Only local
+ MESSAGE_TYPE_SYSTEM_MESSAGE_GAP = 6;
+}
+
+enum ImageType {
+ IMAGE_TYPE_UNKNOWN_UNSPECIFIED = 0;
+
+ // Raster image files is payload data that can be read as a raster image
+ IMAGE_TYPE_PNG = 1;
+ IMAGE_TYPE_JPEG = 2;
+ IMAGE_TYPE_WEBP = 3;
+ IMAGE_TYPE_GIF = 4;
+}
diff --git a/packages/status-core/proto/communities/v1/membership_update_message.proto b/packages/status-core/proto/communities/v1/membership_update_message.proto
new file mode 100644
index 00000000..9952bffd
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/membership_update_message.proto
@@ -0,0 +1,45 @@
+syntax = "proto3";
+
+package communities.v1;
+
+import "communities/v1/chat_message.proto";
+import "communities/v1/emoji_reaction.proto";
+
+message MembershipUpdateEvent {
+ // Lamport timestamp of the event
+ uint64 clock = 1;
+ // List of public keys of objects of the action
+ repeated string members = 2;
+ // Name of the chat for the CHAT_CREATED/NAME_CHANGED event types
+ string name = 3;
+ // The type of the event
+ EventType type = 4;
+
+ enum EventType {
+ UNKNOWN = 0;
+ CHAT_CREATED = 1;
+ NAME_CHANGED = 2;
+ MEMBERS_ADDED = 3;
+ MEMBER_JOINED = 4;
+ MEMBER_REMOVED = 5;
+ ADMINS_ADDED = 6;
+ ADMIN_REMOVED = 7;
+ }
+}
+
+// MembershipUpdateMessage is a message used to propagate information
+// about group membership changes.
+// For more information, see https://github.com/status-im/specs/blob/master/status-group-chats-spec.md.
+message MembershipUpdateMessage {
+ // The chat id of the private group chat
+ string chat_id = 1;
+ // A list of events for this group chat, first x bytes are the signature, then is a
+ // protobuf encoded MembershipUpdateEvent
+ repeated bytes events = 2;
+
+ // An optional chat message
+ oneof chat_entity {
+ ChatMessage message = 3;
+ EmojiReaction emoji_reaction = 4;
+ }
+}
\ No newline at end of file
diff --git a/packages/status-core/proto/communities/v1/status_update.proto b/packages/status-core/proto/communities/v1/status_update.proto
new file mode 100644
index 00000000..759b390e
--- /dev/null
+++ b/packages/status-core/proto/communities/v1/status_update.proto
@@ -0,0 +1,32 @@
+syntax = "proto3";
+
+package communities.v1;
+
+/* Specs:
+:AUTOMATIC
+ To Send - "AUTOMATIC" status ping every 5 minutes
+ Display - Online for up to 5 minutes from the last clock, after that Offline
+:ALWAYS_ONLINE
+ To Send - "ALWAYS_ONLINE" status ping every 5 minutes
+ Display - Online for up to 2 weeks from the last clock, after that Offline
+:INACTIVE
+ To Send - A single "INACTIVE" status ping
+ Display - Offline forever
+Note: Only send pings if the user interacted with the app in the last x minutes. */
+message StatusUpdate {
+
+ uint64 clock = 1;
+
+ StatusType status_type = 2;
+
+ string custom_text = 3;
+
+ enum StatusType {
+ UNKNOWN_STATUS_TYPE = 0;
+ AUTOMATIC = 1;
+ DO_NOT_DISTURB = 2;
+ ALWAYS_ONLINE = 3;
+ INACTIVE = 4;
+ };
+
+ }
\ No newline at end of file
diff --git a/packages/status-core/proto/status/v1/application_metadata_message.proto b/packages/status-core/proto/status/v1/application_metadata_message.proto
new file mode 100644
index 00000000..53997cb0
--- /dev/null
+++ b/packages/status-core/proto/status/v1/application_metadata_message.proto
@@ -0,0 +1,50 @@
+syntax = "proto3";
+
+package status.v1;
+
+message ApplicationMetadataMessage {
+ // Signature of the payload field
+ bytes signature = 1;
+ // This is the encoded protobuf of the application level message, i.e ChatMessage
+ bytes payload = 2;
+
+ // The type of protobuf message sent
+ Type type = 3;
+
+ enum Type {
+ TYPE_UNKNOWN_UNSPECIFIED = 0;
+ TYPE_CHAT_MESSAGE = 1;
+ TYPE_CONTACT_UPDATE = 2;
+ TYPE_MEMBERSHIP_UPDATE_MESSAGE = 3;
+ TYPE_PAIR_INSTALLATION = 4;
+ TYPE_SYNC_INSTALLATION = 5;
+ TYPE_REQUEST_ADDRESS_FOR_TRANSACTION = 6;
+ TYPE_ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION = 7;
+ TYPE_DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION = 8;
+ TYPE_REQUEST_TRANSACTION = 9;
+ TYPE_SEND_TRANSACTION = 10;
+ TYPE_DECLINE_REQUEST_TRANSACTION = 11;
+ TYPE_SYNC_INSTALLATION_CONTACT = 12;
+ TYPE_SYNC_INSTALLATION_ACCOUNT = 13;
+ TYPE_SYNC_INSTALLATION_PUBLIC_CHAT = 14;
+ TYPE_CONTACT_CODE_ADVERTISEMENT = 15;
+ TYPE_PUSH_NOTIFICATION_REGISTRATION = 16;
+ TYPE_PUSH_NOTIFICATION_REGISTRATION_RESPONSE = 17;
+ TYPE_PUSH_NOTIFICATION_QUERY = 18;
+ TYPE_PUSH_NOTIFICATION_QUERY_RESPONSE = 19;
+ TYPE_PUSH_NOTIFICATION_REQUEST = 20;
+ TYPE_PUSH_NOTIFICATION_RESPONSE = 21;
+ TYPE_EMOJI_REACTION = 22;
+ TYPE_GROUP_CHAT_INVITATION = 23;
+ TYPE_CHAT_IDENTITY = 24;
+ TYPE_COMMUNITY_DESCRIPTION = 25;
+ TYPE_COMMUNITY_INVITATION = 26;
+ TYPE_COMMUNITY_REQUEST_TO_JOIN = 27;
+ TYPE_PIN_MESSAGE = 28;
+ TYPE_EDIT_MESSAGE = 29;
+ TYPE_STATUS_UPDATE = 30;
+ TYPE_DELETE_MESSAGE = 31;
+ TYPE_SYNC_INSTALLATION_COMMUNITY = 32;
+ TYPE_ANONYMOUS_METRIC_BATCH = 33;
+ }
+}
diff --git a/packages/status-core/src/chat.ts b/packages/status-core/src/chat.ts
new file mode 100644
index 00000000..6392f425
--- /dev/null
+++ b/packages/status-core/src/chat.ts
@@ -0,0 +1,85 @@
+import { idToContentTopic } from "./contentTopic";
+import { createSymKeyFromPassword } from "./encryption";
+import { ChatMessage, Content } from "./wire/chat_message";
+import { CommunityChat } from "./wire/community_chat";
+
+/**
+ * Represent a chat room. Only public chats are currently supported.
+ */
+export class Chat {
+ private lastClockValue?: number;
+ private lastMessage?: ChatMessage;
+
+ private constructor(
+ public id: string,
+ public symKey: Uint8Array,
+ public communityChat?: CommunityChat
+ ) {}
+
+ /**
+ * Create a public chat room.
+ * [[Community.instantiateChat]] MUST be used for chats belonging to a community.
+ */
+ public static async create(
+ id: string,
+ communityChat?: CommunityChat
+ ): Promise {
+ const symKey = await createSymKeyFromPassword(id);
+
+ return new Chat(id, symKey, communityChat);
+ }
+
+ public get contentTopic(): string {
+ return idToContentTopic(this.id);
+ }
+
+ public createMessage(content: Content, responseTo?: string): ChatMessage {
+ const { timestamp, clock } = this._nextClockAndTimestamp();
+
+ const message = ChatMessage.createMessage(
+ clock,
+ timestamp,
+ this.id,
+ content,
+ responseTo
+ );
+
+ this._updateClockFromMessage(message);
+
+ return message;
+ }
+
+ public handleNewMessage(message: ChatMessage): void {
+ this._updateClockFromMessage(message);
+ }
+
+ private _nextClockAndTimestamp(): { clock: number; timestamp: number } {
+ let clock = this.lastClockValue;
+ const timestamp = Date.now();
+
+ if (!clock || clock < timestamp) {
+ clock = timestamp;
+ } else {
+ clock += 1;
+ }
+
+ return { clock, timestamp };
+ }
+
+ private _updateClockFromMessage(message: ChatMessage): void {
+ if (
+ !this.lastMessage ||
+ !this.lastMessage.clock ||
+ (message.clock && this.lastMessage.clock <= message.clock)
+ ) {
+ this.lastMessage = message;
+ }
+
+ if (
+ !this.lastClockValue ||
+ (message.clock && this.lastClockValue < message.clock)
+ ) {
+ this.lastClockValue = message.clock;
+ }
+ }
+}
diff --git a/packages/status-core/src/community.spec.ts b/packages/status-core/src/community.spec.ts
new file mode 100644
index 00000000..d25285ea
--- /dev/null
+++ b/packages/status-core/src/community.spec.ts
@@ -0,0 +1,42 @@
+import { expect } from "chai";
+import { Waku } from "js-waku";
+
+import { Community } from "./community";
+import { CommunityDescription } from "./wire/community_description";
+
+describe("Community [live data]", () => {
+ before(function () {
+ if (process.env.CI) {
+ // Skip live data test in CI
+ this.skip();
+ }
+ });
+
+ it("Retrieves community description For DappConnect Test from Waku prod fleet", async function () {
+ this.timeout(20000);
+ const waku = await Waku.create({ bootstrap: { default: true } });
+
+ await waku.waitForRemotePeer();
+
+ const community = await Community.instantiateCommunity(
+ "0x02cf13719c8b836bebd4e430c497ee38e798a43e4d8c4760c34bbd9bf4f2434d26",
+ waku
+ );
+ const desc = community.description as CommunityDescription;
+ expect(desc).to.not.be.undefined;
+
+ expect(desc.identity?.displayName).to.eq("Test Community");
+
+ const descChats = Array.from(desc.chats.values()).map(
+ (chat) => chat?.identity?.displayName
+ );
+ expect(descChats).to.include("Test Chat");
+ expect(descChats).to.include("Additional Chat");
+
+ const chats = Array.from(community.chats.values()).map(
+ (chat) => chat?.communityChat?.identity?.displayName
+ );
+ expect(chats).to.include("Test Chat");
+ expect(chats).to.include("Additional Chat");
+ });
+});
diff --git a/packages/status-core/src/community.ts b/packages/status-core/src/community.ts
new file mode 100644
index 00000000..424bd8ac
--- /dev/null
+++ b/packages/status-core/src/community.ts
@@ -0,0 +1,92 @@
+import debug from "debug";
+import { Waku } from "js-waku";
+
+import { Chat } from "./chat";
+import { bufToHex, hexToBuf } from "./utils";
+import { CommunityChat } from "./wire/community_chat";
+import { CommunityDescription } from "./wire/community_description";
+
+const dbg = debug("communities:community");
+
+export class Community {
+ public publicKey: Uint8Array;
+ private waku: Waku;
+ public chats: Map; // Chat id, Chat
+ public description?: CommunityDescription;
+
+ constructor(publicKey: Uint8Array, waku: Waku) {
+ this.publicKey = publicKey;
+ this.waku = waku;
+ this.chats = new Map();
+ }
+
+ /**
+ * Instantiate a Community by retrieving its details from the Waku network.
+ *
+ * This class is used to interact with existing communities only,
+ * the Status Desktop or Mobile app must be used to manage a community.
+ *
+ * @param publicKey The community's public key in hex format.
+ * Can be found in the community's invite link: https://join.status.im/c/
+ * @param waku The Waku instance, used to retrieve Community information from the network.
+ */
+ public static async instantiateCommunity(
+ publicKey: string,
+ waku: Waku
+ ): Promise {
+ const community = new Community(hexToBuf(publicKey), waku);
+
+ await community.refreshCommunityDescription();
+
+ return community;
+ }
+
+ public get publicKeyStr(): string {
+ return bufToHex(this.publicKey);
+ }
+
+ /**
+ * Retrieve and update community information from the network.
+ * Uses most recent community description message available.
+ */
+ async refreshCommunityDescription(): Promise {
+ const desc = await CommunityDescription.retrieve(
+ this.publicKey,
+ this.waku.store
+ );
+
+ if (!desc) {
+ dbg(`Failed to retrieve Community Description for ${this.publicKeyStr}`);
+ return;
+ }
+
+ this.description = desc;
+
+ await Promise.all(
+ Array.from(this.description.chats).map(([chatUuid, communityChat]) => {
+ return this.instantiateChat(chatUuid, communityChat);
+ })
+ );
+ }
+
+ /**
+ * Instantiate [[Chat]] object based on the passed chat name.
+ * The Chat MUST already be part of the Community and the name MUST be exact (including casing).
+ *
+ * @throws string If the Community Description is unavailable or the chat is not found;
+ */
+ private async instantiateChat(
+ chatUuid: string,
+ communityChat: CommunityChat
+ ): Promise {
+ if (!this.description)
+ throw "Failed to retrieve community description, cannot instantiate chat";
+
+ const chatId = this.publicKeyStr + chatUuid;
+ if (this.chats.get(chatId)) return;
+
+ const chat = await Chat.create(chatId, communityChat);
+
+ this.chats.set(chatId, chat);
+ }
+}
diff --git a/packages/status-core/src/contacts.ts b/packages/status-core/src/contacts.ts
new file mode 100644
index 00000000..ee67b930
--- /dev/null
+++ b/packages/status-core/src/contacts.ts
@@ -0,0 +1,169 @@
+import { PageDirection, Waku, WakuMessage } from "js-waku";
+
+import { idToContactCodeTopic } from "./contentTopic";
+import { Identity } from "./identity";
+import { StatusUpdate_StatusType } from "./proto/communities/v1/status_update";
+import { bufToHex, getLatestUserNickname } from "./utils";
+import { ChatIdentity } from "./wire/chat_identity";
+import { StatusUpdate } from "./wire/status_update";
+
+const STATUS_BROADCAST_INTERVAL = 30000;
+const NICKNAME_BROADCAST_INTERVAL = 300000;
+
+export class Contacts {
+ waku: Waku;
+ identity: Identity | undefined;
+ nickname?: string;
+ private callback: (publicKey: string, clock: number) => void;
+ private callbackNickname: (publicKey: string, nickname: string) => void;
+ private contacts: string[] = [];
+
+ /**
+ * Contacts holds a list of user contacts and listens to their status broadcast
+ *
+ * When watched user broadcast callback is called.
+ *
+ * Class also broadcasts own status on contact-code topic
+ *
+ * @param identity identity of user that is used to broadcast status message
+ *
+ * @param waku waku class used to listen to broadcast and broadcast status
+ *
+ * @param callback callback function called when user status broadcast is received
+ */
+ public constructor(
+ identity: Identity | undefined,
+ waku: Waku,
+ callback: (publicKey: string, clock: number) => void,
+ callbackNickname: (publicKey: string, nickname: string) => void,
+ nickname?: string
+ ) {
+ this.waku = waku;
+ this.identity = identity;
+ this.nickname = nickname;
+ this.callback = callback;
+ this.callbackNickname = callbackNickname;
+ this.startBroadcast();
+ if (identity) {
+ this.addContact(bufToHex(identity.publicKey));
+ }
+ }
+
+ /**
+ * Add contact to watch list of status broadcast
+ *
+ * When user broadcasts its status callback is called
+ *
+ * @param publicKey public key of user
+ */
+ public addContact(publicKey: string): void {
+ if (!this.contacts.find((e) => publicKey === e)) {
+ const now = new Date();
+ const callback = (wakuMessage: WakuMessage): void => {
+ if (wakuMessage.payload) {
+ const msg = StatusUpdate.decode(wakuMessage.payload);
+ this.callback(publicKey, msg.clock ?? 0);
+ }
+ };
+ this.contacts.push(publicKey);
+ this.callback(publicKey, 0);
+ this.waku.store.queryHistory([idToContactCodeTopic(publicKey)], {
+ callback: (msgs) => msgs.forEach((e) => callback(e)),
+ timeFilter: {
+ startTime: new Date(now.getTime() - STATUS_BROADCAST_INTERVAL * 2),
+ endTime: now,
+ },
+ });
+ this.waku.store.queryHistory([idToContactCodeTopic(publicKey)], {
+ callback: (msgs) =>
+ msgs.some((e) => {
+ try {
+ if (e.payload) {
+ const chatIdentity = ChatIdentity.decode(e?.payload);
+ if (chatIdentity) {
+ this.callbackNickname(
+ publicKey,
+ chatIdentity?.displayName ?? ""
+ );
+ }
+ return true;
+ }
+ } catch {
+ return false;
+ }
+ }),
+ pageDirection: PageDirection.BACKWARD,
+ });
+ this.waku.relay.addObserver(callback, [idToContactCodeTopic(publicKey)]);
+ }
+ }
+
+ private startBroadcast(): void {
+ const send = async (): Promise => {
+ if (this.identity) {
+ const statusUpdate = StatusUpdate.create(
+ StatusUpdate_StatusType.AUTOMATIC,
+ ""
+ );
+ const msg = await WakuMessage.fromBytes(
+ statusUpdate.encode(),
+ idToContactCodeTopic(bufToHex(this.identity.publicKey))
+ );
+ this.waku.relay.send(msg);
+ }
+ };
+
+ const handleNickname = async (): Promise => {
+ if (this.identity) {
+ const now = new Date().getTime();
+ const { clock, nickname: newNickname } = await getLatestUserNickname(
+ this.identity.publicKey,
+ this.waku
+ );
+
+ if (this.nickname) {
+ if (this.nickname !== newNickname) {
+ await sendNickname();
+ } else {
+ if (clock < now - NICKNAME_BROADCAST_INTERVAL) {
+ await sendNickname();
+ }
+ }
+ } else {
+ this.nickname = newNickname;
+ this.callbackNickname(bufToHex(this.identity.publicKey), newNickname);
+ if (clock < now - NICKNAME_BROADCAST_INTERVAL) {
+ await sendNickname();
+ }
+ }
+ }
+ setInterval(send, NICKNAME_BROADCAST_INTERVAL);
+ };
+
+ const sendNickname = async (): Promise => {
+ if (this.identity) {
+ const publicKey = bufToHex(this.identity.publicKey);
+ if (this.nickname) {
+ const chatIdentity = new ChatIdentity({
+ clock: new Date().getTime(),
+ color: "",
+ description: "",
+ emoji: "",
+ images: {},
+ ensName: "",
+ displayName: this?.nickname ?? "",
+ });
+ const msg = await WakuMessage.fromBytes(
+ chatIdentity.encode(),
+ idToContactCodeTopic(publicKey),
+ { sigPrivKey: this.identity.privateKey }
+ );
+ await this.waku.relay.send(msg);
+ }
+ }
+ };
+ handleNickname();
+ send();
+ setInterval(send, STATUS_BROADCAST_INTERVAL);
+ }
+}
diff --git a/packages/status-core/src/contentTopic.ts b/packages/status-core/src/contentTopic.ts
new file mode 100644
index 00000000..48c1dc22
--- /dev/null
+++ b/packages/status-core/src/contentTopic.ts
@@ -0,0 +1,22 @@
+import { Buffer } from "buffer";
+
+import { keccak256 } from "js-sha3";
+
+const TopicLength = 4;
+
+/**
+ * Get the content topic of for a given Chat or Community
+ * @param id The Chat id or Community id (hex string prefixed with 0x).
+ * @returns string The Waku v2 Content Topic.
+ */
+export function idToContentTopic(id: string): string {
+ const hash = keccak256.arrayBuffer(id);
+
+ const topic = Buffer.from(hash).slice(0, TopicLength);
+
+ return "/waku/1/" + "0x" + topic.toString("hex") + "/rfc26";
+}
+
+export function idToContactCodeTopic(id: string): string {
+ return idToContentTopic(id + "-contact-code");
+}
diff --git a/packages/status-core/src/encryption.spec.ts b/packages/status-core/src/encryption.spec.ts
new file mode 100644
index 00000000..c4b51897
--- /dev/null
+++ b/packages/status-core/src/encryption.spec.ts
@@ -0,0 +1,24 @@
+import { expect } from "chai";
+
+import { createSymKeyFromPassword } from "./encryption";
+
+describe("Encryption", () => {
+ it("Generate symmetric key from password", async function () {
+ const str = "arbitrary data here";
+ const symKey = await createSymKeyFromPassword(str);
+
+ expect(Buffer.from(symKey).toString("hex")).to.eq(
+ "c49ad65ebf2a7b7253bf400e3d27719362a91b2c9b9f54d50a69117021666c33"
+ );
+ });
+
+ it("Generate symmetric key from password for chat", async function () {
+ const str =
+ "0x02dcec6041fb999d65f1d33363e08c93d3c1f6f0fbbb26add383e2cf46c2b921f41dc14fd8-9a8b-4df5-a358-2c3067be5439";
+ const symKey = await createSymKeyFromPassword(str);
+
+ expect(Buffer.from(symKey).toString("hex")).to.eq(
+ "76ff5bf0a74a8e724367c7fc003f066d477641f468768a8da2817addf5c2ce76"
+ );
+ });
+});
diff --git a/packages/status-core/src/encryption.ts b/packages/status-core/src/encryption.ts
new file mode 100644
index 00000000..e27d06af
--- /dev/null
+++ b/packages/status-core/src/encryption.ts
@@ -0,0 +1,15 @@
+import pbkdf2 from "pbkdf2";
+
+const AESKeyLength = 32; // bytes
+
+export async function createSymKeyFromPassword(
+ password: string
+): Promise {
+ return pbkdf2.pbkdf2Sync(
+ Buffer.from(password, "utf-8"),
+ "",
+ 65356,
+ AESKeyLength,
+ "sha256"
+ );
+}
diff --git a/packages/status-core/src/groupChats.ts b/packages/status-core/src/groupChats.ts
new file mode 100644
index 00000000..ce85c818
--- /dev/null
+++ b/packages/status-core/src/groupChats.ts
@@ -0,0 +1,459 @@
+import { Waku, WakuMessage } from "js-waku";
+import { DecryptionMethod } from "js-waku/build/main/lib/waku_message";
+
+import { createSymKeyFromPassword } from "./encryption";
+import { Identity } from "./identity";
+import { MembershipUpdateEvent_EventType } from "./proto/communities/v1/membership_update_message";
+import { getNegotiatedTopic, getPartitionedTopic } from "./topics";
+import { bufToHex, compressPublicKey } from "./utils";
+import {
+ MembershipSignedEvent,
+ MembershipUpdateMessage,
+} from "./wire/membership_update_message";
+
+import { ChatMessage, Content } from ".";
+
+type GroupMember = {
+ id: string;
+ topic: string;
+ symKey: Uint8Array;
+ partitionedTopic: string;
+};
+
+export type GroupChat = {
+ chatId: string;
+ members: GroupMember[];
+ admins?: string[];
+ name?: string;
+ removed: boolean;
+};
+
+export type GroupChatsType = {
+ [id: string]: GroupChat;
+};
+/* TODO: add chat messages encryption */
+
+class GroupChatUsers {
+ private users: { [id: string]: GroupMember } = {};
+ private identity: Identity;
+
+ public constructor(_identity: Identity) {
+ this.identity = _identity;
+ }
+
+ public async getUser(id: string): Promise {
+ if (this.users[id]) {
+ return this.users[id];
+ }
+ const topic = await getNegotiatedTopic(this.identity, id);
+ const symKey = await createSymKeyFromPassword(topic);
+ const partitionedTopic = getPartitionedTopic(id);
+ const groupUser: GroupMember = { topic, symKey, id, partitionedTopic };
+ this.users[id] = groupUser;
+ return groupUser;
+ }
+}
+
+export class GroupChats {
+ waku: Waku;
+ identity: Identity;
+ private callback: (chats: GroupChat) => void;
+ private removeCallback: (chats: GroupChat) => void;
+ private addMessage: (message: ChatMessage, sender: string) => void;
+ private groupChatUsers;
+
+ public chats: GroupChatsType = {};
+ /**
+ * GroupChats holds a list of private chats and listens to their status broadcast
+ *
+ * @param identity identity of user
+ *
+ * @param waku waku class used to listen to broadcast and broadcast status
+ *
+ * @param callback callback function called when new private group chat is ceated
+ *
+ * @param removeCallback callback function when private group chat is to be removed
+ *
+ * @param addMessage callback function when
+ */
+ public constructor(
+ identity: Identity,
+ waku: Waku,
+ callback: (chat: GroupChat) => void,
+ removeCallback: (chat: GroupChat) => void,
+ addMessage: (message: ChatMessage, sender: string) => void
+ ) {
+ this.waku = waku;
+ this.identity = identity;
+ this.groupChatUsers = new GroupChatUsers(identity);
+ this.callback = callback;
+ this.removeCallback = removeCallback;
+ this.addMessage = addMessage;
+ this.listen();
+ }
+
+ /**
+ * Send chat message on given private chat
+ *
+ * @param chatId chat id of private group chat
+ *
+ * @param text text message to send
+ */
+ public async sendMessage(
+ chatId: string,
+ content: Content,
+ responseTo?: string
+ ): Promise {
+ const now = Date.now();
+ const chat = this.chats[chatId];
+ if (chat) {
+ await Promise.all(
+ chat.members.map(async (member) => {
+ const chatMessage = ChatMessage.createMessage(
+ now,
+ now,
+ chatId,
+ content,
+ responseTo
+ );
+ const wakuMessage = await WakuMessage.fromBytes(
+ chatMessage.encode(),
+ member.topic,
+ { sigPrivKey: this.identity.privateKey, symKey: member.symKey }
+ );
+ this.waku.relay.send(wakuMessage);
+ })
+ );
+ }
+ }
+
+ private async handleUpdateEvent(
+ chatId: string,
+ event: MembershipSignedEvent,
+ useCallback: boolean
+ ): Promise {
+ const signer = event.signer ? bufToHex(event.signer) : "";
+ const thisUser = bufToHex(this.identity.publicKey);
+ const chat: GroupChat | undefined = this.chats[chatId];
+ if (signer) {
+ switch (event.event.type) {
+ case MembershipUpdateEvent_EventType.CHAT_CREATED: {
+ const members: GroupMember[] = [];
+ await Promise.all(
+ event.event.members.map(async (member) => {
+ members.push(await this.groupChatUsers.getUser(member));
+ })
+ );
+ await this.addChat(
+ {
+ chatId: chatId,
+ members,
+ admins: [signer],
+ removed: false,
+ },
+ useCallback
+ );
+ break;
+ }
+ case MembershipUpdateEvent_EventType.MEMBER_REMOVED: {
+ if (chat) {
+ chat.members = chat.members.filter(
+ (member) => !event.event.members.includes(member.id)
+ );
+ if (event.event.members.includes(thisUser)) {
+ await this.removeChat(
+ {
+ ...chat,
+ removed: true,
+ },
+ useCallback
+ );
+ } else {
+ if (!chat.removed && useCallback) {
+ this.callback(this.chats[chatId]);
+ }
+ }
+ }
+ break;
+ }
+ case MembershipUpdateEvent_EventType.MEMBERS_ADDED: {
+ if (chat && chat.admins?.includes(signer)) {
+ const members: GroupMember[] = [];
+ await Promise.all(
+ event.event.members.map(async (member) => {
+ members.push(await this.groupChatUsers.getUser(member));
+ })
+ );
+ chat.members.push(...members);
+ if (
+ chat.members.findIndex((member) => member.id === thisUser) > -1
+ ) {
+ chat.removed = false;
+ await this.addChat(chat, useCallback);
+ }
+ }
+ break;
+ }
+ case MembershipUpdateEvent_EventType.NAME_CHANGED: {
+ if (chat) {
+ if (chat.admins?.includes(signer)) {
+ chat.name = event.event.name;
+ this.callback(chat);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private async decodeUpdateMessage(
+ message: WakuMessage,
+ useCallback: boolean
+ ): Promise {
+ try {
+ if (message?.payload) {
+ const membershipUpdate = MembershipUpdateMessage.decode(
+ message.payload
+ );
+ await Promise.all(
+ membershipUpdate.events.map(
+ async (event) =>
+ await this.handleUpdateEvent(
+ membershipUpdate.chatId,
+ event,
+ useCallback
+ )
+ )
+ );
+ }
+ } catch {
+ return;
+ }
+ }
+
+ private handleWakuChatMessage(
+ message: WakuMessage,
+ chat: GroupChat,
+ member: string
+ ): void {
+ try {
+ if (message.payload) {
+ const chatMessage = ChatMessage.decode(message.payload);
+ if (chatMessage) {
+ if (chatMessage.chatId === chat.chatId) {
+ let sender = member;
+ if (message.signaturePublicKey) {
+ sender = compressPublicKey(message.signaturePublicKey);
+ }
+ this.addMessage(chatMessage, sender);
+ }
+ }
+ }
+ } catch {
+ return;
+ }
+ }
+
+ private async handleChatObserver(
+ chat: GroupChat,
+ removeObserver?: boolean
+ ): Promise {
+ const observerFunction = removeObserver ? "deleteObserver" : "addObserver";
+ await Promise.all(
+ chat.members.map(async (member) => {
+ if (!removeObserver) {
+ this.waku.relay.addDecryptionKey(member.symKey, {
+ method: DecryptionMethod.Symmetric,
+ contentTopics: [member.topic],
+ });
+ }
+ this.waku.relay[observerFunction](
+ (message) => this.handleWakuChatMessage(message, chat, member.id),
+ [member.topic]
+ );
+ })
+ );
+ }
+
+ private async addChat(chat: GroupChat, useCallback: boolean): Promise {
+ if (this.chats[chat.chatId]) {
+ this.chats[chat.chatId] = chat;
+ if (useCallback) {
+ this.callback(chat);
+ }
+ } else {
+ this.chats[chat.chatId] = chat;
+ if (useCallback) {
+ await this.handleChatObserver(chat);
+ this.callback(chat);
+ }
+ }
+ }
+
+ private async removeChat(
+ chat: GroupChat,
+ useCallback: boolean
+ ): Promise {
+ this.chats[chat.chatId] = chat;
+ if (useCallback) {
+ await this.handleChatObserver(chat, true);
+ this.removeCallback(chat);
+ }
+ }
+
+ private async listen(): Promise {
+ const topic = getPartitionedTopic(bufToHex(this.identity.publicKey));
+ const messages = await this.waku.store.queryHistory([topic]);
+ messages.sort((a, b) =>
+ (a?.timestamp?.getTime() ?? 0) < (b?.timestamp?.getTime() ?? 0) ? -1 : 1
+ );
+ for (let i = 0; i < messages.length; i++) {
+ await this.decodeUpdateMessage(messages[i], false);
+ }
+ this.waku.relay.addObserver(
+ (message) => this.decodeUpdateMessage(message, true),
+ [topic]
+ );
+ await Promise.all(
+ Object.values(this.chats).map(async (chat) => {
+ if (!chat?.removed) {
+ await this.handleChatObserver(chat);
+ this.callback(chat);
+ }
+ })
+ );
+ }
+
+ private async sendUpdateMessage(
+ payload: Uint8Array,
+ members: GroupMember[]
+ ): Promise {
+ const wakuMessages = await Promise.all(
+ members.map(
+ async (member) =>
+ await WakuMessage.fromBytes(payload, member.partitionedTopic)
+ )
+ );
+ wakuMessages.forEach((msg) => this.waku.relay.send(msg));
+ }
+
+ /**
+ * Sends a change chat name chat membership update message
+ *
+ * @param chatId a chat id to which message is to be sent
+ *
+ * @param name a name which chat should be changed to
+ */
+ public async changeChatName(chatId: string, name: string): Promise {
+ const payload = MembershipUpdateMessage.create(chatId, this.identity);
+ const chat = this.chats[chatId];
+ if (chat && payload) {
+ payload.addNameChangeEvent(name);
+ await this.sendUpdateMessage(payload.encode(), chat.members);
+ }
+ }
+
+ /**
+ * Sends a add members group chat membership update message with given members
+ *
+ * @param chatId a chat id to which message is to be sent
+ *
+ * @param members a list of members to be added
+ */
+ public async addMembers(chatId: string, members: string[]): Promise {
+ const payload = MembershipUpdateMessage.create(chatId, this.identity);
+ const chat = this.chats[chatId];
+ if (chat && payload) {
+ const newMembers: GroupMember[] = [];
+
+ await Promise.all(
+ members
+ .filter(
+ (member) =>
+ !chat.members.map((chatMember) => chatMember.id).includes(member)
+ )
+ .map(async (member) => {
+ newMembers.push(await this.groupChatUsers.getUser(member));
+ })
+ );
+
+ payload.addMembersAddedEvent(newMembers.map((member) => member.id));
+ await this.sendUpdateMessage(payload.encode(), [
+ ...chat.members,
+ ...newMembers,
+ ]);
+ }
+ }
+
+ /**
+ * Sends a create group chat membership update message with given members
+ *
+ * @param members a list of public keys of members to be included in private group chat
+ */
+ public async createGroupChat(members: string[]): Promise {
+ const payload = MembershipUpdateMessage.createChat(
+ this.identity,
+ members
+ ).encode();
+
+ const newMembers: GroupMember[] = [];
+
+ await Promise.all(
+ members.map(async (member) => {
+ newMembers.push(await this.groupChatUsers.getUser(member));
+ })
+ );
+
+ await this.sendUpdateMessage(payload, newMembers);
+ }
+
+ /**
+ * Sends a remove member to private group chat
+ *
+ * @param chatId id of private group chat
+ */
+ public async quitChat(chatId: string): Promise {
+ const payload = MembershipUpdateMessage.create(chatId, this.identity);
+ const chat = this.chats[chatId];
+ payload.addMemberRemovedEvent(bufToHex(this.identity.publicKey));
+ await this.sendUpdateMessage(payload.encode(), chat.members);
+ }
+
+ /**
+ * Retrieve previous messages from a Waku Store node for the given chat Id.
+ *
+ */
+ public async retrievePreviousMessages(
+ chatId: string,
+ startTime: Date,
+ endTime: Date
+ ): Promise {
+ const chat = this.chats[chatId];
+
+ if (!chat)
+ throw `Failed to retrieve messages, chat is not joined: ${chatId}`;
+
+ const _callback = (wakuMessages: WakuMessage[], member: string): void => {
+ wakuMessages.forEach((wakuMessage: WakuMessage) =>
+ this.handleWakuChatMessage(wakuMessage, chat, member)
+ );
+ };
+
+ const amountOfMessages: number[] = [];
+
+ await Promise.all(
+ chat.members.map(async (member) => {
+ const msgLength = (
+ await this.waku.store.queryHistory([member.topic], {
+ timeFilter: { startTime, endTime },
+ callback: (msg) => _callback(msg, member.id),
+ decryptionKeys: [member.symKey],
+ })
+ ).length;
+ amountOfMessages.push(msgLength);
+ })
+ );
+ return amountOfMessages.reduce((a, b) => a + b);
+ }
+}
diff --git a/packages/status-core/src/identity.ts b/packages/status-core/src/identity.ts
new file mode 100644
index 00000000..c8011024
--- /dev/null
+++ b/packages/status-core/src/identity.ts
@@ -0,0 +1,39 @@
+import { Buffer } from "buffer";
+
+import { keccak256 } from "js-sha3";
+import { generatePrivateKey } from "js-waku";
+import * as secp256k1 from "secp256k1";
+
+import { hexToBuf } from "./utils";
+
+export class Identity {
+ private pubKey: Uint8Array;
+ public constructor(public privateKey: Uint8Array) {
+ this.pubKey = secp256k1.publicKeyCreate(this.privateKey, true);
+ }
+
+ public static generate(): Identity {
+ const privateKey = generatePrivateKey();
+ return new Identity(privateKey);
+ }
+
+ /**
+ * Hashes the payload with SHA3-256 and signs the result using the internal private key.
+ */
+ public sign(payload: Uint8Array): Uint8Array {
+ const hash = keccak256(payload);
+ const { signature, recid } = secp256k1.ecdsaSign(
+ hexToBuf(hash),
+ this.privateKey
+ );
+
+ return Buffer.concat([signature, Buffer.from([recid])]);
+ }
+
+ /**
+ * Returns the compressed public key.
+ */
+ public get publicKey(): Uint8Array {
+ return this.pubKey;
+ }
+}
diff --git a/packages/status-core/src/index.ts b/packages/status-core/src/index.ts
new file mode 100644
index 00000000..1ccede10
--- /dev/null
+++ b/packages/status-core/src/index.ts
@@ -0,0 +1,18 @@
+export { Identity } from "./identity";
+export { Messenger } from "./messenger";
+export { Community } from "./community";
+export { Contacts } from "./contacts";
+export { Chat } from "./chat";
+export * from "./groupChats";
+export * as utils from "./utils";
+export { ApplicationMetadataMessage } from "./wire/application_metadata_message";
+export {
+ ChatMessage,
+ ContentType,
+ Content,
+ StickerContent,
+ ImageContent,
+ AudioContent,
+ TextContent,
+} from "./wire/chat_message";
+export { getNodesFromHostedJson } from "js-waku";
diff --git a/packages/status-core/src/messenger.spec.ts b/packages/status-core/src/messenger.spec.ts
new file mode 100644
index 00000000..24e488e9
--- /dev/null
+++ b/packages/status-core/src/messenger.spec.ts
@@ -0,0 +1,178 @@
+import { expect } from "chai";
+import debug from "debug";
+import { Protocols } from "js-waku/build/main/lib/waku";
+
+import { Community } from "./community";
+import { Identity } from "./identity";
+import { Messenger } from "./messenger";
+import { bufToHex } from "./utils";
+import { ApplicationMetadataMessage } from "./wire/application_metadata_message";
+import { ContentType } from "./wire/chat_message";
+
+const testChatId = "test-chat-id";
+
+const dbg = debug("communities:test:messenger");
+
+describe("Messenger", () => {
+ let messengerAlice: Messenger;
+ let messengerBob: Messenger;
+ let identityAlice: Identity;
+ let identityBob: Identity;
+
+ beforeEach(async function () {
+ this.timeout(20_000);
+
+ dbg("Generate keys");
+ identityAlice = Identity.generate();
+ identityBob = Identity.generate();
+
+ dbg("Create messengers");
+
+ [messengerAlice, messengerBob] = await Promise.all([
+ Messenger.create(identityAlice, { bootstrap: {} }),
+ Messenger.create(identityBob, {
+ bootstrap: {},
+ libp2p: { addresses: { listen: ["/ip4/0.0.0.0/tcp/0/ws"] } },
+ }),
+ ]);
+
+ dbg("Connect messengers");
+ // Connect both messengers together for test purposes
+ messengerAlice.waku.addPeerToAddressBook(
+ messengerBob.waku.libp2p.peerId,
+ messengerBob.waku.libp2p.multiaddrs
+ );
+
+ dbg("Wait for remote peer");
+ await Promise.all([
+ messengerAlice.waku.waitForRemotePeer([Protocols.Relay]),
+ messengerBob.waku.waitForRemotePeer([Protocols.Relay]),
+ ]);
+ dbg("Messengers ready");
+ });
+
+ it("Sends & Receive public chat messages", async function () {
+ this.timeout(10_000);
+
+ await messengerAlice.joinChatById(testChatId);
+ await messengerBob.joinChatById(testChatId);
+
+ const text = "This is a message.";
+
+ const receivedMessagePromise: Promise =
+ new Promise((resolve) => {
+ messengerBob.addObserver((message) => {
+ resolve(message);
+ }, testChatId);
+ });
+
+ await messengerAlice.sendMessage(testChatId, {
+ text,
+ contentType: ContentType.Text,
+ });
+
+ const receivedMessage = await receivedMessagePromise;
+
+ expect(receivedMessage.chatMessage?.text).to.eq(text);
+ });
+
+ it("public chat messages have signers", async function () {
+ this.timeout(10_000);
+
+ await messengerAlice.joinChatById(testChatId);
+ await messengerBob.joinChatById(testChatId);
+
+ const text = "This is a message.";
+
+ const receivedMessagePromise: Promise =
+ new Promise((resolve) => {
+ messengerBob.addObserver((message) => {
+ resolve(message);
+ }, testChatId);
+ });
+
+ await messengerAlice.sendMessage(testChatId, {
+ text,
+ contentType: ContentType.Text,
+ });
+
+ const receivedMessage = await receivedMessagePromise;
+
+ expect(bufToHex(receivedMessage.signer!)).to.eq(
+ bufToHex(identityAlice.publicKey)
+ );
+ });
+
+ afterEach(async function () {
+ this.timeout(5000);
+ await messengerAlice.stop();
+ await messengerBob.stop();
+ });
+});
+
+describe("Messenger [live data]", () => {
+ before(function () {
+ if (process.env.CI) {
+ // Skip live data test in CI
+ this.skip();
+ }
+ });
+
+ let messenger: Messenger;
+ let identity: Identity;
+
+ beforeEach(async function () {
+ this.timeout(20_000);
+
+ dbg("Generate keys");
+ identity = Identity.generate();
+
+ dbg("Create messengers");
+
+ messenger = await Messenger.create(identity, {
+ bootstrap: { default: true },
+ });
+
+ dbg("Wait to be connected to a peer");
+ await messenger.waku.waitForRemotePeer();
+ dbg("Messengers ready");
+ });
+
+ it("Receive public chat messages", async function () {
+ this.timeout(20_000);
+
+ const community = await Community.instantiateCommunity(
+ "0x02cf13719c8b836bebd4e430c497ee38e798a43e4d8c4760c34bbd9bf4f2434d26",
+ messenger.waku
+ );
+
+ await messenger.joinChats(community.chats.values());
+
+ const startTime = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
+ const endTime = new Date();
+
+ const chat = Array.from(community.chats.values()).find(
+ (chat) => chat.communityChat?.identity?.displayName === "Test Chat"
+ );
+
+ if (!chat) throw "Could not find foobar chat";
+
+ console.log(chat);
+
+ await messenger.retrievePreviousMessages(
+ chat.id,
+ startTime,
+ endTime,
+ (metadata) => {
+ metadata.forEach((m) => {
+ console.log("Message", m.chatMessage?.text);
+ });
+ }
+ );
+ });
+
+ afterEach(async function () {
+ this.timeout(5000);
+ await messenger.stop();
+ });
+});
diff --git a/packages/status-core/src/messenger.ts b/packages/status-core/src/messenger.ts
new file mode 100644
index 00000000..2ebbd650
--- /dev/null
+++ b/packages/status-core/src/messenger.ts
@@ -0,0 +1,268 @@
+import debug from "debug";
+import { Waku, WakuMessage } from "js-waku";
+import { CreateOptions as WakuCreateOptions } from "js-waku/build/main/lib/waku";
+import { DecryptionMethod } from "js-waku/build/main/lib/waku_message";
+
+import { Chat } from "./chat";
+import { Identity } from "./identity";
+import { ApplicationMetadataMessage_Type } from "./proto/status/v1/application_metadata_message";
+import { getLatestUserNickname } from "./utils";
+import { ApplicationMetadataMessage } from "./wire/application_metadata_message";
+import { ChatMessage, Content } from "./wire/chat_message";
+
+const dbg = debug("communities:messenger");
+
+export class Messenger {
+ waku: Waku;
+ chatsById: Map;
+ observers: {
+ [chatId: string]: Set<
+ (
+ message: ApplicationMetadataMessage,
+ timestamp: Date,
+ chatId: string
+ ) => void
+ >;
+ };
+ identity: Identity | undefined;
+
+ private constructor(identity: Identity | undefined, waku: Waku) {
+ this.identity = identity;
+ this.waku = waku;
+ this.chatsById = new Map();
+ this.observers = {};
+ }
+
+ public static async create(
+ identity: Identity | undefined,
+ wakuOptions?: WakuCreateOptions
+ ): Promise {
+ const _wakuOptions = Object.assign(
+ { bootstrap: { default: true } },
+ wakuOptions
+ );
+ const waku = await Waku.create(_wakuOptions);
+ return new Messenger(identity, waku);
+ }
+
+ /**
+ * Joins a public chat using its id.
+ *
+ * For community chats, prefer [[joinChat]].
+ *
+ * Use `addListener` to get messages received on this chat.
+ */
+ public async joinChatById(chatId: string): Promise {
+ const chat = await Chat.create(chatId);
+
+ await this.joinChat(chat);
+ }
+
+ /**
+ * Joins several of public chats.
+ *
+ * Use `addListener` to get messages received on these chats.
+ */
+ public async joinChats(chats: Iterable): Promise {
+ await Promise.all(
+ Array.from(chats).map((chat) => {
+ return this.joinChat(chat);
+ })
+ );
+ }
+
+ /**
+ * Joins a public chat.
+ *
+ * Use `addListener` to get messages received on this chat.
+ */
+ public async joinChat(chat: Chat): Promise {
+ if (this.chatsById.has(chat.id))
+ throw `Failed to join chat, it is already joined: ${chat.id}`;
+
+ this.waku.addDecryptionKey(chat.symKey, {
+ method: DecryptionMethod.Symmetric,
+ contentTopics: [chat.contentTopic],
+ });
+
+ this.waku.relay.addObserver(
+ (wakuMessage: WakuMessage) => {
+ if (!wakuMessage.payload || !wakuMessage.timestamp) return;
+
+ const message = ApplicationMetadataMessage.decode(wakuMessage.payload);
+
+ switch (message.type) {
+ case ApplicationMetadataMessage_Type.TYPE_CHAT_MESSAGE:
+ this._handleNewChatMessage(chat, message, wakuMessage.timestamp);
+ break;
+ default:
+ dbg("Received unsupported message type", message.type);
+ }
+ },
+ [chat.contentTopic]
+ );
+
+ this.chatsById.set(chat.id, chat);
+ }
+
+ /**
+ * Sends a message on the given chat Id.
+ */
+ public async sendMessage(
+ chatId: string,
+ content: Content,
+ responseTo?: string
+ ): Promise {
+ if (this.identity) {
+ const chat = this.chatsById.get(chatId);
+ if (!chat) throw `Failed to send message, chat not joined: ${chatId}`;
+
+ const chatMessage = chat.createMessage(content, responseTo);
+
+ const appMetadataMessage = ApplicationMetadataMessage.create(
+ chatMessage.encode(),
+ ApplicationMetadataMessage_Type.TYPE_CHAT_MESSAGE,
+ this.identity
+ );
+
+ const wakuMessage = await WakuMessage.fromBytes(
+ appMetadataMessage.encode(),
+ chat.contentTopic,
+ { symKey: chat.symKey, sigPrivKey: this.identity.privateKey }
+ );
+
+ await this.waku.relay.send(wakuMessage);
+ }
+ }
+
+ /**
+ * Add an observer of new messages received on the given chat id.
+ *
+ * @throws string If the chat has not been joined first using [joinChat].
+ */
+ public addObserver(
+ observer: (
+ message: ApplicationMetadataMessage,
+ timestamp: Date,
+ chatId: string
+ ) => void,
+ chatId: string | string[]
+ ): void {
+ let chats = [];
+
+ if (typeof chatId === "string") {
+ chats.push(chatId);
+ } else {
+ chats = [...chatId];
+ }
+
+ chats.forEach((id) => {
+ if (!this.chatsById.has(id))
+ throw "Cannot add observer on a chat that is not joined.";
+ if (!this.observers[id]) {
+ this.observers[id] = new Set();
+ }
+
+ this.observers[id].add(observer);
+ });
+ }
+
+ /**
+ * Delete an observer of new messages received on the given chat id.
+ *
+ * @throws string If the chat has not been joined first using [joinChat].
+ */
+
+ deleteObserver(
+ observer: (message: ApplicationMetadataMessage) => void,
+ chatId: string
+ ): void {
+ if (this.observers[chatId]) {
+ this.observers[chatId].delete(observer);
+ }
+ }
+
+ /**
+ * Stops the messenger.
+ */
+ public async stop(): Promise {
+ await this.waku.stop();
+ }
+
+ /**
+ * Retrieve previous messages from a Waku Store node for the given chat Id.
+ *
+ * Note: note sure what is the preferred interface: callback or returning all messages
+ * Callback is more flexible and allow processing messages as they are retrieved instead of waiting for the
+ * full retrieval via paging to be done.
+ */
+ public async retrievePreviousMessages(
+ chatId: string,
+ startTime: Date,
+ endTime: Date,
+ callback?: (messages: ApplicationMetadataMessage[]) => void
+ ): Promise {
+ const chat = this.chatsById.get(chatId);
+ if (!chat)
+ throw `Failed to retrieve messages, chat is not joined: ${chatId}`;
+
+ const _callback = (wakuMessages: WakuMessage[]): void => {
+ const isDefined = (
+ msg: ApplicationMetadataMessage | undefined
+ ): msg is ApplicationMetadataMessage => {
+ return !!msg;
+ };
+
+ const messages = wakuMessages.map((wakuMessage: WakuMessage) => {
+ if (!wakuMessage.payload || !wakuMessage.timestamp) return;
+
+ const message = ApplicationMetadataMessage.decode(wakuMessage.payload);
+
+ switch (message.type) {
+ case ApplicationMetadataMessage_Type.TYPE_CHAT_MESSAGE:
+ this._handleNewChatMessage(chat, message, wakuMessage.timestamp);
+ return message;
+ default:
+ dbg("Retrieved unsupported message type", message.type);
+ return;
+ }
+ });
+ if (callback) {
+ callback(messages.filter(isDefined));
+ }
+ };
+ const allMessages = await this.waku.store.queryHistory(
+ [chat.contentTopic],
+ {
+ timeFilter: { startTime, endTime },
+ callback: _callback,
+ }
+ );
+ return allMessages.length;
+ }
+
+ private _handleNewChatMessage(
+ chat: Chat,
+ message: ApplicationMetadataMessage,
+ timestamp: Date
+ ): void {
+ if (!message.payload || !message.type || !message.signature) return;
+
+ const chatMessage = ChatMessage.decode(message.payload);
+ chat.handleNewMessage(chatMessage);
+
+ if (this.observers[chat.id]) {
+ this.observers[chat.id].forEach((observer) => {
+ observer(message, timestamp, chat.id);
+ });
+ }
+ }
+
+ async checkIfUserInWakuNetwork(publicKey: Uint8Array): Promise {
+ const { clock, nickname } = await getLatestUserNickname(
+ publicKey,
+ this.waku
+ );
+ return clock > 0 && nickname !== "";
+ }
+}
diff --git a/packages/status-core/src/proto/communities/v1/chat_identity.ts b/packages/status-core/src/proto/communities/v1/chat_identity.ts
new file mode 100644
index 00000000..c75a7900
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/chat_identity.ts
@@ -0,0 +1,532 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+import {
+ ImageType,
+ imageTypeFromJSON,
+ imageTypeToJSON,
+} from "../../communities/v1/enums";
+
+export const protobufPackage = "communities.v1";
+
+/** ChatIdentity represents the user defined identity associated with their public chat key */
+export interface ChatIdentity {
+ /** Lamport timestamp of the message */
+ clock: number;
+ /** ens_name is the valid ENS name associated with the chat key */
+ ensName: string;
+ /** images is a string indexed mapping of images associated with an identity */
+ images: { [key: string]: IdentityImage };
+ /** display name is the user set identity, valid only for organisations */
+ displayName: string;
+ /** description is the user set description, valid only for organisations */
+ description: string;
+ color: string;
+ emoji: string;
+}
+
+export interface ChatIdentity_ImagesEntry {
+ key: string;
+ value: IdentityImage | undefined;
+}
+
+/** ProfileImage represents data associated with a user's profile image */
+export interface IdentityImage {
+ /**
+ * payload is a context based payload for the profile image data,
+ * context is determined by the `source_type`
+ */
+ payload: Uint8Array;
+ /** source_type signals the image payload source */
+ sourceType: IdentityImage_SourceType;
+ /** image_type signals the image type and method of parsing the payload */
+ imageType: ImageType;
+}
+
+/** SourceType are the predefined types of image source allowed */
+export enum IdentityImage_SourceType {
+ UNKNOWN_SOURCE_TYPE = 0,
+ /** RAW_PAYLOAD - RAW_PAYLOAD image byte data */
+ RAW_PAYLOAD = 1,
+ /**
+ * ENS_AVATAR - ENS_AVATAR uses the ENS record's resolver get-text-data.avatar data
+ * The `payload` field will be ignored if ENS_AVATAR is selected
+ * The application will read and parse the ENS avatar data as image payload data, URLs will be ignored
+ * The parent `ChatMessageIdentity` must have a valid `ens_name` set
+ */
+ ENS_AVATAR = 2,
+ UNRECOGNIZED = -1,
+}
+
+export function identityImage_SourceTypeFromJSON(
+ object: any
+): IdentityImage_SourceType {
+ switch (object) {
+ case 0:
+ case "UNKNOWN_SOURCE_TYPE":
+ return IdentityImage_SourceType.UNKNOWN_SOURCE_TYPE;
+ case 1:
+ case "RAW_PAYLOAD":
+ return IdentityImage_SourceType.RAW_PAYLOAD;
+ case 2:
+ case "ENS_AVATAR":
+ return IdentityImage_SourceType.ENS_AVATAR;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return IdentityImage_SourceType.UNRECOGNIZED;
+ }
+}
+
+export function identityImage_SourceTypeToJSON(
+ object: IdentityImage_SourceType
+): string {
+ switch (object) {
+ case IdentityImage_SourceType.UNKNOWN_SOURCE_TYPE:
+ return "UNKNOWN_SOURCE_TYPE";
+ case IdentityImage_SourceType.RAW_PAYLOAD:
+ return "RAW_PAYLOAD";
+ case IdentityImage_SourceType.ENS_AVATAR:
+ return "ENS_AVATAR";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const baseChatIdentity: object = {
+ clock: 0,
+ ensName: "",
+ displayName: "",
+ description: "",
+ color: "",
+ emoji: "",
+};
+
+export const ChatIdentity = {
+ encode(
+ message: ChatIdentity,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.ensName !== "") {
+ writer.uint32(18).string(message.ensName);
+ }
+ Object.entries(message.images).forEach(([key, value]) => {
+ ChatIdentity_ImagesEntry.encode(
+ { key: key as any, value },
+ writer.uint32(26).fork()
+ ).ldelim();
+ });
+ if (message.displayName !== "") {
+ writer.uint32(34).string(message.displayName);
+ }
+ if (message.description !== "") {
+ writer.uint32(42).string(message.description);
+ }
+ if (message.color !== "") {
+ writer.uint32(50).string(message.color);
+ }
+ if (message.emoji !== "") {
+ writer.uint32(58).string(message.emoji);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): ChatIdentity {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseChatIdentity } as ChatIdentity;
+ message.images = {};
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.ensName = reader.string();
+ break;
+ case 3:
+ const entry3 = ChatIdentity_ImagesEntry.decode(
+ reader,
+ reader.uint32()
+ );
+ if (entry3.value !== undefined) {
+ message.images[entry3.key] = entry3.value;
+ }
+ break;
+ case 4:
+ message.displayName = reader.string();
+ break;
+ case 5:
+ message.description = reader.string();
+ break;
+ case 6:
+ message.color = reader.string();
+ break;
+ case 7:
+ message.emoji = reader.string();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): ChatIdentity {
+ const message = { ...baseChatIdentity } as ChatIdentity;
+ message.images = {};
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.ensName !== undefined && object.ensName !== null) {
+ message.ensName = String(object.ensName);
+ } else {
+ message.ensName = "";
+ }
+ if (object.images !== undefined && object.images !== null) {
+ Object.entries(object.images).forEach(([key, value]) => {
+ message.images[key] = IdentityImage.fromJSON(value);
+ });
+ }
+ if (object.displayName !== undefined && object.displayName !== null) {
+ message.displayName = String(object.displayName);
+ } else {
+ message.displayName = "";
+ }
+ if (object.description !== undefined && object.description !== null) {
+ message.description = String(object.description);
+ } else {
+ message.description = "";
+ }
+ if (object.color !== undefined && object.color !== null) {
+ message.color = String(object.color);
+ } else {
+ message.color = "";
+ }
+ if (object.emoji !== undefined && object.emoji !== null) {
+ message.emoji = String(object.emoji);
+ } else {
+ message.emoji = "";
+ }
+ return message;
+ },
+
+ toJSON(message: ChatIdentity): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.ensName !== undefined && (obj.ensName = message.ensName);
+ obj.images = {};
+ if (message.images) {
+ Object.entries(message.images).forEach(([k, v]) => {
+ obj.images[k] = IdentityImage.toJSON(v);
+ });
+ }
+ message.displayName !== undefined &&
+ (obj.displayName = message.displayName);
+ message.description !== undefined &&
+ (obj.description = message.description);
+ message.color !== undefined && (obj.color = message.color);
+ message.emoji !== undefined && (obj.emoji = message.emoji);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): ChatIdentity {
+ const message = { ...baseChatIdentity } as ChatIdentity;
+ message.images = {};
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.ensName !== undefined && object.ensName !== null) {
+ message.ensName = object.ensName;
+ } else {
+ message.ensName = "";
+ }
+ if (object.images !== undefined && object.images !== null) {
+ Object.entries(object.images).forEach(([key, value]) => {
+ if (value !== undefined) {
+ message.images[key] = IdentityImage.fromPartial(value);
+ }
+ });
+ }
+ if (object.displayName !== undefined && object.displayName !== null) {
+ message.displayName = object.displayName;
+ } else {
+ message.displayName = "";
+ }
+ if (object.description !== undefined && object.description !== null) {
+ message.description = object.description;
+ } else {
+ message.description = "";
+ }
+ if (object.color !== undefined && object.color !== null) {
+ message.color = object.color;
+ } else {
+ message.color = "";
+ }
+ if (object.emoji !== undefined && object.emoji !== null) {
+ message.emoji = object.emoji;
+ } else {
+ message.emoji = "";
+ }
+ return message;
+ },
+};
+
+const baseChatIdentity_ImagesEntry: object = { key: "" };
+
+export const ChatIdentity_ImagesEntry = {
+ encode(
+ message: ChatIdentity_ImagesEntry,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.key !== "") {
+ writer.uint32(10).string(message.key);
+ }
+ if (message.value !== undefined) {
+ IdentityImage.encode(message.value, writer.uint32(18).fork()).ldelim();
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): ChatIdentity_ImagesEntry {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseChatIdentity_ImagesEntry,
+ } as ChatIdentity_ImagesEntry;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.key = reader.string();
+ break;
+ case 2:
+ message.value = IdentityImage.decode(reader, reader.uint32());
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): ChatIdentity_ImagesEntry {
+ const message = {
+ ...baseChatIdentity_ImagesEntry,
+ } as ChatIdentity_ImagesEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = String(object.key);
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = IdentityImage.fromJSON(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+
+ toJSON(message: ChatIdentity_ImagesEntry): unknown {
+ const obj: any = {};
+ message.key !== undefined && (obj.key = message.key);
+ message.value !== undefined &&
+ (obj.value = message.value
+ ? IdentityImage.toJSON(message.value)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): ChatIdentity_ImagesEntry {
+ const message = {
+ ...baseChatIdentity_ImagesEntry,
+ } as ChatIdentity_ImagesEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = object.key;
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = IdentityImage.fromPartial(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+};
+
+const baseIdentityImage: object = { sourceType: 0, imageType: 0 };
+
+export const IdentityImage = {
+ encode(
+ message: IdentityImage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.payload.length !== 0) {
+ writer.uint32(10).bytes(message.payload);
+ }
+ if (message.sourceType !== 0) {
+ writer.uint32(16).int32(message.sourceType);
+ }
+ if (message.imageType !== 0) {
+ writer.uint32(24).int32(message.imageType);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): IdentityImage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseIdentityImage } as IdentityImage;
+ message.payload = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.payload = reader.bytes();
+ break;
+ case 2:
+ message.sourceType = reader.int32() as any;
+ break;
+ case 3:
+ message.imageType = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): IdentityImage {
+ const message = { ...baseIdentityImage } as IdentityImage;
+ message.payload = new Uint8Array();
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = bytesFromBase64(object.payload);
+ }
+ if (object.sourceType !== undefined && object.sourceType !== null) {
+ message.sourceType = identityImage_SourceTypeFromJSON(object.sourceType);
+ } else {
+ message.sourceType = 0;
+ }
+ if (object.imageType !== undefined && object.imageType !== null) {
+ message.imageType = imageTypeFromJSON(object.imageType);
+ } else {
+ message.imageType = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: IdentityImage): unknown {
+ const obj: any = {};
+ message.payload !== undefined &&
+ (obj.payload = base64FromBytes(
+ message.payload !== undefined ? message.payload : new Uint8Array()
+ ));
+ message.sourceType !== undefined &&
+ (obj.sourceType = identityImage_SourceTypeToJSON(message.sourceType));
+ message.imageType !== undefined &&
+ (obj.imageType = imageTypeToJSON(message.imageType));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): IdentityImage {
+ const message = { ...baseIdentityImage } as IdentityImage;
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = object.payload;
+ } else {
+ message.payload = new Uint8Array();
+ }
+ if (object.sourceType !== undefined && object.sourceType !== null) {
+ message.sourceType = object.sourceType;
+ } else {
+ message.sourceType = 0;
+ }
+ if (object.imageType !== undefined && object.imageType !== null) {
+ message.imageType = object.imageType;
+ } else {
+ message.imageType = 0;
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+const atob: (b64: string) => string =
+ globalThis.atob ||
+ ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
+function bytesFromBase64(b64: string): Uint8Array {
+ const bin = atob(b64);
+ const arr = new Uint8Array(bin.length);
+ for (let i = 0; i < bin.length; ++i) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return arr;
+}
+
+const btoa: (bin: string) => string =
+ globalThis.btoa ||
+ ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
+function base64FromBytes(arr: Uint8Array): string {
+ const bin: string[] = [];
+ for (const byte of arr) {
+ bin.push(String.fromCharCode(byte));
+ }
+ return btoa(bin.join(""));
+}
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+function longToNumber(long: Long): number {
+ if (long.gt(Number.MAX_SAFE_INTEGER)) {
+ throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
+ }
+ return long.toNumber();
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/communities/v1/chat_message.ts b/packages/status-core/src/proto/communities/v1/chat_message.ts
new file mode 100644
index 00000000..41adb57b
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/chat_message.ts
@@ -0,0 +1,1105 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+import {
+ ImageType,
+ MessageType,
+ imageTypeFromJSON,
+ imageTypeToJSON,
+ messageTypeFromJSON,
+ messageTypeToJSON,
+} from "../../communities/v1/enums";
+
+export const protobufPackage = "communities.v1";
+
+export interface StickerMessage {
+ hash: string;
+ pack: number;
+}
+
+export interface ImageMessage {
+ payload: Uint8Array;
+ type: ImageType;
+}
+
+export interface AudioMessage {
+ payload: Uint8Array;
+ type: AudioMessage_AudioType;
+ durationMs: number;
+}
+
+export enum AudioMessage_AudioType {
+ AUDIO_TYPE_UNKNOWN_UNSPECIFIED = 0,
+ AUDIO_TYPE_AAC = 1,
+ AUDIO_TYPE_AMR = 2,
+ UNRECOGNIZED = -1,
+}
+
+export function audioMessage_AudioTypeFromJSON(
+ object: any
+): AudioMessage_AudioType {
+ switch (object) {
+ case 0:
+ case "AUDIO_TYPE_UNKNOWN_UNSPECIFIED":
+ return AudioMessage_AudioType.AUDIO_TYPE_UNKNOWN_UNSPECIFIED;
+ case 1:
+ case "AUDIO_TYPE_AAC":
+ return AudioMessage_AudioType.AUDIO_TYPE_AAC;
+ case 2:
+ case "AUDIO_TYPE_AMR":
+ return AudioMessage_AudioType.AUDIO_TYPE_AMR;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return AudioMessage_AudioType.UNRECOGNIZED;
+ }
+}
+
+export function audioMessage_AudioTypeToJSON(
+ object: AudioMessage_AudioType
+): string {
+ switch (object) {
+ case AudioMessage_AudioType.AUDIO_TYPE_UNKNOWN_UNSPECIFIED:
+ return "AUDIO_TYPE_UNKNOWN_UNSPECIFIED";
+ case AudioMessage_AudioType.AUDIO_TYPE_AAC:
+ return "AUDIO_TYPE_AAC";
+ case AudioMessage_AudioType.AUDIO_TYPE_AMR:
+ return "AUDIO_TYPE_AMR";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+export interface EditMessage {
+ clock: number;
+ /** Text of the message */
+ text: string;
+ chatId: string;
+ messageId: string;
+ /** Grant for community edit messages */
+ grant: Uint8Array;
+ /** The type of message (public/one-to-one/private-group-chat) */
+ messageType: MessageType;
+}
+
+export interface DeleteMessage {
+ clock: number;
+ chatId: string;
+ messageId: string;
+ /** Grant for community delete messages */
+ grant: Uint8Array;
+ /** The type of message (public/one-to-one/private-group-chat) */
+ messageType: MessageType;
+}
+
+export interface ChatMessage {
+ /** Lamport timestamp of the chat message */
+ clock: number;
+ /**
+ * Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
+ * so that we don't rely on it
+ */
+ timestamp: number;
+ /** Text of the message */
+ text: string;
+ /** Id of the message that we are replying to */
+ responseTo: string;
+ /** Ens name of the sender */
+ ensName: string;
+ /**
+ * Chat id, this field is symmetric for public-chats and private group chats,
+ * but asymmetric in case of one-to-ones, as the sender will use the chat-id
+ * of the received, while the receiver will use the chat-id of the sender.
+ * Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
+ */
+ chatId: string;
+ /** The type of message (public/one-to-one/private-group-chat) */
+ messageType: MessageType;
+ /** The type of the content of the message */
+ contentType: ChatMessage_ContentType;
+ sticker: StickerMessage | undefined;
+ image: ImageMessage | undefined;
+ audio: AudioMessage | undefined;
+ community: Uint8Array | undefined;
+ /** Grant for community chat messages */
+ grant?: Uint8Array | undefined;
+}
+
+export enum ChatMessage_ContentType {
+ CONTENT_TYPE_UNKNOWN_UNSPECIFIED = 0,
+ CONTENT_TYPE_TEXT_PLAIN = 1,
+ CONTENT_TYPE_STICKER = 2,
+ CONTENT_TYPE_STATUS = 3,
+ CONTENT_TYPE_EMOJI = 4,
+ CONTENT_TYPE_TRANSACTION_COMMAND = 5,
+ /** CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP - Only local */
+ CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP = 6,
+ CONTENT_TYPE_IMAGE = 7,
+ CONTENT_TYPE_AUDIO = 8,
+ CONTENT_TYPE_COMMUNITY = 9,
+ /** CONTENT_TYPE_SYSTEM_MESSAGE_GAP - Only local */
+ CONTENT_TYPE_SYSTEM_MESSAGE_GAP = 10,
+ UNRECOGNIZED = -1,
+}
+
+export function chatMessage_ContentTypeFromJSON(
+ object: any
+): ChatMessage_ContentType {
+ switch (object) {
+ case 0:
+ case "CONTENT_TYPE_UNKNOWN_UNSPECIFIED":
+ return ChatMessage_ContentType.CONTENT_TYPE_UNKNOWN_UNSPECIFIED;
+ case 1:
+ case "CONTENT_TYPE_TEXT_PLAIN":
+ return ChatMessage_ContentType.CONTENT_TYPE_TEXT_PLAIN;
+ case 2:
+ case "CONTENT_TYPE_STICKER":
+ return ChatMessage_ContentType.CONTENT_TYPE_STICKER;
+ case 3:
+ case "CONTENT_TYPE_STATUS":
+ return ChatMessage_ContentType.CONTENT_TYPE_STATUS;
+ case 4:
+ case "CONTENT_TYPE_EMOJI":
+ return ChatMessage_ContentType.CONTENT_TYPE_EMOJI;
+ case 5:
+ case "CONTENT_TYPE_TRANSACTION_COMMAND":
+ return ChatMessage_ContentType.CONTENT_TYPE_TRANSACTION_COMMAND;
+ case 6:
+ case "CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP":
+ return ChatMessage_ContentType.CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP;
+ case 7:
+ case "CONTENT_TYPE_IMAGE":
+ return ChatMessage_ContentType.CONTENT_TYPE_IMAGE;
+ case 8:
+ case "CONTENT_TYPE_AUDIO":
+ return ChatMessage_ContentType.CONTENT_TYPE_AUDIO;
+ case 9:
+ case "CONTENT_TYPE_COMMUNITY":
+ return ChatMessage_ContentType.CONTENT_TYPE_COMMUNITY;
+ case 10:
+ case "CONTENT_TYPE_SYSTEM_MESSAGE_GAP":
+ return ChatMessage_ContentType.CONTENT_TYPE_SYSTEM_MESSAGE_GAP;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return ChatMessage_ContentType.UNRECOGNIZED;
+ }
+}
+
+export function chatMessage_ContentTypeToJSON(
+ object: ChatMessage_ContentType
+): string {
+ switch (object) {
+ case ChatMessage_ContentType.CONTENT_TYPE_UNKNOWN_UNSPECIFIED:
+ return "CONTENT_TYPE_UNKNOWN_UNSPECIFIED";
+ case ChatMessage_ContentType.CONTENT_TYPE_TEXT_PLAIN:
+ return "CONTENT_TYPE_TEXT_PLAIN";
+ case ChatMessage_ContentType.CONTENT_TYPE_STICKER:
+ return "CONTENT_TYPE_STICKER";
+ case ChatMessage_ContentType.CONTENT_TYPE_STATUS:
+ return "CONTENT_TYPE_STATUS";
+ case ChatMessage_ContentType.CONTENT_TYPE_EMOJI:
+ return "CONTENT_TYPE_EMOJI";
+ case ChatMessage_ContentType.CONTENT_TYPE_TRANSACTION_COMMAND:
+ return "CONTENT_TYPE_TRANSACTION_COMMAND";
+ case ChatMessage_ContentType.CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP:
+ return "CONTENT_TYPE_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP";
+ case ChatMessage_ContentType.CONTENT_TYPE_IMAGE:
+ return "CONTENT_TYPE_IMAGE";
+ case ChatMessage_ContentType.CONTENT_TYPE_AUDIO:
+ return "CONTENT_TYPE_AUDIO";
+ case ChatMessage_ContentType.CONTENT_TYPE_COMMUNITY:
+ return "CONTENT_TYPE_COMMUNITY";
+ case ChatMessage_ContentType.CONTENT_TYPE_SYSTEM_MESSAGE_GAP:
+ return "CONTENT_TYPE_SYSTEM_MESSAGE_GAP";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const baseStickerMessage: object = { hash: "", pack: 0 };
+
+export const StickerMessage = {
+ encode(
+ message: StickerMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.hash !== "") {
+ writer.uint32(10).string(message.hash);
+ }
+ if (message.pack !== 0) {
+ writer.uint32(16).int32(message.pack);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): StickerMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseStickerMessage } as StickerMessage;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.hash = reader.string();
+ break;
+ case 2:
+ message.pack = reader.int32();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): StickerMessage {
+ const message = { ...baseStickerMessage } as StickerMessage;
+ if (object.hash !== undefined && object.hash !== null) {
+ message.hash = String(object.hash);
+ } else {
+ message.hash = "";
+ }
+ if (object.pack !== undefined && object.pack !== null) {
+ message.pack = Number(object.pack);
+ } else {
+ message.pack = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: StickerMessage): unknown {
+ const obj: any = {};
+ message.hash !== undefined && (obj.hash = message.hash);
+ message.pack !== undefined && (obj.pack = message.pack);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): StickerMessage {
+ const message = { ...baseStickerMessage } as StickerMessage;
+ if (object.hash !== undefined && object.hash !== null) {
+ message.hash = object.hash;
+ } else {
+ message.hash = "";
+ }
+ if (object.pack !== undefined && object.pack !== null) {
+ message.pack = object.pack;
+ } else {
+ message.pack = 0;
+ }
+ return message;
+ },
+};
+
+const baseImageMessage: object = { type: 0 };
+
+export const ImageMessage = {
+ encode(
+ message: ImageMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.payload.length !== 0) {
+ writer.uint32(10).bytes(message.payload);
+ }
+ if (message.type !== 0) {
+ writer.uint32(16).int32(message.type);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): ImageMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseImageMessage } as ImageMessage;
+ message.payload = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.payload = reader.bytes();
+ break;
+ case 2:
+ message.type = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): ImageMessage {
+ const message = { ...baseImageMessage } as ImageMessage;
+ message.payload = new Uint8Array();
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = bytesFromBase64(object.payload);
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = imageTypeFromJSON(object.type);
+ } else {
+ message.type = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: ImageMessage): unknown {
+ const obj: any = {};
+ message.payload !== undefined &&
+ (obj.payload = base64FromBytes(
+ message.payload !== undefined ? message.payload : new Uint8Array()
+ ));
+ message.type !== undefined && (obj.type = imageTypeToJSON(message.type));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): ImageMessage {
+ const message = { ...baseImageMessage } as ImageMessage;
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = object.payload;
+ } else {
+ message.payload = new Uint8Array();
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = object.type;
+ } else {
+ message.type = 0;
+ }
+ return message;
+ },
+};
+
+const baseAudioMessage: object = { type: 0, durationMs: 0 };
+
+export const AudioMessage = {
+ encode(
+ message: AudioMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.payload.length !== 0) {
+ writer.uint32(10).bytes(message.payload);
+ }
+ if (message.type !== 0) {
+ writer.uint32(16).int32(message.type);
+ }
+ if (message.durationMs !== 0) {
+ writer.uint32(24).uint64(message.durationMs);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): AudioMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseAudioMessage } as AudioMessage;
+ message.payload = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.payload = reader.bytes();
+ break;
+ case 2:
+ message.type = reader.int32() as any;
+ break;
+ case 3:
+ message.durationMs = longToNumber(reader.uint64() as Long);
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): AudioMessage {
+ const message = { ...baseAudioMessage } as AudioMessage;
+ message.payload = new Uint8Array();
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = bytesFromBase64(object.payload);
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = audioMessage_AudioTypeFromJSON(object.type);
+ } else {
+ message.type = 0;
+ }
+ if (object.durationMs !== undefined && object.durationMs !== null) {
+ message.durationMs = Number(object.durationMs);
+ } else {
+ message.durationMs = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: AudioMessage): unknown {
+ const obj: any = {};
+ message.payload !== undefined &&
+ (obj.payload = base64FromBytes(
+ message.payload !== undefined ? message.payload : new Uint8Array()
+ ));
+ message.type !== undefined &&
+ (obj.type = audioMessage_AudioTypeToJSON(message.type));
+ message.durationMs !== undefined && (obj.durationMs = message.durationMs);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): AudioMessage {
+ const message = { ...baseAudioMessage } as AudioMessage;
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = object.payload;
+ } else {
+ message.payload = new Uint8Array();
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = object.type;
+ } else {
+ message.type = 0;
+ }
+ if (object.durationMs !== undefined && object.durationMs !== null) {
+ message.durationMs = object.durationMs;
+ } else {
+ message.durationMs = 0;
+ }
+ return message;
+ },
+};
+
+const baseEditMessage: object = {
+ clock: 0,
+ text: "",
+ chatId: "",
+ messageId: "",
+ messageType: 0,
+};
+
+export const EditMessage = {
+ encode(
+ message: EditMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.text !== "") {
+ writer.uint32(18).string(message.text);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(26).string(message.chatId);
+ }
+ if (message.messageId !== "") {
+ writer.uint32(34).string(message.messageId);
+ }
+ if (message.grant.length !== 0) {
+ writer.uint32(42).bytes(message.grant);
+ }
+ if (message.messageType !== 0) {
+ writer.uint32(48).int32(message.messageType);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): EditMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseEditMessage } as EditMessage;
+ message.grant = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.text = reader.string();
+ break;
+ case 3:
+ message.chatId = reader.string();
+ break;
+ case 4:
+ message.messageId = reader.string();
+ break;
+ case 5:
+ message.grant = reader.bytes();
+ break;
+ case 6:
+ message.messageType = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): EditMessage {
+ const message = { ...baseEditMessage } as EditMessage;
+ message.grant = new Uint8Array();
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.text !== undefined && object.text !== null) {
+ message.text = String(object.text);
+ } else {
+ message.text = "";
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageId !== undefined && object.messageId !== null) {
+ message.messageId = String(object.messageId);
+ } else {
+ message.messageId = "";
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = bytesFromBase64(object.grant);
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = messageTypeFromJSON(object.messageType);
+ } else {
+ message.messageType = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: EditMessage): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.text !== undefined && (obj.text = message.text);
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.messageId !== undefined && (obj.messageId = message.messageId);
+ message.grant !== undefined &&
+ (obj.grant = base64FromBytes(
+ message.grant !== undefined ? message.grant : new Uint8Array()
+ ));
+ message.messageType !== undefined &&
+ (obj.messageType = messageTypeToJSON(message.messageType));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): EditMessage {
+ const message = { ...baseEditMessage } as EditMessage;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.text !== undefined && object.text !== null) {
+ message.text = object.text;
+ } else {
+ message.text = "";
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageId !== undefined && object.messageId !== null) {
+ message.messageId = object.messageId;
+ } else {
+ message.messageId = "";
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = object.grant;
+ } else {
+ message.grant = new Uint8Array();
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = object.messageType;
+ } else {
+ message.messageType = 0;
+ }
+ return message;
+ },
+};
+
+const baseDeleteMessage: object = {
+ clock: 0,
+ chatId: "",
+ messageId: "",
+ messageType: 0,
+};
+
+export const DeleteMessage = {
+ encode(
+ message: DeleteMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(18).string(message.chatId);
+ }
+ if (message.messageId !== "") {
+ writer.uint32(26).string(message.messageId);
+ }
+ if (message.grant.length !== 0) {
+ writer.uint32(34).bytes(message.grant);
+ }
+ if (message.messageType !== 0) {
+ writer.uint32(40).int32(message.messageType);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): DeleteMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseDeleteMessage } as DeleteMessage;
+ message.grant = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.chatId = reader.string();
+ break;
+ case 3:
+ message.messageId = reader.string();
+ break;
+ case 4:
+ message.grant = reader.bytes();
+ break;
+ case 5:
+ message.messageType = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): DeleteMessage {
+ const message = { ...baseDeleteMessage } as DeleteMessage;
+ message.grant = new Uint8Array();
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageId !== undefined && object.messageId !== null) {
+ message.messageId = String(object.messageId);
+ } else {
+ message.messageId = "";
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = bytesFromBase64(object.grant);
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = messageTypeFromJSON(object.messageType);
+ } else {
+ message.messageType = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: DeleteMessage): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.messageId !== undefined && (obj.messageId = message.messageId);
+ message.grant !== undefined &&
+ (obj.grant = base64FromBytes(
+ message.grant !== undefined ? message.grant : new Uint8Array()
+ ));
+ message.messageType !== undefined &&
+ (obj.messageType = messageTypeToJSON(message.messageType));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): DeleteMessage {
+ const message = { ...baseDeleteMessage } as DeleteMessage;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageId !== undefined && object.messageId !== null) {
+ message.messageId = object.messageId;
+ } else {
+ message.messageId = "";
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = object.grant;
+ } else {
+ message.grant = new Uint8Array();
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = object.messageType;
+ } else {
+ message.messageType = 0;
+ }
+ return message;
+ },
+};
+
+const baseChatMessage: object = {
+ clock: 0,
+ timestamp: 0,
+ text: "",
+ responseTo: "",
+ ensName: "",
+ chatId: "",
+ messageType: 0,
+ contentType: 0,
+};
+
+export const ChatMessage = {
+ encode(
+ message: ChatMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.timestamp !== 0) {
+ writer.uint32(16).uint64(message.timestamp);
+ }
+ if (message.text !== "") {
+ writer.uint32(26).string(message.text);
+ }
+ if (message.responseTo !== "") {
+ writer.uint32(34).string(message.responseTo);
+ }
+ if (message.ensName !== "") {
+ writer.uint32(42).string(message.ensName);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(50).string(message.chatId);
+ }
+ if (message.messageType !== 0) {
+ writer.uint32(56).int32(message.messageType);
+ }
+ if (message.contentType !== 0) {
+ writer.uint32(64).int32(message.contentType);
+ }
+ if (message.sticker !== undefined) {
+ StickerMessage.encode(message.sticker, writer.uint32(74).fork()).ldelim();
+ }
+ if (message.image !== undefined) {
+ ImageMessage.encode(message.image, writer.uint32(82).fork()).ldelim();
+ }
+ if (message.audio !== undefined) {
+ AudioMessage.encode(message.audio, writer.uint32(90).fork()).ldelim();
+ }
+ if (message.community !== undefined) {
+ writer.uint32(98).bytes(message.community);
+ }
+ if (message.grant !== undefined) {
+ writer.uint32(106).bytes(message.grant);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): ChatMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseChatMessage } as ChatMessage;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.timestamp = longToNumber(reader.uint64() as Long);
+ break;
+ case 3:
+ message.text = reader.string();
+ break;
+ case 4:
+ message.responseTo = reader.string();
+ break;
+ case 5:
+ message.ensName = reader.string();
+ break;
+ case 6:
+ message.chatId = reader.string();
+ break;
+ case 7:
+ message.messageType = reader.int32() as any;
+ break;
+ case 8:
+ message.contentType = reader.int32() as any;
+ break;
+ case 9:
+ message.sticker = StickerMessage.decode(reader, reader.uint32());
+ break;
+ case 10:
+ message.image = ImageMessage.decode(reader, reader.uint32());
+ break;
+ case 11:
+ message.audio = AudioMessage.decode(reader, reader.uint32());
+ break;
+ case 12:
+ message.community = reader.bytes();
+ break;
+ case 13:
+ message.grant = reader.bytes();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): ChatMessage {
+ const message = { ...baseChatMessage } as ChatMessage;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.timestamp !== undefined && object.timestamp !== null) {
+ message.timestamp = Number(object.timestamp);
+ } else {
+ message.timestamp = 0;
+ }
+ if (object.text !== undefined && object.text !== null) {
+ message.text = String(object.text);
+ } else {
+ message.text = "";
+ }
+ if (object.responseTo !== undefined && object.responseTo !== null) {
+ message.responseTo = String(object.responseTo);
+ } else {
+ message.responseTo = "";
+ }
+ if (object.ensName !== undefined && object.ensName !== null) {
+ message.ensName = String(object.ensName);
+ } else {
+ message.ensName = "";
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = messageTypeFromJSON(object.messageType);
+ } else {
+ message.messageType = 0;
+ }
+ if (object.contentType !== undefined && object.contentType !== null) {
+ message.contentType = chatMessage_ContentTypeFromJSON(object.contentType);
+ } else {
+ message.contentType = 0;
+ }
+ if (object.sticker !== undefined && object.sticker !== null) {
+ message.sticker = StickerMessage.fromJSON(object.sticker);
+ } else {
+ message.sticker = undefined;
+ }
+ if (object.image !== undefined && object.image !== null) {
+ message.image = ImageMessage.fromJSON(object.image);
+ } else {
+ message.image = undefined;
+ }
+ if (object.audio !== undefined && object.audio !== null) {
+ message.audio = AudioMessage.fromJSON(object.audio);
+ } else {
+ message.audio = undefined;
+ }
+ if (object.community !== undefined && object.community !== null) {
+ message.community = bytesFromBase64(object.community);
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = bytesFromBase64(object.grant);
+ }
+ return message;
+ },
+
+ toJSON(message: ChatMessage): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.timestamp !== undefined && (obj.timestamp = message.timestamp);
+ message.text !== undefined && (obj.text = message.text);
+ message.responseTo !== undefined && (obj.responseTo = message.responseTo);
+ message.ensName !== undefined && (obj.ensName = message.ensName);
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.messageType !== undefined &&
+ (obj.messageType = messageTypeToJSON(message.messageType));
+ message.contentType !== undefined &&
+ (obj.contentType = chatMessage_ContentTypeToJSON(message.contentType));
+ message.sticker !== undefined &&
+ (obj.sticker = message.sticker
+ ? StickerMessage.toJSON(message.sticker)
+ : undefined);
+ message.image !== undefined &&
+ (obj.image = message.image
+ ? ImageMessage.toJSON(message.image)
+ : undefined);
+ message.audio !== undefined &&
+ (obj.audio = message.audio
+ ? AudioMessage.toJSON(message.audio)
+ : undefined);
+ message.community !== undefined &&
+ (obj.community =
+ message.community !== undefined
+ ? base64FromBytes(message.community)
+ : undefined);
+ message.grant !== undefined &&
+ (obj.grant =
+ message.grant !== undefined
+ ? base64FromBytes(message.grant)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): ChatMessage {
+ const message = { ...baseChatMessage } as ChatMessage;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.timestamp !== undefined && object.timestamp !== null) {
+ message.timestamp = object.timestamp;
+ } else {
+ message.timestamp = 0;
+ }
+ if (object.text !== undefined && object.text !== null) {
+ message.text = object.text;
+ } else {
+ message.text = "";
+ }
+ if (object.responseTo !== undefined && object.responseTo !== null) {
+ message.responseTo = object.responseTo;
+ } else {
+ message.responseTo = "";
+ }
+ if (object.ensName !== undefined && object.ensName !== null) {
+ message.ensName = object.ensName;
+ } else {
+ message.ensName = "";
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = object.messageType;
+ } else {
+ message.messageType = 0;
+ }
+ if (object.contentType !== undefined && object.contentType !== null) {
+ message.contentType = object.contentType;
+ } else {
+ message.contentType = 0;
+ }
+ if (object.sticker !== undefined && object.sticker !== null) {
+ message.sticker = StickerMessage.fromPartial(object.sticker);
+ } else {
+ message.sticker = undefined;
+ }
+ if (object.image !== undefined && object.image !== null) {
+ message.image = ImageMessage.fromPartial(object.image);
+ } else {
+ message.image = undefined;
+ }
+ if (object.audio !== undefined && object.audio !== null) {
+ message.audio = AudioMessage.fromPartial(object.audio);
+ } else {
+ message.audio = undefined;
+ }
+ if (object.community !== undefined && object.community !== null) {
+ message.community = object.community;
+ } else {
+ message.community = undefined;
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = object.grant;
+ } else {
+ message.grant = undefined;
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+const atob: (b64: string) => string =
+ globalThis.atob ||
+ ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
+function bytesFromBase64(b64: string): Uint8Array {
+ const bin = atob(b64);
+ const arr = new Uint8Array(bin.length);
+ for (let i = 0; i < bin.length; ++i) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return arr;
+}
+
+const btoa: (bin: string) => string =
+ globalThis.btoa ||
+ ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
+function base64FromBytes(arr: Uint8Array): string {
+ const bin: string[] = [];
+ for (const byte of arr) {
+ bin.push(String.fromCharCode(byte));
+ }
+ return btoa(bin.join(""));
+}
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+function longToNumber(long: Long): number {
+ if (long.gt(Number.MAX_SAFE_INTEGER)) {
+ throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
+ }
+ return long.toNumber();
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/communities/v1/communities.ts b/packages/status-core/src/proto/communities/v1/communities.ts
new file mode 100644
index 00000000..aabe78ec
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/communities.ts
@@ -0,0 +1,1768 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+import { ChatIdentity } from "../../communities/v1/chat_identity";
+
+export const protobufPackage = "communities.v1";
+
+export interface Grant {
+ communityId: Uint8Array;
+ memberId: Uint8Array;
+ chatId: string;
+ clock: number;
+}
+
+export interface CommunityMember {
+ roles: CommunityMember_Roles[];
+}
+
+export enum CommunityMember_Roles {
+ UNKNOWN_ROLE = 0,
+ ROLE_ALL = 1,
+ ROLE_MANAGE_USERS = 2,
+ UNRECOGNIZED = -1,
+}
+
+export function communityMember_RolesFromJSON(
+ object: any
+): CommunityMember_Roles {
+ switch (object) {
+ case 0:
+ case "UNKNOWN_ROLE":
+ return CommunityMember_Roles.UNKNOWN_ROLE;
+ case 1:
+ case "ROLE_ALL":
+ return CommunityMember_Roles.ROLE_ALL;
+ case 2:
+ case "ROLE_MANAGE_USERS":
+ return CommunityMember_Roles.ROLE_MANAGE_USERS;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return CommunityMember_Roles.UNRECOGNIZED;
+ }
+}
+
+export function communityMember_RolesToJSON(
+ object: CommunityMember_Roles
+): string {
+ switch (object) {
+ case CommunityMember_Roles.UNKNOWN_ROLE:
+ return "UNKNOWN_ROLE";
+ case CommunityMember_Roles.ROLE_ALL:
+ return "ROLE_ALL";
+ case CommunityMember_Roles.ROLE_MANAGE_USERS:
+ return "ROLE_MANAGE_USERS";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+export interface CommunityPermissions {
+ ensOnly: boolean;
+ /** https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md is a candidate for the algorithm to be used in case we want to have private communityal chats, lighter than pairwise encryption using the DR, less secure, but more efficient for large number of participants */
+ private: boolean;
+ access: CommunityPermissions_Access;
+}
+
+export enum CommunityPermissions_Access {
+ UNKNOWN_ACCESS = 0,
+ NO_MEMBERSHIP = 1,
+ INVITATION_ONLY = 2,
+ ON_REQUEST = 3,
+ UNRECOGNIZED = -1,
+}
+
+export function communityPermissions_AccessFromJSON(
+ object: any
+): CommunityPermissions_Access {
+ switch (object) {
+ case 0:
+ case "UNKNOWN_ACCESS":
+ return CommunityPermissions_Access.UNKNOWN_ACCESS;
+ case 1:
+ case "NO_MEMBERSHIP":
+ return CommunityPermissions_Access.NO_MEMBERSHIP;
+ case 2:
+ case "INVITATION_ONLY":
+ return CommunityPermissions_Access.INVITATION_ONLY;
+ case 3:
+ case "ON_REQUEST":
+ return CommunityPermissions_Access.ON_REQUEST;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return CommunityPermissions_Access.UNRECOGNIZED;
+ }
+}
+
+export function communityPermissions_AccessToJSON(
+ object: CommunityPermissions_Access
+): string {
+ switch (object) {
+ case CommunityPermissions_Access.UNKNOWN_ACCESS:
+ return "UNKNOWN_ACCESS";
+ case CommunityPermissions_Access.NO_MEMBERSHIP:
+ return "NO_MEMBERSHIP";
+ case CommunityPermissions_Access.INVITATION_ONLY:
+ return "INVITATION_ONLY";
+ case CommunityPermissions_Access.ON_REQUEST:
+ return "ON_REQUEST";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+export interface CommunityDescription {
+ clock: number;
+ members: { [key: string]: CommunityMember };
+ permissions: CommunityPermissions | undefined;
+ identity: ChatIdentity | undefined;
+ chats: { [key: string]: CommunityChat };
+ banList: string[];
+ categories: { [key: string]: CommunityCategory };
+}
+
+export interface CommunityDescription_MembersEntry {
+ key: string;
+ value: CommunityMember | undefined;
+}
+
+export interface CommunityDescription_ChatsEntry {
+ key: string;
+ value: CommunityChat | undefined;
+}
+
+export interface CommunityDescription_CategoriesEntry {
+ key: string;
+ value: CommunityCategory | undefined;
+}
+
+export interface CommunityChat {
+ members: { [key: string]: CommunityMember };
+ permissions: CommunityPermissions | undefined;
+ identity: ChatIdentity | undefined;
+ categoryId: string;
+ position: number;
+}
+
+export interface CommunityChat_MembersEntry {
+ key: string;
+ value: CommunityMember | undefined;
+}
+
+export interface CommunityCategory {
+ categoryId: string;
+ name: string;
+ position: number;
+}
+
+export interface CommunityInvitation {
+ communityDescription: Uint8Array;
+ grant: Uint8Array;
+ chatId: string;
+ publicKey: Uint8Array;
+}
+
+export interface CommunityRequestToJoin {
+ clock: number;
+ ensName: string;
+ chatId: string;
+ communityId: Uint8Array;
+}
+
+export interface CommunityRequestToJoinResponse {
+ clock: number;
+ community: CommunityDescription | undefined;
+ accepted: boolean;
+ grant: Uint8Array;
+}
+
+const baseGrant: object = { chatId: "", clock: 0 };
+
+export const Grant = {
+ encode(message: Grant, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
+ if (message.communityId.length !== 0) {
+ writer.uint32(10).bytes(message.communityId);
+ }
+ if (message.memberId.length !== 0) {
+ writer.uint32(18).bytes(message.memberId);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(26).string(message.chatId);
+ }
+ if (message.clock !== 0) {
+ writer.uint32(32).uint64(message.clock);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): Grant {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseGrant } as Grant;
+ message.communityId = new Uint8Array();
+ message.memberId = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.communityId = reader.bytes();
+ break;
+ case 2:
+ message.memberId = reader.bytes();
+ break;
+ case 3:
+ message.chatId = reader.string();
+ break;
+ case 4:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): Grant {
+ const message = { ...baseGrant } as Grant;
+ message.communityId = new Uint8Array();
+ message.memberId = new Uint8Array();
+ if (object.communityId !== undefined && object.communityId !== null) {
+ message.communityId = bytesFromBase64(object.communityId);
+ }
+ if (object.memberId !== undefined && object.memberId !== null) {
+ message.memberId = bytesFromBase64(object.memberId);
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: Grant): unknown {
+ const obj: any = {};
+ message.communityId !== undefined &&
+ (obj.communityId = base64FromBytes(
+ message.communityId !== undefined
+ ? message.communityId
+ : new Uint8Array()
+ ));
+ message.memberId !== undefined &&
+ (obj.memberId = base64FromBytes(
+ message.memberId !== undefined ? message.memberId : new Uint8Array()
+ ));
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.clock !== undefined && (obj.clock = message.clock);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): Grant {
+ const message = { ...baseGrant } as Grant;
+ if (object.communityId !== undefined && object.communityId !== null) {
+ message.communityId = object.communityId;
+ } else {
+ message.communityId = new Uint8Array();
+ }
+ if (object.memberId !== undefined && object.memberId !== null) {
+ message.memberId = object.memberId;
+ } else {
+ message.memberId = new Uint8Array();
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ return message;
+ },
+};
+
+const baseCommunityMember: object = { roles: 0 };
+
+export const CommunityMember = {
+ encode(
+ message: CommunityMember,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ writer.uint32(10).fork();
+ for (const v of message.roles) {
+ writer.int32(v);
+ }
+ writer.ldelim();
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): CommunityMember {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityMember } as CommunityMember;
+ message.roles = [];
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ if ((tag & 7) === 2) {
+ const end2 = reader.uint32() + reader.pos;
+ while (reader.pos < end2) {
+ message.roles.push(reader.int32() as any);
+ }
+ } else {
+ message.roles.push(reader.int32() as any);
+ }
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityMember {
+ const message = { ...baseCommunityMember } as CommunityMember;
+ message.roles = [];
+ if (object.roles !== undefined && object.roles !== null) {
+ for (const e of object.roles) {
+ message.roles.push(communityMember_RolesFromJSON(e));
+ }
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityMember): unknown {
+ const obj: any = {};
+ if (message.roles) {
+ obj.roles = message.roles.map((e) => communityMember_RolesToJSON(e));
+ } else {
+ obj.roles = [];
+ }
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): CommunityMember {
+ const message = { ...baseCommunityMember } as CommunityMember;
+ message.roles = [];
+ if (object.roles !== undefined && object.roles !== null) {
+ for (const e of object.roles) {
+ message.roles.push(e);
+ }
+ }
+ return message;
+ },
+};
+
+const baseCommunityPermissions: object = {
+ ensOnly: false,
+ private: false,
+ access: 0,
+};
+
+export const CommunityPermissions = {
+ encode(
+ message: CommunityPermissions,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.ensOnly === true) {
+ writer.uint32(8).bool(message.ensOnly);
+ }
+ if (message.private === true) {
+ writer.uint32(16).bool(message.private);
+ }
+ if (message.access !== 0) {
+ writer.uint32(24).int32(message.access);
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityPermissions {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityPermissions } as CommunityPermissions;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.ensOnly = reader.bool();
+ break;
+ case 2:
+ message.private = reader.bool();
+ break;
+ case 3:
+ message.access = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityPermissions {
+ const message = { ...baseCommunityPermissions } as CommunityPermissions;
+ if (object.ensOnly !== undefined && object.ensOnly !== null) {
+ message.ensOnly = Boolean(object.ensOnly);
+ } else {
+ message.ensOnly = false;
+ }
+ if (object.private !== undefined && object.private !== null) {
+ message.private = Boolean(object.private);
+ } else {
+ message.private = false;
+ }
+ if (object.access !== undefined && object.access !== null) {
+ message.access = communityPermissions_AccessFromJSON(object.access);
+ } else {
+ message.access = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityPermissions): unknown {
+ const obj: any = {};
+ message.ensOnly !== undefined && (obj.ensOnly = message.ensOnly);
+ message.private !== undefined && (obj.private = message.private);
+ message.access !== undefined &&
+ (obj.access = communityPermissions_AccessToJSON(message.access));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): CommunityPermissions {
+ const message = { ...baseCommunityPermissions } as CommunityPermissions;
+ if (object.ensOnly !== undefined && object.ensOnly !== null) {
+ message.ensOnly = object.ensOnly;
+ } else {
+ message.ensOnly = false;
+ }
+ if (object.private !== undefined && object.private !== null) {
+ message.private = object.private;
+ } else {
+ message.private = false;
+ }
+ if (object.access !== undefined && object.access !== null) {
+ message.access = object.access;
+ } else {
+ message.access = 0;
+ }
+ return message;
+ },
+};
+
+const baseCommunityDescription: object = { clock: 0, banList: "" };
+
+export const CommunityDescription = {
+ encode(
+ message: CommunityDescription,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ Object.entries(message.members).forEach(([key, value]) => {
+ CommunityDescription_MembersEntry.encode(
+ { key: key as any, value },
+ writer.uint32(18).fork()
+ ).ldelim();
+ });
+ if (message.permissions !== undefined) {
+ CommunityPermissions.encode(
+ message.permissions,
+ writer.uint32(26).fork()
+ ).ldelim();
+ }
+ if (message.identity !== undefined) {
+ ChatIdentity.encode(message.identity, writer.uint32(42).fork()).ldelim();
+ }
+ Object.entries(message.chats).forEach(([key, value]) => {
+ CommunityDescription_ChatsEntry.encode(
+ { key: key as any, value },
+ writer.uint32(50).fork()
+ ).ldelim();
+ });
+ for (const v of message.banList) {
+ writer.uint32(58).string(v!);
+ }
+ Object.entries(message.categories).forEach(([key, value]) => {
+ CommunityDescription_CategoriesEntry.encode(
+ { key: key as any, value },
+ writer.uint32(66).fork()
+ ).ldelim();
+ });
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityDescription {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityDescription } as CommunityDescription;
+ message.members = {};
+ message.chats = {};
+ message.banList = [];
+ message.categories = {};
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ const entry2 = CommunityDescription_MembersEntry.decode(
+ reader,
+ reader.uint32()
+ );
+ if (entry2.value !== undefined) {
+ message.members[entry2.key] = entry2.value;
+ }
+ break;
+ case 3:
+ message.permissions = CommunityPermissions.decode(
+ reader,
+ reader.uint32()
+ );
+ break;
+ case 5:
+ message.identity = ChatIdentity.decode(reader, reader.uint32());
+ break;
+ case 6:
+ const entry6 = CommunityDescription_ChatsEntry.decode(
+ reader,
+ reader.uint32()
+ );
+ if (entry6.value !== undefined) {
+ message.chats[entry6.key] = entry6.value;
+ }
+ break;
+ case 7:
+ message.banList.push(reader.string());
+ break;
+ case 8:
+ const entry8 = CommunityDescription_CategoriesEntry.decode(
+ reader,
+ reader.uint32()
+ );
+ if (entry8.value !== undefined) {
+ message.categories[entry8.key] = entry8.value;
+ }
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityDescription {
+ const message = { ...baseCommunityDescription } as CommunityDescription;
+ message.members = {};
+ message.chats = {};
+ message.banList = [];
+ message.categories = {};
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.members !== undefined && object.members !== null) {
+ Object.entries(object.members).forEach(([key, value]) => {
+ message.members[key] = CommunityMember.fromJSON(value);
+ });
+ }
+ if (object.permissions !== undefined && object.permissions !== null) {
+ message.permissions = CommunityPermissions.fromJSON(object.permissions);
+ } else {
+ message.permissions = undefined;
+ }
+ if (object.identity !== undefined && object.identity !== null) {
+ message.identity = ChatIdentity.fromJSON(object.identity);
+ } else {
+ message.identity = undefined;
+ }
+ if (object.chats !== undefined && object.chats !== null) {
+ Object.entries(object.chats).forEach(([key, value]) => {
+ message.chats[key] = CommunityChat.fromJSON(value);
+ });
+ }
+ if (object.banList !== undefined && object.banList !== null) {
+ for (const e of object.banList) {
+ message.banList.push(String(e));
+ }
+ }
+ if (object.categories !== undefined && object.categories !== null) {
+ Object.entries(object.categories).forEach(([key, value]) => {
+ message.categories[key] = CommunityCategory.fromJSON(value);
+ });
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityDescription): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ obj.members = {};
+ if (message.members) {
+ Object.entries(message.members).forEach(([k, v]) => {
+ obj.members[k] = CommunityMember.toJSON(v);
+ });
+ }
+ message.permissions !== undefined &&
+ (obj.permissions = message.permissions
+ ? CommunityPermissions.toJSON(message.permissions)
+ : undefined);
+ message.identity !== undefined &&
+ (obj.identity = message.identity
+ ? ChatIdentity.toJSON(message.identity)
+ : undefined);
+ obj.chats = {};
+ if (message.chats) {
+ Object.entries(message.chats).forEach(([k, v]) => {
+ obj.chats[k] = CommunityChat.toJSON(v);
+ });
+ }
+ if (message.banList) {
+ obj.banList = message.banList.map((e) => e);
+ } else {
+ obj.banList = [];
+ }
+ obj.categories = {};
+ if (message.categories) {
+ Object.entries(message.categories).forEach(([k, v]) => {
+ obj.categories[k] = CommunityCategory.toJSON(v);
+ });
+ }
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): CommunityDescription {
+ const message = { ...baseCommunityDescription } as CommunityDescription;
+ message.members = {};
+ message.chats = {};
+ message.banList = [];
+ message.categories = {};
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.members !== undefined && object.members !== null) {
+ Object.entries(object.members).forEach(([key, value]) => {
+ if (value !== undefined) {
+ message.members[key] = CommunityMember.fromPartial(value);
+ }
+ });
+ }
+ if (object.permissions !== undefined && object.permissions !== null) {
+ message.permissions = CommunityPermissions.fromPartial(
+ object.permissions
+ );
+ } else {
+ message.permissions = undefined;
+ }
+ if (object.identity !== undefined && object.identity !== null) {
+ message.identity = ChatIdentity.fromPartial(object.identity);
+ } else {
+ message.identity = undefined;
+ }
+ if (object.chats !== undefined && object.chats !== null) {
+ Object.entries(object.chats).forEach(([key, value]) => {
+ if (value !== undefined) {
+ message.chats[key] = CommunityChat.fromPartial(value);
+ }
+ });
+ }
+ if (object.banList !== undefined && object.banList !== null) {
+ for (const e of object.banList) {
+ message.banList.push(e);
+ }
+ }
+ if (object.categories !== undefined && object.categories !== null) {
+ Object.entries(object.categories).forEach(([key, value]) => {
+ if (value !== undefined) {
+ message.categories[key] = CommunityCategory.fromPartial(value);
+ }
+ });
+ }
+ return message;
+ },
+};
+
+const baseCommunityDescription_MembersEntry: object = { key: "" };
+
+export const CommunityDescription_MembersEntry = {
+ encode(
+ message: CommunityDescription_MembersEntry,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.key !== "") {
+ writer.uint32(10).string(message.key);
+ }
+ if (message.value !== undefined) {
+ CommunityMember.encode(message.value, writer.uint32(18).fork()).ldelim();
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityDescription_MembersEntry {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseCommunityDescription_MembersEntry,
+ } as CommunityDescription_MembersEntry;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.key = reader.string();
+ break;
+ case 2:
+ message.value = CommunityMember.decode(reader, reader.uint32());
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityDescription_MembersEntry {
+ const message = {
+ ...baseCommunityDescription_MembersEntry,
+ } as CommunityDescription_MembersEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = String(object.key);
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityMember.fromJSON(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityDescription_MembersEntry): unknown {
+ const obj: any = {};
+ message.key !== undefined && (obj.key = message.key);
+ message.value !== undefined &&
+ (obj.value = message.value
+ ? CommunityMember.toJSON(message.value)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): CommunityDescription_MembersEntry {
+ const message = {
+ ...baseCommunityDescription_MembersEntry,
+ } as CommunityDescription_MembersEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = object.key;
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityMember.fromPartial(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+};
+
+const baseCommunityDescription_ChatsEntry: object = { key: "" };
+
+export const CommunityDescription_ChatsEntry = {
+ encode(
+ message: CommunityDescription_ChatsEntry,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.key !== "") {
+ writer.uint32(10).string(message.key);
+ }
+ if (message.value !== undefined) {
+ CommunityChat.encode(message.value, writer.uint32(18).fork()).ldelim();
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityDescription_ChatsEntry {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseCommunityDescription_ChatsEntry,
+ } as CommunityDescription_ChatsEntry;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.key = reader.string();
+ break;
+ case 2:
+ message.value = CommunityChat.decode(reader, reader.uint32());
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityDescription_ChatsEntry {
+ const message = {
+ ...baseCommunityDescription_ChatsEntry,
+ } as CommunityDescription_ChatsEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = String(object.key);
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityChat.fromJSON(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityDescription_ChatsEntry): unknown {
+ const obj: any = {};
+ message.key !== undefined && (obj.key = message.key);
+ message.value !== undefined &&
+ (obj.value = message.value
+ ? CommunityChat.toJSON(message.value)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): CommunityDescription_ChatsEntry {
+ const message = {
+ ...baseCommunityDescription_ChatsEntry,
+ } as CommunityDescription_ChatsEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = object.key;
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityChat.fromPartial(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+};
+
+const baseCommunityDescription_CategoriesEntry: object = { key: "" };
+
+export const CommunityDescription_CategoriesEntry = {
+ encode(
+ message: CommunityDescription_CategoriesEntry,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.key !== "") {
+ writer.uint32(10).string(message.key);
+ }
+ if (message.value !== undefined) {
+ CommunityCategory.encode(
+ message.value,
+ writer.uint32(18).fork()
+ ).ldelim();
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityDescription_CategoriesEntry {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseCommunityDescription_CategoriesEntry,
+ } as CommunityDescription_CategoriesEntry;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.key = reader.string();
+ break;
+ case 2:
+ message.value = CommunityCategory.decode(reader, reader.uint32());
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityDescription_CategoriesEntry {
+ const message = {
+ ...baseCommunityDescription_CategoriesEntry,
+ } as CommunityDescription_CategoriesEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = String(object.key);
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityCategory.fromJSON(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityDescription_CategoriesEntry): unknown {
+ const obj: any = {};
+ message.key !== undefined && (obj.key = message.key);
+ message.value !== undefined &&
+ (obj.value = message.value
+ ? CommunityCategory.toJSON(message.value)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): CommunityDescription_CategoriesEntry {
+ const message = {
+ ...baseCommunityDescription_CategoriesEntry,
+ } as CommunityDescription_CategoriesEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = object.key;
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityCategory.fromPartial(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+};
+
+const baseCommunityChat: object = { categoryId: "", position: 0 };
+
+export const CommunityChat = {
+ encode(
+ message: CommunityChat,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ Object.entries(message.members).forEach(([key, value]) => {
+ CommunityChat_MembersEntry.encode(
+ { key: key as any, value },
+ writer.uint32(10).fork()
+ ).ldelim();
+ });
+ if (message.permissions !== undefined) {
+ CommunityPermissions.encode(
+ message.permissions,
+ writer.uint32(18).fork()
+ ).ldelim();
+ }
+ if (message.identity !== undefined) {
+ ChatIdentity.encode(message.identity, writer.uint32(26).fork()).ldelim();
+ }
+ if (message.categoryId !== "") {
+ writer.uint32(34).string(message.categoryId);
+ }
+ if (message.position !== 0) {
+ writer.uint32(40).int32(message.position);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): CommunityChat {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityChat } as CommunityChat;
+ message.members = {};
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ const entry1 = CommunityChat_MembersEntry.decode(
+ reader,
+ reader.uint32()
+ );
+ if (entry1.value !== undefined) {
+ message.members[entry1.key] = entry1.value;
+ }
+ break;
+ case 2:
+ message.permissions = CommunityPermissions.decode(
+ reader,
+ reader.uint32()
+ );
+ break;
+ case 3:
+ message.identity = ChatIdentity.decode(reader, reader.uint32());
+ break;
+ case 4:
+ message.categoryId = reader.string();
+ break;
+ case 5:
+ message.position = reader.int32();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityChat {
+ const message = { ...baseCommunityChat } as CommunityChat;
+ message.members = {};
+ if (object.members !== undefined && object.members !== null) {
+ Object.entries(object.members).forEach(([key, value]) => {
+ message.members[key] = CommunityMember.fromJSON(value);
+ });
+ }
+ if (object.permissions !== undefined && object.permissions !== null) {
+ message.permissions = CommunityPermissions.fromJSON(object.permissions);
+ } else {
+ message.permissions = undefined;
+ }
+ if (object.identity !== undefined && object.identity !== null) {
+ message.identity = ChatIdentity.fromJSON(object.identity);
+ } else {
+ message.identity = undefined;
+ }
+ if (object.categoryId !== undefined && object.categoryId !== null) {
+ message.categoryId = String(object.categoryId);
+ } else {
+ message.categoryId = "";
+ }
+ if (object.position !== undefined && object.position !== null) {
+ message.position = Number(object.position);
+ } else {
+ message.position = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityChat): unknown {
+ const obj: any = {};
+ obj.members = {};
+ if (message.members) {
+ Object.entries(message.members).forEach(([k, v]) => {
+ obj.members[k] = CommunityMember.toJSON(v);
+ });
+ }
+ message.permissions !== undefined &&
+ (obj.permissions = message.permissions
+ ? CommunityPermissions.toJSON(message.permissions)
+ : undefined);
+ message.identity !== undefined &&
+ (obj.identity = message.identity
+ ? ChatIdentity.toJSON(message.identity)
+ : undefined);
+ message.categoryId !== undefined && (obj.categoryId = message.categoryId);
+ message.position !== undefined && (obj.position = message.position);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): CommunityChat {
+ const message = { ...baseCommunityChat } as CommunityChat;
+ message.members = {};
+ if (object.members !== undefined && object.members !== null) {
+ Object.entries(object.members).forEach(([key, value]) => {
+ if (value !== undefined) {
+ message.members[key] = CommunityMember.fromPartial(value);
+ }
+ });
+ }
+ if (object.permissions !== undefined && object.permissions !== null) {
+ message.permissions = CommunityPermissions.fromPartial(
+ object.permissions
+ );
+ } else {
+ message.permissions = undefined;
+ }
+ if (object.identity !== undefined && object.identity !== null) {
+ message.identity = ChatIdentity.fromPartial(object.identity);
+ } else {
+ message.identity = undefined;
+ }
+ if (object.categoryId !== undefined && object.categoryId !== null) {
+ message.categoryId = object.categoryId;
+ } else {
+ message.categoryId = "";
+ }
+ if (object.position !== undefined && object.position !== null) {
+ message.position = object.position;
+ } else {
+ message.position = 0;
+ }
+ return message;
+ },
+};
+
+const baseCommunityChat_MembersEntry: object = { key: "" };
+
+export const CommunityChat_MembersEntry = {
+ encode(
+ message: CommunityChat_MembersEntry,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.key !== "") {
+ writer.uint32(10).string(message.key);
+ }
+ if (message.value !== undefined) {
+ CommunityMember.encode(message.value, writer.uint32(18).fork()).ldelim();
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityChat_MembersEntry {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseCommunityChat_MembersEntry,
+ } as CommunityChat_MembersEntry;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.key = reader.string();
+ break;
+ case 2:
+ message.value = CommunityMember.decode(reader, reader.uint32());
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityChat_MembersEntry {
+ const message = {
+ ...baseCommunityChat_MembersEntry,
+ } as CommunityChat_MembersEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = String(object.key);
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityMember.fromJSON(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityChat_MembersEntry): unknown {
+ const obj: any = {};
+ message.key !== undefined && (obj.key = message.key);
+ message.value !== undefined &&
+ (obj.value = message.value
+ ? CommunityMember.toJSON(message.value)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): CommunityChat_MembersEntry {
+ const message = {
+ ...baseCommunityChat_MembersEntry,
+ } as CommunityChat_MembersEntry;
+ if (object.key !== undefined && object.key !== null) {
+ message.key = object.key;
+ } else {
+ message.key = "";
+ }
+ if (object.value !== undefined && object.value !== null) {
+ message.value = CommunityMember.fromPartial(object.value);
+ } else {
+ message.value = undefined;
+ }
+ return message;
+ },
+};
+
+const baseCommunityCategory: object = { categoryId: "", name: "", position: 0 };
+
+export const CommunityCategory = {
+ encode(
+ message: CommunityCategory,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.categoryId !== "") {
+ writer.uint32(10).string(message.categoryId);
+ }
+ if (message.name !== "") {
+ writer.uint32(18).string(message.name);
+ }
+ if (message.position !== 0) {
+ writer.uint32(24).int32(message.position);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): CommunityCategory {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityCategory } as CommunityCategory;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.categoryId = reader.string();
+ break;
+ case 2:
+ message.name = reader.string();
+ break;
+ case 3:
+ message.position = reader.int32();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityCategory {
+ const message = { ...baseCommunityCategory } as CommunityCategory;
+ if (object.categoryId !== undefined && object.categoryId !== null) {
+ message.categoryId = String(object.categoryId);
+ } else {
+ message.categoryId = "";
+ }
+ if (object.name !== undefined && object.name !== null) {
+ message.name = String(object.name);
+ } else {
+ message.name = "";
+ }
+ if (object.position !== undefined && object.position !== null) {
+ message.position = Number(object.position);
+ } else {
+ message.position = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityCategory): unknown {
+ const obj: any = {};
+ message.categoryId !== undefined && (obj.categoryId = message.categoryId);
+ message.name !== undefined && (obj.name = message.name);
+ message.position !== undefined && (obj.position = message.position);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): CommunityCategory {
+ const message = { ...baseCommunityCategory } as CommunityCategory;
+ if (object.categoryId !== undefined && object.categoryId !== null) {
+ message.categoryId = object.categoryId;
+ } else {
+ message.categoryId = "";
+ }
+ if (object.name !== undefined && object.name !== null) {
+ message.name = object.name;
+ } else {
+ message.name = "";
+ }
+ if (object.position !== undefined && object.position !== null) {
+ message.position = object.position;
+ } else {
+ message.position = 0;
+ }
+ return message;
+ },
+};
+
+const baseCommunityInvitation: object = { chatId: "" };
+
+export const CommunityInvitation = {
+ encode(
+ message: CommunityInvitation,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.communityDescription.length !== 0) {
+ writer.uint32(10).bytes(message.communityDescription);
+ }
+ if (message.grant.length !== 0) {
+ writer.uint32(18).bytes(message.grant);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(26).string(message.chatId);
+ }
+ if (message.publicKey.length !== 0) {
+ writer.uint32(34).bytes(message.publicKey);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): CommunityInvitation {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityInvitation } as CommunityInvitation;
+ message.communityDescription = new Uint8Array();
+ message.grant = new Uint8Array();
+ message.publicKey = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.communityDescription = reader.bytes();
+ break;
+ case 2:
+ message.grant = reader.bytes();
+ break;
+ case 3:
+ message.chatId = reader.string();
+ break;
+ case 4:
+ message.publicKey = reader.bytes();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityInvitation {
+ const message = { ...baseCommunityInvitation } as CommunityInvitation;
+ message.communityDescription = new Uint8Array();
+ message.grant = new Uint8Array();
+ message.publicKey = new Uint8Array();
+ if (
+ object.communityDescription !== undefined &&
+ object.communityDescription !== null
+ ) {
+ message.communityDescription = bytesFromBase64(
+ object.communityDescription
+ );
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = bytesFromBase64(object.grant);
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.publicKey !== undefined && object.publicKey !== null) {
+ message.publicKey = bytesFromBase64(object.publicKey);
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityInvitation): unknown {
+ const obj: any = {};
+ message.communityDescription !== undefined &&
+ (obj.communityDescription = base64FromBytes(
+ message.communityDescription !== undefined
+ ? message.communityDescription
+ : new Uint8Array()
+ ));
+ message.grant !== undefined &&
+ (obj.grant = base64FromBytes(
+ message.grant !== undefined ? message.grant : new Uint8Array()
+ ));
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.publicKey !== undefined &&
+ (obj.publicKey = base64FromBytes(
+ message.publicKey !== undefined ? message.publicKey : new Uint8Array()
+ ));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): CommunityInvitation {
+ const message = { ...baseCommunityInvitation } as CommunityInvitation;
+ if (
+ object.communityDescription !== undefined &&
+ object.communityDescription !== null
+ ) {
+ message.communityDescription = object.communityDescription;
+ } else {
+ message.communityDescription = new Uint8Array();
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = object.grant;
+ } else {
+ message.grant = new Uint8Array();
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.publicKey !== undefined && object.publicKey !== null) {
+ message.publicKey = object.publicKey;
+ } else {
+ message.publicKey = new Uint8Array();
+ }
+ return message;
+ },
+};
+
+const baseCommunityRequestToJoin: object = {
+ clock: 0,
+ ensName: "",
+ chatId: "",
+};
+
+export const CommunityRequestToJoin = {
+ encode(
+ message: CommunityRequestToJoin,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.ensName !== "") {
+ writer.uint32(18).string(message.ensName);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(26).string(message.chatId);
+ }
+ if (message.communityId.length !== 0) {
+ writer.uint32(34).bytes(message.communityId);
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityRequestToJoin {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseCommunityRequestToJoin } as CommunityRequestToJoin;
+ message.communityId = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.ensName = reader.string();
+ break;
+ case 3:
+ message.chatId = reader.string();
+ break;
+ case 4:
+ message.communityId = reader.bytes();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityRequestToJoin {
+ const message = { ...baseCommunityRequestToJoin } as CommunityRequestToJoin;
+ message.communityId = new Uint8Array();
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.ensName !== undefined && object.ensName !== null) {
+ message.ensName = String(object.ensName);
+ } else {
+ message.ensName = "";
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.communityId !== undefined && object.communityId !== null) {
+ message.communityId = bytesFromBase64(object.communityId);
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityRequestToJoin): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.ensName !== undefined && (obj.ensName = message.ensName);
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.communityId !== undefined &&
+ (obj.communityId = base64FromBytes(
+ message.communityId !== undefined
+ ? message.communityId
+ : new Uint8Array()
+ ));
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): CommunityRequestToJoin {
+ const message = { ...baseCommunityRequestToJoin } as CommunityRequestToJoin;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.ensName !== undefined && object.ensName !== null) {
+ message.ensName = object.ensName;
+ } else {
+ message.ensName = "";
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.communityId !== undefined && object.communityId !== null) {
+ message.communityId = object.communityId;
+ } else {
+ message.communityId = new Uint8Array();
+ }
+ return message;
+ },
+};
+
+const baseCommunityRequestToJoinResponse: object = {
+ clock: 0,
+ accepted: false,
+};
+
+export const CommunityRequestToJoinResponse = {
+ encode(
+ message: CommunityRequestToJoinResponse,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.community !== undefined) {
+ CommunityDescription.encode(
+ message.community,
+ writer.uint32(18).fork()
+ ).ldelim();
+ }
+ if (message.accepted === true) {
+ writer.uint32(24).bool(message.accepted);
+ }
+ if (message.grant.length !== 0) {
+ writer.uint32(34).bytes(message.grant);
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): CommunityRequestToJoinResponse {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseCommunityRequestToJoinResponse,
+ } as CommunityRequestToJoinResponse;
+ message.grant = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.community = CommunityDescription.decode(
+ reader,
+ reader.uint32()
+ );
+ break;
+ case 3:
+ message.accepted = reader.bool();
+ break;
+ case 4:
+ message.grant = reader.bytes();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): CommunityRequestToJoinResponse {
+ const message = {
+ ...baseCommunityRequestToJoinResponse,
+ } as CommunityRequestToJoinResponse;
+ message.grant = new Uint8Array();
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.community !== undefined && object.community !== null) {
+ message.community = CommunityDescription.fromJSON(object.community);
+ } else {
+ message.community = undefined;
+ }
+ if (object.accepted !== undefined && object.accepted !== null) {
+ message.accepted = Boolean(object.accepted);
+ } else {
+ message.accepted = false;
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = bytesFromBase64(object.grant);
+ }
+ return message;
+ },
+
+ toJSON(message: CommunityRequestToJoinResponse): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.community !== undefined &&
+ (obj.community = message.community
+ ? CommunityDescription.toJSON(message.community)
+ : undefined);
+ message.accepted !== undefined && (obj.accepted = message.accepted);
+ message.grant !== undefined &&
+ (obj.grant = base64FromBytes(
+ message.grant !== undefined ? message.grant : new Uint8Array()
+ ));
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): CommunityRequestToJoinResponse {
+ const message = {
+ ...baseCommunityRequestToJoinResponse,
+ } as CommunityRequestToJoinResponse;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.community !== undefined && object.community !== null) {
+ message.community = CommunityDescription.fromPartial(object.community);
+ } else {
+ message.community = undefined;
+ }
+ if (object.accepted !== undefined && object.accepted !== null) {
+ message.accepted = object.accepted;
+ } else {
+ message.accepted = false;
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = object.grant;
+ } else {
+ message.grant = new Uint8Array();
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+const atob: (b64: string) => string =
+ globalThis.atob ||
+ ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
+function bytesFromBase64(b64: string): Uint8Array {
+ const bin = atob(b64);
+ const arr = new Uint8Array(bin.length);
+ for (let i = 0; i < bin.length; ++i) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return arr;
+}
+
+const btoa: (bin: string) => string =
+ globalThis.btoa ||
+ ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
+function base64FromBytes(arr: Uint8Array): string {
+ const bin: string[] = [];
+ for (const byte of arr) {
+ bin.push(String.fromCharCode(byte));
+ }
+ return btoa(bin.join(""));
+}
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+function longToNumber(long: Long): number {
+ if (long.gt(Number.MAX_SAFE_INTEGER)) {
+ throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
+ }
+ return long.toNumber();
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/communities/v1/emoji_reaction.ts b/packages/status-core/src/proto/communities/v1/emoji_reaction.ts
new file mode 100644
index 00000000..9a4ec13c
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/emoji_reaction.ts
@@ -0,0 +1,328 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+import {
+ MessageType,
+ messageTypeFromJSON,
+ messageTypeToJSON,
+} from "../../communities/v1/enums";
+
+export const protobufPackage = "communities.v1";
+
+export interface EmojiReaction {
+ /** clock Lamport timestamp of the chat message */
+ clock: number;
+ /**
+ * chat_id the ID of the chat the message belongs to, for query efficiency the chat_id is stored in the db even though the
+ * target message also stores the chat_id
+ */
+ chatId: string;
+ /** message_id the ID of the target message that the user wishes to react to */
+ messageId: string;
+ /** message_type is (somewhat confusingly) the ID of the type of chat the message belongs to */
+ messageType: MessageType;
+ /** type the ID of the emoji the user wishes to react with */
+ type: EmojiReaction_Type;
+ /** whether this is a rectraction of a previously sent emoji */
+ retracted: boolean;
+ /** Grant for organisation chat messages */
+ grant: Uint8Array;
+}
+
+export enum EmojiReaction_Type {
+ UNKNOWN_EMOJI_REACTION_TYPE = 0,
+ LOVE = 1,
+ THUMBS_UP = 2,
+ THUMBS_DOWN = 3,
+ LAUGH = 4,
+ SAD = 5,
+ ANGRY = 6,
+ UNRECOGNIZED = -1,
+}
+
+export function emojiReaction_TypeFromJSON(object: any): EmojiReaction_Type {
+ switch (object) {
+ case 0:
+ case "UNKNOWN_EMOJI_REACTION_TYPE":
+ return EmojiReaction_Type.UNKNOWN_EMOJI_REACTION_TYPE;
+ case 1:
+ case "LOVE":
+ return EmojiReaction_Type.LOVE;
+ case 2:
+ case "THUMBS_UP":
+ return EmojiReaction_Type.THUMBS_UP;
+ case 3:
+ case "THUMBS_DOWN":
+ return EmojiReaction_Type.THUMBS_DOWN;
+ case 4:
+ case "LAUGH":
+ return EmojiReaction_Type.LAUGH;
+ case 5:
+ case "SAD":
+ return EmojiReaction_Type.SAD;
+ case 6:
+ case "ANGRY":
+ return EmojiReaction_Type.ANGRY;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return EmojiReaction_Type.UNRECOGNIZED;
+ }
+}
+
+export function emojiReaction_TypeToJSON(object: EmojiReaction_Type): string {
+ switch (object) {
+ case EmojiReaction_Type.UNKNOWN_EMOJI_REACTION_TYPE:
+ return "UNKNOWN_EMOJI_REACTION_TYPE";
+ case EmojiReaction_Type.LOVE:
+ return "LOVE";
+ case EmojiReaction_Type.THUMBS_UP:
+ return "THUMBS_UP";
+ case EmojiReaction_Type.THUMBS_DOWN:
+ return "THUMBS_DOWN";
+ case EmojiReaction_Type.LAUGH:
+ return "LAUGH";
+ case EmojiReaction_Type.SAD:
+ return "SAD";
+ case EmojiReaction_Type.ANGRY:
+ return "ANGRY";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const baseEmojiReaction: object = {
+ clock: 0,
+ chatId: "",
+ messageId: "",
+ messageType: 0,
+ type: 0,
+ retracted: false,
+};
+
+export const EmojiReaction = {
+ encode(
+ message: EmojiReaction,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.chatId !== "") {
+ writer.uint32(18).string(message.chatId);
+ }
+ if (message.messageId !== "") {
+ writer.uint32(26).string(message.messageId);
+ }
+ if (message.messageType !== 0) {
+ writer.uint32(32).int32(message.messageType);
+ }
+ if (message.type !== 0) {
+ writer.uint32(40).int32(message.type);
+ }
+ if (message.retracted === true) {
+ writer.uint32(48).bool(message.retracted);
+ }
+ if (message.grant.length !== 0) {
+ writer.uint32(58).bytes(message.grant);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): EmojiReaction {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseEmojiReaction } as EmojiReaction;
+ message.grant = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.chatId = reader.string();
+ break;
+ case 3:
+ message.messageId = reader.string();
+ break;
+ case 4:
+ message.messageType = reader.int32() as any;
+ break;
+ case 5:
+ message.type = reader.int32() as any;
+ break;
+ case 6:
+ message.retracted = reader.bool();
+ break;
+ case 7:
+ message.grant = reader.bytes();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): EmojiReaction {
+ const message = { ...baseEmojiReaction } as EmojiReaction;
+ message.grant = new Uint8Array();
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageId !== undefined && object.messageId !== null) {
+ message.messageId = String(object.messageId);
+ } else {
+ message.messageId = "";
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = messageTypeFromJSON(object.messageType);
+ } else {
+ message.messageType = 0;
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = emojiReaction_TypeFromJSON(object.type);
+ } else {
+ message.type = 0;
+ }
+ if (object.retracted !== undefined && object.retracted !== null) {
+ message.retracted = Boolean(object.retracted);
+ } else {
+ message.retracted = false;
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = bytesFromBase64(object.grant);
+ }
+ return message;
+ },
+
+ toJSON(message: EmojiReaction): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ message.messageId !== undefined && (obj.messageId = message.messageId);
+ message.messageType !== undefined &&
+ (obj.messageType = messageTypeToJSON(message.messageType));
+ message.type !== undefined &&
+ (obj.type = emojiReaction_TypeToJSON(message.type));
+ message.retracted !== undefined && (obj.retracted = message.retracted);
+ message.grant !== undefined &&
+ (obj.grant = base64FromBytes(
+ message.grant !== undefined ? message.grant : new Uint8Array()
+ ));
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): EmojiReaction {
+ const message = { ...baseEmojiReaction } as EmojiReaction;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.messageId !== undefined && object.messageId !== null) {
+ message.messageId = object.messageId;
+ } else {
+ message.messageId = "";
+ }
+ if (object.messageType !== undefined && object.messageType !== null) {
+ message.messageType = object.messageType;
+ } else {
+ message.messageType = 0;
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = object.type;
+ } else {
+ message.type = 0;
+ }
+ if (object.retracted !== undefined && object.retracted !== null) {
+ message.retracted = object.retracted;
+ } else {
+ message.retracted = false;
+ }
+ if (object.grant !== undefined && object.grant !== null) {
+ message.grant = object.grant;
+ } else {
+ message.grant = new Uint8Array();
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+const atob: (b64: string) => string =
+ globalThis.atob ||
+ ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
+function bytesFromBase64(b64: string): Uint8Array {
+ const bin = atob(b64);
+ const arr = new Uint8Array(bin.length);
+ for (let i = 0; i < bin.length; ++i) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return arr;
+}
+
+const btoa: (bin: string) => string =
+ globalThis.btoa ||
+ ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
+function base64FromBytes(arr: Uint8Array): string {
+ const bin: string[] = [];
+ for (const byte of arr) {
+ bin.push(String.fromCharCode(byte));
+ }
+ return btoa(bin.join(""));
+}
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+function longToNumber(long: Long): number {
+ if (long.gt(Number.MAX_SAFE_INTEGER)) {
+ throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
+ }
+ return long.toNumber();
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/communities/v1/enums.ts b/packages/status-core/src/proto/communities/v1/enums.ts
new file mode 100644
index 00000000..ee21d817
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/enums.ts
@@ -0,0 +1,125 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+
+export const protobufPackage = "communities.v1";
+
+export enum MessageType {
+ MESSAGE_TYPE_UNKNOWN_UNSPECIFIED = 0,
+ MESSAGE_TYPE_ONE_TO_ONE = 1,
+ MESSAGE_TYPE_MESSAGE_TYPE_PUBLIC_GROUP = 2,
+ MESSAGE_TYPE_PRIVATE_GROUP = 3,
+ /** MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP - Only local */
+ MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP = 4,
+ MESSAGE_TYPE_COMMUNITY_CHAT = 5,
+ /** MESSAGE_TYPE_SYSTEM_MESSAGE_GAP - Only local */
+ MESSAGE_TYPE_SYSTEM_MESSAGE_GAP = 6,
+ UNRECOGNIZED = -1,
+}
+
+export function messageTypeFromJSON(object: any): MessageType {
+ switch (object) {
+ case 0:
+ case "MESSAGE_TYPE_UNKNOWN_UNSPECIFIED":
+ return MessageType.MESSAGE_TYPE_UNKNOWN_UNSPECIFIED;
+ case 1:
+ case "MESSAGE_TYPE_ONE_TO_ONE":
+ return MessageType.MESSAGE_TYPE_ONE_TO_ONE;
+ case 2:
+ case "MESSAGE_TYPE_MESSAGE_TYPE_PUBLIC_GROUP":
+ return MessageType.MESSAGE_TYPE_MESSAGE_TYPE_PUBLIC_GROUP;
+ case 3:
+ case "MESSAGE_TYPE_PRIVATE_GROUP":
+ return MessageType.MESSAGE_TYPE_PRIVATE_GROUP;
+ case 4:
+ case "MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP":
+ return MessageType.MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP;
+ case 5:
+ case "MESSAGE_TYPE_COMMUNITY_CHAT":
+ return MessageType.MESSAGE_TYPE_COMMUNITY_CHAT;
+ case 6:
+ case "MESSAGE_TYPE_SYSTEM_MESSAGE_GAP":
+ return MessageType.MESSAGE_TYPE_SYSTEM_MESSAGE_GAP;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return MessageType.UNRECOGNIZED;
+ }
+}
+
+export function messageTypeToJSON(object: MessageType): string {
+ switch (object) {
+ case MessageType.MESSAGE_TYPE_UNKNOWN_UNSPECIFIED:
+ return "MESSAGE_TYPE_UNKNOWN_UNSPECIFIED";
+ case MessageType.MESSAGE_TYPE_ONE_TO_ONE:
+ return "MESSAGE_TYPE_ONE_TO_ONE";
+ case MessageType.MESSAGE_TYPE_MESSAGE_TYPE_PUBLIC_GROUP:
+ return "MESSAGE_TYPE_MESSAGE_TYPE_PUBLIC_GROUP";
+ case MessageType.MESSAGE_TYPE_PRIVATE_GROUP:
+ return "MESSAGE_TYPE_PRIVATE_GROUP";
+ case MessageType.MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP:
+ return "MESSAGE_TYPE_SYSTEM_MESSAGE_PRIVATE_GROUP";
+ case MessageType.MESSAGE_TYPE_COMMUNITY_CHAT:
+ return "MESSAGE_TYPE_COMMUNITY_CHAT";
+ case MessageType.MESSAGE_TYPE_SYSTEM_MESSAGE_GAP:
+ return "MESSAGE_TYPE_SYSTEM_MESSAGE_GAP";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+export enum ImageType {
+ IMAGE_TYPE_UNKNOWN_UNSPECIFIED = 0,
+ /** IMAGE_TYPE_PNG - Raster image files is payload data that can be read as a raster image */
+ IMAGE_TYPE_PNG = 1,
+ IMAGE_TYPE_JPEG = 2,
+ IMAGE_TYPE_WEBP = 3,
+ IMAGE_TYPE_GIF = 4,
+ UNRECOGNIZED = -1,
+}
+
+export function imageTypeFromJSON(object: any): ImageType {
+ switch (object) {
+ case 0:
+ case "IMAGE_TYPE_UNKNOWN_UNSPECIFIED":
+ return ImageType.IMAGE_TYPE_UNKNOWN_UNSPECIFIED;
+ case 1:
+ case "IMAGE_TYPE_PNG":
+ return ImageType.IMAGE_TYPE_PNG;
+ case 2:
+ case "IMAGE_TYPE_JPEG":
+ return ImageType.IMAGE_TYPE_JPEG;
+ case 3:
+ case "IMAGE_TYPE_WEBP":
+ return ImageType.IMAGE_TYPE_WEBP;
+ case 4:
+ case "IMAGE_TYPE_GIF":
+ return ImageType.IMAGE_TYPE_GIF;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return ImageType.UNRECOGNIZED;
+ }
+}
+
+export function imageTypeToJSON(object: ImageType): string {
+ switch (object) {
+ case ImageType.IMAGE_TYPE_UNKNOWN_UNSPECIFIED:
+ return "IMAGE_TYPE_UNKNOWN_UNSPECIFIED";
+ case ImageType.IMAGE_TYPE_PNG:
+ return "IMAGE_TYPE_PNG";
+ case ImageType.IMAGE_TYPE_JPEG:
+ return "IMAGE_TYPE_JPEG";
+ case ImageType.IMAGE_TYPE_WEBP:
+ return "IMAGE_TYPE_WEBP";
+ case ImageType.IMAGE_TYPE_GIF:
+ return "IMAGE_TYPE_GIF";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/communities/v1/membership_update_message.ts b/packages/status-core/src/proto/communities/v1/membership_update_message.ts
new file mode 100644
index 00000000..9c0e4e73
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/membership_update_message.ts
@@ -0,0 +1,436 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+import { ChatMessage } from "../../communities/v1/chat_message";
+import { EmojiReaction } from "../../communities/v1/emoji_reaction";
+
+export const protobufPackage = "communities.v1";
+
+export interface MembershipUpdateEvent {
+ /** Lamport timestamp of the event */
+ clock: number;
+ /** List of public keys of objects of the action */
+ members: string[];
+ /** Name of the chat for the CHAT_CREATED/NAME_CHANGED event types */
+ name: string;
+ /** The type of the event */
+ type: MembershipUpdateEvent_EventType;
+}
+
+export enum MembershipUpdateEvent_EventType {
+ UNKNOWN = 0,
+ CHAT_CREATED = 1,
+ NAME_CHANGED = 2,
+ MEMBERS_ADDED = 3,
+ MEMBER_JOINED = 4,
+ MEMBER_REMOVED = 5,
+ ADMINS_ADDED = 6,
+ ADMIN_REMOVED = 7,
+ UNRECOGNIZED = -1,
+}
+
+export function membershipUpdateEvent_EventTypeFromJSON(
+ object: any
+): MembershipUpdateEvent_EventType {
+ switch (object) {
+ case 0:
+ case "UNKNOWN":
+ return MembershipUpdateEvent_EventType.UNKNOWN;
+ case 1:
+ case "CHAT_CREATED":
+ return MembershipUpdateEvent_EventType.CHAT_CREATED;
+ case 2:
+ case "NAME_CHANGED":
+ return MembershipUpdateEvent_EventType.NAME_CHANGED;
+ case 3:
+ case "MEMBERS_ADDED":
+ return MembershipUpdateEvent_EventType.MEMBERS_ADDED;
+ case 4:
+ case "MEMBER_JOINED":
+ return MembershipUpdateEvent_EventType.MEMBER_JOINED;
+ case 5:
+ case "MEMBER_REMOVED":
+ return MembershipUpdateEvent_EventType.MEMBER_REMOVED;
+ case 6:
+ case "ADMINS_ADDED":
+ return MembershipUpdateEvent_EventType.ADMINS_ADDED;
+ case 7:
+ case "ADMIN_REMOVED":
+ return MembershipUpdateEvent_EventType.ADMIN_REMOVED;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return MembershipUpdateEvent_EventType.UNRECOGNIZED;
+ }
+}
+
+export function membershipUpdateEvent_EventTypeToJSON(
+ object: MembershipUpdateEvent_EventType
+): string {
+ switch (object) {
+ case MembershipUpdateEvent_EventType.UNKNOWN:
+ return "UNKNOWN";
+ case MembershipUpdateEvent_EventType.CHAT_CREATED:
+ return "CHAT_CREATED";
+ case MembershipUpdateEvent_EventType.NAME_CHANGED:
+ return "NAME_CHANGED";
+ case MembershipUpdateEvent_EventType.MEMBERS_ADDED:
+ return "MEMBERS_ADDED";
+ case MembershipUpdateEvent_EventType.MEMBER_JOINED:
+ return "MEMBER_JOINED";
+ case MembershipUpdateEvent_EventType.MEMBER_REMOVED:
+ return "MEMBER_REMOVED";
+ case MembershipUpdateEvent_EventType.ADMINS_ADDED:
+ return "ADMINS_ADDED";
+ case MembershipUpdateEvent_EventType.ADMIN_REMOVED:
+ return "ADMIN_REMOVED";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+/**
+ * MembershipUpdateMessage is a message used to propagate information
+ * about group membership changes.
+ * For more information, see https://github.com/status-im/specs/blob/master/status-group-chats-spec.md.
+ */
+export interface MembershipUpdateMessage {
+ /** The chat id of the private group chat */
+ chatId: string;
+ /**
+ * A list of events for this group chat, first x bytes are the signature, then is a
+ * protobuf encoded MembershipUpdateEvent
+ */
+ events: Uint8Array[];
+ message: ChatMessage | undefined;
+ emojiReaction: EmojiReaction | undefined;
+}
+
+const baseMembershipUpdateEvent: object = {
+ clock: 0,
+ members: "",
+ name: "",
+ type: 0,
+};
+
+export const MembershipUpdateEvent = {
+ encode(
+ message: MembershipUpdateEvent,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ for (const v of message.members) {
+ writer.uint32(18).string(v!);
+ }
+ if (message.name !== "") {
+ writer.uint32(26).string(message.name);
+ }
+ if (message.type !== 0) {
+ writer.uint32(32).int32(message.type);
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): MembershipUpdateEvent {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseMembershipUpdateEvent } as MembershipUpdateEvent;
+ message.members = [];
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.members.push(reader.string());
+ break;
+ case 3:
+ message.name = reader.string();
+ break;
+ case 4:
+ message.type = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): MembershipUpdateEvent {
+ const message = { ...baseMembershipUpdateEvent } as MembershipUpdateEvent;
+ message.members = [];
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.members !== undefined && object.members !== null) {
+ for (const e of object.members) {
+ message.members.push(String(e));
+ }
+ }
+ if (object.name !== undefined && object.name !== null) {
+ message.name = String(object.name);
+ } else {
+ message.name = "";
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = membershipUpdateEvent_EventTypeFromJSON(object.type);
+ } else {
+ message.type = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: MembershipUpdateEvent): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ if (message.members) {
+ obj.members = message.members.map((e) => e);
+ } else {
+ obj.members = [];
+ }
+ message.name !== undefined && (obj.name = message.name);
+ message.type !== undefined &&
+ (obj.type = membershipUpdateEvent_EventTypeToJSON(message.type));
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): MembershipUpdateEvent {
+ const message = { ...baseMembershipUpdateEvent } as MembershipUpdateEvent;
+ message.members = [];
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.members !== undefined && object.members !== null) {
+ for (const e of object.members) {
+ message.members.push(e);
+ }
+ }
+ if (object.name !== undefined && object.name !== null) {
+ message.name = object.name;
+ } else {
+ message.name = "";
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = object.type;
+ } else {
+ message.type = 0;
+ }
+ return message;
+ },
+};
+
+const baseMembershipUpdateMessage: object = { chatId: "" };
+
+export const MembershipUpdateMessage = {
+ encode(
+ message: MembershipUpdateMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.chatId !== "") {
+ writer.uint32(10).string(message.chatId);
+ }
+ for (const v of message.events) {
+ writer.uint32(18).bytes(v!);
+ }
+ if (message.message !== undefined) {
+ ChatMessage.encode(message.message, writer.uint32(26).fork()).ldelim();
+ }
+ if (message.emojiReaction !== undefined) {
+ EmojiReaction.encode(
+ message.emojiReaction,
+ writer.uint32(34).fork()
+ ).ldelim();
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): MembershipUpdateMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseMembershipUpdateMessage,
+ } as MembershipUpdateMessage;
+ message.events = [];
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.chatId = reader.string();
+ break;
+ case 2:
+ message.events.push(reader.bytes());
+ break;
+ case 3:
+ message.message = ChatMessage.decode(reader, reader.uint32());
+ break;
+ case 4:
+ message.emojiReaction = EmojiReaction.decode(reader, reader.uint32());
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): MembershipUpdateMessage {
+ const message = {
+ ...baseMembershipUpdateMessage,
+ } as MembershipUpdateMessage;
+ message.events = [];
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = String(object.chatId);
+ } else {
+ message.chatId = "";
+ }
+ if (object.events !== undefined && object.events !== null) {
+ for (const e of object.events) {
+ message.events.push(bytesFromBase64(e));
+ }
+ }
+ if (object.message !== undefined && object.message !== null) {
+ message.message = ChatMessage.fromJSON(object.message);
+ } else {
+ message.message = undefined;
+ }
+ if (object.emojiReaction !== undefined && object.emojiReaction !== null) {
+ message.emojiReaction = EmojiReaction.fromJSON(object.emojiReaction);
+ } else {
+ message.emojiReaction = undefined;
+ }
+ return message;
+ },
+
+ toJSON(message: MembershipUpdateMessage): unknown {
+ const obj: any = {};
+ message.chatId !== undefined && (obj.chatId = message.chatId);
+ if (message.events) {
+ obj.events = message.events.map((e) =>
+ base64FromBytes(e !== undefined ? e : new Uint8Array())
+ );
+ } else {
+ obj.events = [];
+ }
+ message.message !== undefined &&
+ (obj.message = message.message
+ ? ChatMessage.toJSON(message.message)
+ : undefined);
+ message.emojiReaction !== undefined &&
+ (obj.emojiReaction = message.emojiReaction
+ ? EmojiReaction.toJSON(message.emojiReaction)
+ : undefined);
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): MembershipUpdateMessage {
+ const message = {
+ ...baseMembershipUpdateMessage,
+ } as MembershipUpdateMessage;
+ message.events = [];
+ if (object.chatId !== undefined && object.chatId !== null) {
+ message.chatId = object.chatId;
+ } else {
+ message.chatId = "";
+ }
+ if (object.events !== undefined && object.events !== null) {
+ for (const e of object.events) {
+ message.events.push(e);
+ }
+ }
+ if (object.message !== undefined && object.message !== null) {
+ message.message = ChatMessage.fromPartial(object.message);
+ } else {
+ message.message = undefined;
+ }
+ if (object.emojiReaction !== undefined && object.emojiReaction !== null) {
+ message.emojiReaction = EmojiReaction.fromPartial(object.emojiReaction);
+ } else {
+ message.emojiReaction = undefined;
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+const atob: (b64: string) => string =
+ globalThis.atob ||
+ ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
+function bytesFromBase64(b64: string): Uint8Array {
+ const bin = atob(b64);
+ const arr = new Uint8Array(bin.length);
+ for (let i = 0; i < bin.length; ++i) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return arr;
+}
+
+const btoa: (bin: string) => string =
+ globalThis.btoa ||
+ ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
+function base64FromBytes(arr: Uint8Array): string {
+ const bin: string[] = [];
+ for (const byte of arr) {
+ bin.push(String.fromCharCode(byte));
+ }
+ return btoa(bin.join(""));
+}
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+function longToNumber(long: Long): number {
+ if (long.gt(Number.MAX_SAFE_INTEGER)) {
+ throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
+ }
+ return long.toNumber();
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/communities/v1/status_update.ts b/packages/status-core/src/proto/communities/v1/status_update.ts
new file mode 100644
index 00000000..31e9f122
--- /dev/null
+++ b/packages/status-core/src/proto/communities/v1/status_update.ts
@@ -0,0 +1,212 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+
+export const protobufPackage = "communities.v1";
+
+/**
+ * Specs:
+ * :AUTOMATIC
+ * To Send - "AUTOMATIC" status ping every 5 minutes
+ * Display - Online for up to 5 minutes from the last clock, after that Offline
+ * :ALWAYS_ONLINE
+ * To Send - "ALWAYS_ONLINE" status ping every 5 minutes
+ * Display - Online for up to 2 weeks from the last clock, after that Offline
+ * :INACTIVE
+ * To Send - A single "INACTIVE" status ping
+ * Display - Offline forever
+ * Note: Only send pings if the user interacted with the app in the last x minutes.
+ */
+export interface StatusUpdate {
+ clock: number;
+ statusType: StatusUpdate_StatusType;
+ customText: string;
+}
+
+export enum StatusUpdate_StatusType {
+ UNKNOWN_STATUS_TYPE = 0,
+ AUTOMATIC = 1,
+ DO_NOT_DISTURB = 2,
+ ALWAYS_ONLINE = 3,
+ INACTIVE = 4,
+ UNRECOGNIZED = -1,
+}
+
+export function statusUpdate_StatusTypeFromJSON(
+ object: any
+): StatusUpdate_StatusType {
+ switch (object) {
+ case 0:
+ case "UNKNOWN_STATUS_TYPE":
+ return StatusUpdate_StatusType.UNKNOWN_STATUS_TYPE;
+ case 1:
+ case "AUTOMATIC":
+ return StatusUpdate_StatusType.AUTOMATIC;
+ case 2:
+ case "DO_NOT_DISTURB":
+ return StatusUpdate_StatusType.DO_NOT_DISTURB;
+ case 3:
+ case "ALWAYS_ONLINE":
+ return StatusUpdate_StatusType.ALWAYS_ONLINE;
+ case 4:
+ case "INACTIVE":
+ return StatusUpdate_StatusType.INACTIVE;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return StatusUpdate_StatusType.UNRECOGNIZED;
+ }
+}
+
+export function statusUpdate_StatusTypeToJSON(
+ object: StatusUpdate_StatusType
+): string {
+ switch (object) {
+ case StatusUpdate_StatusType.UNKNOWN_STATUS_TYPE:
+ return "UNKNOWN_STATUS_TYPE";
+ case StatusUpdate_StatusType.AUTOMATIC:
+ return "AUTOMATIC";
+ case StatusUpdate_StatusType.DO_NOT_DISTURB:
+ return "DO_NOT_DISTURB";
+ case StatusUpdate_StatusType.ALWAYS_ONLINE:
+ return "ALWAYS_ONLINE";
+ case StatusUpdate_StatusType.INACTIVE:
+ return "INACTIVE";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const baseStatusUpdate: object = { clock: 0, statusType: 0, customText: "" };
+
+export const StatusUpdate = {
+ encode(
+ message: StatusUpdate,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.clock !== 0) {
+ writer.uint32(8).uint64(message.clock);
+ }
+ if (message.statusType !== 0) {
+ writer.uint32(16).int32(message.statusType);
+ }
+ if (message.customText !== "") {
+ writer.uint32(26).string(message.customText);
+ }
+ return writer;
+ },
+
+ decode(input: _m0.Reader | Uint8Array, length?: number): StatusUpdate {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = { ...baseStatusUpdate } as StatusUpdate;
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.clock = longToNumber(reader.uint64() as Long);
+ break;
+ case 2:
+ message.statusType = reader.int32() as any;
+ break;
+ case 3:
+ message.customText = reader.string();
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): StatusUpdate {
+ const message = { ...baseStatusUpdate } as StatusUpdate;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = Number(object.clock);
+ } else {
+ message.clock = 0;
+ }
+ if (object.statusType !== undefined && object.statusType !== null) {
+ message.statusType = statusUpdate_StatusTypeFromJSON(object.statusType);
+ } else {
+ message.statusType = 0;
+ }
+ if (object.customText !== undefined && object.customText !== null) {
+ message.customText = String(object.customText);
+ } else {
+ message.customText = "";
+ }
+ return message;
+ },
+
+ toJSON(message: StatusUpdate): unknown {
+ const obj: any = {};
+ message.clock !== undefined && (obj.clock = message.clock);
+ message.statusType !== undefined &&
+ (obj.statusType = statusUpdate_StatusTypeToJSON(message.statusType));
+ message.customText !== undefined && (obj.customText = message.customText);
+ return obj;
+ },
+
+ fromPartial(object: DeepPartial): StatusUpdate {
+ const message = { ...baseStatusUpdate } as StatusUpdate;
+ if (object.clock !== undefined && object.clock !== null) {
+ message.clock = object.clock;
+ } else {
+ message.clock = 0;
+ }
+ if (object.statusType !== undefined && object.statusType !== null) {
+ message.statusType = object.statusType;
+ } else {
+ message.statusType = 0;
+ }
+ if (object.customText !== undefined && object.customText !== null) {
+ message.customText = object.customText;
+ } else {
+ message.customText = "";
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+function longToNumber(long: Long): number {
+ if (long.gt(Number.MAX_SAFE_INTEGER)) {
+ throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
+ }
+ return long.toNumber();
+}
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/proto/status/v1/application_metadata_message.ts b/packages/status-core/src/proto/status/v1/application_metadata_message.ts
new file mode 100644
index 00000000..25a169f9
--- /dev/null
+++ b/packages/status-core/src/proto/status/v1/application_metadata_message.ts
@@ -0,0 +1,409 @@
+/* eslint-disable */
+import Long from "long";
+import _m0 from "protobufjs/minimal";
+
+export const protobufPackage = "status.v1";
+
+export interface ApplicationMetadataMessage {
+ /** Signature of the payload field */
+ signature: Uint8Array;
+ /** This is the encoded protobuf of the application level message, i.e ChatMessage */
+ payload: Uint8Array;
+ /** The type of protobuf message sent */
+ type: ApplicationMetadataMessage_Type;
+}
+
+export enum ApplicationMetadataMessage_Type {
+ TYPE_UNKNOWN_UNSPECIFIED = 0,
+ TYPE_CHAT_MESSAGE = 1,
+ TYPE_CONTACT_UPDATE = 2,
+ TYPE_MEMBERSHIP_UPDATE_MESSAGE = 3,
+ TYPE_PAIR_INSTALLATION = 4,
+ TYPE_SYNC_INSTALLATION = 5,
+ TYPE_REQUEST_ADDRESS_FOR_TRANSACTION = 6,
+ TYPE_ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION = 7,
+ TYPE_DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION = 8,
+ TYPE_REQUEST_TRANSACTION = 9,
+ TYPE_SEND_TRANSACTION = 10,
+ TYPE_DECLINE_REQUEST_TRANSACTION = 11,
+ TYPE_SYNC_INSTALLATION_CONTACT = 12,
+ TYPE_SYNC_INSTALLATION_ACCOUNT = 13,
+ TYPE_SYNC_INSTALLATION_PUBLIC_CHAT = 14,
+ TYPE_CONTACT_CODE_ADVERTISEMENT = 15,
+ TYPE_PUSH_NOTIFICATION_REGISTRATION = 16,
+ TYPE_PUSH_NOTIFICATION_REGISTRATION_RESPONSE = 17,
+ TYPE_PUSH_NOTIFICATION_QUERY = 18,
+ TYPE_PUSH_NOTIFICATION_QUERY_RESPONSE = 19,
+ TYPE_PUSH_NOTIFICATION_REQUEST = 20,
+ TYPE_PUSH_NOTIFICATION_RESPONSE = 21,
+ TYPE_EMOJI_REACTION = 22,
+ TYPE_GROUP_CHAT_INVITATION = 23,
+ TYPE_CHAT_IDENTITY = 24,
+ TYPE_COMMUNITY_DESCRIPTION = 25,
+ TYPE_COMMUNITY_INVITATION = 26,
+ TYPE_COMMUNITY_REQUEST_TO_JOIN = 27,
+ TYPE_PIN_MESSAGE = 28,
+ TYPE_EDIT_MESSAGE = 29,
+ TYPE_STATUS_UPDATE = 30,
+ TYPE_DELETE_MESSAGE = 31,
+ TYPE_SYNC_INSTALLATION_COMMUNITY = 32,
+ TYPE_ANONYMOUS_METRIC_BATCH = 33,
+ UNRECOGNIZED = -1,
+}
+
+export function applicationMetadataMessage_TypeFromJSON(
+ object: any
+): ApplicationMetadataMessage_Type {
+ switch (object) {
+ case 0:
+ case "TYPE_UNKNOWN_UNSPECIFIED":
+ return ApplicationMetadataMessage_Type.TYPE_UNKNOWN_UNSPECIFIED;
+ case 1:
+ case "TYPE_CHAT_MESSAGE":
+ return ApplicationMetadataMessage_Type.TYPE_CHAT_MESSAGE;
+ case 2:
+ case "TYPE_CONTACT_UPDATE":
+ return ApplicationMetadataMessage_Type.TYPE_CONTACT_UPDATE;
+ case 3:
+ case "TYPE_MEMBERSHIP_UPDATE_MESSAGE":
+ return ApplicationMetadataMessage_Type.TYPE_MEMBERSHIP_UPDATE_MESSAGE;
+ case 4:
+ case "TYPE_PAIR_INSTALLATION":
+ return ApplicationMetadataMessage_Type.TYPE_PAIR_INSTALLATION;
+ case 5:
+ case "TYPE_SYNC_INSTALLATION":
+ return ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION;
+ case 6:
+ case "TYPE_REQUEST_ADDRESS_FOR_TRANSACTION":
+ return ApplicationMetadataMessage_Type.TYPE_REQUEST_ADDRESS_FOR_TRANSACTION;
+ case 7:
+ case "TYPE_ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION":
+ return ApplicationMetadataMessage_Type.TYPE_ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION;
+ case 8:
+ case "TYPE_DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION":
+ return ApplicationMetadataMessage_Type.TYPE_DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION;
+ case 9:
+ case "TYPE_REQUEST_TRANSACTION":
+ return ApplicationMetadataMessage_Type.TYPE_REQUEST_TRANSACTION;
+ case 10:
+ case "TYPE_SEND_TRANSACTION":
+ return ApplicationMetadataMessage_Type.TYPE_SEND_TRANSACTION;
+ case 11:
+ case "TYPE_DECLINE_REQUEST_TRANSACTION":
+ return ApplicationMetadataMessage_Type.TYPE_DECLINE_REQUEST_TRANSACTION;
+ case 12:
+ case "TYPE_SYNC_INSTALLATION_CONTACT":
+ return ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_CONTACT;
+ case 13:
+ case "TYPE_SYNC_INSTALLATION_ACCOUNT":
+ return ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_ACCOUNT;
+ case 14:
+ case "TYPE_SYNC_INSTALLATION_PUBLIC_CHAT":
+ return ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_PUBLIC_CHAT;
+ case 15:
+ case "TYPE_CONTACT_CODE_ADVERTISEMENT":
+ return ApplicationMetadataMessage_Type.TYPE_CONTACT_CODE_ADVERTISEMENT;
+ case 16:
+ case "TYPE_PUSH_NOTIFICATION_REGISTRATION":
+ return ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_REGISTRATION;
+ case 17:
+ case "TYPE_PUSH_NOTIFICATION_REGISTRATION_RESPONSE":
+ return ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_REGISTRATION_RESPONSE;
+ case 18:
+ case "TYPE_PUSH_NOTIFICATION_QUERY":
+ return ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_QUERY;
+ case 19:
+ case "TYPE_PUSH_NOTIFICATION_QUERY_RESPONSE":
+ return ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_QUERY_RESPONSE;
+ case 20:
+ case "TYPE_PUSH_NOTIFICATION_REQUEST":
+ return ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_REQUEST;
+ case 21:
+ case "TYPE_PUSH_NOTIFICATION_RESPONSE":
+ return ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_RESPONSE;
+ case 22:
+ case "TYPE_EMOJI_REACTION":
+ return ApplicationMetadataMessage_Type.TYPE_EMOJI_REACTION;
+ case 23:
+ case "TYPE_GROUP_CHAT_INVITATION":
+ return ApplicationMetadataMessage_Type.TYPE_GROUP_CHAT_INVITATION;
+ case 24:
+ case "TYPE_CHAT_IDENTITY":
+ return ApplicationMetadataMessage_Type.TYPE_CHAT_IDENTITY;
+ case 25:
+ case "TYPE_COMMUNITY_DESCRIPTION":
+ return ApplicationMetadataMessage_Type.TYPE_COMMUNITY_DESCRIPTION;
+ case 26:
+ case "TYPE_COMMUNITY_INVITATION":
+ return ApplicationMetadataMessage_Type.TYPE_COMMUNITY_INVITATION;
+ case 27:
+ case "TYPE_COMMUNITY_REQUEST_TO_JOIN":
+ return ApplicationMetadataMessage_Type.TYPE_COMMUNITY_REQUEST_TO_JOIN;
+ case 28:
+ case "TYPE_PIN_MESSAGE":
+ return ApplicationMetadataMessage_Type.TYPE_PIN_MESSAGE;
+ case 29:
+ case "TYPE_EDIT_MESSAGE":
+ return ApplicationMetadataMessage_Type.TYPE_EDIT_MESSAGE;
+ case 30:
+ case "TYPE_STATUS_UPDATE":
+ return ApplicationMetadataMessage_Type.TYPE_STATUS_UPDATE;
+ case 31:
+ case "TYPE_DELETE_MESSAGE":
+ return ApplicationMetadataMessage_Type.TYPE_DELETE_MESSAGE;
+ case 32:
+ case "TYPE_SYNC_INSTALLATION_COMMUNITY":
+ return ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_COMMUNITY;
+ case 33:
+ case "TYPE_ANONYMOUS_METRIC_BATCH":
+ return ApplicationMetadataMessage_Type.TYPE_ANONYMOUS_METRIC_BATCH;
+ case -1:
+ case "UNRECOGNIZED":
+ default:
+ return ApplicationMetadataMessage_Type.UNRECOGNIZED;
+ }
+}
+
+export function applicationMetadataMessage_TypeToJSON(
+ object: ApplicationMetadataMessage_Type
+): string {
+ switch (object) {
+ case ApplicationMetadataMessage_Type.TYPE_UNKNOWN_UNSPECIFIED:
+ return "TYPE_UNKNOWN_UNSPECIFIED";
+ case ApplicationMetadataMessage_Type.TYPE_CHAT_MESSAGE:
+ return "TYPE_CHAT_MESSAGE";
+ case ApplicationMetadataMessage_Type.TYPE_CONTACT_UPDATE:
+ return "TYPE_CONTACT_UPDATE";
+ case ApplicationMetadataMessage_Type.TYPE_MEMBERSHIP_UPDATE_MESSAGE:
+ return "TYPE_MEMBERSHIP_UPDATE_MESSAGE";
+ case ApplicationMetadataMessage_Type.TYPE_PAIR_INSTALLATION:
+ return "TYPE_PAIR_INSTALLATION";
+ case ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION:
+ return "TYPE_SYNC_INSTALLATION";
+ case ApplicationMetadataMessage_Type.TYPE_REQUEST_ADDRESS_FOR_TRANSACTION:
+ return "TYPE_REQUEST_ADDRESS_FOR_TRANSACTION";
+ case ApplicationMetadataMessage_Type.TYPE_ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION:
+ return "TYPE_ACCEPT_REQUEST_ADDRESS_FOR_TRANSACTION";
+ case ApplicationMetadataMessage_Type.TYPE_DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION:
+ return "TYPE_DECLINE_REQUEST_ADDRESS_FOR_TRANSACTION";
+ case ApplicationMetadataMessage_Type.TYPE_REQUEST_TRANSACTION:
+ return "TYPE_REQUEST_TRANSACTION";
+ case ApplicationMetadataMessage_Type.TYPE_SEND_TRANSACTION:
+ return "TYPE_SEND_TRANSACTION";
+ case ApplicationMetadataMessage_Type.TYPE_DECLINE_REQUEST_TRANSACTION:
+ return "TYPE_DECLINE_REQUEST_TRANSACTION";
+ case ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_CONTACT:
+ return "TYPE_SYNC_INSTALLATION_CONTACT";
+ case ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_ACCOUNT:
+ return "TYPE_SYNC_INSTALLATION_ACCOUNT";
+ case ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_PUBLIC_CHAT:
+ return "TYPE_SYNC_INSTALLATION_PUBLIC_CHAT";
+ case ApplicationMetadataMessage_Type.TYPE_CONTACT_CODE_ADVERTISEMENT:
+ return "TYPE_CONTACT_CODE_ADVERTISEMENT";
+ case ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_REGISTRATION:
+ return "TYPE_PUSH_NOTIFICATION_REGISTRATION";
+ case ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_REGISTRATION_RESPONSE:
+ return "TYPE_PUSH_NOTIFICATION_REGISTRATION_RESPONSE";
+ case ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_QUERY:
+ return "TYPE_PUSH_NOTIFICATION_QUERY";
+ case ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_QUERY_RESPONSE:
+ return "TYPE_PUSH_NOTIFICATION_QUERY_RESPONSE";
+ case ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_REQUEST:
+ return "TYPE_PUSH_NOTIFICATION_REQUEST";
+ case ApplicationMetadataMessage_Type.TYPE_PUSH_NOTIFICATION_RESPONSE:
+ return "TYPE_PUSH_NOTIFICATION_RESPONSE";
+ case ApplicationMetadataMessage_Type.TYPE_EMOJI_REACTION:
+ return "TYPE_EMOJI_REACTION";
+ case ApplicationMetadataMessage_Type.TYPE_GROUP_CHAT_INVITATION:
+ return "TYPE_GROUP_CHAT_INVITATION";
+ case ApplicationMetadataMessage_Type.TYPE_CHAT_IDENTITY:
+ return "TYPE_CHAT_IDENTITY";
+ case ApplicationMetadataMessage_Type.TYPE_COMMUNITY_DESCRIPTION:
+ return "TYPE_COMMUNITY_DESCRIPTION";
+ case ApplicationMetadataMessage_Type.TYPE_COMMUNITY_INVITATION:
+ return "TYPE_COMMUNITY_INVITATION";
+ case ApplicationMetadataMessage_Type.TYPE_COMMUNITY_REQUEST_TO_JOIN:
+ return "TYPE_COMMUNITY_REQUEST_TO_JOIN";
+ case ApplicationMetadataMessage_Type.TYPE_PIN_MESSAGE:
+ return "TYPE_PIN_MESSAGE";
+ case ApplicationMetadataMessage_Type.TYPE_EDIT_MESSAGE:
+ return "TYPE_EDIT_MESSAGE";
+ case ApplicationMetadataMessage_Type.TYPE_STATUS_UPDATE:
+ return "TYPE_STATUS_UPDATE";
+ case ApplicationMetadataMessage_Type.TYPE_DELETE_MESSAGE:
+ return "TYPE_DELETE_MESSAGE";
+ case ApplicationMetadataMessage_Type.TYPE_SYNC_INSTALLATION_COMMUNITY:
+ return "TYPE_SYNC_INSTALLATION_COMMUNITY";
+ case ApplicationMetadataMessage_Type.TYPE_ANONYMOUS_METRIC_BATCH:
+ return "TYPE_ANONYMOUS_METRIC_BATCH";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const baseApplicationMetadataMessage: object = { type: 0 };
+
+export const ApplicationMetadataMessage = {
+ encode(
+ message: ApplicationMetadataMessage,
+ writer: _m0.Writer = _m0.Writer.create()
+ ): _m0.Writer {
+ if (message.signature.length !== 0) {
+ writer.uint32(10).bytes(message.signature);
+ }
+ if (message.payload.length !== 0) {
+ writer.uint32(18).bytes(message.payload);
+ }
+ if (message.type !== 0) {
+ writer.uint32(24).int32(message.type);
+ }
+ return writer;
+ },
+
+ decode(
+ input: _m0.Reader | Uint8Array,
+ length?: number
+ ): ApplicationMetadataMessage {
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
+ let end = length === undefined ? reader.len : reader.pos + length;
+ const message = {
+ ...baseApplicationMetadataMessage,
+ } as ApplicationMetadataMessage;
+ message.signature = new Uint8Array();
+ message.payload = new Uint8Array();
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1:
+ message.signature = reader.bytes();
+ break;
+ case 2:
+ message.payload = reader.bytes();
+ break;
+ case 3:
+ message.type = reader.int32() as any;
+ break;
+ default:
+ reader.skipType(tag & 7);
+ break;
+ }
+ }
+ return message;
+ },
+
+ fromJSON(object: any): ApplicationMetadataMessage {
+ const message = {
+ ...baseApplicationMetadataMessage,
+ } as ApplicationMetadataMessage;
+ message.signature = new Uint8Array();
+ message.payload = new Uint8Array();
+ if (object.signature !== undefined && object.signature !== null) {
+ message.signature = bytesFromBase64(object.signature);
+ }
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = bytesFromBase64(object.payload);
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = applicationMetadataMessage_TypeFromJSON(object.type);
+ } else {
+ message.type = 0;
+ }
+ return message;
+ },
+
+ toJSON(message: ApplicationMetadataMessage): unknown {
+ const obj: any = {};
+ message.signature !== undefined &&
+ (obj.signature = base64FromBytes(
+ message.signature !== undefined ? message.signature : new Uint8Array()
+ ));
+ message.payload !== undefined &&
+ (obj.payload = base64FromBytes(
+ message.payload !== undefined ? message.payload : new Uint8Array()
+ ));
+ message.type !== undefined &&
+ (obj.type = applicationMetadataMessage_TypeToJSON(message.type));
+ return obj;
+ },
+
+ fromPartial(
+ object: DeepPartial
+ ): ApplicationMetadataMessage {
+ const message = {
+ ...baseApplicationMetadataMessage,
+ } as ApplicationMetadataMessage;
+ if (object.signature !== undefined && object.signature !== null) {
+ message.signature = object.signature;
+ } else {
+ message.signature = new Uint8Array();
+ }
+ if (object.payload !== undefined && object.payload !== null) {
+ message.payload = object.payload;
+ } else {
+ message.payload = new Uint8Array();
+ }
+ if (object.type !== undefined && object.type !== null) {
+ message.type = object.type;
+ } else {
+ message.type = 0;
+ }
+ return message;
+ },
+};
+
+declare var self: any | undefined;
+declare var window: any | undefined;
+declare var global: any | undefined;
+var globalThis: any = (() => {
+ if (typeof globalThis !== "undefined") return globalThis;
+ if (typeof self !== "undefined") return self;
+ if (typeof window !== "undefined") return window;
+ if (typeof global !== "undefined") return global;
+ throw "Unable to locate global object";
+})();
+
+const atob: (b64: string) => string =
+ globalThis.atob ||
+ ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
+function bytesFromBase64(b64: string): Uint8Array {
+ const bin = atob(b64);
+ const arr = new Uint8Array(bin.length);
+ for (let i = 0; i < bin.length; ++i) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return arr;
+}
+
+const btoa: (bin: string) => string =
+ globalThis.btoa ||
+ ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
+function base64FromBytes(arr: Uint8Array): string {
+ const bin: string[] = [];
+ for (const byte of arr) {
+ bin.push(String.fromCharCode(byte));
+ }
+ return btoa(bin.join(""));
+}
+
+type Builtin =
+ | Date
+ | Function
+ | Uint8Array
+ | string
+ | number
+ | boolean
+ | undefined;
+export type DeepPartial = T extends Builtin
+ ? T
+ : T extends Array
+ ? Array>
+ : T extends ReadonlyArray
+ ? ReadonlyArray>
+ : T extends {}
+ ? { [K in keyof T]?: DeepPartial }
+ : Partial;
+
+if (_m0.util.Long !== Long) {
+ _m0.util.Long = Long as any;
+ _m0.configure();
+}
diff --git a/packages/status-core/src/topics.ts b/packages/status-core/src/topics.ts
new file mode 100644
index 00000000..389706c4
--- /dev/null
+++ b/packages/status-core/src/topics.ts
@@ -0,0 +1,46 @@
+import { BN } from "bn.js";
+import { derive } from "ecies-geth";
+import { ec } from "elliptic";
+import { bufToHex } from "js-waku/build/main/lib/utils";
+
+import { idToContentTopic } from "./contentTopic";
+import { hexToBuf } from "./utils";
+
+import { Identity } from ".";
+
+const EC = new ec("secp256k1");
+const partitionsNum = new BN(5000);
+
+/**
+ * Get the partitioned topic https://specs.status.im/spec/3#partitioned-topic
+ * @param publicKey Public key of recipient
+ * @returns string The Waku v2 Content Topic.
+ */
+export function getPartitionedTopic(publicKey: string): string {
+ const key = EC.keyFromPublic(publicKey.slice(2), "hex");
+ const X = key.getPublic().getX();
+
+ const partition = X.mod(partitionsNum);
+
+ const partitionTopic = `contact-discovery-${partition.toString()}`;
+
+ return idToContentTopic(partitionTopic);
+}
+
+/**
+ * Get the negotiated topic https://specs.status.im/spec/3#negotiated-topic
+ * @param identity identity of user
+ * @param publicKey Public key of recipient
+ * @returns string The Waku v2 Content Topic.
+ */
+export async function getNegotiatedTopic(
+ identity: Identity,
+ publicKey: string
+): Promise {
+ const key = EC.keyFromPublic(publicKey.slice(2), "hex");
+ const sharedSecret = await derive(
+ Buffer.from(identity.privateKey),
+ hexToBuf(key.getPublic("hex"))
+ );
+ return idToContentTopic(bufToHex(sharedSecret));
+}
diff --git a/packages/status-core/src/utils.ts b/packages/status-core/src/utils.ts
new file mode 100644
index 00000000..84ecf2ff
--- /dev/null
+++ b/packages/status-core/src/utils.ts
@@ -0,0 +1,57 @@
+import { ec } from "elliptic";
+import { PageDirection, utils, Waku } from "js-waku";
+
+import { idToContactCodeTopic } from "./contentTopic";
+import { ChatIdentity } from "./proto/communities/v1/chat_identity";
+
+const EC = new ec("secp256k1");
+
+const hexToBuf = utils.hexToBuf;
+export { hexToBuf };
+
+/**
+ * Return hex string with 0x prefix (commonly used for string format of a community id/public key.
+ */
+export function bufToHex(buf: Uint8Array): string {
+ return "0x" + utils.bufToHex(buf);
+}
+
+export function compressPublicKey(key: Uint8Array): string {
+ const PubKey = EC.keyFromPublic(key);
+ return "0x" + PubKey.getPublic(true, "hex");
+}
+
+export function genPrivateKeyWithEntropy(key: string): Uint8Array {
+ const pair = EC.genKeyPair({ entropy: key });
+ return hexToBuf("0x" + pair.getPrivate("hex"));
+}
+
+export async function getLatestUserNickname(
+ key: Uint8Array,
+ waku: Waku
+): Promise<{ clock: number; nickname: string }> {
+ const publicKey = bufToHex(key);
+ let nickname = "";
+ let clock = 0;
+ await waku.store.queryHistory([idToContactCodeTopic(publicKey)], {
+ callback: (msgs) =>
+ msgs.some((e) => {
+ try {
+ if (e.payload) {
+ const chatIdentity = ChatIdentity.decode(e?.payload);
+ if (chatIdentity) {
+ if (chatIdentity?.displayName) {
+ clock = chatIdentity?.clock ?? 0;
+ nickname = chatIdentity?.displayName;
+ }
+ }
+ return true;
+ }
+ } catch {
+ return false;
+ }
+ }),
+ pageDirection: PageDirection.BACKWARD,
+ });
+ return { clock, nickname };
+}
diff --git a/packages/status-core/src/wire/application_metadata_message.ts b/packages/status-core/src/wire/application_metadata_message.ts
new file mode 100644
index 00000000..f7458b57
--- /dev/null
+++ b/packages/status-core/src/wire/application_metadata_message.ts
@@ -0,0 +1,75 @@
+import { keccak256 } from "js-sha3";
+import { Reader } from "protobufjs";
+import secp256k1 from "secp256k1";
+
+import { Identity } from "../identity";
+import * as proto from "../proto/status/v1/application_metadata_message";
+import { ApplicationMetadataMessage_Type } from "../proto/status/v1/application_metadata_message";
+import { hexToBuf } from "../utils";
+
+import { ChatMessage } from "./chat_message";
+
+export class ApplicationMetadataMessage {
+ private constructor(public proto: proto.ApplicationMetadataMessage) {}
+
+ /**
+ * Create a chat message to be sent to an Open (permission = no membership) community
+ */
+ public static create(
+ payload: Uint8Array,
+ type: ApplicationMetadataMessage_Type,
+ identity: Identity
+ ): ApplicationMetadataMessage {
+ const signature = identity.sign(payload);
+
+ const proto = {
+ signature,
+ payload,
+ type,
+ };
+
+ return new ApplicationMetadataMessage(proto);
+ }
+
+ static decode(bytes: Uint8Array): ApplicationMetadataMessage {
+ const protoBuf = proto.ApplicationMetadataMessage.decode(
+ Reader.create(bytes)
+ );
+
+ return new ApplicationMetadataMessage(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.ApplicationMetadataMessage.encode(this.proto).finish();
+ }
+
+ public get signature(): Uint8Array | undefined {
+ return this.proto.signature;
+ }
+
+ public get payload(): Uint8Array | undefined {
+ return this.proto.payload;
+ }
+ public get type(): ApplicationMetadataMessage_Type | undefined {
+ return this.proto.type;
+ }
+
+ /**
+ * Returns a chat message if the type is [TYPE_CHAT_MESSAGE], undefined otherwise.
+ */
+ public get chatMessage(): ChatMessage | undefined {
+ if (!this.payload) return;
+
+ return ChatMessage.decode(this.payload);
+ }
+
+ public get signer(): Uint8Array | undefined {
+ if (!this.signature || !this.payload) return;
+
+ const signature = this.signature.slice(0, 64);
+ const recid = this.signature.slice(64)[0];
+ const hash = keccak256(this.payload);
+
+ return secp256k1.ecdsaRecover(signature, recid, hexToBuf(hash));
+ }
+}
diff --git a/packages/status-core/src/wire/chat_identity.ts b/packages/status-core/src/wire/chat_identity.ts
new file mode 100644
index 00000000..b43c8ecb
--- /dev/null
+++ b/packages/status-core/src/wire/chat_identity.ts
@@ -0,0 +1,51 @@
+import { Reader } from "protobufjs";
+
+import * as proto from "../proto/communities/v1/chat_identity";
+import { IdentityImage } from "../proto/communities/v1/chat_identity";
+
+export class ChatIdentity {
+ public constructor(public proto: proto.ChatIdentity) {}
+
+ static decode(bytes: Uint8Array): ChatIdentity {
+ const protoBuf = proto.ChatIdentity.decode(Reader.create(bytes));
+
+ return new ChatIdentity(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.ChatIdentity.encode(this.proto).finish();
+ }
+
+ /** Lamport timestamp of the message */
+ get clock(): number | undefined {
+ return this.proto.clock;
+ }
+
+ /** ens_name is the valid ENS name associated with the chat key */
+ get ensName(): string | undefined {
+ return this.proto.ensName;
+ }
+
+ /** images is a string indexed mapping of images associated with an identity */
+ get images(): { [key: string]: IdentityImage } | undefined {
+ return this.proto.images;
+ }
+
+ /** display name is the user set identity, valid only for organisations */
+ get displayName(): string | undefined {
+ return this.proto.displayName;
+ }
+
+ /** description is the user set description, valid only for organisations */
+ get description(): string | undefined {
+ return this.proto.description;
+ }
+
+ get color(): string | undefined {
+ return this.proto.color;
+ }
+
+ get emoji(): string | undefined {
+ return this.proto.emoji;
+ }
+}
diff --git a/packages/status-core/src/wire/chat_message.spec.ts b/packages/status-core/src/wire/chat_message.spec.ts
new file mode 100644
index 00000000..48c0a56e
--- /dev/null
+++ b/packages/status-core/src/wire/chat_message.spec.ts
@@ -0,0 +1,78 @@
+import { expect } from "chai";
+
+import {
+ AudioMessage_AudioType,
+ ChatMessage_ContentType,
+} from "../proto/communities/v1/chat_message";
+import { ImageType } from "../proto/communities/v1/enums";
+
+import {
+ AudioContent,
+ ChatMessage,
+ ContentType,
+ ImageContent,
+ StickerContent,
+} from "./chat_message";
+
+describe("Chat Message", () => {
+ it("Encode & decode Image message", () => {
+ const payload = Buffer.from([1, 1]);
+
+ const imageContent: ImageContent = {
+ image: payload,
+ imageType: ImageType.IMAGE_TYPE_PNG,
+ contentType: ContentType.Image,
+ };
+
+ const message = ChatMessage.createMessage(1, 1, "chat-id", imageContent);
+
+ const buf = message.encode();
+ const dec = ChatMessage.decode(buf);
+
+ expect(dec.contentType).eq(ChatMessage_ContentType.CONTENT_TYPE_IMAGE);
+ expect(dec.image?.payload?.toString()).eq(payload.toString());
+ expect(dec.image?.type).eq(ImageType.IMAGE_TYPE_PNG);
+ });
+
+ it("Encode & decode Audio message", () => {
+ const payload = Buffer.from([1, 1]);
+ const durationMs = 12345;
+
+ const audioContent: AudioContent = {
+ audio: payload,
+ audioType: AudioMessage_AudioType.AUDIO_TYPE_AAC,
+ durationMs,
+ contentType: ContentType.Audio,
+ };
+
+ const message = ChatMessage.createMessage(1, 1, "chat-id", audioContent);
+
+ const buf = message.encode();
+ const dec = ChatMessage.decode(buf);
+
+ expect(dec.contentType).eq(ChatMessage_ContentType.CONTENT_TYPE_AUDIO);
+ expect(dec.audio?.payload?.toString()).eq(payload.toString());
+ expect(dec.audio?.type).eq(ImageType.IMAGE_TYPE_PNG);
+ expect(dec.audio?.durationMs).eq(durationMs);
+ });
+
+ it("Encode & decode Sticker message", () => {
+ const hash = "deadbeef";
+ const pack = 12345;
+
+ const stickerContent: StickerContent = {
+ hash,
+ pack,
+ contentType: ContentType.Sticker,
+ };
+
+ const message = ChatMessage.createMessage(1, 1, "chat-id", stickerContent);
+
+ const buf = message.encode();
+ const dec = ChatMessage.decode(buf);
+
+ expect(dec.contentType).eq(ChatMessage_ContentType.CONTENT_TYPE_STICKER);
+ expect(dec.sticker?.hash).eq(hash);
+ expect(dec.sticker?.pack).eq(pack);
+ });
+});
diff --git a/packages/status-core/src/wire/chat_message.ts b/packages/status-core/src/wire/chat_message.ts
new file mode 100644
index 00000000..3dda0482
--- /dev/null
+++ b/packages/status-core/src/wire/chat_message.ts
@@ -0,0 +1,226 @@
+import { Reader } from "protobufjs";
+
+import * as proto from "../proto/communities/v1/chat_message";
+import {
+ AudioMessage,
+ AudioMessage_AudioType,
+ ChatMessage_ContentType,
+ ImageMessage,
+ StickerMessage,
+} from "../proto/communities/v1/chat_message";
+import { ImageType, MessageType } from "../proto/communities/v1/enums";
+
+export type Content =
+ | TextContent
+ | StickerContent
+ | ImageContent
+ | AudioContent;
+
+export enum ContentType {
+ Text,
+ Sticker,
+ Image,
+ Audio,
+}
+
+export interface TextContent {
+ text: string;
+ contentType: ContentType.Text;
+}
+
+export interface StickerContent {
+ hash: string;
+ pack: number;
+ contentType: ContentType.Sticker;
+}
+
+export interface ImageContent {
+ image: Uint8Array;
+ imageType: ImageType;
+ contentType: ContentType.Image;
+}
+
+export interface AudioContent {
+ audio: Uint8Array;
+ audioType: AudioMessage_AudioType;
+ durationMs: number;
+ contentType: ContentType.Audio;
+}
+
+function isText(content: Content): content is TextContent {
+ return content.contentType === ContentType.Text;
+}
+
+function isSticker(content: Content): content is StickerContent {
+ return content.contentType === ContentType.Sticker;
+}
+
+function isImage(content: Content): content is ImageContent {
+ return content.contentType === ContentType.Image;
+}
+
+function isAudio(content: Content): content is AudioContent {
+ return content.contentType === ContentType.Audio;
+}
+
+export class ChatMessage {
+ private constructor(public proto: proto.ChatMessage) {}
+
+ /**
+ * Create a chat message to be sent to an Open (permission = no membership) community.
+ *
+ * @throws string If mediaContent is malformed
+ */
+ public static createMessage(
+ clock: number,
+ timestamp: number,
+ chatId: string,
+ content: Content,
+ responseTo?: string
+ ): ChatMessage {
+ let sticker,
+ image,
+ audio,
+ text = "Upgrade to the latest version to see this media content.";
+ let contentType = ChatMessage_ContentType.CONTENT_TYPE_TEXT_PLAIN;
+
+ if (isText(content)) {
+ if (!content.text) throw "Malformed Text Content";
+ text = content.text;
+ contentType = ChatMessage_ContentType.CONTENT_TYPE_TEXT_PLAIN;
+ } else if (isSticker(content)) {
+ if (!content.hash || !content.pack) throw "Malformed Sticker Content";
+ sticker = {
+ hash: content.hash,
+ pack: content.pack,
+ };
+ contentType = ChatMessage_ContentType.CONTENT_TYPE_STICKER;
+ } else if (isImage(content)) {
+ if (!content.image || !content.imageType) throw "Malformed Image Content";
+ image = {
+ payload: content.image,
+ type: content.imageType,
+ };
+ contentType = ChatMessage_ContentType.CONTENT_TYPE_IMAGE;
+ } else if (isAudio(content)) {
+ if (!content.audio || !content.audioType || !content.durationMs)
+ throw "Malformed Audio Content";
+ audio = {
+ payload: content.audio,
+ type: content.audioType,
+ durationMs: content.durationMs,
+ };
+ contentType = ChatMessage_ContentType.CONTENT_TYPE_AUDIO;
+ }
+
+ const proto = {
+ clock, // ms?
+ timestamp, //ms?
+ text,
+ /** Id of the message that we are replying to */
+ responseTo: responseTo ?? "",
+ /** Ens name of the sender */
+ ensName: "",
+ /** Public Key of the community (TBC) **/
+ chatId,
+ /** The type of message (public/one-to-one/private-group-chat) */
+ messageType: MessageType.MESSAGE_TYPE_COMMUNITY_CHAT,
+ /** The type of the content of the message */
+ contentType,
+ sticker,
+ image,
+ audio,
+ community: undefined, // Used to share a community
+ grant: undefined,
+ };
+
+ return new ChatMessage(proto);
+ }
+
+ static decode(bytes: Uint8Array): ChatMessage {
+ const protoBuf = proto.ChatMessage.decode(Reader.create(bytes));
+
+ return new ChatMessage(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.ChatMessage.encode(this.proto).finish();
+ }
+
+ /** Lamport timestamp of the chat message */
+ public get clock(): number | undefined {
+ return this.proto.clock;
+ }
+
+ /**
+ * Unix timestamps in milliseconds, currently not used as we use whisper as more reliable, but here
+ * so that we don't rely on it
+ */
+ public get timestamp(): number | undefined {
+ return this.proto.timestamp;
+ }
+
+ /**
+ * Text of the message
+ */
+ public get text(): string | undefined {
+ return this.proto.text;
+ }
+
+ /**
+ * Id of the message that we are replying to
+ */
+ public get responseTo(): string | undefined {
+ return this.proto.responseTo;
+ }
+
+ /**
+ * Ens name of the sender
+ */
+ public get ensName(): string | undefined {
+ return this.proto.ensName;
+ }
+
+ /**
+ * Chat id, this field is symmetric for public-chats and private group chats,
+ * but asymmetric in case of one-to-ones, as the sender will use the chat-id
+ * of the received, while the receiver will use the chat-id of the sender.
+ * Probably should be the concatenation of sender-pk & receiver-pk in alphabetical order
+ */
+ public get chatId(): string {
+ return this.proto.chatId;
+ }
+
+ /**
+ * The type of message (public/one-to-one/private-group-chat)
+ */
+ public get messageType(): MessageType | undefined {
+ return this.proto.messageType;
+ }
+
+ /**
+ * The type of the content of the message
+ */
+ public get contentType(): ChatMessage_ContentType | undefined {
+ return this.proto.contentType;
+ }
+
+ public get sticker(): StickerMessage | undefined {
+ return this.proto.sticker;
+ }
+
+ public get image(): ImageMessage | undefined {
+ return this.proto.image;
+ }
+
+ public get audio(): AudioMessage | undefined {
+ return this.proto.audio;
+ }
+
+ /**
+ * Used when sharing a community via a chat message.
+ */
+ public get community(): Uint8Array | undefined {
+ return this.proto.community;
+ }
+}
diff --git a/packages/status-core/src/wire/community_chat.ts b/packages/status-core/src/wire/community_chat.ts
new file mode 100644
index 00000000..474c2b99
--- /dev/null
+++ b/packages/status-core/src/wire/community_chat.ts
@@ -0,0 +1,59 @@
+import { Reader } from "protobufjs";
+
+import * as proto from "../proto/communities/v1/communities";
+import {
+ CommunityMember,
+ CommunityPermissions,
+} from "../proto/communities/v1/communities";
+
+import { ChatIdentity } from "./chat_identity";
+
+export class CommunityChat {
+ public constructor(public proto: proto.CommunityChat) {}
+
+ /**
+ * Decode the payload as CommunityChat message.
+ *
+ * @throws
+ */
+ static decode(bytes: Uint8Array): CommunityChat {
+ const protoBuf = proto.CommunityChat.decode(Reader.create(bytes));
+
+ return new CommunityChat(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.CommunityChat.encode(this.proto).finish();
+ }
+
+ // TODO: check and document what is the key of the returned Map;
+ public get members(): Map {
+ const map = new Map();
+
+ for (const key of Object.keys(this.proto.members)) {
+ map.set(key, this.proto.members[key]);
+ }
+
+ return map;
+ }
+
+ public get permissions(): CommunityPermissions | undefined {
+ return this.proto.permissions;
+ }
+
+ public get identity(): ChatIdentity | undefined {
+ if (!this.proto.identity) return;
+
+ return new ChatIdentity(this.proto.identity);
+ }
+
+ // TODO: Document this
+ public get categoryId(): string | undefined {
+ return this.proto.categoryId;
+ }
+
+ // TODO: Document this
+ public get position(): number | undefined {
+ return this.proto.position;
+ }
+}
diff --git a/packages/status-core/src/wire/community_description.ts b/packages/status-core/src/wire/community_description.ts
new file mode 100644
index 00000000..b4bef503
--- /dev/null
+++ b/packages/status-core/src/wire/community_description.ts
@@ -0,0 +1,101 @@
+import debug from "debug";
+import { WakuMessage, WakuStore } from "js-waku";
+import { Reader } from "protobufjs";
+
+import { idToContentTopic } from "../contentTopic";
+import { createSymKeyFromPassword } from "../encryption";
+import * as proto from "../proto/communities/v1/communities";
+import { bufToHex } from "../utils";
+
+import { ApplicationMetadataMessage } from "./application_metadata_message";
+import { ChatIdentity } from "./chat_identity";
+import { CommunityChat } from "./community_chat";
+
+const dbg = debug("communities:wire:community_description");
+
+export class CommunityDescription {
+ private constructor(public proto: proto.CommunityDescription) {}
+
+ static decode(bytes: Uint8Array): CommunityDescription {
+ const protoBuf = proto.CommunityDescription.decode(Reader.create(bytes));
+
+ return new CommunityDescription(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.CommunityDescription.encode(this.proto).finish();
+ }
+
+ /**
+ * Retrieves the most recent Community Description it can find on the network.
+ */
+ public static async retrieve(
+ communityPublicKey: Uint8Array,
+ wakuStore: WakuStore
+ ): Promise {
+ const hexCommunityPublicKey = bufToHex(communityPublicKey);
+ const contentTopic = idToContentTopic(hexCommunityPublicKey);
+
+ let communityDescription: CommunityDescription | undefined;
+
+ const callback = (messages: WakuMessage[]): void => {
+ // Value found, stop processing
+ if (communityDescription) return;
+
+ // Process most recent message first
+ const orderedMessages = messages.reverse();
+ orderedMessages.forEach((message: WakuMessage) => {
+ if (!message.payload) return;
+ try {
+ const metadata = ApplicationMetadataMessage.decode(message.payload);
+ if (!metadata.payload) return;
+
+ const _communityDescription = CommunityDescription.decode(
+ metadata.payload
+ );
+
+ if (!_communityDescription.identity) return;
+
+ communityDescription = _communityDescription;
+ } catch (e) {
+ dbg(
+ `Failed to decode message as CommunityDescription found on content topic ${contentTopic}`,
+ e
+ );
+ }
+ });
+ };
+
+ const symKey = await createSymKeyFromPassword(hexCommunityPublicKey);
+
+ await wakuStore
+ .queryHistory([contentTopic], {
+ callback,
+ decryptionKeys: [symKey],
+ })
+ .catch((e) => {
+ dbg(
+ `Failed to retrieve community description for ${hexCommunityPublicKey}`,
+ e
+ );
+ });
+
+ return communityDescription;
+ }
+
+ get identity(): ChatIdentity | undefined {
+ if (!this.proto.identity) return;
+
+ return new ChatIdentity(this.proto.identity);
+ }
+
+ get chats(): Map {
+ const map = new Map();
+
+ for (const key of Object.keys(this.proto.chats)) {
+ map.set(key, this.proto.chats[key]);
+ }
+
+ return map;
+ }
+}
diff --git a/packages/status-core/src/wire/membership_update_message.ts b/packages/status-core/src/wire/membership_update_message.ts
new file mode 100644
index 00000000..bc4bd543
--- /dev/null
+++ b/packages/status-core/src/wire/membership_update_message.ts
@@ -0,0 +1,201 @@
+import { keccak256 } from "js-sha3";
+import { Reader } from "protobufjs";
+import * as secp256k1 from "secp256k1";
+import { v4 as uuidV4 } from "uuid";
+
+import { Identity } from "..";
+import * as proto from "../proto/communities/v1/membership_update_message";
+import { bufToHex, hexToBuf } from "../utils";
+
+export class MembershipUpdateEvent {
+ public constructor(public proto: proto.MembershipUpdateEvent) {}
+
+ static decode(bytes: Uint8Array): MembershipUpdateEvent {
+ const protoBuf = proto.MembershipUpdateEvent.decode(Reader.create(bytes));
+ return new MembershipUpdateEvent(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.MembershipUpdateEvent.encode(this.proto).finish();
+ }
+
+ public get members(): string[] {
+ return this.proto.members;
+ }
+
+ public get name(): string {
+ return this.proto.name;
+ }
+
+ public get clock(): number {
+ return this.proto.clock;
+ }
+
+ public get type(): proto.MembershipUpdateEvent_EventType {
+ return this.proto.type;
+ }
+}
+
+export class MembershipSignedEvent {
+ public sig: Uint8Array;
+ public event: MembershipUpdateEvent;
+ private chatId: string;
+
+ public constructor(
+ sig: Uint8Array,
+ event: MembershipUpdateEvent,
+ chatId: string
+ ) {
+ this.sig = sig;
+ this.event = event;
+ this.chatId = chatId;
+ }
+
+ public get signer(): Uint8Array | undefined {
+ const encEvent = this.event.encode();
+ const eventToSign = Buffer.concat([hexToBuf(this.chatId), encEvent]);
+
+ if (!this.sig || !eventToSign) return;
+
+ const signature = this.sig.slice(0, 64);
+ const recid = this.sig.slice(64)[0];
+ const hash = keccak256(eventToSign);
+
+ return secp256k1.ecdsaRecover(signature, recid, hexToBuf(hash));
+ }
+}
+
+export class MembershipUpdateMessage {
+ private clock: number = Date.now();
+ private identity: Identity = Identity.generate();
+ public constructor(public proto: proto.MembershipUpdateMessage) {}
+
+ public static create(
+ chatId: string,
+ identity: Identity
+ ): MembershipUpdateMessage {
+ const partial = proto.MembershipUpdateMessage.fromPartial({
+ chatId,
+ events: [],
+ });
+ const newMessage = new MembershipUpdateMessage(partial);
+ newMessage.clock = Date.now();
+ newMessage.identity = identity;
+ return newMessage;
+ }
+
+ private addEvent(event: MembershipUpdateEvent): void {
+ const encEvent = event.encode();
+ const eventToSign = Buffer.concat([hexToBuf(this.proto.chatId), encEvent]);
+ const signature = this.identity.sign(eventToSign);
+ this.proto.events.push(Buffer.concat([signature, encEvent]));
+ }
+
+ public static createChat(
+ identity: Identity,
+ members: string[],
+ name?: string
+ ): MembershipUpdateMessage {
+ const chatId = `${uuidV4()}-${bufToHex(identity.publicKey)}`;
+
+ const message = this.create(chatId, identity);
+ const type = proto.MembershipUpdateEvent_EventType.CHAT_CREATED;
+ const event = new MembershipUpdateEvent({
+ clock: message.clock,
+ members,
+ name: name ?? "",
+ type,
+ });
+ message.addEvent(event);
+ return message;
+ }
+
+ public addNameChangeEvent(name: string): void {
+ const type = proto.MembershipUpdateEvent_EventType.NAME_CHANGED;
+ const event = new MembershipUpdateEvent({
+ clock: this.clock,
+ members: [],
+ name: name,
+ type,
+ });
+ this.addEvent(event);
+ }
+
+ public addMembersAddedEvent(members: string[]): void {
+ const type = proto.MembershipUpdateEvent_EventType.MEMBERS_ADDED;
+ const event = new MembershipUpdateEvent({
+ clock: this.clock,
+ members,
+ name: "",
+ type,
+ });
+ this.addEvent(event);
+ }
+
+ public addMemberJoinedEvent(member: string): void {
+ const type = proto.MembershipUpdateEvent_EventType.MEMBER_JOINED;
+ const event = new MembershipUpdateEvent({
+ clock: this.clock,
+ members: [member],
+ name: "",
+ type,
+ });
+ this.addEvent(event);
+ }
+
+ public addMemberRemovedEvent(member: string): void {
+ const type = proto.MembershipUpdateEvent_EventType.MEMBER_REMOVED;
+ const event = new MembershipUpdateEvent({
+ clock: this.clock,
+ members: [member],
+ name: "",
+ type,
+ });
+ this.addEvent(event);
+ }
+
+ public addAdminsAddedEvent(members: string[]): void {
+ const type = proto.MembershipUpdateEvent_EventType.ADMINS_ADDED;
+ const event = new MembershipUpdateEvent({
+ clock: this.clock,
+ members,
+ name: "",
+ type,
+ });
+ this.addEvent(event);
+ }
+
+ public addAdminRemovedEvent(member: string): void {
+ const type = proto.MembershipUpdateEvent_EventType.ADMINS_ADDED;
+ const event = new MembershipUpdateEvent({
+ clock: this.clock,
+ members: [member],
+ name: "",
+ type,
+ });
+ this.addEvent(event);
+ }
+
+ static decode(bytes: Uint8Array): MembershipUpdateMessage {
+ const protoBuf = proto.MembershipUpdateMessage.decode(Reader.create(bytes));
+ return new MembershipUpdateMessage(protoBuf);
+ }
+
+ public get events(): MembershipSignedEvent[] {
+ return this.proto.events.map((bufArray) => {
+ return new MembershipSignedEvent(
+ bufArray.slice(0, 65),
+ MembershipUpdateEvent.decode(bufArray.slice(65)),
+ this.chatId
+ );
+ });
+ }
+
+ public get chatId(): string {
+ return this.proto.chatId;
+ }
+
+ encode(): Uint8Array {
+ return proto.MembershipUpdateMessage.encode(this.proto).finish();
+ }
+}
diff --git a/packages/status-core/src/wire/status_update.ts b/packages/status-core/src/wire/status_update.ts
new file mode 100644
index 00000000..25d5e357
--- /dev/null
+++ b/packages/status-core/src/wire/status_update.ts
@@ -0,0 +1,49 @@
+import { Reader } from "protobufjs";
+
+import * as proto from "../proto/communities/v1/status_update";
+
+export class StatusUpdate {
+ public constructor(public proto: proto.StatusUpdate) {}
+
+ public static create(
+ statusType: proto.StatusUpdate_StatusType,
+ customText: string
+ ): StatusUpdate {
+ const clock = Date.now();
+
+ const proto = {
+ clock,
+ statusType,
+ customText,
+ };
+
+ return new StatusUpdate(proto);
+ }
+
+ /**
+ * Decode the payload as CommunityChat message.
+ *
+ * @throws
+ */
+ static decode(bytes: Uint8Array): StatusUpdate {
+ const protoBuf = proto.StatusUpdate.decode(Reader.create(bytes));
+
+ return new StatusUpdate(protoBuf);
+ }
+
+ encode(): Uint8Array {
+ return proto.StatusUpdate.encode(this.proto).finish();
+ }
+
+ public get clock(): number | undefined {
+ return this.proto.clock;
+ }
+
+ public get statusType(): proto.StatusUpdate_StatusType | undefined {
+ return this.proto.statusType;
+ }
+
+ public get customText(): string | undefined {
+ return this.proto.customText;
+ }
+}
diff --git a/packages/status-core/tsconfig.json b/packages/status-core/tsconfig.json
new file mode 100644
index 00000000..482825d4
--- /dev/null
+++ b/packages/status-core/tsconfig.json
@@ -0,0 +1,51 @@
+{
+ "compilerOptions": {
+ "incremental": true,
+ "target": "es6",
+ "outDir": "dist",
+ "rootDir": "src",
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "declaration": true,
+ "sourceMap": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "composite": true,
+ "strict": true /* Enable all strict type-checking options. */,
+
+ /* Strict Type-Checking Options */
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "strictPropertyInitialization": true,
+ "noImplicitThis": true,
+ "alwaysStrict": true,
+
+ /* Additional Checks */
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": false /* to set at a later stage */,
+ "noFallthroughCasesInSwitch": true,
+ "forceConsistentCasingInFileNames": true,
+
+ /* Debugging Options */
+ "traceResolution": false,
+ "listEmittedFiles": false,
+ "listFiles": false,
+ "pretty": true,
+
+ // Due to broken types in indirect dependencies
+ "skipLibCheck": true,
+
+ "lib": ["es6", "dom"],
+ "typeRoots": [
+ "./node_modules/@types",
+ "./src/types",
+ "../../node_modules/@types"
+ ]
+ },
+ "include": ["src"],
+ "exclude": ["node_modules/**"],
+ "types": ["mocha"],
+ "compileOnSave": false
+}
diff --git a/packages/status-react/.eslintrc.json b/packages/status-react/.eslintrc.json
new file mode 100644
index 00000000..051027ab
--- /dev/null
+++ b/packages/status-react/.eslintrc.json
@@ -0,0 +1,42 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": { "project": "./tsconfig.json" },
+ "env": { "es6": true },
+ "ignorePatterns": ["node_modules", "dist", "coverage", "proto"],
+ "plugins": ["import", "eslint-comments", "functional"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:eslint-comments/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:import/typescript",
+ "plugin:react-hooks/recommended",
+ "prettier"
+ ],
+ "globals": { "BigInt": true, "console": true, "WebAssembly": true },
+ "rules": {
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "eslint-comments/disable-enable-pair": [
+ "error",
+ { "allowWholeFile": true }
+ ],
+ "eslint-comments/no-unused-disable": "error",
+ "import/order": [
+ "error",
+ { "newlines-between": "always", "alphabetize": { "order": "asc" } }
+ ],
+ "no-constant-condition": ["error", { "checkLoops": false }],
+ "sort-imports": [
+ "error",
+ { "ignoreDeclarationSort": true, "ignoreCase": true }
+ ]
+ },
+ "overrides": [
+ {
+ "files": ["*.spec.ts", "**/test_utils/*.ts"],
+ "rules": {
+ "@typescript-eslint/no-non-null-assertion": "off"
+ }
+ }
+ ]
+}
diff --git a/packages/status-react/.mocharc.json b/packages/status-react/.mocharc.json
new file mode 100644
index 00000000..b65763d3
--- /dev/null
+++ b/packages/status-react/.mocharc.json
@@ -0,0 +1,6 @@
+{
+ "extension": ["ts"],
+ "spec": "src/**/*.spec.ts",
+ "require": "ts-node/register",
+ "exit": true
+}
diff --git a/packages/status-react/.prettierignore b/packages/status-react/.prettierignore
new file mode 100644
index 00000000..996c3a37
--- /dev/null
+++ b/packages/status-react/.prettierignore
@@ -0,0 +1,2 @@
+# package.json is formatted by package managers, so we ignore it here
+package.json
diff --git a/packages/status-react/README.md b/packages/status-react/README.md
new file mode 100644
index 00000000..ae921546
--- /dev/null
+++ b/packages/status-react/README.md
@@ -0,0 +1 @@
+# `status-react`
\ No newline at end of file
diff --git a/packages/status-react/buf.gen.yaml b/packages/status-react/buf.gen.yaml
new file mode 100644
index 00000000..40edf963
--- /dev/null
+++ b/packages/status-react/buf.gen.yaml
@@ -0,0 +1,6 @@
+version: v1beta1
+
+plugins:
+ - name: ts_proto
+ out: ./src/proto
+ opt: grpc_js,esModuleInterop=true
diff --git a/packages/status-react/buf.yaml b/packages/status-react/buf.yaml
new file mode 100644
index 00000000..c7b2d892
--- /dev/null
+++ b/packages/status-react/buf.yaml
@@ -0,0 +1,5 @@
+version: v1beta1
+
+build:
+ roots:
+ - ./proto
diff --git a/packages/status-react/package.json b/packages/status-react/package.json
new file mode 100644
index 00000000..8f6911ac
--- /dev/null
+++ b/packages/status-react/package.json
@@ -0,0 +1,69 @@
+{
+ "name": "@status-im/react",
+ "version": "0.0.0",
+ "license": "MIT OR Apache-2.0",
+ "homepage": "https://github.com/status-im/status-web",
+ "repository": {
+ "url": "https://github.com/status-im/status-web.git",
+ "directory": "packages/status-react",
+ "type": "git"
+ },
+ "bugs": {
+ "url": "https://github.com/status-im/status-web/issues"
+ },
+ "main": "dist/cjs/src/index.js",
+ "module": "dist/esm/src/index.js",
+ "types": "dist/esm/src/index.d.ts",
+ "scripts": {
+ "build": "run-s 'build:*'",
+ "build:esm": "tsc --module es2020 --target es2017 --outDir dist/esm",
+ "build:cjs": "tsc --outDir dist/cjs",
+ "fix": "run-s 'fix:*'",
+ "fix:prettier": "prettier './{src,test}/**/*.{ts,tsx}' \"./*.json\" --write",
+ "fix:lint": "eslint './{src,test}/**/*.{ts,tsx}' --fix",
+ "test": "run-s 'test:*'",
+ "test:lint": "eslint './{src,test}/**/*.{ts,tsx}'",
+ "test:prettier": "prettier './{src,test}/**/*.{ts,tsx}' \"./*.json\" --list-different",
+ "proto": "run-s 'proto:*'",
+ "proto:lint": "buf lint",
+ "proto:build": "buf generate"
+ },
+ "devDependencies": {
+ "@hcaptcha/react-hcaptcha": "^1.0.0",
+ "@types/chai": "^4.2.21",
+ "@types/emoji-mart": "^3.0.6",
+ "@types/hcaptcha__react-hcaptcha": "^0.1.5",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^16.9.6",
+ "@types/qrcode.react": "^1.0.2",
+ "@types/react": "^17.0.16",
+ "@types/styled-components": "^5.1.12",
+ "@typescript-eslint/eslint-plugin": "^4.29.0",
+ "@typescript-eslint/parser": "^4.29.0",
+ "chai": "^4.3.4",
+ "copyfiles": "^2.4.1",
+ "eslint": "^7.32.0",
+ "eslint-plugin-react-hooks": "^4.3.0",
+ "jsdom": "^16.7.0",
+ "jsdom-global": "^3.0.2",
+ "mocha": "^9.0.3",
+ "npm-run-all": "^4.1.5",
+ "npm-watch": "^0.11.0",
+ "prettier": "^2.3.2",
+ "qrcode.react": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ts-node": "^10.1.0",
+ "typescript": "^4.3.5"
+ },
+ "dependencies": {
+ "@status-im/core": "^0.0.0",
+ "emoji-mart": "^3.0.1",
+ "html-entities": "^2.3.2",
+ "js-sha3": "^0.8.0",
+ "js-waku": "^0.16.0",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "react-is": "^17.0.2",
+ "styled-components": "^5.3.1"
+ }
+}
diff --git a/packages/status-react/src/components/ActivityCenter/ActivityButton.tsx b/packages/status-react/src/components/ActivityCenter/ActivityButton.tsx
new file mode 100644
index 00000000..939b7ee2
--- /dev/null
+++ b/packages/status-react/src/components/ActivityCenter/ActivityButton.tsx
@@ -0,0 +1,116 @@
+import React, { useMemo, useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useIdentity } from "../../contexts/identityProvider";
+import { useActivities } from "../../hooks/useActivities";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { TopBtn } from "../Chat/ChatTopbar";
+import { ActivityIcon } from "../Icons/ActivityIcon";
+
+import { ActivityCenter } from "./ActivityCenter";
+
+interface ActivityButtonProps {
+ className?: string;
+}
+
+export function ActivityButton({ className }: ActivityButtonProps) {
+ const { activities, activityDispatch } = useActivities();
+ const identity = useIdentity();
+ const disabled = useMemo(() => !identity, [identity]);
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowActivityCenter(false));
+
+ const [showActivityCenter, setShowActivityCenter] = useState(false);
+ const badgeAmount = useMemo(
+ () => activities.filter((activity) => !activity.isRead).length,
+ [activities]
+ );
+
+ return (
+
+ setShowActivityCenter(!showActivityCenter)}
+ disabled={disabled}
+ >
+
+ {badgeAmount > 0 && (
+ 99
+ ? "countless"
+ : badgeAmount > 9
+ ? "wide"
+ : undefined
+ }
+ >
+ {badgeAmount < 100 ? badgeAmount : "∞"}
+
+ )}
+
+ {showActivityCenter && (
+
+ )}
+
+ );
+}
+
+export const ActivityWrapper = styled.div`
+ padding-left: 10px;
+ margin-left: 10px;
+ position: relative;
+
+ &:before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 50%;
+ width: 2px;
+ height: 24px;
+ transform: translateY(-50%);
+ border-radius: 1px;
+ background: ${({ theme }) => theme.primary};
+ opacity: 0.1;
+ }
+
+ &.creation {
+ padding-left: 0px;
+ margin-left: 16px;
+
+ &:before {
+ width: 0px;
+ height: 0px;
+ }
+ }
+`;
+
+const NotificationBagde = styled.div`
+ width: 18px;
+ height: 18px;
+ position: absolute;
+ top: -2px;
+ right: -2px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ border-radius: 50%;
+ font-size: 12px;
+ line-height: 16px;
+ font-weight: 500;
+ background-color: ${({ theme }) => theme.notificationColor};
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+ border-radius: 9px;
+
+ &.wide {
+ width: 26px;
+ right: -7px;
+ }
+
+ &.countless {
+ width: 22px;
+ }
+`;
diff --git a/packages/status-react/src/components/ActivityCenter/ActivityCenter.tsx b/packages/status-react/src/components/ActivityCenter/ActivityCenter.tsx
new file mode 100644
index 00000000..5c18c8d3
--- /dev/null
+++ b/packages/status-react/src/components/ActivityCenter/ActivityCenter.tsx
@@ -0,0 +1,189 @@
+import React, { useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { ActivityAction } from "../../hooks/useActivities";
+import { Activity } from "../../models/Activity";
+import { buttonTransparentStyles } from "../Buttons/buttonStyle";
+import { Tooltip } from "../Form/Tooltip";
+import { HideIcon } from "../Icons/HideIcon";
+import { ReadIcon } from "../Icons/ReadIcon";
+import { ShowIcon } from "../Icons/ShowIcon";
+
+import { ActivityMessage } from "./ActivityMessage";
+
+interface ActivityCenterProps {
+ activities: Activity[];
+ setShowActivityCenter: (val: boolean) => void;
+ activityDispatch: React.Dispatch;
+}
+
+export function ActivityCenter({
+ activities,
+ setShowActivityCenter,
+ activityDispatch,
+}: ActivityCenterProps) {
+ const { contacts } = useMessengerContext();
+
+ const shownActivities = useMemo(
+ () =>
+ activities.filter(
+ (activity) => !contacts?.[activity.user]?.blocked ?? true
+ ),
+ [contacts, activities]
+ );
+
+ const [hideRead, setHideRead] = useState(false);
+
+ const [filter, setFilter] = useState("");
+
+ const filteredActivities = shownActivities.filter((activity) =>
+ filter
+ ? activity.type === filter
+ : hideRead
+ ? activity.isRead !== true
+ : activity
+ );
+
+ return (
+
+
+
+ setFilter("")}>All
+ setFilter("mention")}>Mentions
+ setFilter("reply")}>Replies
+ setFilter("request")}>
+ Contact requests
+
+
+
+
+ activityDispatch({ type: "setAllAsRead" })}
+ >
+
+
+
+
+
+ setHideRead(!hideRead)}>
+ {hideRead ? : }
+
+
+
+
+
+ {filteredActivities.length > 0 ? (
+
+ {filteredActivities.map((activity) => (
+
+ ))}
+
+ ) : (
+ Notifications will appear here
+ )}
+
+ );
+}
+
+const ActivityBlock = styled.div`
+ width: 600px;
+ height: 770px;
+ display: flex;
+ flex-direction: column;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ box-shadow: 0px 12px 24px rgba(0, 34, 51, 0.1);
+ border-radius: 8px;
+ position: absolute;
+ top: calc(100% + 4px);
+ right: 0;
+ z-index: 100;
+`;
+
+const ActivityFilter = styled.div`
+ display: flex;
+ justify-content: space-between;
+ padding: 13px 16px;
+`;
+
+export const FlexDiv = styled.div`
+ display: flex;
+`;
+
+const FilterBtn = styled.button`
+ ${buttonTransparentStyles}
+
+ & + & {
+ margin-left: 8px;
+ }
+`;
+
+const BtnWrapper = styled.div`
+ position: relative;
+
+ &:hover > div {
+ visibility: visible;
+ }
+`;
+
+export const ActivityBtn = styled.button`
+ width: 32px;
+ height: 32px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 8px;
+ align-self: center;
+
+ &:hover {
+ background: ${({ theme }) => theme.buttonBgHover};
+ }
+
+ &.read {
+ &:hover {
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+ }
+
+ &.accept {
+ &:hover {
+ background: rgba(78, 188, 96, 0.1);
+ }
+ }
+
+ &.decline {
+ &:hover {
+ background: rgba(255, 45, 85, 0.1);
+ }
+ }
+
+ & + & {
+ margin-left: 8px;
+ }
+`;
+
+const Activities = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ overflow: auto;
+`;
+
+const EmptyActivities = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex: 1;
+ width: 100%;
+ color: ${({ theme }) => theme.secondary};
+`;
+
+const Btns = styled.div`
+ display: flex;
+ align-items: center;
+`;
diff --git a/packages/status-react/src/components/ActivityCenter/ActivityMessage.tsx b/packages/status-react/src/components/ActivityCenter/ActivityMessage.tsx
new file mode 100644
index 00000000..455e8a92
--- /dev/null
+++ b/packages/status-react/src/components/ActivityCenter/ActivityMessage.tsx
@@ -0,0 +1,386 @@
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { useScrollToMessage } from "../../contexts/scrollProvider";
+import { ActivityAction } from "../../hooks/useActivities";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { Activity } from "../../models/Activity";
+import { equalDate } from "../../utils/equalDate";
+import { DownloadButton } from "../Buttons/DownloadButton";
+import { Mention } from "../Chat/ChatMessageContent";
+import { Logo } from "../CommunityIdentity";
+import { ContactMenu } from "../Form/ContactMenu";
+import { Tooltip } from "../Form/Tooltip";
+import { CheckIcon } from "../Icons/CheckIcon";
+import { ClearSvg } from "../Icons/ClearIcon";
+import { CommunityIcon } from "../Icons/CommunityIcon";
+import { GroupIcon } from "../Icons/GroupIcon";
+import { MoreIcon } from "../Icons/MoreIcon";
+import { ReadMessageIcon } from "../Icons/ReadMessageIcon";
+import { ReplyIcon } from "../Icons/ReplyActivityIcon";
+import { UntrustworthIcon } from "../Icons/UntrustworthIcon";
+import { UserIcon } from "../Icons/UserIcon";
+import {
+ ContentWrapper,
+ DateSeparator,
+ MessageHeaderWrapper,
+ MessageOuterWrapper,
+ MessageText,
+ TimeWrapper,
+ UserAddress,
+ UserName,
+ UserNameWrapper,
+} from "../Messages/Styles";
+import { ProfileModalName } from "../Modals/ProfileModal";
+import { textMediumStyles, textSmallStyles } from "../Text";
+
+import { ActivityBtn, FlexDiv } from "./ActivityCenter";
+
+const today = new Date();
+
+type ActivityMessageProps = {
+ activity: Activity;
+ setShowActivityCenter: (val: boolean) => void;
+ activityDispatch: React.Dispatch;
+};
+
+export function ActivityMessage({
+ activity,
+ setShowActivityCenter,
+ activityDispatch,
+}: ActivityMessageProps) {
+ const { contacts, channelsDispatch } = useMessengerContext();
+ const scroll = useScrollToMessage();
+ const { setModal } = useModal(ProfileModalName);
+ const showChannel = () => {
+ "channel" in activity &&
+ channelsDispatch({ type: "ChangeActive", payload: activity.channel.id }),
+ setShowActivityCenter(false);
+ };
+
+ const [showMenu, setShowMenu] = useState(false);
+
+ const type = activity.type;
+
+ const contact = useMemo(
+ () => contacts[activity.user],
+ [activity.user, contacts]
+ );
+
+ const [elements, setElements] = useState<
+ (string | React.ReactElement | undefined)[]
+ >(["message" in activity ? activity.message?.content : undefined]);
+
+ useEffect(() => {
+ if ("message" in activity) {
+ const split = activity.message?.content.split(" ");
+ const newSplit = split.flatMap((element, idx) => {
+ if (element.startsWith("@")) {
+ return [
+ true}
+ className="activity"
+ />,
+ " ",
+ ];
+ }
+ return [element, " "];
+ });
+ newSplit.pop();
+ setElements(newSplit);
+ }
+ }, [activity]);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ return (
+
+
+ {equalDate(activity.date, today)
+ ? "Today"
+ : activity.date.toLocaleDateString()}
+
+
+
+ <>
+
+
+
+
+ {
+ setModal({
+ id: activity.user,
+ renamingState: false,
+ requestState: false,
+ });
+ }}
+ >
+ {" "}
+ {contact?.customName ?? activity.user.slice(0, 10)}
+
+ {contact?.customName && (
+
+ {activity.user.slice(0, 5)}...{activity.user.slice(-3)}
+
+ )}
+ {contact.isUntrustworthy && }
+
+
+ {activity.date.toLocaleString("en-US", {
+ hour: "numeric",
+ minute: "numeric",
+ hour12: true,
+ })}
+
+
+ {type === "request" && (
+
+ Contact request
+ {activity.requestType === "outcome"
+ ? ` to ${activity.user.slice(0, 10)}`
+ : ": "}
+
+ )}
+ {type === "invitation" && (
+
+ {`Invited you to join a community `}
+
+
+
+ {activity.invitation?.icon === undefined &&
+ activity.invitation?.name.slice(0, 1).toUpperCase()}
+
+ {activity.invitation?.name}
+
+
+ )}
+
+ {"message" in activity && activity.message?.content && (
+ {
+ scroll(activity.message, activity.channel.id);
+ setShowActivityCenter(false);
+ }}
+ >
+ {elements.map((el) => el)}
+
+ )}
+ {activity.type === "request" &&
+ activity.requestType === "income" &&
+ activity.request}
+
+ {type === "mention" &&
+ activity.channel &&
+ activity.channel.type !== "dm" && (
+
+ {activity.channel.type === "group" ? : "#"}{" "}
+ {` ${activity.channel.name.slice(0, 10)}`}
+
+ )}
+ {type === "reply" && activity.quote && (
+
+ {activity.quote.image && (
+ Posted an image in
+ )}
+
+ {activity.quote.content}
+
+
+ )}
+ {type === "invitation" && (
+
+ {`To access other communities, `}
+
+
+ )}
+
+ >
+ {type === "request" &&
+ !activity.status &&
+ activity.requestType === "income" && (
+ <>
+ {
+ activityDispatch({
+ type: "setStatus",
+ payload: { id: activity.id, status: "accepted" },
+ });
+ }}
+ className="accept"
+ >
+
+
+ {
+ activityDispatch({
+ type: "setStatus",
+ payload: { id: activity.id, status: "declined" },
+ });
+ }}
+ className="decline"
+ >
+
+
+ {
+ setShowMenu((e) => !e);
+ }}
+ ref={ref}
+ >
+ {showMenu && (
+
+ )}
+
+
+ >
+ )}
+ {type === "request" && activity.status === "accepted" && (
+ Accepted
+ )}
+ {type === "request" && activity.status === "declined" && (
+ Declined
+ )}
+ {type === "request" && activity.status === "sent" && (
+ Sent
+ )}
+ {(type === "mention" || type === "reply") && (
+
+
+ activityDispatch({ type: "setAsRead", payload: activity.id })
+ }
+ className={`${activity.isRead && "read"}`}
+ >
+
+
+
+
+ )}
+
+
+ );
+}
+
+const InviteDiv = styled.div`
+ display: flex;
+ margin-top: -4px;
+`;
+
+const BtnWrapper = styled.div`
+ position: relative;
+
+ &:hover > div {
+ visibility: visible;
+ }
+`;
+
+const ActivityDate = styled(DateSeparator)`
+ justify-content: flex-start;
+ padding: 8px 16px;
+ margin: 0;
+`;
+
+const MessageWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ align-items: flex-start;
+ padding: 8px 16px;
+
+ &.unread {
+ background: ${({ theme }) => theme.buttonBgHover};
+ }
+`;
+
+const ActivityText = styled(MessageText)`
+ white-space: unset;
+ margin-bottom: 8px;
+`;
+
+const Tag = styled.div`
+ width: fit-content;
+ max-width: 200px;
+ display: flex;
+ align-items: center;
+
+ border: 1px solid ${({ theme }) => theme.secondary};
+ border-radius: 11px;
+ padding: 0 6px;
+ cursor: pointer;
+
+ font-weight: 500;
+ color: ${({ theme }) => theme.secondary};
+ ${textSmallStyles}
+
+ & > span {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+`;
+
+const ContextHeading = styled.p`
+ font-style: italic;
+ color: ${({ theme }) => theme.secondary};
+ flex-shrink: 0;
+ white-space: pre-wrap;
+ ${textMediumStyles}
+`;
+
+const RequestStatus = styled.p`
+ font-weight: 500;
+ align-self: center;
+ text-align: end;
+ color: ${({ theme }) => theme.secondary};
+ ${textSmallStyles}
+
+ &.accepted {
+ color: ${({ theme }) => theme.greenColor};
+ }
+
+ &.declined {
+ color: ${({ theme }) => theme.redColor};
+ }
+`;
+
+const ActivityContent = styled(ContentWrapper)`
+ max-width: calc(100% - 80px);
+ flex: 1;
+`;
+
+const ActivityUserName = styled(UserName)`
+ cursor: pointer;
+
+ &:hover {
+ text-decoration: underline;
+ }
+`;
+
+const ReplyWrapper = styled.div`
+ max-width: 100%;
+ display: flex;
+ align-items: center;
+
+ & > p {
+ margin-right: 4px;
+ }
+`;
+
+const CommunityLogo = styled(Logo)`
+ width: 16px;
+ height: 16px;
+ margin: 0 2px 0 4px;
+
+ ${textSmallStyles}
+`;
diff --git a/packages/status-react/src/components/Buttons/BackButton.tsx b/packages/status-react/src/components/Buttons/BackButton.tsx
new file mode 100644
index 00000000..152c6265
--- /dev/null
+++ b/packages/status-react/src/components/Buttons/BackButton.tsx
@@ -0,0 +1,31 @@
+import React from "react";
+import styled from "styled-components";
+
+import { LeftIcon } from "../Icons/LeftIcon";
+
+interface BackButtonProps {
+ onBtnClick: () => void;
+ className?: string;
+}
+
+export function BackButton({ onBtnClick, className }: BackButtonProps) {
+ return (
+
+
+
+ );
+}
+
+const BackBtn = styled.button`
+ position: absolute;
+ left: 0;
+ top: 8px;
+ width: 32px;
+ height: 44px;
+ padding: 0;
+
+ &.narrow {
+ position: static;
+ margin-right: 13px;
+ }
+`;
diff --git a/packages/status-react/src/components/Buttons/DownloadButton.tsx b/packages/status-react/src/components/Buttons/DownloadButton.tsx
new file mode 100644
index 00000000..aabbb4b4
--- /dev/null
+++ b/packages/status-react/src/components/Buttons/DownloadButton.tsx
@@ -0,0 +1,84 @@
+import React, { useEffect, useState } from "react";
+import styled from "styled-components";
+
+import { buttonStyles } from "./buttonStyle";
+
+const userAgent = window.navigator.userAgent;
+const platform = window.navigator.platform;
+const macosPlatforms = ["Macintosh", "MacIntel", "MacPPC", "Mac68K"];
+const windowsPlatforms = ["Win32", "Win64", "Windows", "WinCE"];
+const iosPlatforms = ["iPhone", "iPad", "iPod"];
+
+interface DownloadButtonProps {
+ className?: string;
+}
+
+export const DownloadButton = ({ className }: DownloadButtonProps) => {
+ const [link, setlink] = useState("https://status.im/get/");
+ const [os, setOs] = useState(null);
+
+ useEffect(() => {
+ if (macosPlatforms.includes(platform)) {
+ setlink(
+ "https://status-im-files.ams3.cdn.digitaloceanspaces.com/StatusIm-Desktop-v0.3.0-beta-a8c37d.dmg"
+ );
+ setOs("Mac");
+ } else if (iosPlatforms.includes(platform)) {
+ setlink(
+ "https://apps.apple.com/us/app/status-private-communication/id1178893006"
+ );
+ setOs("iOS");
+ } else if (windowsPlatforms.includes(platform)) {
+ setlink(
+ "https://status-im-files.ams3.cdn.digitaloceanspaces.com/StatusIm-Desktop-v0.3.0-beta-a8c37d.exe"
+ );
+ setOs("Windows");
+ } else if (/Android/.test(userAgent)) {
+ setlink(
+ "https://play.google.com/store/apps/details?id=im.status.ethereum"
+ );
+ setOs("Android");
+ } else if (/Linux/.test(platform)) {
+ setlink(
+ "https://status-im-files.ams3.cdn.digitaloceanspaces.com/StatusIm-Desktop-v0.3.0-beta-a8c37d.tar.gz"
+ );
+ setOs("Linux");
+ }
+ }, []);
+
+ return (
+
+ {os
+ ? `${className === "activity" ? "d" : "D"}ownload Status for ${os}`
+ : `${className === "activity" ? "d" : "D"}ownload Status`}
+
+ );
+};
+
+const Link = styled.a`
+ margin-top: 24px;
+ padding: 11px 32px;
+
+ ${buttonStyles}
+
+ &.activity {
+ margin: 0;
+ padding: 0;
+ color: ${({ theme }) => theme.secondary};
+ font-style: italic;
+ border-radius: 0;
+ font-weight: 400;
+ text-decoration: underline;
+ background: inherit;
+
+ &:hover {
+ background: inherit;
+ color: ${({ theme }) => theme.tertiary};
+ }
+ }
+`;
diff --git a/packages/status-react/src/components/Buttons/buttonStyle.ts b/packages/status-react/src/components/Buttons/buttonStyle.ts
new file mode 100644
index 00000000..fd29e47b
--- /dev/null
+++ b/packages/status-react/src/components/Buttons/buttonStyle.ts
@@ -0,0 +1,59 @@
+import styled, { css } from "styled-components";
+
+export const buttonStyles = css`
+ font-family: "Inter";
+ font-weight: 500;
+ font-size: 15px;
+ line-height: 22px;
+ text-align: center;
+ border-radius: 8px;
+ color: ${({ theme }) => theme.tertiary};
+ background: ${({ theme }) => theme.buttonBg};
+
+ &:hover {
+ background: ${({ theme }) => theme.buttonBgHover};
+ }
+
+ &:focus {
+ background: ${({ theme }) => theme.buttonBg};
+ }
+`;
+
+export const buttonTransparentStyles = css`
+ font-family: "Inter";
+ font-weight: 500;
+ font-size: 13px;
+ line-height: 18px;
+ text-align: center;
+ color: ${({ theme }) => theme.tertiary};
+ background: inherit;
+ padding: 10px 12px;
+ border-radius: 8px;
+
+ &:hover {
+ background: ${({ theme }) => theme.buttonBgHover};
+ }
+
+ &:focus {
+ background: ${({ theme }) => theme.buttonBg};
+ }
+`;
+
+export const ButtonNo = styled.button`
+ padding: 11px 24px;
+ margin-right: 16px;
+
+ ${buttonStyles}
+ background: ${({ theme }) => theme.buttonNoBg};
+ color: ${({ theme }) => theme.redColor};
+
+ &:hover {
+ background: ${({ theme }) => theme.buttonNoBgHover};
+ }
+`;
+
+export const ButtonYes = styled.button`
+ padding: 11px 24px;
+
+ ${buttonStyles}
+`;
diff --git a/packages/status-react/src/components/Channels/Channel.tsx b/packages/status-react/src/components/Channels/Channel.tsx
new file mode 100644
index 00000000..6aa60d91
--- /dev/null
+++ b/packages/status-react/src/components/Channels/Channel.tsx
@@ -0,0 +1,211 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { ChannelData } from "../../models/ChannelData";
+import { ChannelMenu } from "../Form/ChannelMenu";
+import { Tooltip } from "../Form/Tooltip";
+import { GroupIcon } from "../Icons/GroupIcon";
+import { MutedIcon } from "../Icons/MutedIcon";
+import { textMediumStyles } from "../Text";
+
+import { ChannelIcon } from "./ChannelIcon";
+
+function RenderChannelName({
+ channel,
+ activeView,
+ className,
+}: {
+ channel: ChannelData;
+ activeView?: boolean;
+ className?: string;
+}) {
+ const { activeChannel } = useMessengerContext();
+ switch (channel.type) {
+ case "group":
+ return (
+
+ {!activeView && (
+
+ )}
+ {` ${channel.name}`}
+
+ );
+ case "channel":
+ return {`# ${channel.name}`}
;
+ case "dm":
+ return {channel.name.slice(0, 20)}
;
+ }
+}
+
+interface ChannelProps {
+ channel: ChannelData;
+ notified?: boolean;
+ mention?: number;
+ isActive: boolean;
+ activeView?: boolean;
+ onClick?: () => void;
+ setEditGroup?: React.Dispatch>;
+}
+
+export function Channel({
+ channel,
+ isActive,
+ activeView,
+ onClick,
+ notified,
+ mention,
+ setEditGroup,
+}: ChannelProps) {
+ const narrow = useNarrow();
+ const { channelsDispatch } = useMessengerContext();
+
+ return (
+
+
+
+
+
+
+ {channel?.isMuted && activeView && !narrow && (
+
+ channelsDispatch({ type: "ToggleMuted", payload: channel.id })
+ }
+ >
+
+
+
+ )}
+
+ {activeView && (
+ {channel.description}
+ )}
+
+
+ {!activeView && !!mention && !channel?.isMuted && (
+ {mention}
+ )}
+ {channel?.isMuted && !activeView && }
+ {!activeView && (
+
+ )}
+
+ );
+}
+
+const ChannelWrapper = styled.div<{ isNarrow?: boolean }>`
+ width: ${({ isNarrow }) => (isNarrow ? "calc(100% - 162px)" : "100%")};
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px;
+ border-radius: 8px;
+ position: relative;
+ cursor: pointer;
+
+ &.active,
+ &:active {
+ background-color: ${({ theme }) => theme.activeChannelBackground};
+ }
+
+ &:hover {
+ background-color: ${({ theme, isNarrow }) => isNarrow && theme.border};
+ }
+`;
+
+export const ChannelInfo = styled.div<{ activeView?: boolean }>`
+ display: flex;
+ align-items: ${({ activeView }) => (activeView ? "flex-start" : "center")};
+ overflow-x: hidden;
+`;
+
+const ChannelTextInfo = styled.div<{ activeView?: boolean }>`
+ display: flex;
+ flex-direction: column;
+ text-overflow: ellipsis;
+ overflow-x: hidden;
+ white-space: nowrap;
+ padding: ${({ activeView }) => activeView && "0 24px 24px 0"};
+`;
+
+const ChannelNameWrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+export const ChannelName = styled(RenderChannelName)<{
+ muted?: boolean;
+ notified?: boolean;
+ active?: boolean;
+ activeView?: boolean;
+}>`
+ font-weight: ${({ notified, muted, active }) =>
+ notified && !muted && !active ? "600" : "500"};
+ opacity: ${({ notified, muted, active }) =>
+ muted ? "0.4" : notified || active ? "1.0" : "0.7"};
+ color: ${({ theme }) => theme.primary};
+ margin-right: ${({ muted, activeView }) =>
+ muted && activeView ? "8px" : ""};
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ ${textMediumStyles}
+`;
+
+const ChannelDescription = styled.p`
+ font-size: 12px;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ color: ${({ theme }) => theme.secondary};
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+`;
+
+const NotificationBagde = styled.div`
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ font-size: 12px;
+ line-height: 16px;
+ font-weight: 500;
+ background-color: ${({ theme }) => theme.notificationColor};
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+`;
+
+const MutedBtn = styled.button`
+ padding: 0;
+ border: none;
+ outline: none;
+ position: relative;
+
+ &:hover > svg {
+ fill-opacity: 1;
+ }
+
+ &:hover > div {
+ visibility: visible;
+ }
+`;
diff --git a/packages/status-react/src/components/Channels/ChannelIcon.tsx b/packages/status-react/src/components/Channels/ChannelIcon.tsx
new file mode 100644
index 00000000..7f736b48
--- /dev/null
+++ b/packages/status-react/src/components/Channels/ChannelIcon.tsx
@@ -0,0 +1,54 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useNarrow } from "../../contexts/narrowProvider";
+import { ChannelData } from "../../models/ChannelData";
+
+interface ChannelIconProps {
+ channel: ChannelData;
+ activeView?: boolean;
+}
+
+export function ChannelIcon({ channel, activeView }: ChannelIconProps) {
+ const narrow = useNarrow();
+
+ return (
+
+ {!channel.icon && channel.name.slice(0, 1).toUpperCase()}
+
+ );
+}
+
+export const ChannelLogo = styled.div<{ icon?: string }>`
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ margin-right: 10px;
+ border-radius: 50%;
+ font-weight: bold;
+ font-size: 15px;
+ line-height: 20px;
+ background-color: ${({ theme }) => theme.iconColor};
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-image: ${({ icon }) => icon && `url(${icon}`};
+ color: ${({ theme }) => theme.iconTextColor};
+
+ &.active {
+ width: 36px;
+ height: 36px;
+ font-size: 20px;
+ }
+
+ &.narrow {
+ width: 40px;
+ height: 40px;
+ font-size: 20px;
+ }
+`;
diff --git a/packages/status-react/src/components/Channels/Channels.tsx b/packages/status-react/src/components/Channels/Channels.tsx
new file mode 100644
index 00000000..9fdc2043
--- /dev/null
+++ b/packages/status-react/src/components/Channels/Channels.tsx
@@ -0,0 +1,164 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { ChatState, useChatState } from "../../contexts/chatStateProvider";
+import { useIdentity } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { CreateIcon } from "../Icons/CreateIcon";
+import { UserCreation } from "../UserCreation/UserCreation";
+
+import { Channel } from "./Channel";
+
+interface ChannelsProps {
+ onCommunityClick?: () => void;
+ setEditGroup?: React.Dispatch>;
+}
+
+type GenerateChannelsProps = ChannelsProps & {
+ type: string;
+};
+
+function GenerateChannels({
+ type,
+ onCommunityClick,
+ setEditGroup,
+}: GenerateChannelsProps) {
+ const { mentions, notifications, activeChannel, channelsDispatch, channels } =
+ useMessengerContext();
+
+ const channelList = useMemo(() => Object.values(channels), [channels]);
+
+ const setChatState = useChatState()[1];
+ return (
+ <>
+ {channelList
+ .filter((channel) => channel.type === type)
+ .map((channel) => (
+ 0}
+ mention={mentions?.[channel.id]}
+ onClick={() => {
+ channelsDispatch({ type: "ChangeActive", payload: channel.id });
+ if (onCommunityClick) {
+ onCommunityClick();
+ }
+ setChatState(ChatState.ChatBody);
+ }}
+ setEditGroup={setEditGroup}
+ />
+ ))}
+ >
+ );
+}
+
+type ChatsListProps = {
+ onCommunityClick?: () => void;
+ setEditGroup?: React.Dispatch>;
+};
+
+function ChatsSideBar({ onCommunityClick, setEditGroup }: ChatsListProps) {
+ const setChatState = useChatState()[1];
+ return (
+ <>
+
+ Messages
+ setChatState(ChatState.ChatCreation)}>
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export function Channels({ onCommunityClick, setEditGroup }: ChannelsProps) {
+ const identity = useIdentity();
+ return (
+
+
+
+ {identity ? (
+
+ ) : (
+
+ )}
+
+
+ );
+}
+
+export const ChannelList = styled.div`
+ display: flex;
+ flex-direction: column;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ }
+`;
+
+const Chats = styled.div`
+ display: flex;
+ flex-direction: column;
+ padding-top: 16px;
+ margin-top: 16px;
+ position: relative;
+
+ &::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: calc(100% - 24px);
+ height: 1px;
+ background-color: ${({ theme }) => theme.primary};
+ opacity: 0.1;
+ }
+`;
+
+const ChatsBar = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+`;
+
+const ChatsList = styled.div`
+ display: flex;
+ flex-direction: column;
+`;
+
+const Heading = styled.p`
+ font-weight: bold;
+ font-size: 17px;
+ line-height: 24px;
+ color: ${({ theme }) => theme.primary};
+`;
+
+const EditBtn = styled.button`
+ width: 32px;
+ height: 32px;
+ border-radius: 8px;
+ padding: 0;
+
+ &:hover {
+ background: ${({ theme }) => theme.inputColor};
+ }
+
+ &:active {
+ background: ${({ theme }) => theme.sectionBackgroundColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Channels/EmptyChannel.tsx b/packages/status-react/src/components/Channels/EmptyChannel.tsx
new file mode 100644
index 00000000..2af55a36
--- /dev/null
+++ b/packages/status-react/src/components/Channels/EmptyChannel.tsx
@@ -0,0 +1,129 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { ChannelData } from "../../models/ChannelData";
+import { textMediumStyles } from "../Text";
+
+import { ChannelInfo, ChannelName } from "./Channel";
+import { ChannelLogo } from "./ChannelIcon";
+
+type ChannelBeggingTextProps = {
+ channel: ChannelData;
+};
+
+function ChannelBeggingText({ channel }: ChannelBeggingTextProps) {
+ const userPK = useUserPublicKey();
+ const { contacts } = useMessengerContext();
+ const members = useMemo(() => {
+ if (channel?.members && userPK) {
+ return channel.members
+ .filter((contact) => contact.id !== userPK)
+ .map((member) => contacts?.[member.id] ?? member);
+ }
+ return [];
+ }, [channel, contacts, userPK]);
+
+ switch (channel.type) {
+ case "dm":
+ return (
+
+ Any messages you send here are encrypted and can only be read by you
+ and
+ {channel.name.slice(0, 10)}.
+
+ );
+ case "group":
+ return (
+
+ {userPK && {userPK}} created a group with{" "}
+ {members.map((contact, idx) => (
+
+ {contact?.customName ?? contact.trueName.slice(0, 10)}
+ {idx < members.length - 1 && <> and >}
+
+ ))}
+
+ );
+ case "channel":
+ return (
+
+ Welcome to the beginning of the #{channel.name} channel!
+
+ );
+ }
+ return null;
+}
+
+type EmptyChannelProps = {
+ channel: ChannelData;
+};
+
+export function EmptyChannel({ channel }: EmptyChannelProps) {
+ const narrow = useNarrow();
+
+ return (
+
+
+
+ {" "}
+ {!channel.icon && channel.name.slice(0, 1).toUpperCase()}
+
+
+
+
+
+ );
+}
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 32px;
+
+ &.wide {
+ margin-top: 24px;
+ }
+`;
+
+const ChannelInfoEmpty = styled(ChannelInfo)`
+ flex-direction: column;
+`;
+
+const ChannelLogoEmpty = styled(ChannelLogo)`
+ width: 120px;
+ height: 120px;
+ font-weight: bold;
+ font-size: 51px;
+ line-height: 62px;
+ margin-bottom: 16px;
+`;
+
+const ChannelNameEmpty = styled(ChannelName)`
+ font-weight: bold;
+ font-size: 22px;
+ line-height: 30px;
+ margin-bottom: 16px;
+`;
+
+const EmptyText = styled.p`
+ display: inline-block;
+ color: ${({ theme }) => theme.secondary};
+ max-width: 310px;
+ text-align: center;
+
+ & > span {
+ color: ${({ theme }) => theme.primary};
+ }
+
+ ${textMediumStyles}
+`;
+
+const EmptyTextGroup = styled(EmptyText)`
+ & > span {
+ word-break: break-all;
+ }
+`;
diff --git a/packages/status-react/src/components/Chat/ChatBody.tsx b/packages/status-react/src/components/Chat/ChatBody.tsx
new file mode 100644
index 00000000..a83fea70
--- /dev/null
+++ b/packages/status-react/src/components/Chat/ChatBody.tsx
@@ -0,0 +1,182 @@
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { Reply } from "../../hooks/useReply";
+import { ChannelData } from "../../models/ChannelData";
+import { TokenRequirement } from "../Form/TokenRequirement";
+import { MessagesList } from "../Messages/MessagesList";
+import { NarrowChannels } from "../NarrowMode/NarrowChannels";
+import { NarrowMembers } from "../NarrowMode/NarrowMembers";
+import { LoadingSkeleton } from "../Skeleton/LoadingSkeleton";
+
+import { ChatCreation } from "./ChatCreation";
+import { ChatInput } from "./ChatInput";
+import { ChatTopbar, ChatTopbarLoading } from "./ChatTopbar";
+
+export enum ChatBodyState {
+ Chat,
+ Channels,
+ Members,
+}
+
+function ChatBodyLoading() {
+ const narrow = useNarrow();
+ return (
+
+
+
+
+ undefined} />
+
+
+ );
+}
+
+type ChatBodyContentProps = {
+ showState: ChatBodyState;
+ switchShowState: (state: ChatBodyState) => void;
+ channel: ChannelData;
+};
+
+function ChatBodyContent({
+ showState,
+ switchShowState,
+ channel,
+}: ChatBodyContentProps) {
+ const [reply, setReply] = useState(undefined);
+
+ switch (showState) {
+ case ChatBodyState.Chat:
+ return (
+ <>
+
+
+ >
+ );
+ case ChatBodyState.Channels:
+ return (
+ switchShowState(ChatBodyState.Channels)}
+ />
+ );
+ case ChatBodyState.Members:
+ return (
+ switchShowState(ChatBodyState.Members)}
+ />
+ );
+ }
+}
+
+interface ChatBodyProps {
+ onClick: () => void;
+ showMembers: boolean;
+ permission: boolean;
+ editGroup: boolean;
+ setEditGroup: React.Dispatch>;
+}
+
+export function ChatBody({
+ onClick,
+ showMembers,
+ permission,
+ editGroup,
+ setEditGroup,
+}: ChatBodyProps) {
+ const { activeChannel, loadingMessenger } = useMessengerContext();
+
+ const narrow = useNarrow();
+ const className = useMemo(() => (narrow ? "narrow" : ""), [narrow]);
+
+ const [showState, setShowState] = useState(ChatBodyState.Chat);
+ const switchShowState = useCallback(
+ (state: ChatBodyState) => {
+ if (narrow) {
+ setShowState((prev) => (prev === state ? ChatBodyState.Chat : state));
+ }
+ },
+ [narrow]
+ );
+
+ useEffect(() => {
+ if (!narrow) {
+ setShowState(ChatBodyState.Chat);
+ }
+ }, [narrow]);
+
+ if (!loadingMessenger && activeChannel) {
+ return (
+
+
+ {editGroup ? (
+
+ ) : (
+ <>
+
+
+ >
+ )}
+
+ {!permission && (
+
+
+
+ )}
+
+ );
+ }
+
+ return ;
+}
+
+export const Wrapper = styled.div`
+ width: 61%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ height: 100%;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ position: relative;
+
+ &.narrow {
+ width: 100%;
+ }
+`;
+
+const ChatBodyWrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+`;
+
+const BluredWrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: flex-end;
+ justify-content: center;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ background: ${({ theme }) => theme.bodyBackgroundGradient};
+ backdrop-filter: blur(4px);
+ z-index: 2;
+`;
diff --git a/packages/status-react/src/components/Chat/ChatCreation.tsx b/packages/status-react/src/components/Chat/ChatCreation.tsx
new file mode 100644
index 00000000..9d5e409e
--- /dev/null
+++ b/packages/status-react/src/components/Chat/ChatCreation.tsx
@@ -0,0 +1,387 @@
+import React, { useCallback, useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { ChatState, useChatState } from "../../contexts/chatStateProvider";
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { ChannelData } from "../../models/ChannelData";
+import { ActivityButton } from "../ActivityCenter/ActivityButton";
+import { BackButton } from "../Buttons/BackButton";
+import { buttonStyles } from "../Buttons/buttonStyle";
+import { CrossIcon } from "../Icons/CrossIcon";
+import { Member } from "../Members/Member";
+import { SearchBlock } from "../SearchBlock";
+import { textMediumStyles } from "../Text";
+
+import { ChatInput } from "./ChatInput";
+
+interface ChatCreationProps {
+ setEditGroup?: (val: boolean) => void;
+ activeChannel?: ChannelData;
+}
+
+export function ChatCreation({
+ setEditGroup,
+ activeChannel,
+}: ChatCreationProps) {
+ const narrow = useNarrow();
+ const userPK = useUserPublicKey();
+ const [query, setQuery] = useState("");
+ const [groupChatMembersIds, setGroupChatMembersIds] = useState(
+ activeChannel?.members?.map((member) => member.id) ?? []
+ );
+ const { contacts, createGroupChat, addMembers } = useMessengerContext();
+
+ const groupChatMembers = useMemo(
+ () => groupChatMembersIds.map((id) => contacts[id]).filter((e) => !!e),
+ [groupChatMembersIds, contacts]
+ );
+
+ const contactsList = useMemo(() => {
+ return Object.values(contacts)
+ .filter(
+ (member) =>
+ member.id.includes(query) ||
+ member?.customName?.includes(query) ||
+ member.trueName.includes(query)
+ )
+ .filter((member) => !groupChatMembersIds.includes(member.id));
+ }, [query, groupChatMembersIds, contacts]);
+
+ const setChatState = useChatState()[1];
+
+ const addMember = useCallback(
+ (member: string) => {
+ setGroupChatMembersIds((prevMembers: string[]) => {
+ if (
+ prevMembers.find((mem) => mem === member) ||
+ prevMembers.length >= 5
+ ) {
+ return prevMembers;
+ } else {
+ return [...prevMembers, member];
+ }
+ });
+ setQuery("");
+ },
+ [setGroupChatMembersIds]
+ );
+ const removeMember = useCallback(
+ (member: string) => {
+ setGroupChatMembersIds((prev) => prev.filter((e) => e != member));
+ },
+ [setGroupChatMembersIds]
+ );
+
+ const createChat = useCallback(
+ (group: string[]) => {
+ if (userPK) {
+ const newGroup = group.slice();
+ newGroup.push(userPK);
+ createGroupChat(newGroup);
+ setChatState(ChatState.ChatBody);
+ }
+ },
+ [userPK, createGroupChat, setChatState]
+ );
+
+ const handleCreationClick = useCallback(() => {
+ if (!activeChannel) {
+ createChat(groupChatMembers.map((member) => member.id));
+ } else {
+ addMembers(
+ groupChatMembers.map((member) => member.id),
+ activeChannel.id
+ );
+ }
+ setEditGroup?.(false);
+ }, [activeChannel, groupChatMembers, createChat, addMembers, setEditGroup]);
+
+ return (
+
+
+ {narrow && (
+
+ setEditGroup
+ ? setEditGroup?.(false)
+ : setChatState(ChatState.ChatBody)
+ }
+ className="narrow"
+ />
+ )}
+
+
+ To:
+
+ {groupChatMembers.map((member) => (
+
+
+ {member?.customName?.slice(0, 10) ??
+ member.trueName.slice(0, 10)}
+
+ removeMember(member.id)}>
+
+
+
+ ))}
+
+ {groupChatMembers.length < 5 && (
+
+ setQuery(e.currentTarget.value)}
+ />
+
+ )}
+ {!narrow && groupChatMembers.length === 5 && (
+ 5 user Limit reached
+ )}
+
+ {narrow && groupChatMembers.length === 5 && (
+ 5 user Limit reached
+ )}
+
+
+ Confirm
+
+ {!narrow && }
+ {!narrow && (
+
+ )}
+
+ {((!setEditGroup && groupChatMembers.length === 0) || narrow) &&
+ Object.keys(contacts).length > 0 && (
+
+ Contacts
+
+ {userPK && narrow
+ ? contactsList.map((contact) => (
+
+ addMember(contact.id)}
+ />
+
+ ))
+ : Object.values(contacts)
+ .filter(
+ (e) =>
+ e.id != userPK && !groupChatMembersIds.includes(e.id)
+ )
+ .map((contact) => (
+
+ addMember(contact.id)}
+ />
+
+ ))}
+
+
+ )}
+ {!setEditGroup && Object.keys(contacts).length === 0 && (
+
+
+ You only can send direct messages to your Contacts.{" "}
+
+
+ {" "}
+ Send a contact request to the person you would like to chat with,
+ you will be able to chat with them once they have accepted your
+ contact request.
+
+
+ )}
+
+ {!activeChannel && (
+ member.id)}
+ />
+ )}
+
+ );
+}
+
+const CreationWrapper = styled.div`
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ flex: 1;
+ background-color: ${({ theme }) => theme.bodyBackgroundColor};
+ padding: 8px 16px;
+
+ &.narrow {
+ width: 100%;
+ max-width: 100%;
+ }
+`;
+
+const CreationBar = styled.div`
+ display: flex;
+ align-items: center;
+ margin-bottom: 24px;
+ position: relative;
+
+ &.limit {
+ align-items: flex-start;
+ }
+`;
+
+const Column = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ flex: 1;
+ margin-right: 16px;
+ overflow-x: hidden;
+`;
+
+const InputBar = styled.div`
+ display: flex;
+ align-items: center;
+ width: 100%;
+ height: 44px;
+ background-color: ${({ theme }) => theme.inputColor};
+ border: 1px solid ${({ theme }) => theme.inputColor};
+ border-radius: 8px;
+ padding: 6px 16px;
+
+ ${textMediumStyles}
+`;
+
+const Input = styled.input`
+ width: 100%;
+ min-width: 20px;
+ background-color: ${({ theme }) => theme.inputColor};
+ border: 1px solid ${({ theme }) => theme.inputColor};
+ outline: none;
+ resize: none;
+
+ ${textMediumStyles}
+
+ &:focus {
+ outline: none;
+ caret-color: ${({ theme }) => theme.notificationColor};
+ }
+`;
+
+const InputText = styled.div`
+ color: ${({ theme }) => theme.secondary};
+ margin-right: 8px;
+`;
+
+const CreationBtn = styled.button`
+ padding: 11px 24px;
+ ${buttonStyles}
+
+ &:disabled {
+ background: ${({ theme }) => theme.inputColor};
+ color: ${({ theme }) => theme.secondary};
+ }
+`;
+
+const StyledList = styled.div`
+ display: flex;
+ overflow-x: scroll;
+ margin-right: 8px;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+`;
+
+const StyledMember = styled.div`
+ display: flex;
+ align-items: center;
+ padding: 4px 4px 4px 8px;
+ background: ${({ theme }) => theme.tertiary};
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+ border-radius: 8px;
+
+ & + & {
+ margin-left: 8px;
+ }
+`;
+
+const StyledName = styled.p`
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+
+ ${textMediumStyles}
+`;
+
+const CloseButton = styled.button`
+ width: 20px;
+ height: 20px;
+`;
+
+const Contacts = styled.div`
+ height: calc(100% - 44px);
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ overflow: auto;
+`;
+
+const Contact = styled.div`
+ display: flex;
+ align-items: center;
+ padding: 12px 12px 0 16px;
+ border-radius: 8px;
+
+ &:hover {
+ background: ${({ theme }) => theme.inputColor};
+ }
+`;
+
+const ContactsHeading = styled.p`
+ color: ${({ theme }) => theme.secondary};
+
+ ${textMediumStyles}
+`;
+
+export const ContactsList = styled.div`
+ display: flex;
+ flex-direction: column;
+`;
+
+const EmptyContacts = styled(Contacts)`
+ justify-content: center;
+ align-items: center;
+`;
+
+const EmptyContactsHeading = styled(ContactsHeading)`
+ max-width: 550px;
+ margin-bottom: 24px;
+ text-align: center;
+`;
+
+const SearchMembers = styled.div`
+ position: relative;
+ flex: 1;
+`;
+
+const LimitAlert = styled.p`
+ text-transform: uppercase;
+ margin-left: auto;
+ color: ${({ theme }) => theme.redColor};
+ white-space: nowrap;
+
+ &.narrow {
+ margin: 8px 0 0;
+ }
+`;
diff --git a/packages/status-react/src/components/Chat/ChatInput.tsx b/packages/status-react/src/components/Chat/ChatInput.tsx
new file mode 100644
index 00000000..fb90817d
--- /dev/null
+++ b/packages/status-react/src/components/Chat/ChatInput.tsx
@@ -0,0 +1,562 @@
+import { EmojiData } from "emoji-mart";
+import React, {
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import styled from "styled-components";
+
+import { ChatState, useChatState } from "../../contexts/chatStateProvider";
+import { useIdentity } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { Reply } from "../../hooks/useReply";
+import { uintToImgUrl } from "../../utils/uintToImgUrl";
+import { ClearBtn } from "../Form/inputStyles";
+import { ClearSvg } from "../Icons/ClearIcon";
+import { ClearSvgFull } from "../Icons/ClearIconFull";
+import { EmojiIcon } from "../Icons/EmojiIcon";
+import { GifIcon } from "../Icons/GifIcon";
+import { PictureIcon } from "../Icons/PictureIcon";
+import { ReplySvg } from "../Icons/ReplyIcon";
+import { StickerIcon } from "../Icons/StickerIcon";
+import "emoji-mart/css/emoji-mart.css";
+import { SizeLimitModal, SizeLimitModalName } from "../Modals/SizeLimitModal";
+import { UserCreationStartModalName } from "../Modals/UserCreationStartModal";
+import { SearchBlock } from "../SearchBlock";
+import { textMediumStyles, textSmallStyles } from "../Text";
+
+import { EmojiPicker } from "./EmojiPicker";
+
+interface ChatInputProps {
+ reply?: Reply | undefined;
+ setReply?: (val: Reply | undefined) => void;
+ createChat?: (group: string[]) => void;
+ group?: string[];
+}
+
+export function ChatInput({
+ reply,
+ setReply,
+ createChat,
+ group,
+}: ChatInputProps) {
+ const narrow = useNarrow();
+ const identity = useIdentity();
+ const setChatState = useChatState()[1];
+ const disabled = useMemo(() => !identity, [identity]);
+ const { sendMessage, contacts } = useMessengerContext();
+ const [content, setContent] = useState("");
+ const [clearComponent, setClearComponent] = useState("");
+ const [showEmoji, setShowEmoji] = useState(false);
+ const [inputHeight, setInputHeight] = useState(40);
+ const [imageUint, setImageUint] = useState(undefined);
+
+ const { setModal } = useModal(SizeLimitModalName);
+ const { setModal: setCreationStartModal } = useModal(
+ UserCreationStartModalName
+ );
+
+ const [query, setQuery] = useState("");
+
+ const inputRef = useRef(null);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowEmoji(false));
+
+ const image = useMemo(
+ () => (imageUint ? uintToImgUrl(imageUint) : ""),
+ [imageUint]
+ );
+
+ const addEmoji = useCallback(
+ (e: EmojiData) => {
+ if ("unified" in e) {
+ const sym = e.unified.split("-");
+ const codesArray: string[] = [];
+ sym.forEach((el: string) => codesArray.push("0x" + el));
+ const emoji = String.fromCodePoint(
+ ...(codesArray as unknown as number[])
+ );
+ if (inputRef.current) {
+ inputRef.current.appendChild(document.createTextNode(emoji));
+ }
+ setContent((p) => p + emoji);
+ }
+ },
+ [setContent]
+ );
+
+ const resizeTextArea = useCallback((target: HTMLDivElement) => {
+ target.style.height = "40px";
+ target.style.height = `${Math.min(target.scrollHeight, 438)}px`;
+ setInputHeight(target.scrollHeight);
+ }, []);
+
+ const rowHeight = inputHeight + (image ? 73 : 0);
+
+ const onInputChange = useCallback(
+ (e: React.ChangeEvent) => {
+ const element = document.getSelection();
+ const inputElement = inputRef.current;
+ if (inputElement && element && element.rangeCount > 0) {
+ const selection = element?.getRangeAt(0)?.startOffset;
+ const parentElement = element.anchorNode?.parentElement;
+ if (parentElement && parentElement.tagName === "B") {
+ parentElement.outerHTML = parentElement.innerText;
+ const range = document.createRange();
+ const sel = window.getSelection();
+ if (element.anchorNode.firstChild) {
+ const childNumber =
+ element.focusOffset === 0 ? 0 : element.focusOffset - 1;
+ range.setStart(
+ element.anchorNode.childNodes[childNumber],
+ selection
+ );
+ }
+ range.collapse(true);
+
+ sel?.removeAllRanges();
+ sel?.addRange(range);
+ }
+ }
+ const target = e.target;
+ resizeTextArea(target);
+ setContent(target.textContent ?? "");
+ },
+ [resizeTextArea]
+ );
+
+ const onInputKeyPress = useCallback(
+ (e: React.KeyboardEvent) => {
+ if (e.key == "Enter" && !e.getModifierState("Shift")) {
+ e.preventDefault();
+ (e.target as HTMLDivElement).style.height = "40px";
+ setInputHeight(40);
+ sendMessage(content, imageUint, reply?.id);
+ setImageUint(undefined);
+ setClearComponent("");
+ if (inputRef.current) {
+ inputRef.current.innerHTML = "";
+ }
+ setContent("");
+ if (setReply) setReply(undefined);
+ if (createChat && group) {
+ createChat(group);
+ setChatState(ChatState.ChatBody);
+ }
+ }
+ },
+ [
+ content,
+ imageUint,
+ createChat,
+ group,
+ sendMessage,
+ reply?.id,
+ setChatState,
+ setReply,
+ ]
+ );
+
+ const [selectedElement, setSelectedElement] = useState<{
+ element: Selection | null;
+ start: number;
+ end: number;
+ text: string;
+ node: Node | null;
+ }>({ element: null, start: 0, end: 0, text: "", node: null });
+
+ const handleCursorChange = useCallback(() => {
+ const element = document.getSelection();
+ if (element && element.rangeCount > 0) {
+ const selection = element?.getRangeAt(0)?.startOffset;
+ const text = element?.anchorNode?.textContent;
+ if (selection && text) {
+ const end = text.indexOf(" ", selection);
+ const start = text.lastIndexOf(" ", selection - 1);
+ setSelectedElement({
+ element,
+ start,
+ end,
+ text,
+ node: element.anchorNode,
+ });
+ const substring = text.substring(
+ start > -1 ? start + 1 : 0,
+ end > -1 ? end : undefined
+ );
+ if (substring.startsWith("@")) {
+ setQuery(substring.slice(1));
+ } else {
+ setQuery("");
+ }
+ }
+ }
+ }, []);
+
+ useEffect(handleCursorChange, [content, handleCursorChange]);
+
+ const addMention = useCallback(
+ (contact: string) => {
+ if (inputRef?.current) {
+ const { element, start, end, text, node } = selectedElement;
+ if (element && text && node) {
+ const firstSlice = text.slice(0, start > -1 ? start : 0);
+ const secondSlice = text.slice(end > -1 ? end : content.length);
+ const replaceContent = `${firstSlice} @${contact}${secondSlice}`;
+ const spaceElement = document.createTextNode(" ");
+ const contactElement = document.createElement("span");
+ contactElement.innerText = `@${contact}`;
+
+ if (contactElement && element.rangeCount > 0) {
+ const range = element.getRangeAt(0);
+ range.setStart(node, start > -1 ? start : 0);
+ if (end === -1 || end > text.length) {
+ range.setEnd(node, text.length);
+ } else {
+ range.setEnd(node, end);
+ }
+ range.deleteContents();
+ if (end === -1) {
+ range.insertNode(spaceElement.cloneNode());
+ }
+ range.insertNode(contactElement);
+ if (start > -1) {
+ range.insertNode(spaceElement.cloneNode());
+ }
+ range.collapse();
+ }
+ inputRef.current.focus();
+ setQuery("");
+ setContent(replaceContent);
+ resizeTextArea(inputRef.current);
+ }
+ }
+ },
+ [inputRef, content, selectedElement, resizeTextArea]
+ );
+
+ return (
+
+
+
+
+ {
+ const fileReader = new FileReader();
+ fileReader.onloadend = (s) => {
+ const arr = new Uint8Array(s.target?.result as ArrayBuffer);
+ setImageUint(arr);
+ };
+
+ if (e?.target?.files?.[0]) {
+ if (e.target.files[0].size < 1024 * 1024) {
+ fileReader.readAsArrayBuffer(e.target.files[0]);
+ } else {
+ setModal(true);
+ }
+ }
+ }}
+ />
+
+
+ {reply && (
+
+
+ {" "}
+ {" "}
+ {contacts[reply.sender]?.customName ??
+ contacts[reply.sender].trueName}
+
+ {reply.content}
+ {reply.image && }
+ {
+ if (setReply) setReply(undefined);
+ }}
+ >
+ {" "}
+
+
+
+ )}
+
+
+ {image && (
+
+
+ setImageUint(undefined)}>
+
+
+
+ )}
+ {narrow && !identity ? (
+ setCreationStartModal(true)}>
+ Click here to join discussion
+
+ ) : (
+
+ )}
+ {query && (
+
+ )}
+
+
+
+ {
+ if (!disabled) setShowEmoji(!showEmoji);
+ }}
+ disabled={disabled}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const InputWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ position: relative;
+`;
+
+const EmojiWrapper = styled.div`
+ position: relative;
+`;
+
+const View = styled.div`
+ display: flex;
+ align-items: flex-end;
+ padding: 6px 8px 6px 10px;
+ position: relative;
+
+ &.creation {
+ padding: 0;
+ }
+`;
+
+const InputArea = styled.div`
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ max-height: 438px;
+ padding: 2px;
+ background: ${({ theme }) => theme.inputColor};
+ border-radius: 16px 16px 4px 16px;
+`;
+
+const Row = styled.div`
+ position: relative;
+ display: flex;
+ align-items: center;
+ width: 100%;
+ max-height: 438px;
+ padding-right: 6px;
+ background: ${({ theme }) => theme.inputColor};
+ border-radius: 16px 16px 4px 16px;
+`;
+
+const InputButtons = styled.div`
+ display: flex;
+ align-self: flex-end;
+
+ button + button {
+ margin-left: 4px;
+ }
+`;
+
+const ImageWrapper = styled.div`
+ width: 64px;
+ position: relative;
+`;
+const ImagePreview = styled.img`
+ width: 64px;
+ height: 64px;
+ border-radius: 16px 16px 4px 16px;
+ margin-left: 8px;
+ margin-top: 9px;
+`;
+
+const ClearImgBtn = styled(ClearBtn)`
+ width: 24px;
+ height: 24px;
+ top: 4px;
+ right: -20px;
+ transform: none;
+ padding: 0;
+ border: 2px solid ${({ theme }) => theme.inputColor};
+ background-color: ${({ theme }) => theme.inputColor};
+`;
+
+const Input = styled.div`
+ display: block;
+ width: 100%;
+ height: 40px;
+ max-height: 438px;
+ overflow: auto;
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
+ padding: 8px 0 8px 12px;
+ background: ${({ theme }) => theme.inputColor};
+ border: 1px solid ${({ theme }) => theme.inputColor};
+ color: ${({ theme }) => theme.primary};
+ border-radius: 16px 16px 4px 16px;
+ outline: none;
+
+ ${textMediumStyles};
+
+ &.disabled {
+ color: ${({ theme }) => theme.secondary};
+ cursor: default;
+ }
+
+ &:focus {
+ outline: none;
+ caret-color: ${({ theme }) => theme.notificationColor};
+ }
+
+ &::-webkit-scrollbar {
+ width: 0;
+ }
+
+ & > span {
+ display: inline;
+ color: ${({ theme }) => theme.mentionColor};
+ background: ${({ theme }) => theme.mentionBg};
+ border-radius: 4px;
+ font-weight: 500;
+ position: relative;
+ padding: 0 2px;
+ cursor: pointer;
+
+ &:hover {
+ background: ${({ theme }) => theme.mentionBgHover};
+ cursor: default;
+ }
+ }
+`;
+
+const AddPictureInputWrapper = styled.div`
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 32px;
+ height: 32px;
+ margin-right: 4px;
+
+ & > input[type="file"]::-webkit-file-upload-button {
+ cursor: pointer;
+ }
+
+ & > input:disabled::-webkit-file-upload-button {
+ cursor: default;
+ }
+`;
+
+const AddPictureInput = styled.input`
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+`;
+
+const ChatButton = styled.button`
+ width: 32px;
+ height: 32px;
+
+ &:disabled {
+ cursor: default;
+ }
+`;
+
+const CloseButton = styled(ChatButton)`
+ position: absolute;
+ top: 0;
+ right: 0;
+`;
+
+const ReplyWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ padding: 6px 12px;
+ background: rgba(0, 0, 0, 0.1);
+ color: ${({ theme }) => theme.primary};
+ border-radius: 14px 14px 4px 14px;
+ position: relative;
+`;
+
+export const ReplyTo = styled.div`
+ display: flex;
+ align-items: center;
+ font-weight: 500;
+ ${textSmallStyles};
+`;
+
+export const ReplyOn = styled.div`
+ width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ ${textSmallStyles};
+`;
+
+const JoinBtn = styled.button`
+ color: ${({ theme }) => theme.secondary};
+ background: ${({ theme }) => theme.inputColor};
+ border: none;
+ outline: none;
+ padding: 0 10px;
+ text-align: start;
+
+ ${textMediumStyles};
+`;
diff --git a/packages/status-react/src/components/Chat/ChatMessageContent.tsx b/packages/status-react/src/components/Chat/ChatMessageContent.tsx
new file mode 100644
index 00000000..87e4bf6a
--- /dev/null
+++ b/packages/status-react/src/components/Chat/ChatMessageContent.tsx
@@ -0,0 +1,233 @@
+import { decode } from "html-entities";
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useFetchMetadata } from "../../contexts/fetchMetadataProvider";
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { ChatMessage } from "../../models/ChatMessage";
+import { Metadata } from "../../models/Metadata";
+import { ContactMenu } from "../Form/ContactMenu";
+import { ImageMenu } from "../Form/ImageMenu";
+import { textMediumStyles, textSmallStyles } from "../Text";
+
+interface MentionProps {
+ id: string;
+ setMentioned: (val: boolean) => void;
+ className?: string;
+}
+
+export function Mention({ id, setMentioned, className }: MentionProps) {
+ const { contacts } = useMessengerContext();
+ const contact = useMemo(() => contacts[id.slice(1)], [id, contacts]);
+ const [showMenu, setShowMenu] = useState(false);
+ const userPK = useUserPublicKey();
+
+ useEffect(() => {
+ if (userPK && contact) {
+ if (contact.id === userPK) setMentioned(true);
+ }
+ }, [contact, userPK, setMentioned]);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ if (!contact) return <>{id}>;
+ return (
+ setShowMenu(!showMenu)}
+ className={className}
+ ref={ref}
+ >
+ {`@${contact?.customName ?? contact.trueName}`}
+ {showMenu && }
+
+ );
+}
+
+type ChatMessageContentProps = {
+ message: ChatMessage;
+ setImage: (image: string) => void;
+ setLinkOpen: (link: string) => void;
+ setMentioned: (val: boolean) => void;
+};
+
+export function ChatMessageContent({
+ message,
+ setImage,
+ setLinkOpen,
+ setMentioned,
+}: ChatMessageContentProps) {
+ const fetchMetadata = useFetchMetadata();
+ const { content, image } = useMemo(() => message, [message]);
+ const [elements, setElements] = useState<(string | React.ReactElement)[]>([
+ content,
+ ]);
+ const [link, setLink] = useState(undefined);
+ const [openGraph, setOpenGraph] = useState(undefined);
+
+ useEffect(() => {
+ let link;
+ const split = content.split(" ");
+ const newSplit = split.flatMap((element, idx) => {
+ if (element.startsWith("http://") || element.startsWith("https://")) {
+ link = element;
+ return [
+ setLinkOpen(element)}>
+ {element}
+ ,
+ " ",
+ ];
+ }
+ if (element.startsWith("@")) {
+ return [
+ ,
+ " ",
+ ];
+ }
+ return [element, " "];
+ });
+ newSplit.pop();
+ setLink(link);
+ setElements(newSplit);
+ }, [content, setLink, setMentioned, setElements, setLinkOpen]);
+
+ useEffect(() => {
+ const updatePreview = async () => {
+ if (link && fetchMetadata) {
+ try {
+ const metadata = await fetchMetadata(link);
+ if (metadata) {
+ setOpenGraph(metadata);
+ }
+ } catch {
+ return;
+ }
+ }
+ };
+ updatePreview();
+ }, [link, fetchMetadata]);
+
+ return (
+
+ {elements.map((el) => el)}
+ {image && (
+
+ {
+ setImage(image);
+ }}
+ />
+
+
+ )}
+ {openGraph && (
+ setLinkOpen(link ?? "")}>
+
+ {openGraph["og:title"]}
+
+ {openGraph["og:site_name"]}
+
+
+ )}
+
+ );
+}
+
+const MessageImageWrapper = styled.div`
+ width: 147px;
+ height: 196px;
+ margin-top: 8px;
+ position: relative;
+`;
+
+const MessageImage = styled.img`
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ border-radius: 16px;
+ cursor: pointer;
+`;
+
+const PreviewSiteNameWrapper = styled.div`
+ font-family: "Inter";
+ font-style: normal;
+ font-weight: normal;
+ font-size: 12px;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ margin-top: 2px;
+ color: #939ba1;
+ margin-left: 12px;
+`;
+
+const PreviewTitleWrapper = styled.div`
+ margin-top: 7px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ font-family: Inter;
+ font-style: normal;
+ font-weight: 500;
+ width: 290px;
+ margin-left: 12px;
+
+ ${textSmallStyles}
+`;
+
+const PreviewImage = styled.img`
+ border-radius: 15px 15px 15px 4px;
+ width: 305px;
+ height: 170px;
+`;
+
+const PreviewWrapper = styled.div`
+ margin-top: 9px;
+ background: #ffffff;
+ width: 305px;
+ height: 224px;
+ border: 1px solid #eef2f5;
+ box-sizing: border-box;
+ border-radius: 16px 16px 16px 4px;
+ display: flex;
+ flex-direction: column;
+ padding: 0px;
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+`;
+
+const MentionBLock = styled.div`
+ display: inline-flex;
+ color: ${({ theme }) => theme.mentionColor};
+ background: ${({ theme }) => theme.mentionBgHover};
+ border-radius: 4px;
+ font-weight: 500;
+ position: relative;
+ padding: 0 2px;
+ cursor: pointer;
+
+ &:hover {
+ background: ${({ theme }) => theme.mentionHover};
+ }
+
+ &.activity {
+ max-width: 488px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ ${textMediumStyles}
+`;
+
+const Link = styled.a`
+ text-decoration: underline;
+ cursor: pointer;
+ color: ${({ theme }) => theme.memberNameColor};
+`;
diff --git a/packages/status-react/src/components/Chat/ChatTopbar.tsx b/packages/status-react/src/components/Chat/ChatTopbar.tsx
new file mode 100644
index 00000000..32d521a7
--- /dev/null
+++ b/packages/status-react/src/components/Chat/ChatTopbar.tsx
@@ -0,0 +1,209 @@
+import React, { useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import {
+ ActivityButton,
+ ActivityWrapper,
+} from "../ActivityCenter/ActivityButton";
+import { Channel } from "../Channels/Channel";
+import { Community } from "../Community";
+import { ChannelMenu } from "../Form/ChannelMenu";
+import { ActivityIcon } from "../Icons/ActivityIcon";
+import { MembersIcon } from "../Icons/MembersIcon";
+import { MoreIcon } from "../Icons/MoreIcon";
+import { CommunitySkeleton } from "../Skeleton/CommunitySkeleton";
+import { Loading } from "../Skeleton/Loading";
+
+import { ChatBodyState } from "./ChatBody";
+
+export function ChatTopbarLoading() {
+ const narrow = useNarrow();
+
+ return (
+
+
+
+
+
+
+
+ {!narrow && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+type ChatTopbarProps = {
+ showState: ChatBodyState;
+ onClick: () => void;
+ switchShowState: (state: ChatBodyState) => void;
+ showMembers: boolean;
+ setEditGroup: React.Dispatch>;
+};
+
+export function ChatTopbar({
+ showState,
+ onClick,
+ switchShowState,
+ showMembers,
+ setEditGroup,
+}: ChatTopbarProps) {
+ const { activeChannel, loadingMessenger } = useMessengerContext();
+
+ const narrow = useNarrow();
+ const [showChannelMenu, setShowChannelMenu] = useState(false);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowChannelMenu(false));
+
+ if (!activeChannel) {
+ return ;
+ }
+
+ return (
+
+
+ {!loadingMessenger ? (
+ <>
+ {narrow && (
+
+
+
+ )}
+
+ switchShowState(ChatBodyState.Channels)}
+ />
+ >
+ ) : (
+
+
+
+ )}
+
+
+
+ {!narrow && activeChannel.type !== "dm" && (
+
+
+
+ )}
+
+ setShowChannelMenu(!showChannelMenu)}>
+
+ {showChannelMenu && (
+ switchShowState(ChatBodyState.Members)}
+ setShowChannelMenu={setShowChannelMenu}
+ setEditGroup={setEditGroup}
+ className={`${narrow && "narrow"}`}
+ />
+ )}
+
+
+ {!narrow && }
+
+ {loadingMessenger && }
+
+ );
+}
+
+const Topbar = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ padding: 5px 8px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ position: relative;
+
+ &.narrow {
+ width: 100%;
+ }
+`;
+
+const ChannelWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ max-width: 80%;
+
+ &.narrow {
+ width: calc(100% - 46px);
+ }
+`;
+
+const SkeletonWrapper = styled.div`
+ padding: 8px;
+`;
+
+const CommunityWrap = styled.div`
+ padding-right: 10px;
+ margin-right: 16px;
+ position: relative;
+
+ &.narrow {
+ margin-right: 8px;
+ }
+
+ &:after {
+ content: "";
+ position: absolute;
+ right: 0;
+ top: 50%;
+ width: 2px;
+ height: 24px;
+ transform: translateY(-50%);
+ border-radius: 1px;
+ background: ${({ theme }) => theme.primary};
+ opacity: 0.1;
+ }
+`;
+
+const MenuWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ padding: 8px 0;
+`;
+
+export const TopBtn = styled.button`
+ width: 32px;
+ height: 32px;
+ border-radius: 8px;
+ padding: 0;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ position: relative;
+
+ &:hover {
+ background: ${({ theme }) => theme.inputColor};
+ }
+
+ &:active {
+ background: ${({ theme }) => theme.sectionBackgroundColor};
+ }
+
+ &:disabled {
+ cursor: default;
+ }
+`;
diff --git a/packages/status-react/src/components/Chat/EmojiPicker.tsx b/packages/status-react/src/components/Chat/EmojiPicker.tsx
new file mode 100644
index 00000000..eb424031
--- /dev/null
+++ b/packages/status-react/src/components/Chat/EmojiPicker.tsx
@@ -0,0 +1,41 @@
+import { EmojiData, Picker } from "emoji-mart";
+import React from "react";
+import { useTheme } from "styled-components";
+
+import { useLow } from "../../contexts/narrowProvider";
+import { lightTheme, Theme } from "../../styles/themes";
+
+type EmojiPickerProps = {
+ showEmoji: boolean;
+ addEmoji: (e: EmojiData) => void;
+ bottom: number;
+};
+
+export function EmojiPicker({ showEmoji, addEmoji, bottom }: EmojiPickerProps) {
+ const theme = useTheme() as Theme;
+ const low = useLow();
+
+ if (showEmoji) {
+ return (
+
+ );
+ }
+ return null;
+}
diff --git a/packages/status-react/src/components/Community.tsx b/packages/status-react/src/components/Community.tsx
new file mode 100644
index 00000000..d25a0ec5
--- /dev/null
+++ b/packages/status-react/src/components/Community.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../contexts/messengerProvider";
+import { useModal } from "../contexts/modalProvider";
+
+import { CommunityIdentity } from "./CommunityIdentity";
+import { CommunityModalName } from "./Modals/CommunityModal";
+import { CommunitySkeleton } from "./Skeleton/CommunitySkeleton";
+
+interface CommunityProps {
+ className?: string;
+}
+
+export function Community({ className }: CommunityProps) {
+ const { communityData } = useMessengerContext();
+ const { setModal } = useModal(CommunityModalName);
+
+ if (!communityData) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+ <>
+
+ >
+ );
+}
+
+const SkeletonWrapper = styled.div`
+ margin-bottom: 16px;
+`;
diff --git a/packages/status-react/src/components/CommunityChat.tsx b/packages/status-react/src/components/CommunityChat.tsx
new file mode 100644
index 00000000..7a65c5bc
--- /dev/null
+++ b/packages/status-react/src/components/CommunityChat.tsx
@@ -0,0 +1,67 @@
+import React, { useRef } from "react";
+import { ThemeProvider } from "styled-components";
+import styled from "styled-components";
+
+import { ConfigType } from "..";
+import { ChatStateProvider } from "../contexts/chatStateProvider";
+import { ConfigProvider } from "../contexts/configProvider";
+import { FetchMetadataProvider } from "../contexts/fetchMetadataProvider";
+import { IdentityProvider } from "../contexts/identityProvider";
+import { MessengerProvider } from "../contexts/messengerProvider";
+import { ModalProvider } from "../contexts/modalProvider";
+import { NarrowProvider } from "../contexts/narrowProvider";
+import { ScrollProvider } from "../contexts/scrollProvider";
+import { ToastProvider } from "../contexts/toastProvider";
+import { Metadata } from "../models/Metadata";
+import { GlobalStyle } from "../styles/GlobalStyle";
+import { Theme } from "../styles/themes";
+
+import { CommunityChatRoom } from "./CommunityChatRoom";
+
+interface CommunityChatProps {
+ theme: Theme;
+ communityKey: string;
+ config: ConfigType;
+ fetchMetadata?: (url: string) => Promise;
+}
+
+export function CommunityChat({
+ theme,
+ config,
+ fetchMetadata,
+ communityKey,
+}: CommunityChatProps) {
+ const ref = useRef(null);
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const Wrapper = styled.div`
+ height: 100%;
+ overflow: hidden;
+`;
diff --git a/packages/status-react/src/components/CommunityChatRoom.tsx b/packages/status-react/src/components/CommunityChatRoom.tsx
new file mode 100644
index 00000000..9208ad60
--- /dev/null
+++ b/packages/status-react/src/components/CommunityChatRoom.tsx
@@ -0,0 +1,104 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+
+import { ChatState, useChatState } from "../contexts/chatStateProvider";
+import { useMessengerContext } from "../contexts/messengerProvider";
+import { useNarrow } from "../contexts/narrowProvider";
+
+import { Channels } from "./Channels/Channels";
+import { ChatBody } from "./Chat/ChatBody";
+import { ChatCreation } from "./Chat/ChatCreation";
+import { Community } from "./Community";
+import { Members } from "./Members/Members";
+import { AgreementModal } from "./Modals/AgreementModal";
+import { CoinbaseModal } from "./Modals/CoinbaseModal";
+import { CommunityModal } from "./Modals/CommunityModal";
+import { EditModal } from "./Modals/EditModal";
+import { LeavingModal } from "./Modals/LeavingModal";
+import { LogoutModal } from "./Modals/LogoutModal";
+import { ProfileFoundModal } from "./Modals/ProfileFoundModal";
+import { ProfileModal } from "./Modals/ProfileModal";
+import { StatusModal } from "./Modals/StatusModal";
+import { UserCreationModal } from "./Modals/UserCreationModal";
+import { UserCreationStartModal } from "./Modals/UserCreationStartModal";
+import { WalletConnectModal } from "./Modals/WalletConnectModal";
+import { WalletModal } from "./Modals/WalletModal";
+import { ToastMessageList } from "./ToastMessages/ToastMessageList";
+
+function Modals() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export function CommunityChatRoom() {
+ const [state] = useChatState();
+ const [showMembers, setShowMembers] = useState(false);
+ const [editGroup, setEditGroup] = useState(false);
+ const narrow = useNarrow();
+ const { activeChannel } = useMessengerContext();
+
+ return (
+
+ {!narrow && (
+
+
+
+
+ )}
+ {state === ChatState.ChatBody && (
+ setShowMembers(!showMembers)}
+ showMembers={showMembers}
+ permission={true}
+ editGroup={editGroup}
+ setEditGroup={setEditGroup}
+ />
+ )}
+ {showMembers &&
+ !narrow &&
+ state === ChatState.ChatBody &&
+ activeChannel &&
+ activeChannel.type !== "dm" && }
+ {state === ChatState.ChatCreation && }
+
+
+
+ );
+}
+
+const ChatWrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ position: relative;
+`;
+
+const ChannelsWrapper = styled.div`
+ width: 21%;
+ height: 100%;
+ min-width: 250px;
+ background-color: ${({ theme }) => theme.sectionBackgroundColor};
+ padding: 10px 16px;
+ display: flex;
+ flex-direction: column;
+`;
+
+const StyledCommunity = styled(Community)`
+ padding: 0 0 0 8px;
+ margin: 0 0 16px;
+`;
diff --git a/packages/status-react/src/components/CommunityIdentity.tsx b/packages/status-react/src/components/CommunityIdentity.tsx
new file mode 100644
index 00000000..1219e9ad
--- /dev/null
+++ b/packages/status-react/src/components/CommunityIdentity.tsx
@@ -0,0 +1,84 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../contexts/messengerProvider";
+
+import { textMediumStyles } from "./Text";
+
+export interface CommunityIdentityProps {
+ subtitle: string;
+ className?: string;
+}
+
+export const CommunityIdentity = ({
+ subtitle,
+ className,
+}: CommunityIdentityProps) => {
+ const { communityData } = useMessengerContext();
+
+ return (
+
+
+ {" "}
+ {communityData?.icon === undefined &&
+ communityData?.name.slice(0, 1).toUpperCase()}
+
+
+ {communityData?.name}
+ {subtitle}
+
+
+ );
+};
+
+const Row = styled.div`
+ display: flex;
+`;
+
+export const Column = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+`;
+
+export const Logo = styled.div`
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ border-radius: 50%;
+ margin-right: 8px;
+ background-color: ${({ theme }) => theme.tertiary};
+ background-size: cover;
+ background-repeat: no-repeat;
+ color: ${({ theme }) => theme.iconTextColor};
+ font-weight: bold;
+ font-size: 15px;
+ line-height: 20px;
+`;
+
+const Name = styled.p`
+ font-family: "Inter", sans-serif;
+ font-weight: 500;
+ text-align: left;
+ color: ${({ theme }) => theme.primary};
+ white-space: nowrap;
+
+ ${textMediumStyles}
+`;
+
+const Subtitle = styled.p`
+ font-family: "Inter", sans-serif;
+ font-size: 12px;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ color: ${({ theme }) => theme.secondary};
+`;
diff --git a/packages/status-react/src/components/Form/ChannelMenu.tsx b/packages/status-react/src/components/Form/ChannelMenu.tsx
new file mode 100644
index 00000000..d5f4e660
--- /dev/null
+++ b/packages/status-react/src/components/Form/ChannelMenu.tsx
@@ -0,0 +1,193 @@
+import React, { useMemo, useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { useContextMenu } from "../../hooks/useContextMenu";
+import { ChannelData } from "../../models/ChannelData";
+import { AddMemberIcon } from "../Icons/AddMemberIcon";
+import { CheckIcon } from "../Icons/CheckIcon";
+import { DeleteIcon } from "../Icons/DeleteIcon";
+import { DownloadIcon } from "../Icons/DownloadIcon";
+import { EditIcon } from "../Icons/EditIcon";
+import { LeftIcon } from "../Icons/LeftIcon";
+import { MembersSmallIcon } from "../Icons/MembersSmallIcon";
+import { MuteIcon } from "../Icons/MuteIcon";
+import { NextIcon } from "../Icons/NextIcon";
+import { ProfileIcon } from "../Icons/ProfileIcon";
+import { EditModalName } from "../Modals/EditModal";
+import { LeavingModalName } from "../Modals/LeavingModal";
+import { ProfileModalName } from "../Modals/ProfileModal";
+
+import { DropdownMenu, MenuItem, MenuSection, MenuText } from "./DropdownMenu";
+import { MuteMenu } from "./MuteMenu";
+
+interface ChannelMenuProps {
+ channel: ChannelData;
+ setShowChannelMenu?: (val: boolean) => void;
+ showNarrowMembers?: boolean;
+ switchMemberList?: () => void;
+ setEditGroup?: (val: boolean) => void;
+ className?: string;
+}
+
+export const ChannelMenu = ({
+ channel,
+ setShowChannelMenu,
+ showNarrowMembers,
+ switchMemberList,
+ setEditGroup,
+ className,
+}: ChannelMenuProps) => {
+ const narrow = useNarrow();
+ const { clearNotifications, channelsDispatch } = useMessengerContext();
+ const { setModal } = useModal(EditModalName);
+ const { setModal: setLeavingModal } = useModal(LeavingModalName);
+ const { setModal: setProfileModal } = useModal(ProfileModalName);
+ const [showSubmenu, setShowSubmenu] = useState(false);
+
+ const { showMenu, setShowMenu: setShowSideMenu } = useContextMenu(
+ channel.id + "contextMenu"
+ );
+
+ const setShowMenu = useMemo(
+ () => (setShowChannelMenu ? setShowChannelMenu : setShowSideMenu),
+ [setShowChannelMenu, setShowSideMenu]
+ );
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ if (showMenu || setShowChannelMenu) {
+ return (
+
+ {narrow && channel.type !== "dm" && (
+
+ )}
+ {channel.type === "group" && (
+ <>
+
+
+ >
+ )}
+ {channel.type === "dm" && (
+
+ )}
+
+
+
+
+
+ {(channel.type === "group" || channel.type === "dm") && (
+
+ )}
+
+ );
+ } else {
+ return null;
+ }
+};
+
+const ChannelDropdown = styled(DropdownMenu)`
+ top: calc(100% + 4px);
+ right: 0px;
+
+ &.side {
+ top: 20px;
+ left: calc(100% - 35px);
+ right: unset;
+ }
+
+ &.sideNarrow {
+ top: 20px;
+ right: 8px;
+ }
+`;
diff --git a/packages/status-react/src/components/Form/ContactMenu.tsx b/packages/status-react/src/components/Form/ContactMenu.tsx
new file mode 100644
index 00000000..4749c58d
--- /dev/null
+++ b/packages/status-react/src/components/Form/ContactMenu.tsx
@@ -0,0 +1,163 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { AddContactIcon } from "../Icons/AddContactIcon";
+import { BlockSvg } from "../Icons/BlockIcon";
+import { ChatSvg } from "../Icons/ChatIcon";
+import { EditIcon } from "../Icons/EditIcon";
+import { ProfileIcon } from "../Icons/ProfileIcon";
+import { UntrustworthIcon } from "../Icons/UntrustworthIcon";
+import { UserIcon } from "../Icons/UserIcon";
+import { WarningSvg } from "../Icons/WarningIcon";
+import { UserAddress } from "../Messages/Styles";
+import { ProfileModalName } from "../Modals/ProfileModal";
+import { textMediumStyles } from "../Text";
+
+import { DropdownMenu, MenuItem, MenuText } from "./DropdownMenu";
+
+type ContactMenuProps = {
+ id: string;
+ setShowMenu: (val: boolean) => void;
+};
+
+export function ContactMenu({ id, setShowMenu }: ContactMenuProps) {
+ const userPK = useUserPublicKey();
+ const { contacts, contactsDispatch } = useMessengerContext();
+ const contact = useMemo(() => contacts[id], [id, contacts]);
+ const isUser = useMemo(() => {
+ if (userPK) {
+ return id === userPK;
+ } else {
+ return false;
+ }
+ }, [id, userPK]);
+
+ const { setModal } = useModal(ProfileModalName);
+
+ if (!contact) return null;
+ return (
+
+
+
+
+ {contact?.customName ?? contact.trueName}
+ {contact.isUntrustworthy && }
+
+ {contact?.customName && (
+ ({contact.trueName})
+ )}
+
+ {id.slice(0, 10)}...{id.slice(-3)}
+
+
+
+
+ {!contact.isFriend && (
+
+ )}
+ {contact.isFriend && (
+
+ )}
+
+
+
+
+
+ {!contact.isFriend && !isUser && (
+
+ )}
+
+
+ );
+}
+
+const ContactDropdown = styled(DropdownMenu)`
+ top: 20px;
+ left: 0px;
+ width: 222px;
+`;
+
+const ContactInfo = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+const MenuSection = styled.div`
+ margin-top: 5px;
+ padding-top: 5px;
+ border-top: 1px solid ${({ theme }) => theme.inputColor};
+`;
+
+const UserNameWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ margin-bottom: 4px;
+`;
+
+const UserName = styled.p`
+ color: ${({ theme }) => theme.primary};
+ margin-right: 4px;
+
+ ${textMediumStyles}
+`;
+
+const UserTrueName = styled.p`
+ color: ${({ theme }) => theme.primary};
+ font-size: 12px;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ margin-top: 4px;
+`;
diff --git a/packages/status-react/src/components/Form/CopyInput.tsx b/packages/status-react/src/components/Form/CopyInput.tsx
new file mode 100644
index 00000000..06ecd829
--- /dev/null
+++ b/packages/status-react/src/components/Form/CopyInput.tsx
@@ -0,0 +1,30 @@
+import React from "react";
+
+import { copy } from "../../utils/copy";
+import { reduceString } from "../../utils/reduceString";
+
+import {
+ ButtonWrapper,
+ InputBtn,
+ InputWrapper,
+ Label,
+ Text,
+ Wrapper,
+} from "./inputStyles";
+
+interface CopyInputProps {
+ label?: string;
+ value: string;
+}
+
+export const CopyInput = ({ label, value }: CopyInputProps) => (
+
+ {label && }
+
+ {reduceString(value, 15, 15)}
+
+ copy(value)}>Copy
+
+
+
+);
diff --git a/packages/status-react/src/components/Form/DropdownMenu.tsx b/packages/status-react/src/components/Form/DropdownMenu.tsx
new file mode 100644
index 00000000..0542cf45
--- /dev/null
+++ b/packages/status-react/src/components/Form/DropdownMenu.tsx
@@ -0,0 +1,94 @@
+import React, { ReactNode } from "react";
+import styled from "styled-components";
+
+import { textSmallStyles } from "../Text";
+
+type DropdownMenuProps = {
+ children: ReactNode;
+ className?: string;
+ style?: { top: number; left: number };
+ menuRef?: React.MutableRefObject;
+ id?: string;
+};
+
+export function DropdownMenu({
+ children,
+ className,
+ style,
+ menuRef,
+ id,
+}: DropdownMenuProps) {
+ return (
+
+ {children}
+
+ );
+}
+
+const MenuBlock = styled.div`
+ width: 207px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ box-shadow: 0px 2px 4px rgba(0, 34, 51, 0.16),
+ 0px 4px 12px rgba(0, 34, 51, 0.08);
+ border-radius: 8px;
+ padding: 8px 0;
+ position: absolute;
+ z-index: 2;
+`;
+
+const MenuList = styled.ul`
+ list-style: none;
+`;
+
+export const MenuItem = styled.li`
+ width: 100%;
+ display: flex;
+ align-items: center;
+ padding: 8px 8px 8px 14px;
+ cursor: pointer;
+ color: ${({ theme }) => theme.primary};
+ position: relative;
+
+ &:hover,
+ &:hover > span {
+ background: ${({ theme }) => theme.border};
+ }
+
+ &.picker:hover {
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+
+ & > svg.red {
+ fill: ${({ theme }) => theme.redColor};
+ }
+`;
+
+export const MenuText = styled.span`
+ margin-left: 6px;
+ color: ${({ theme }) => theme.primary};
+
+ &.red {
+ color: ${({ theme }) => theme.redColor};
+ }
+
+ ${textSmallStyles}
+`;
+
+export const MenuSection = styled.div`
+ padding: 4px 0;
+ margin: 4px 0;
+ border-top: 1px solid ${({ theme }) => theme.inputColor};
+ border-bottom: 1px solid ${({ theme }) => theme.inputColor};
+
+ &.channel {
+ padding: 0;
+ margin: 0;
+ border: none;
+ }
+
+ &.message {
+ padding: 4px 0 0;
+ margin: 4px 0 0;
+ border-bottom: none;
+ }
+`;
diff --git a/packages/status-react/src/components/Form/ImageMenu.tsx b/packages/status-react/src/components/Form/ImageMenu.tsx
new file mode 100644
index 00000000..4fa1a934
--- /dev/null
+++ b/packages/status-react/src/components/Form/ImageMenu.tsx
@@ -0,0 +1,42 @@
+import React, { useRef } from "react";
+import styled from "styled-components";
+
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { useContextMenu } from "../../hooks/useContextMenu";
+import { copyImg } from "../../utils/copyImg";
+import { downloadImg } from "../../utils/downloadImg";
+import { CopyIcon } from "../Icons/CopyIcon";
+import { DownloadIcon } from "../Icons/DownloadIcon";
+
+import { DropdownMenu, MenuItem, MenuText } from "./DropdownMenu";
+
+interface ImageMenuProps {
+ imageId: string;
+}
+
+export const ImageMenu = ({ imageId }: ImageMenuProps) => {
+ const { showMenu, setShowMenu } = useContextMenu(imageId);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ return showMenu ? (
+
+
+
+
+ ) : (
+ <>>
+ );
+};
+
+const ImageDropdown = styled(DropdownMenu)`
+ width: 176px;
+ left: 120px;
+ top: 46px;
+`;
diff --git a/packages/status-react/src/components/Form/LoginInstructions.tsx b/packages/status-react/src/components/Form/LoginInstructions.tsx
new file mode 100644
index 00000000..820e7c41
--- /dev/null
+++ b/packages/status-react/src/components/Form/LoginInstructions.tsx
@@ -0,0 +1,93 @@
+import React from "react";
+import styled from "styled-components";
+
+import { MobileIcon } from "../Icons/MobileIcon";
+import { ProfileIcon } from "../Icons/ProfileIcon";
+import { ScanIcon } from "../Icons/ScanIcon";
+import { textMediumStyles } from "../Text";
+
+interface LoginInstructionsProps {
+ mobileFlow: boolean;
+}
+
+export function LoginInstructions({ mobileFlow }: LoginInstructionsProps) {
+ return (
+
+
+ Open Status App on your {mobileFlow ? "mobile" : "desktop"}
+
+
+ Navigate yourself to{" "}
+
+ {" "}
+ Profile
+ {" "}
+ tab
+
+
+ Select{" "}
+
+
+ {" "}
+ Sync Settings
+
+
+ Tap{" "}
+
+ {" "}
+ {" "}
+ {" "}
+ {mobileFlow ? "Scan" : "Display"} sync code
+
+
+ {mobileFlow
+ ? "Scan the sync code from this screen"
+ : "Paste the sync code above"}{" "}
+ ↑
+
+
+ );
+}
+
+const Instructions = styled.ol`
+ color: ${({ theme }) => theme.secondary};
+ margin: auto 0;
+ list-style-type: decimal;
+ counter-reset: ollist;
+
+ ${textMediumStyles}
+`;
+
+const InstructionStep = styled.li`
+ display: flex;
+ align-items: center;
+
+ & + & {
+ margin-top: 10px;
+ }
+
+ & > span {
+ color: ${({ theme }) => theme.tertiary};
+ }
+
+ &::before {
+ counter-increment: ollist;
+ content: counter(ollist) ".";
+ margin-right: 4px;
+ }
+`;
+
+const InstructionIcon = styled.div`
+ width: 40px;
+ height: 40px;
+ display: inline-flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ background: ${({ theme }) => theme.buttonBg};
+ color: ${({ theme }) => theme.tertiary};
+ font-size: 8px;
+ line-height: 10px;
+ margin: 0 6px;
+`;
diff --git a/packages/status-react/src/components/Form/MessageMenu.tsx b/packages/status-react/src/components/Form/MessageMenu.tsx
new file mode 100644
index 00000000..476a5e2e
--- /dev/null
+++ b/packages/status-react/src/components/Form/MessageMenu.tsx
@@ -0,0 +1,119 @@
+import { BaseEmoji } from "emoji-mart";
+import React, { useMemo, useRef } from "react";
+import styled from "styled-components";
+
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { useClickPosition } from "../../hooks/useClickPosition";
+import { useContextMenu } from "../../hooks/useContextMenu";
+import { Reply } from "../../hooks/useReply";
+import { ChatMessage } from "../../models/ChatMessage";
+import { DeleteIcon } from "../Icons/DeleteIcon";
+import { EditIcon } from "../Icons/EditIcon";
+import { PinIcon } from "../Icons/PinIcon";
+import { ReplySvg } from "../Icons/ReplyIcon";
+import { ReactionPicker } from "../Reactions/ReactionPicker";
+
+import { DropdownMenu, MenuItem, MenuSection, MenuText } from "./DropdownMenu";
+
+interface MessageMenuProps {
+ message: ChatMessage;
+ messageReactions: BaseEmoji[];
+ setMessageReactions: React.Dispatch>;
+ setReply: (val: Reply | undefined) => void;
+ messageRef: React.MutableRefObject;
+}
+
+export const MessageMenu = ({
+ message,
+ messageReactions,
+ setMessageReactions,
+ setReply,
+ messageRef,
+}: MessageMenuProps) => {
+ const userPK = useUserPublicKey();
+ const { activeChannel } = useMessengerContext();
+ const { showMenu, setShowMenu } = useContextMenu(message.id);
+ const { topPosition, leftPosition } = useClickPosition(messageRef);
+
+ const menuStyle = useMemo(() => {
+ return {
+ top: topPosition,
+ left: leftPosition,
+ };
+ }, [topPosition, leftPosition]);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ const userMessage = useMemo(
+ () => !!userPK && message.sender === userPK,
+ [userPK, message]
+ );
+
+ return userPK && showMenu ? (
+
+
+
+
+
+ {userMessage && (
+
+ )}
+ {activeChannel?.type !== "channel" && (
+
+ )}
+
+ {userMessage && (
+
+ )}
+
+ ) : (
+ <>>
+ );
+};
+
+const MessageDropdown = styled(DropdownMenu)`
+ width: 176px;
+`;
diff --git a/packages/status-react/src/components/Form/MuteMenu.tsx b/packages/status-react/src/components/Form/MuteMenu.tsx
new file mode 100644
index 00000000..9efd1790
--- /dev/null
+++ b/packages/status-react/src/components/Form/MuteMenu.tsx
@@ -0,0 +1,64 @@
+import React, { useCallback } from "react";
+import styled from "styled-components";
+
+import { DropdownMenu, MenuItem, MenuText } from "./DropdownMenu";
+
+interface SubMenuProps {
+ setIsMuted: (val: boolean) => void;
+ className?: string;
+}
+
+export const MuteMenu = ({ setIsMuted, className }: SubMenuProps) => {
+ const muteChannel = useCallback(
+ (timeout: number) => {
+ setIsMuted(true);
+ const timer = setTimeout(() => setIsMuted(false), timeout * 6000000);
+ return () => {
+ clearTimeout(timer);
+ };
+ },
+ [setIsMuted]
+ );
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const MuteDropdown = styled(DropdownMenu)`
+ width: 176px;
+ top: 100%;
+ right: -60px;
+ z-index: 3;
+
+ &.side {
+ width: 176px;
+ top: -8px;
+ left: 100%;
+ right: unset;
+ }
+
+ &.narrow,
+ &.sideNarrow {
+ width: 176px;
+ top: 100%;
+ right: -16px;
+ z-index: 3;
+ }
+`;
diff --git a/packages/status-react/src/components/Form/NameError.tsx b/packages/status-react/src/components/Form/NameError.tsx
new file mode 100644
index 00000000..b47d0c62
--- /dev/null
+++ b/packages/status-react/src/components/Form/NameError.tsx
@@ -0,0 +1,44 @@
+import React from "react";
+import styled from "styled-components";
+
+import { NameErrors } from "../../hooks/useNameError";
+import { Hint } from "../Modals/ModalStyle";
+
+type NameErrorProps = {
+ error: NameErrors;
+};
+
+export function NameError({ error }: NameErrorProps) {
+ switch (error) {
+ case NameErrors.NoError:
+ return null;
+ case NameErrors.NameExists:
+ return (
+
+ Sorry, the name you have chosen is not allowed, try picking another
+ username
+
+ );
+ case NameErrors.BadCharacters:
+ return (
+
+ Only letters, numbers, underscores and hypens allowed
+
+ );
+ case NameErrors.EndingWithEth:
+ return (
+
+ Usernames ending with “_eth” or "-eth" are not allowed
+
+ );
+ case NameErrors.TooLong:
+ return 24 character username limit;
+ }
+}
+
+const ErrorText = styled(Hint)`
+ color: ${({ theme }) => theme.redColor};
+ text-align: center;
+ width: 328px;
+ margin: 8px 0;
+`;
diff --git a/packages/status-react/src/components/Form/PasteInput.tsx b/packages/status-react/src/components/Form/PasteInput.tsx
new file mode 100644
index 00000000..b09a6f15
--- /dev/null
+++ b/packages/status-react/src/components/Form/PasteInput.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import styled from "styled-components";
+
+import { paste } from "../../utils/paste";
+
+import {
+ ButtonWrapper,
+ InputBtn,
+ inputStyles,
+ InputWrapper,
+ Label,
+ Wrapper,
+} from "./inputStyles";
+
+interface PasteInputProps {
+ label: string;
+}
+
+export const PasteInput = ({ label }: PasteInputProps) => (
+
+
+
+
+
+ paste("pasteInput")}>Paste
+
+
+
+);
+
+const Input = styled.input`
+ ${inputStyles}
+ width: 100%;
+
+ &:focus {
+ outline: none;
+ }
+
+ border: none;
+`;
diff --git a/packages/status-react/src/components/Form/TokenRequirement.tsx b/packages/status-react/src/components/Form/TokenRequirement.tsx
new file mode 100644
index 00000000..de308ad5
--- /dev/null
+++ b/packages/status-react/src/components/Form/TokenRequirement.tsx
@@ -0,0 +1,131 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { textMediumStyles } from "../Text";
+
+const communityRequirements = {
+ requirements: [
+ {
+ name: "STN",
+ amount: 10,
+ logo: "https://status.im/img/logo.svg",
+ },
+ ],
+ alternativeRequirements: [
+ {
+ name: "ETH",
+ amount: 1,
+ logo: "https://ethereum.org/static/a110735dade3f354a46fc2446cd52476/db4de/eth-home-icon.webp",
+ },
+ {
+ name: "MKR",
+ amount: 10,
+ logo: "https://cryptologos.cc/logos/maker-mkr-logo.svg?v=017",
+ },
+ ],
+};
+
+export function TokenRequirement() {
+ const { communityData } = useMessengerContext();
+ return (
+
+
+ To join {communityData?.name} community chat you need to
+ hold:
+
+
+ {communityRequirements.requirements.map((req) => (
+
+
+
+ {req.amount} {req.name}{" "}
+
+
+ ))}
+
+ {communityRequirements.alternativeRequirements && or}
+
+ {communityRequirements.alternativeRequirements.map((req) => (
+
+
+
+ {req.amount} {req.name}{" "}
+
+
+ ))}
+
+
+ );
+}
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ height: 50%;
+`;
+
+const Text = styled.p`
+ color: ${({ theme }) => theme.primary};
+ text-align: center;
+ margin-bottom: 16px;
+
+ & > span {
+ font-weight: 700;
+ }
+
+ ${textMediumStyles}
+`;
+
+const Requirement = styled.div`
+ display: flex;
+ align-items: center;
+ border-radius: 16px;
+ padding: 2px 12px 2px 2px;
+ background: ${({ theme }) => theme.buttonBg};
+ color: ${({ theme }) => theme.tertiary};
+
+ &.denial {
+ background: ${({ theme }) => theme.buttonNoBgHover};
+ color: ${({ theme }) => theme.redColor};
+ }
+
+ & + & {
+ margin-left: 18px;
+ }
+`;
+
+const Amount = styled.p`
+ font-weight: 500;
+ text-transform: uppercase;
+ margin-left: 6px;
+
+ ${textMediumStyles}
+`;
+
+const Row = styled.div`
+ display: flex;
+ align-items: center;
+ margin-bottom: 16px;
+`;
+
+const Logo = styled.div`
+ width: 28px;
+ height: 28px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ border-radius: 50%;
+ background-size: cover;
+ background-repeat: no-repeat;
+`;
diff --git a/packages/status-react/src/components/Form/Tooltip.tsx b/packages/status-react/src/components/Form/Tooltip.tsx
new file mode 100644
index 00000000..42489e22
--- /dev/null
+++ b/packages/status-react/src/components/Form/Tooltip.tsx
@@ -0,0 +1,51 @@
+import React from "react";
+import styled from "styled-components";
+
+import { TipIcon } from "../Icons/TipIcon";
+import { textSmallStyles } from "../Text";
+
+type TooltipProps = {
+ tip: string;
+ className?: string;
+};
+
+export function Tooltip({ tip, className }: TooltipProps) {
+ return (
+
+
+ {tip}
+
+
+
+ );
+}
+
+const TooltipWrapper = styled.div`
+ width: max-content;
+ position: absolute;
+ top: calc(-100% - 12px);
+ left: 50%;
+ transform: translateX(-50%);
+ visibility: hidden;
+
+ &.read {
+ left: 18%;
+ }
+
+ &.muted {
+ top: calc(100% + 8px);
+ z-index: 10;
+ }
+`;
+const TooltipBlock = styled.div`
+ background: ${({ theme }) => theme.primary};
+ border-radius: 8px;
+ position: relative;
+ padding: 8px;
+`;
+
+const TooltipText = styled.p`
+ font-weight: 500;
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+ ${textSmallStyles};
+`;
diff --git a/packages/status-react/src/components/Form/inputStyles.ts b/packages/status-react/src/components/Form/inputStyles.ts
new file mode 100644
index 00000000..8c3ed884
--- /dev/null
+++ b/packages/status-react/src/components/Form/inputStyles.ts
@@ -0,0 +1,93 @@
+import styled, { css } from "styled-components";
+
+import { textMediumStyles, textSmallStyles } from "../Text";
+
+export const inputStyles = css`
+ background: ${({ theme }) => theme.inputColor};
+ border-radius: 8px;
+ border: 1px solid ${({ theme }) => theme.inputColor};
+ color: ${({ theme }) => theme.primary};
+ outline: none;
+
+ ${textMediumStyles}
+
+ &:focus {
+ outline: 1px solid ${({ theme }) => theme.tertiary};
+ caret-color: ${({ theme }) => theme.notificationColor};
+ }
+`;
+
+export const Label = styled.p`
+ margin-bottom: 7px;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ color: ${({ theme }) => theme.primary};
+
+ ${textSmallStyles}
+`;
+
+export const InputWrapper = styled.div`
+ width: 100%;
+`;
+
+export const Wrapper = styled.div`
+ position: relative;
+ padding: 14px 70px 14px 8px;
+ background: ${({ theme }) => theme.inputColor};
+ border-radius: 8px;
+`;
+
+export const Text = styled.p`
+ color: ${({ theme }) => theme.primary};
+
+ ${textMediumStyles}
+`;
+
+export const ButtonWrapper = styled.div`
+ position: absolute;
+ top: 50%;
+ right: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ width: 70px;
+ transform: translateY(-50%);
+ background: ${({ theme }) => theme.inputColor};
+ border-radius: 8px;
+`;
+
+export const InputBtn = styled.button`
+ padding: 6px 12px;
+ font-size: 12px;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ color: ${({ theme }) => theme.tertiary};
+ background: ${({ theme }) => theme.buttonBg};
+ border: 1px solid ${({ theme }) => theme.tertiary};
+ border-radius: 6px;
+`;
+
+export const NameInputWrapper = styled.div`
+ position: relative;
+`;
+
+export const NameInput = styled.input`
+ width: 328px;
+ padding: 11px 16px;
+
+ ${inputStyles}
+`;
+
+export const ClearBtn = styled.button`
+ position: absolute;
+ right: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ border-radius: 50%;
+
+ & > svg {
+ fill: ${({ theme }) => theme.secondary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ActivityIcon.tsx b/packages/status-react/src/components/Icons/ActivityIcon.tsx
new file mode 100644
index 00000000..764d4b8f
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ActivityIcon.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import styled from "styled-components";
+
+export const ActivityIcon = () => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.primary};
+`;
diff --git a/packages/status-react/src/components/Icons/AddContactIcon.tsx b/packages/status-react/src/components/Icons/AddContactIcon.tsx
new file mode 100644
index 00000000..dd75b0c2
--- /dev/null
+++ b/packages/status-react/src/components/Icons/AddContactIcon.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import styled from "styled-components";
+
+type AddContactIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function AddContactIcon({
+ width,
+ height,
+ className,
+}: AddContactIconProps) {
+ return (
+
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/AddIcon.tsx b/packages/status-react/src/components/Icons/AddIcon.tsx
new file mode 100644
index 00000000..ad164009
--- /dev/null
+++ b/packages/status-react/src/components/Icons/AddIcon.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+import styled from "styled-components";
+
+export const AddIcon = () => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/AddMemberIcon.tsx b/packages/status-react/src/components/Icons/AddMemberIcon.tsx
new file mode 100644
index 00000000..9e3104dc
--- /dev/null
+++ b/packages/status-react/src/components/Icons/AddMemberIcon.tsx
@@ -0,0 +1,39 @@
+import React from "react";
+import styled from "styled-components";
+
+type AddMemberIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function AddMemberIcon({
+ width,
+ height,
+ className,
+}: AddMemberIconProps) {
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/BlockIcon.tsx b/packages/status-react/src/components/Icons/BlockIcon.tsx
new file mode 100644
index 00000000..eae2daa4
--- /dev/null
+++ b/packages/status-react/src/components/Icons/BlockIcon.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+import styled from "styled-components";
+
+type BlockSvgProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function BlockSvg({ width, height, className }: BlockSvgProps) {
+ return (
+
+ );
+}
+
+export const BlockIcon = () => {
+ return ;
+};
+
+const Icon = styled(BlockSvg)`
+ & > path {
+ fill: ${({ theme }) => theme.redColor};
+ }
+
+ &:hover > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ChainIcon.tsx b/packages/status-react/src/components/Icons/ChainIcon.tsx
new file mode 100644
index 00000000..3fb34b9c
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ChainIcon.tsx
@@ -0,0 +1,30 @@
+import React from "react";
+import styled from "styled-components";
+
+interface ChainIconProps {
+ className?: string;
+}
+
+export const ChainIcon = ({ className }: ChainIconProps) => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+ transform: rotate(15deg);
+
+ &.transformed {
+ transform: matrix(-0.97, 0.26, 0.26, 0.97, 0, 0);
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ChatIcon.tsx b/packages/status-react/src/components/Icons/ChatIcon.tsx
new file mode 100644
index 00000000..dbf998ac
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ChatIcon.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+import styled from "styled-components";
+
+type ChatSvgProps = {
+ width: number;
+ height: number;
+};
+
+export function ChatSvg({ width, height }: ChatSvgProps) {
+ return (
+
+ );
+}
+
+export const ChatIcon = () => {
+ return ;
+};
+
+const Icon = styled(ChatSvg)`
+ & > path {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &:hover > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/CheckIcon.tsx b/packages/status-react/src/components/Icons/CheckIcon.tsx
new file mode 100644
index 00000000..91870685
--- /dev/null
+++ b/packages/status-react/src/components/Icons/CheckIcon.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import styled from "styled-components";
+
+type CheckIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function CheckIcon({ width, height, className }: CheckIconProps) {
+ return (
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.green {
+ fill: ${({ theme }) => theme.greenColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ClearIcon.tsx b/packages/status-react/src/components/Icons/ClearIcon.tsx
new file mode 100644
index 00000000..41ec2120
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ClearIcon.tsx
@@ -0,0 +1,66 @@
+import React from "react";
+import styled from "styled-components";
+
+type ClearSvgProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function ClearSvg({ height, width, className }: ClearSvgProps) {
+ return (
+
+
+
+
+ );
+}
+
+;
+
+export const ClearIcon = () => {
+ return ;
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.profile {
+ fill: ${({ theme }) => theme.secondary};
+ }
+
+ &.input {
+ fill: ${({ theme }) => theme.primary};
+ }
+
+ &.profile > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+
+ &.decline {
+ fill: ${({ theme }) => theme.redColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ClearIconFull.tsx b/packages/status-react/src/components/Icons/ClearIconFull.tsx
new file mode 100644
index 00000000..2144f2a4
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ClearIconFull.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import styled from "styled-components";
+
+type ClearSvgFullProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function ClearSvgFull({ height, width, className }: ClearSvgFullProps) {
+ return (
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+
+ &:hover {
+ fill: ${({ theme }) => theme.primary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/CoinbaseLogo.tsx b/packages/status-react/src/components/Icons/CoinbaseLogo.tsx
new file mode 100644
index 00000000..210cbae8
--- /dev/null
+++ b/packages/status-react/src/components/Icons/CoinbaseLogo.tsx
@@ -0,0 +1,50 @@
+import React from "react";
+
+export const CoinbaseLogo = () => {
+ return (
+
+ );
+};
diff --git a/packages/status-react/src/components/Icons/ColorChatIcon.tsx b/packages/status-react/src/components/Icons/ColorChatIcon.tsx
new file mode 100644
index 00000000..af0e6a82
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ColorChatIcon.tsx
@@ -0,0 +1,148 @@
+import React from "react";
+import styled from "styled-components";
+
+type ColorChatSvgProps = {
+ width: number;
+ height: number;
+};
+
+export function ColorChatSvg({ width, height }: ColorChatSvgProps) {
+ return (
+
+ );
+}
+
+export const ColorChatIcon = () => {
+ return ;
+};
+
+const Icon = styled(ColorChatSvg)`
+ & > path {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &:hover > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/CommunityIcon.tsx b/packages/status-react/src/components/Icons/CommunityIcon.tsx
new file mode 100644
index 00000000..ab7fbc56
--- /dev/null
+++ b/packages/status-react/src/components/Icons/CommunityIcon.tsx
@@ -0,0 +1,43 @@
+import React from "react";
+import styled from "styled-components";
+
+type CommunityIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export const CommunityIcon = ({
+ width,
+ height,
+ className,
+}: CommunityIconProps) => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+
+ &.green {
+ fill: ${({ theme }) => theme.greenColor};
+ }
+
+ &.red {
+ fill: ${({ theme }) => theme.redColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/CopyIcon.tsx b/packages/status-react/src/components/Icons/CopyIcon.tsx
new file mode 100644
index 00000000..72bba1d6
--- /dev/null
+++ b/packages/status-react/src/components/Icons/CopyIcon.tsx
@@ -0,0 +1,31 @@
+import React from "react";
+import styled from "styled-components";
+
+type CopyIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function CopyIcon({ width, height, className }: CopyIconProps) {
+ return (
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/CreateIcon.tsx b/packages/status-react/src/components/Icons/CreateIcon.tsx
new file mode 100644
index 00000000..bbac7845
--- /dev/null
+++ b/packages/status-react/src/components/Icons/CreateIcon.tsx
@@ -0,0 +1,27 @@
+import React from "react";
+import styled from "styled-components";
+
+export const CreateIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.primary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/CrossIcon.tsx b/packages/status-react/src/components/Icons/CrossIcon.tsx
new file mode 100644
index 00000000..4d7d8d51
--- /dev/null
+++ b/packages/status-react/src/components/Icons/CrossIcon.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import styled from "styled-components";
+
+interface CrossIconProps {
+ memberView?: boolean;
+}
+
+export const CrossIcon = ({ memberView }: CrossIconProps) => (
+
+
+
+);
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.primary};
+ }
+
+ &.white {
+ & > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/DeleteIcon.tsx b/packages/status-react/src/components/Icons/DeleteIcon.tsx
new file mode 100644
index 00000000..7e3c693e
--- /dev/null
+++ b/packages/status-react/src/components/Icons/DeleteIcon.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+import styled from "styled-components";
+
+type DeleteIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export const DeleteIcon = ({ width, height, className }: DeleteIconProps) => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.red {
+ fill: ${({ theme }) => theme.redColor};
+ }
+
+ &.grey {
+ fill: ${({ theme }) => theme.secondary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/DownloadIcon.tsx b/packages/status-react/src/components/Icons/DownloadIcon.tsx
new file mode 100644
index 00000000..eedb0ec0
--- /dev/null
+++ b/packages/status-react/src/components/Icons/DownloadIcon.tsx
@@ -0,0 +1,27 @@
+import React from "react";
+import styled from "styled-components";
+
+type DownloadIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function DownloadIcon({ width, height, className }: DownloadIconProps) {
+ return (
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/EditIcon.tsx b/packages/status-react/src/components/Icons/EditIcon.tsx
new file mode 100644
index 00000000..3489b80b
--- /dev/null
+++ b/packages/status-react/src/components/Icons/EditIcon.tsx
@@ -0,0 +1,34 @@
+import React from "react";
+import styled from "styled-components";
+
+type EditIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function EditIcon({ width, height, className }: EditIconProps) {
+ return (
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.grey {
+ fill: ${({ theme }) => theme.secondary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/EmojiIcon.tsx b/packages/status-react/src/components/Icons/EmojiIcon.tsx
new file mode 100644
index 00000000..4487f25c
--- /dev/null
+++ b/packages/status-react/src/components/Icons/EmojiIcon.tsx
@@ -0,0 +1,46 @@
+import React from "react";
+import styled from "styled-components";
+
+interface ThemeProps {
+ isActive?: boolean;
+}
+
+export const EmojiIcon = ({ isActive }: ThemeProps) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.secondary};
+ }
+
+ & > path.active {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/EthereumLogo.tsx b/packages/status-react/src/components/Icons/EthereumLogo.tsx
new file mode 100644
index 00000000..0c0364d6
--- /dev/null
+++ b/packages/status-react/src/components/Icons/EthereumLogo.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+
+export const EthereumLogo = () => (
+
+);
diff --git a/packages/status-react/src/components/Icons/GifIcon.tsx b/packages/status-react/src/components/Icons/GifIcon.tsx
new file mode 100644
index 00000000..1321e041
--- /dev/null
+++ b/packages/status-react/src/components/Icons/GifIcon.tsx
@@ -0,0 +1,46 @@
+import React from "react";
+import styled from "styled-components";
+
+interface ThemeProps {
+ isActive?: boolean;
+}
+
+export const GifIcon = ({ isActive }: ThemeProps) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.secondary};
+ }
+
+ & > path.active {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/GroupIcon.tsx b/packages/status-react/src/components/Icons/GroupIcon.tsx
new file mode 100644
index 00000000..6781d101
--- /dev/null
+++ b/packages/status-react/src/components/Icons/GroupIcon.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+import styled from "styled-components";
+
+interface GroupIconProps {
+ active?: boolean;
+}
+
+export const GroupIcon = ({ active }: GroupIconProps) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+
+ &.active {
+ fill: ${({ theme }) => theme.primary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/HideIcon.tsx b/packages/status-react/src/components/Icons/HideIcon.tsx
new file mode 100644
index 00000000..967e090e
--- /dev/null
+++ b/packages/status-react/src/components/Icons/HideIcon.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import styled from "styled-components";
+
+export const HideIcon = () => (
+
+
+
+
+
+);
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/LeftIcon.tsx b/packages/status-react/src/components/Icons/LeftIcon.tsx
new file mode 100644
index 00000000..971b9545
--- /dev/null
+++ b/packages/status-react/src/components/Icons/LeftIcon.tsx
@@ -0,0 +1,34 @@
+import React from "react";
+import styled from "styled-components";
+
+type LeftIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function LeftIcon({ width, height, className }: LeftIconProps) {
+ return (
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.black {
+ fill: ${({ theme }) => theme.primary};
+ }
+
+ &.red {
+ fill: ${({ theme }) => theme.redColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/LoadingIcon.tsx b/packages/status-react/src/components/Icons/LoadingIcon.tsx
new file mode 100644
index 00000000..e8d3772e
--- /dev/null
+++ b/packages/status-react/src/components/Icons/LoadingIcon.tsx
@@ -0,0 +1,44 @@
+import React from "react";
+import styled, { keyframes } from "styled-components";
+
+const rotation = keyframes`
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+`;
+
+interface LoadingIconProps {
+ className?: string;
+}
+
+export const LoadingIcon = ({ className }: LoadingIconProps) => (
+
+
+
+);
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.primary};
+ }
+ animation: ${rotation} 2s linear infinite;
+
+ &.message {
+ & > path {
+ fill: ${({ theme }) => theme.secondary};
+ }
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/LogoutIcon.tsx b/packages/status-react/src/components/Icons/LogoutIcon.tsx
new file mode 100644
index 00000000..4e9534a0
--- /dev/null
+++ b/packages/status-react/src/components/Icons/LogoutIcon.tsx
@@ -0,0 +1,21 @@
+import React from "react";
+import styled from "styled-components";
+
+export const LogoutIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/MarkerdaoLogo.tsx b/packages/status-react/src/components/Icons/MarkerdaoLogo.tsx
new file mode 100644
index 00000000..1cb39939
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MarkerdaoLogo.tsx
@@ -0,0 +1,33 @@
+import React from "react";
+
+export const MarkerdaoLogo = () => (
+
+);
diff --git a/packages/status-react/src/components/Icons/MembersIcon.tsx b/packages/status-react/src/components/Icons/MembersIcon.tsx
new file mode 100644
index 00000000..47cbd809
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MembersIcon.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import styled from "styled-components";
+
+export const MembersIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.primary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/MembersSmallIcon.tsx b/packages/status-react/src/components/Icons/MembersSmallIcon.tsx
new file mode 100644
index 00000000..f5b574ac
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MembersSmallIcon.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+import styled from "styled-components";
+
+type MembersSmallIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function MembersSmallIcon({
+ height,
+ width,
+ className,
+}: MembersSmallIconProps) {
+ return (
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/MetamaskLogo.tsx b/packages/status-react/src/components/Icons/MetamaskLogo.tsx
new file mode 100644
index 00000000..33a5f161
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MetamaskLogo.tsx
@@ -0,0 +1,217 @@
+import React from "react";
+
+export const MetamaskLogo = () => {
+ return (
+
+ );
+};
diff --git a/packages/status-react/src/components/Icons/MobileIcon.tsx b/packages/status-react/src/components/Icons/MobileIcon.tsx
new file mode 100644
index 00000000..f35c8c0b
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MobileIcon.tsx
@@ -0,0 +1,25 @@
+import React from "react";
+import styled from "styled-components";
+
+export const MobileIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/MoreIcon.tsx b/packages/status-react/src/components/Icons/MoreIcon.tsx
new file mode 100644
index 00000000..39d257c0
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MoreIcon.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import styled from "styled-components";
+
+export const MoreIcon = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.primary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/MuteIcon.tsx b/packages/status-react/src/components/Icons/MuteIcon.tsx
new file mode 100644
index 00000000..33a37caa
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MuteIcon.tsx
@@ -0,0 +1,31 @@
+import React from "react";
+import styled from "styled-components";
+
+type MuteIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function MuteIcon({ width, height, className }: MuteIconProps) {
+ return (
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/MutedIcon.tsx b/packages/status-react/src/components/Icons/MutedIcon.tsx
new file mode 100644
index 00000000..4435bae5
--- /dev/null
+++ b/packages/status-react/src/components/Icons/MutedIcon.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+import styled from "styled-components";
+
+export const MutedIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.primary};
+ fill-opacity: 0.2;
+ flex-shrink: 0;
+`;
diff --git a/packages/status-react/src/components/Icons/NextIcon.tsx b/packages/status-react/src/components/Icons/NextIcon.tsx
new file mode 100644
index 00000000..88be547c
--- /dev/null
+++ b/packages/status-react/src/components/Icons/NextIcon.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import styled from "styled-components";
+
+export const NextIcon = () => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.primary};
+ position: absolute;
+ right: 8px;
+ top: 50%;
+ transform: translateY(-50%);
+`;
diff --git a/packages/status-react/src/components/Icons/PictureIcon.tsx b/packages/status-react/src/components/Icons/PictureIcon.tsx
new file mode 100644
index 00000000..5eeb3878
--- /dev/null
+++ b/packages/status-react/src/components/Icons/PictureIcon.tsx
@@ -0,0 +1,30 @@
+import React from "react";
+import styled from "styled-components";
+
+export const PictureIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.secondary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/PinIcon.tsx b/packages/status-react/src/components/Icons/PinIcon.tsx
new file mode 100644
index 00000000..a2cb3dae
--- /dev/null
+++ b/packages/status-react/src/components/Icons/PinIcon.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+import styled from "styled-components";
+
+type PinIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function PinIcon({ width, height, className }: PinIconProps) {
+ return (
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+
+ &.menu {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &.small {
+ width: 14px;
+ height: 14px;
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ProfileIcon.tsx b/packages/status-react/src/components/Icons/ProfileIcon.tsx
new file mode 100644
index 00000000..a0a13941
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ProfileIcon.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import styled from "styled-components";
+
+type ProfileIconProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function ProfileIcon({ width, height, className }: ProfileIconProps) {
+ return (
+
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/QuoteIcon.tsx b/packages/status-react/src/components/Icons/QuoteIcon.tsx
new file mode 100644
index 00000000..af683958
--- /dev/null
+++ b/packages/status-react/src/components/Icons/QuoteIcon.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import styled from "styled-components";
+
+type QuoteProps = {
+ width: number;
+ height: number;
+};
+
+export function QuoteSvg({ width, height }: QuoteProps) {
+ return (
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ & > path {
+ stroke: ${({ theme }) => theme.secondary};
+ }
+ position: absolute;
+ left: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+`;
diff --git a/packages/status-react/src/components/Icons/ReactionIcon.tsx b/packages/status-react/src/components/Icons/ReactionIcon.tsx
new file mode 100644
index 00000000..aed61508
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ReactionIcon.tsx
@@ -0,0 +1,51 @@
+import React from "react";
+import styled from "styled-components";
+
+type ReactionProps = {
+ className?: string;
+};
+
+export function ReactionSvg({ className }: ReactionProps) {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ width: 22px;
+ height: 22px;
+ fill: ${({ theme }) => theme.secondary};
+
+ &:hover {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &.small {
+ width: 18px;
+ height: 18px;
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ReadIcon.tsx b/packages/status-react/src/components/Icons/ReadIcon.tsx
new file mode 100644
index 00000000..5c18d16c
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ReadIcon.tsx
@@ -0,0 +1,43 @@
+import React from "react";
+import styled from "styled-components";
+
+interface ReadIconProps {
+ isRead?: boolean;
+}
+
+export const ReadIcon = ({ isRead }: ReadIconProps) => {
+ return (
+
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.read {
+ fill: ${({ theme }) => theme.secondary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ReadMessageIcon.tsx b/packages/status-react/src/components/Icons/ReadMessageIcon.tsx
new file mode 100644
index 00000000..f2e60395
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ReadMessageIcon.tsx
@@ -0,0 +1,33 @@
+import React from "react";
+import styled from "styled-components";
+
+interface ReadMessageIconProps {
+ isRead?: boolean;
+}
+
+export const ReadMessageIcon = ({ isRead }: ReadMessageIconProps) => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+
+ &.read {
+ fill: ${({ theme }) => theme.secondary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ReplyActivityIcon.tsx b/packages/status-react/src/components/Icons/ReplyActivityIcon.tsx
new file mode 100644
index 00000000..815d582b
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ReplyActivityIcon.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+import styled from "styled-components";
+
+export const ReplyIcon = () => (
+
+
+
+);
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+ flex-shrink: 0;
+`;
diff --git a/packages/status-react/src/components/Icons/ReplyIcon.tsx b/packages/status-react/src/components/Icons/ReplyIcon.tsx
new file mode 100644
index 00000000..e5c6a87b
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ReplyIcon.tsx
@@ -0,0 +1,34 @@
+import React from "react";
+import styled from "styled-components";
+
+type ReplyProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function ReplySvg({ width, height, className }: ReplyProps) {
+ return (
+
+
+
+ );
+}
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.secondary};
+
+ &.input {
+ fill: ${({ theme }) => theme.primary};
+ }
+
+ &.menu {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/ScanIcon.tsx b/packages/status-react/src/components/Icons/ScanIcon.tsx
new file mode 100644
index 00000000..e6c506cb
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ScanIcon.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import styled from "styled-components";
+
+export const ScanIcon = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/ShowIcon.tsx b/packages/status-react/src/components/Icons/ShowIcon.tsx
new file mode 100644
index 00000000..22eb5aef
--- /dev/null
+++ b/packages/status-react/src/components/Icons/ShowIcon.tsx
@@ -0,0 +1,27 @@
+import React from "react";
+import styled from "styled-components";
+
+export const ShowIcon = () => (
+
+
+
+
+);
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.tertiary};
+`;
diff --git a/packages/status-react/src/components/Icons/StatusIcon.tsx b/packages/status-react/src/components/Icons/StatusIcon.tsx
new file mode 100644
index 00000000..69b6e229
--- /dev/null
+++ b/packages/status-react/src/components/Icons/StatusIcon.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+
+export const StatusIcon = () => (
+
+);
diff --git a/packages/status-react/src/components/Icons/StatusLogo.tsx b/packages/status-react/src/components/Icons/StatusLogo.tsx
new file mode 100644
index 00000000..ad152316
--- /dev/null
+++ b/packages/status-react/src/components/Icons/StatusLogo.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+import styled from "styled-components";
+
+export const StatusLogo = () => (
+
+
+
+
+
+);
+
+const Icon = styled.svg`
+ & > path:first-child {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ & > path:nth-child(2) {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+
+ & > path:last-child {
+ fill: ${({ theme }) => theme.primary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/StickerIcon.tsx b/packages/status-react/src/components/Icons/StickerIcon.tsx
new file mode 100644
index 00000000..0c9ba06b
--- /dev/null
+++ b/packages/status-react/src/components/Icons/StickerIcon.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+import styled from "styled-components";
+
+interface ThemeProps {
+ isActive?: boolean;
+}
+
+export const StickerIcon = ({ isActive }: ThemeProps) => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > path {
+ fill: ${({ theme }) => theme.secondary};
+ }
+
+ & > path.active {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/TipIcon.tsx b/packages/status-react/src/components/Icons/TipIcon.tsx
new file mode 100644
index 00000000..8588c887
--- /dev/null
+++ b/packages/status-react/src/components/Icons/TipIcon.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+import styled from "styled-components";
+
+type TipIconProps = {
+ className?: string;
+};
+
+export const TipIcon = ({ className }: TipIconProps) => {
+ return (
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ fill: ${({ theme }) => theme.primary};
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+
+ &.read {
+ left: 62%;
+ }
+
+ &.muted {
+ top: -8px;
+ transform: rotate(180deg) translateX(50%);
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/UntrustworthIcon.tsx b/packages/status-react/src/components/Icons/UntrustworthIcon.tsx
new file mode 100644
index 00000000..99797a38
--- /dev/null
+++ b/packages/status-react/src/components/Icons/UntrustworthIcon.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import styled from "styled-components";
+
+export const UntrustworthIcon = () => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ & > circle {
+ fill: ${({ theme }) => theme.redColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/UserIcon.tsx b/packages/status-react/src/components/Icons/UserIcon.tsx
new file mode 100644
index 00000000..a919e284
--- /dev/null
+++ b/packages/status-react/src/components/Icons/UserIcon.tsx
@@ -0,0 +1,38 @@
+import React from "react";
+import styled from "styled-components";
+
+interface UserIconProps {
+ memberView?: boolean;
+ modalView?: boolean;
+}
+
+export const UserIcon = ({ memberView, modalView }: UserIconProps) => {
+ return (
+
+
+
+
+ );
+};
+
+const Icon = styled.svg`
+ width: ${({ memberView, modalView }) =>
+ memberView ? "20px" : modalView ? "80px" : "34px"};
+ height: ${({ memberView, modalView }) =>
+ memberView ? "20px" : modalView ? "80px" : "34px"};
+
+ & > path,
+ & > ellipse {
+ fill: ${({ theme }) => theme.iconUserColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Icons/WalletConnectLogo.tsx b/packages/status-react/src/components/Icons/WalletConnectLogo.tsx
new file mode 100644
index 00000000..e55bdc4d
--- /dev/null
+++ b/packages/status-react/src/components/Icons/WalletConnectLogo.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+
+export const WalletConnectLogo = () => {
+ return (
+
+ );
+};
diff --git a/packages/status-react/src/components/Icons/WarningIcon.tsx b/packages/status-react/src/components/Icons/WarningIcon.tsx
new file mode 100644
index 00000000..6e06ec57
--- /dev/null
+++ b/packages/status-react/src/components/Icons/WarningIcon.tsx
@@ -0,0 +1,47 @@
+import React from "react";
+import styled from "styled-components";
+
+type WarningSvgProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function WarningSvg({ width, height, className }: WarningSvgProps) {
+ return (
+
+ );
+}
+
+export const WarningIcon = () => {
+ return ;
+};
+
+const Icon = styled(WarningSvg)`
+ & > path {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &.red > path {
+ fill: ${({ theme }) => theme.redColor};
+ }
+
+ &:hover > path {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Members/Member.tsx b/packages/status-react/src/components/Members/Member.tsx
new file mode 100644
index 00000000..b84866f0
--- /dev/null
+++ b/packages/status-react/src/components/Members/Member.tsx
@@ -0,0 +1,125 @@
+import React, { useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useIdentity } from "../../contexts/identityProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { Contact } from "../../models/Contact";
+import { ContactMenu } from "../Form/ContactMenu";
+import { IconBtn, UserAddress } from "../Messages/Styles";
+
+import { UserLogo } from "./UserLogo";
+
+interface MemberProps {
+ contact: Contact;
+ isOnline?: boolean;
+ isYou?: boolean;
+ onClick?: () => void;
+}
+
+export function Member({ contact, isOnline, isYou, onClick }: MemberProps) {
+ const identity = useIdentity();
+
+ const [showMenu, setShowMenu] = useState(false);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ return (
+
+ {
+ if (identity) setShowMenu((e) => !e);
+ }}
+ ref={ref}
+ >
+ {showMenu && }
+
+
+
+ {contact?.customName ?? contact.trueName}
+
+ {contact.id.slice(0, 5)}...{contact.id.slice(-3)}
+
+
+
+ );
+}
+
+export const MemberData = styled.div`
+ display: flex;
+ align-items: center;
+ margin-bottom: 16px;
+ cursor: pointer;
+
+ &.you {
+ margin-bottom: 0;
+ cursor: default;
+ }
+`;
+
+export const MemberName = styled.p`
+ font-weight: 500;
+ font-size: 15px;
+ line-height: 22px;
+ color: ${({ theme }) => theme.primary};
+ opacity: 0.7;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+`;
+
+export const MemberIcon = styled(IconBtn)`
+ width: 29px;
+ height: 29px;
+
+ &.offline {
+ &::after {
+ content: "";
+ position: absolute;
+ right: -1px;
+ bottom: -2px;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background-color: ${({ theme }) => theme.secondary};
+ border: 2px solid ${({ theme }) => theme.bodyBackgroundColor};
+ }
+ }
+
+ &.online {
+ &::after {
+ content: "";
+ position: absolute;
+ right: -1px;
+ bottom: -2px;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background-color: #4ebc60;
+ border: 2px solid ${({ theme }) => theme.bodyBackgroundColor};
+ }
+ }
+`;
+
+const Column = styled.div`
+ display: flex;
+ flex-direction: column;
+ margin-left: 8px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+`;
diff --git a/packages/status-react/src/components/Members/Members.tsx b/packages/status-react/src/components/Members/Members.tsx
new file mode 100644
index 00000000..3ea35eb4
--- /dev/null
+++ b/packages/status-react/src/components/Members/Members.tsx
@@ -0,0 +1,43 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+
+import { MembersList } from "./MembersList";
+
+export function Members() {
+ const { activeChannel } = useMessengerContext();
+ const heading = useMemo(
+ () =>
+ activeChannel && activeChannel?.type === "group"
+ ? "Group members"
+ : "Members",
+ [activeChannel]
+ );
+
+ return (
+
+ {heading}
+
+
+ );
+}
+
+const MembersWrapper = styled.div`
+ width: 18%;
+ height: 100%;
+ min-width: 164px;
+ display: flex;
+ flex-direction: column;
+ background-color: ${({ theme }) => theme.sectionBackgroundColor};
+ padding: 16px;
+ overflow-y: scroll;
+`;
+
+const MemberHeading = styled.h2`
+ font-weight: 500;
+ font-size: 15px;
+ line-height: 22px;
+ color: ${({ theme }) => theme.primary};
+ margin-bottom: 16px;
+`;
diff --git a/packages/status-react/src/components/Members/MembersList.tsx b/packages/status-react/src/components/Members/MembersList.tsx
new file mode 100644
index 00000000..2aa725d9
--- /dev/null
+++ b/packages/status-react/src/components/Members/MembersList.tsx
@@ -0,0 +1,132 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { Contact } from "../../models/Contact";
+import { buttonStyles } from "../Buttons/buttonStyle";
+import { LogoutIcon } from "../Icons/LogoutIcon";
+import { LogoutModalName } from "../Modals/LogoutModal";
+
+import { Member } from "./Member";
+
+export function MembersList() {
+ const { contacts, nickname, activeChannel } = useMessengerContext();
+ const userPK = useUserPublicKey();
+ const { setModal } = useModal(LogoutModalName);
+
+ const members = useMemo(() => {
+ const contactsArray = Object.values(contacts);
+ if (userPK) {
+ if (
+ activeChannel &&
+ activeChannel.type === "group" &&
+ activeChannel.members
+ ) {
+ const returnContacts: Contact[] = [];
+ activeChannel.members.forEach((member) => {
+ if (contacts[member.id] && member.id != userPK) {
+ returnContacts.push(contacts[member.id]);
+ }
+ });
+ return returnContacts;
+ }
+ return contactsArray.filter((e) => e.id !== userPK);
+ }
+ return contactsArray;
+ }, [activeChannel, contacts, userPK]);
+
+ const onlineContacts = useMemo(
+ () => members.filter((e) => e.online),
+ [members]
+ );
+ const offlineContacts = useMemo(
+ () => members.filter((e) => !e.online),
+ [members]
+ );
+
+ return (
+
+ {userPK && (
+
+ You
+
+
+ setModal(true)}>
+
+
+
+
+ )}
+ {onlineContacts.length > 0 && (
+
+ Online
+ {onlineContacts.map((contact) => (
+
+ ))}
+
+ )}
+ {offlineContacts.length > 0 && (
+
+ Offline
+ {offlineContacts.map((contact) => (
+
+ ))}
+
+ )}
+
+ );
+}
+
+const MembersListWrap = styled.div`
+ display: flex;
+ flex-direction: column;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ }
+`;
+
+const MemberCategory = styled.div`
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 16px;
+`;
+
+const MemberCategoryName = styled.h3`
+ font-weight: normal;
+ font-size: 13px;
+ line-height: 18px;
+ color: ${({ theme }) => theme.secondary};
+ margin-bottom: 8px;
+`;
+
+const Row = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+`;
+
+const LogoutBtn = styled.button`
+ ${buttonStyles}
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ padding: 0;
+`;
diff --git a/packages/status-react/src/components/Members/UserLogo.tsx b/packages/status-react/src/components/Members/UserLogo.tsx
new file mode 100644
index 00000000..7698e121
--- /dev/null
+++ b/packages/status-react/src/components/Members/UserLogo.tsx
@@ -0,0 +1,132 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { Contact } from "../../models/Contact";
+
+type UserLogoProps = {
+ radius: number;
+ colorWheel: [string, number][];
+ contact?: Contact;
+ showOnlineStatus?: boolean;
+ icon?: string;
+};
+
+export function UserLogo({
+ icon,
+ contact,
+ radius,
+ colorWheel,
+ showOnlineStatus,
+}: UserLogoProps) {
+ const conicGradient = useMemo(() => {
+ const colors = colorWheel
+ .map((color, idx) => {
+ const prevDeg = idx === 0 ? "0deg" : `${colorWheel[idx - 1][1]}deg`;
+ return `${color[0]} ${prevDeg} ${color[1]}deg`;
+ })
+ .join(",");
+ return `conic-gradient(${colors})`;
+ }, [colorWheel]);
+
+ const letters = useMemo(() => {
+ if (contact && contact?.customName) {
+ return contact.customName.slice(0, 2);
+ }
+ if (contact && contact.trueName) {
+ return contact.trueName.slice(0, 2);
+ }
+ }, [contact]);
+
+ const logoClassnName = useMemo(() => {
+ if (showOnlineStatus) {
+ if (contact && contact.online) {
+ return "online";
+ }
+ return "offline";
+ }
+ return "";
+ }, [contact, showOnlineStatus]);
+
+ return (
+
+
+ {!icon && {letters}}
+
+
+ );
+}
+
+const TextWrapper = styled.div<{ radius: number }>`
+ font-weight: bold;
+ font-size: calc(${({ radius }) => radius}px / 2.5);
+ line-height: calc(${({ radius }) => radius}px / 2.1);
+ display: flex;
+ align-items: center;
+ text-align: center;
+ letter-spacing: -0.4px;
+ color: ${({ theme }) => theme.iconTextColor};
+`;
+
+const Logo = styled.div<{ radius: number; icon?: string }>`
+ width: calc(${({ radius }) => radius}px - 6px);
+ height: calc(${({ radius }) => radius}px - 6px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ border-radius: 50%;
+ font-weight: bold;
+ font-size: 15px;
+ line-height: 20px;
+ background-color: ${({ theme }) => theme.logoColor};
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-image: ${({ icon }) => icon && `url(${icon}`};
+
+ &.offline {
+ &::after {
+ content: "";
+ position: absolute;
+ right: -1px;
+ bottom: -2px;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background-color: ${({ theme }) => theme.secondary};
+ border: 2px solid ${({ theme }) => theme.bodyBackgroundColor};
+ }
+ }
+
+ &.online {
+ &::after {
+ content: "";
+ position: absolute;
+ right: -1px;
+ bottom: -2px;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background-color: ${({ theme }) => theme.greenColor};
+ border: 2px solid ${({ theme }) => theme.bodyBackgroundColor};
+ }
+ }
+
+ &.empty {
+ background-color: ${({ theme }) => theme.bodyBackgroundColor};
+ background-image: none;
+ }
+`;
+
+export const Wrapper = styled.div<{ radius: number; conicGradient: string }>`
+ width: ${({ radius }) => radius}px;
+ height: ${({ radius }) => radius}px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ background: ${({ conicGradient }) => conicGradient};
+`;
diff --git a/packages/status-react/src/components/Messages/MessageQuote.tsx b/packages/status-react/src/components/Messages/MessageQuote.tsx
new file mode 100644
index 00000000..34c976d7
--- /dev/null
+++ b/packages/status-react/src/components/Messages/MessageQuote.tsx
@@ -0,0 +1,67 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useScrollToMessage } from "../../contexts/scrollProvider";
+import { ChatMessage } from "../../models/ChatMessage";
+import { ReplyOn, ReplyTo } from "../Chat/ChatInput";
+import { QuoteSvg } from "../Icons/QuoteIcon";
+import { UserIcon } from "../Icons/UserIcon";
+
+function calcHeight(quote: ChatMessage) {
+ if (quote.image && quote.content) {
+ return 88;
+ } else if (quote.image && !quote.content) {
+ return 68;
+ } else {
+ return 25;
+ }
+}
+
+type MessageQuoteProps = {
+ quote: ChatMessage | undefined;
+};
+
+export function MessageQuote({ quote }: MessageQuoteProps) {
+ const { contacts } = useMessengerContext();
+ const scroll = useScrollToMessage();
+
+ if (quote && quote.sender) {
+ return (
+ scroll(quote)}>
+
+
+ {" "}
+ {" "}
+ {contacts[quote.sender]?.customName ??
+ contacts[quote.sender].trueName}
+
+ {quote.content}
+ {quote.image && }
+
+ );
+ }
+ return null;
+}
+
+const QuoteWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ padding-left: 48px;
+ position: relative;
+`;
+
+const QuoteSender = styled(ReplyTo)`
+ color: ${({ theme }) => theme.secondary};
+`;
+
+const Quote = styled(ReplyOn)`
+ color: ${({ theme }) => theme.secondary};
+`;
+
+const QuoteImage = styled.img`
+ width: 56px;
+ height: 56px;
+ border-radius: 4px;
+ margin-top: 4px;
+`;
diff --git a/packages/status-react/src/components/Messages/MessageReactions.tsx b/packages/status-react/src/components/Messages/MessageReactions.tsx
new file mode 100644
index 00000000..ce79b23a
--- /dev/null
+++ b/packages/status-react/src/components/Messages/MessageReactions.tsx
@@ -0,0 +1,83 @@
+import { BaseEmoji, Emoji } from "emoji-mart";
+import React, { useCallback } from "react";
+import styled from "styled-components";
+
+import { ReactionButton } from "../Reactions/ReactionButton";
+
+interface MessageReactionsProps {
+ messageReactions: BaseEmoji[];
+ setMessageReactions: React.Dispatch>;
+}
+
+export function MessageReactions({
+ messageReactions,
+ setMessageReactions,
+}: MessageReactionsProps) {
+ const isMyReactionIncluded = (emoji: BaseEmoji) =>
+ messageReactions.includes(emoji); // temporary function while message reactions are not added to waku
+
+ const handleReaction = useCallback(
+ (emoji: BaseEmoji) => {
+ messageReactions.find((e) => e === emoji)
+ ? setMessageReactions((prev) => prev.filter((e) => e != emoji))
+ : setMessageReactions((prev) => [...prev, emoji]);
+ },
+ [messageReactions, setMessageReactions]
+ );
+
+ return (
+
+ {messageReactions.map((reaction) => (
+ handleReaction(reaction)}
+ >
+
+ 1
+
+ ))}
+
+
+ );
+}
+
+export const Reactions = styled.div`
+ display: flex;
+ align-items: center;
+ margin-top: 6px;
+`;
+
+const EmojiReaction = styled.button`
+ display: flex;
+ align-items: center;
+ background: rgba(0, 0, 0, 0.05);
+ border-radius: 2px 10px 10px 10px;
+ color: ${({ theme }) => theme.primary};
+ font-size: 12px;
+ line-height: 16px;
+ padding: 2px 8px 2px 2px;
+ margin-right: 4px;
+
+ &:hover {
+ background: rgba(0, 0, 0, 0.1);
+ }
+
+ & > p {
+ margin-left: 4px;
+ }
+
+ & > span {
+ height: 16px;
+ }
+
+ &.chosen {
+ background: ${({ theme }) => theme.blueBg};
+ border: 1px solid ${({ theme }) => theme.tertiary};
+ color: ${({ theme }) => theme.tertiary};
+ }
+`;
diff --git a/packages/status-react/src/components/Messages/MessagesList.tsx b/packages/status-react/src/components/Messages/MessagesList.tsx
new file mode 100644
index 00000000..73a897ef
--- /dev/null
+++ b/packages/status-react/src/components/Messages/MessagesList.tsx
@@ -0,0 +1,107 @@
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { useChatScrollHandle } from "../../hooks/useChatScrollHandle";
+import { Reply } from "../../hooks/useReply";
+import { ChannelData } from "../../models/ChannelData";
+import { EmptyChannel } from "../Channels/EmptyChannel";
+import { LoadingIcon } from "../Icons/LoadingIcon";
+import { LinkModal, LinkModalName } from "../Modals/LinkModal";
+import { PictureModal, PictureModalName } from "../Modals/PictureModal";
+
+import { UiMessage } from "./UiMessage";
+
+interface MessagesListProps {
+ setReply: (val: Reply | undefined) => void;
+ channel: ChannelData;
+}
+
+export function MessagesList({ setReply, channel }: MessagesListProps) {
+ const narrow = useNarrow();
+ const { messages, contacts } = useMessengerContext();
+ const ref = useRef(null);
+ const loadingMessages = useChatScrollHandle(messages, ref);
+
+ const shownMessages = useMemo(
+ () =>
+ messages.filter(
+ (message) => !contacts?.[message.sender]?.blocked ?? true
+ ),
+ [contacts, messages]
+ );
+
+ const [image, setImage] = useState("");
+ const [link, setLink] = useState("");
+
+ const { setModal: setPictureModal, isVisible: showPictureModal } =
+ useModal(PictureModalName);
+ const { setModal: setLinkModal, isVisible: showLinkModal } =
+ useModal(LinkModalName);
+
+ useEffect(
+ () => (!image ? undefined : setPictureModal(true)),
+ [image, setPictureModal]
+ );
+ useEffect(
+ () => (!link ? undefined : setLinkModal(true)),
+ [link, setLinkModal]
+ );
+
+ useEffect(
+ () => (!showPictureModal ? setImage("") : undefined),
+ [showPictureModal]
+ );
+ useEffect(() => (!showLinkModal ? setLink("") : undefined), [showLinkModal]);
+
+ return (
+
+
+
+
+ {loadingMessages && (
+
+
+
+ )}
+ {shownMessages.map((message, idx) => (
+
+ ))}
+
+ );
+}
+
+const LoadingWrapper = styled.div`
+ display: flex;
+ align-self: center;
+ align-items: center;
+ justify-content: center;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ position: relative;
+`;
+
+const MessagesWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ height: calc(100% - 44px);
+ overflow: auto;
+ padding: 8px 0;
+
+ &.wide {
+ margin-top: -24px;
+ }
+
+ &::-webkit-scrollbar {
+ width: 0;
+ }
+`;
diff --git a/packages/status-react/src/components/Messages/Styles.tsx b/packages/status-react/src/components/Messages/Styles.tsx
new file mode 100644
index 00000000..26f84d9b
--- /dev/null
+++ b/packages/status-react/src/components/Messages/Styles.tsx
@@ -0,0 +1,156 @@
+import styled from "styled-components";
+
+import { textMediumStyles, textSmallStyles } from "../Text";
+
+export const MessageWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 8px 16px;
+ border-left: 2px solid ${({ theme }) => theme.bodyBackgroundColor};
+ position: relative;
+
+ &:hover {
+ background: ${({ theme }) => theme.inputColor};
+ border-color: ${({ theme }) => theme.inputColor};
+ }
+
+ &:hover > div {
+ visibility: visible;
+ }
+
+ &.mention {
+ background: ${({ theme }) => theme.mentionBg};
+ border-color: ${({ theme }) => theme.mentionColor};
+ }
+
+ &.mention:hover {
+ background: ${({ theme }) => theme.mentionBgHover};
+ border-color: ${({ theme }) => theme.mentionColor};
+ }
+`;
+
+export const MessageOuterWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+`;
+
+export const DateSeparator = styled.div`
+ width: 100%;
+ display: flex;
+ flex: 1;
+ height: 100%;
+ text-align: center;
+ justify-content: center;
+ align-items: center;
+ font-family: "Inter";
+ font-style: normal;
+ font-weight: 500;
+ color: #939ba1;
+ margin-top: 16px;
+ margin-bottom: 16px;
+
+ ${textSmallStyles}
+`;
+
+export const ContentWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ margin-left: 8px;
+`;
+
+export const MessageHeaderWrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+export const UserNameWrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+export const UserName = styled.p`
+ font-weight: 500;
+ color: ${({ theme }) => theme.tertiary};
+ margin-right: 4px;
+
+ ${textMediumStyles}
+`;
+
+export const UserNameBtn = styled.button`
+ padding: 0;
+ border: none;
+ outline: none;
+ position: relative;
+ color: ${({ theme }) => theme.tertiary};
+
+ &:hover {
+ text-decoration: underline;
+ }
+
+ &:disabled {
+ cursor: default;
+ text-decoration: none;
+ }
+`;
+
+export const UserAddress = styled.p`
+ font-size: 10px;
+ line-height: 14px;
+ letter-spacing: 0.2px;
+ color: ${({ theme }) => theme.secondary};
+ position: relative;
+ padding-right: 8px;
+
+ &.chat:after {
+ content: "";
+ position: absolute;
+ right: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 4px;
+ height: 4px;
+ border-radius: 50%;
+ background: ${({ theme }) => theme.secondary};
+ }
+`;
+
+export const TimeWrapper = styled.div`
+ font-size: 10px;
+ line-height: 14px;
+ letter-spacing: 0.2px;
+ text-transform: uppercase;
+ color: ${({ theme }) => theme.secondary};
+ margin-left: 4px;
+`;
+
+export const MessageText = styled.div`
+ overflow-wrap: anywhere;
+ width: 100%;
+ white-space: pre-wrap;
+ color: ${({ theme }) => theme.primary};
+`;
+
+export const IconBtn = styled.button`
+ width: 40px;
+ height: 40px;
+ display: flex;
+ justify-content: center;
+ align-items: end;
+ flex-shrink: 0;
+ border: none;
+ border-radius: 50%;
+ background-color: #bcbdff;
+ background-size: contain;
+ background-position: center;
+ padding: 0;
+ outline: none;
+ position: relative;
+ cursor: pointer;
+
+ &:disabled {
+ cursor: default;
+ }
+`;
diff --git a/packages/status-react/src/components/Messages/UiMessage.tsx b/packages/status-react/src/components/Messages/UiMessage.tsx
new file mode 100644
index 00000000..d5748941
--- /dev/null
+++ b/packages/status-react/src/components/Messages/UiMessage.tsx
@@ -0,0 +1,163 @@
+import { BaseEmoji } from "emoji-mart";
+import React, { useMemo, useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useIdentity } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { Reply } from "../../hooks/useReply";
+import { ChatMessage } from "../../models/ChatMessage";
+import { equalDate } from "../../utils";
+import { ChatMessageContent } from "../Chat/ChatMessageContent";
+import { ContactMenu } from "../Form/ContactMenu";
+import { MessageMenu } from "../Form/MessageMenu";
+import { UntrustworthIcon } from "../Icons/UntrustworthIcon";
+import { UserLogo } from "../Members/UserLogo";
+import { Reactions } from "../Reactions/Reactions";
+
+import { MessageQuote } from "./MessageQuote";
+import { MessageReactions } from "./MessageReactions";
+import {
+ ContentWrapper,
+ DateSeparator,
+ IconBtn,
+ MessageHeaderWrapper,
+ MessageOuterWrapper,
+ MessageText,
+ MessageWrapper,
+ TimeWrapper,
+ UserAddress,
+ UserName,
+ UserNameBtn,
+ UserNameWrapper,
+} from "./Styles";
+
+type UiMessageProps = {
+ idx: number;
+ message: ChatMessage;
+ prevMessage: ChatMessage;
+ setImage: (img: string) => void;
+ setLink: (link: string) => void;
+ setReply: (val: Reply | undefined) => void;
+};
+
+export function UiMessage({
+ message,
+ idx,
+ prevMessage,
+ setImage,
+ setLink,
+ setReply,
+}: UiMessageProps) {
+ const today = new Date();
+ const { contacts } = useMessengerContext();
+ const identity = useIdentity();
+
+ const contact = useMemo(
+ () => contacts[message.sender],
+ [message.sender, contacts]
+ );
+ const [showMenu, setShowMenu] = useState(false);
+
+ const [mentioned, setMentioned] = useState(false);
+ const [messageReactions, setMessageReactions] = useState([]);
+
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowMenu(false));
+
+ const messageRef = useRef(null);
+
+ return (
+
+ {(idx === 0 || !equalDate(prevMessage.date, message.date)) && (
+
+ {equalDate(message.date, today)
+ ? "Today"
+ : message.date.toLocaleDateString()}
+
+ )}
+
+
+
+ {
+ if (identity) setShowMenu((e) => !e);
+ }}
+ disabled={!identity}
+ ref={ref}
+ >
+ {showMenu && (
+
+ )}
+
+
+
+
+
+ {
+ if (identity) setShowMenu((e) => !e);
+ }}
+ disabled={!identity}
+ >
+
+ {" "}
+ {contact?.customName ?? contact.trueName}
+
+
+
+ {message.sender.slice(0, 5)}...{message.sender.slice(-3)}
+
+ {contact.isUntrustworthy && }
+
+ {message.date.toLocaleString()}
+
+
+
+
+ {messageReactions.length > 0 && (
+
+ )}
+
+
+
+ {identity && (
+
+ )}
+
+
+ );
+}
+
+const UserMessageWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ position: relative;
+`;
diff --git a/packages/status-react/src/components/Modals/AgreementModal.tsx b/packages/status-react/src/components/Modals/AgreementModal.tsx
new file mode 100644
index 00000000..a542d451
--- /dev/null
+++ b/packages/status-react/src/components/Modals/AgreementModal.tsx
@@ -0,0 +1,156 @@
+import HCaptcha from "@hcaptcha/react-hcaptcha";
+import React, { useState } from "react";
+import styled, { useTheme } from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { lightTheme, Theme } from "../../styles/themes";
+import { Logo } from "../CommunityIdentity";
+import { textMediumStyles } from "../Text";
+
+import { Modal } from "./Modal";
+import { Btn, ButtonSection, Heading, Section, Text } from "./ModalStyle";
+
+export const AgreementModalName = "AgreementModal";
+
+export function AgreementModal() {
+ const theme = useTheme() as Theme;
+ const { communityData } = useMessengerContext();
+ const { setModal } = useModal(AgreementModalName);
+
+ const [checked, setChecked] = useState(false);
+ const [token, setToken] = useState("");
+
+ return (
+
+
+ Welcome to {communityData?.name}
+
+
+
+
+ {" "}
+ {communityData?.icon === undefined &&
+ communityData?.name.slice(0, 1).toUpperCase()}
+
+
+
+ {communityData?.description}
+
+
+
+ setChecked(e.target.checked)}
+ required
+ />
+ I agree with the above
+
+
+
+
+
+
+ {
+ setModal(false);
+ }}
+ disabled={!token || !checked}
+ >
+ Join {communityData?.name}
+
+
+
+ );
+}
+
+const LogoWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ margin-bottom: 24px;
+`;
+
+const CommunityLogo = styled(Logo)`
+ width: 64px;
+ height: 64px;
+`;
+
+const AgreementSection = styled.div`
+ margin-bottom: 24px;
+`;
+
+const Agreements = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+const Agreement = styled.label`
+ display: flex;
+ align-items: center;
+ position: relative;
+ color: ${({ theme }) => theme.primary};
+ padding-left: 26px;
+ margin-right: 48px;
+
+ ${textMediumStyles}
+
+ & input:checked ~ span {
+ background-color: ${({ theme }) => theme.tertiary};
+ border: 1px solid ${({ theme }) => theme.tertiary};
+ border-radius: 2px;
+ }
+
+ & input:checked ~ span:after {
+ display: block;
+ }
+`;
+
+const AgreementInput = styled.input`
+ position: absolute;
+ opacity: 0;
+ height: 0;
+ width: 0;
+`;
+
+const Checkmark = styled.span`
+ position: absolute;
+ top: 2px;
+ left: 0;
+ width: 18px;
+ height: 18px;
+
+ background-color: ${({ theme }) => theme.inputColor};
+ border: 1px solid ${({ theme }) => theme.inputColor};
+ border-radius: 2px;
+ margin: 0 8px 0 0;
+
+ &:after {
+ content: "";
+ position: absolute;
+ display: none;
+
+ left: 5px;
+ top: 1px;
+ width: 4px;
+ height: 9px;
+ border: solid ${({ theme }) => theme.bodyBackgroundColor};
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+ }
+`;
diff --git a/packages/status-react/src/components/Modals/CoinbaseModal.tsx b/packages/status-react/src/components/Modals/CoinbaseModal.tsx
new file mode 100644
index 00000000..787f96f0
--- /dev/null
+++ b/packages/status-react/src/components/Modals/CoinbaseModal.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+
+import { ConnectModal } from "./ConnectModal";
+import { Modal } from "./Modal";
+
+export const CoinbaseModalName = "CoinbaseModal";
+
+export function CoinbaseModal() {
+ return (
+
+
+
+ );
+}
diff --git a/packages/status-react/src/components/Modals/CommunityModal.tsx b/packages/status-react/src/components/Modals/CommunityModal.tsx
new file mode 100644
index 00000000..c739f005
--- /dev/null
+++ b/packages/status-react/src/components/Modals/CommunityModal.tsx
@@ -0,0 +1,76 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { DownloadButton } from "../Buttons/DownloadButton";
+import {
+ CommunityIdentity,
+ CommunityIdentityProps,
+} from "../CommunityIdentity";
+import { CopyInput } from "../Form/CopyInput";
+import { StatusLogo } from "../Icons/StatusLogo";
+import { textSmallStyles } from "../Text";
+
+import { Modal } from "./Modal";
+import { Section, Text } from "./ModalStyle";
+
+export const CommunityModalName = "CommunityModal";
+
+type CommunityModalProps = CommunityIdentityProps;
+
+export const CommunityModal = ({ subtitle }: CommunityModalProps) => {
+ const narrow = useNarrow();
+ const { communityData } = useMessengerContext();
+ return (
+
+
+
+ {communityData?.description}
+
+
+
+
+ To access this community, paste community public key in Status desktop
+ or mobile app.
+ {narrow && }
+
+
+ {!narrow && (
+
+
+
+
+ )}
+
+ );
+};
+
+const BottomSection = styled(Section)`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+const StyledDownloadButton = styled(DownloadButton)`
+ display: inline;
+ padding: 0;
+ margin-left: 4px;
+ background: none;
+ font-size: 13px;
+ line-height: 18px;
+ text-decoration: underline;
+ color: ${({ theme }) => theme.secondary};
+`;
+
+const Hint = styled.p`
+ margin-top: 16px;
+ color: ${({ theme }) => theme.secondary};
+
+ ${textSmallStyles}
+`;
diff --git a/packages/status-react/src/components/Modals/ConnectModal.tsx b/packages/status-react/src/components/Modals/ConnectModal.tsx
new file mode 100644
index 00000000..cbacd2e5
--- /dev/null
+++ b/packages/status-react/src/components/Modals/ConnectModal.tsx
@@ -0,0 +1,32 @@
+import QRCode from "qrcode.react";
+import React from "react";
+
+import { CopyInput } from "../Form/CopyInput";
+
+import { Heading, MiddleSection, QRWrapper, Section, Text } from "./ModalStyle";
+
+export const ConnectModalName = "ConnectModal";
+
+interface ConnectModalProps {
+ name: string;
+ address: string;
+ text: string;
+}
+
+export function ConnectModal({ name, address, text }: ConnectModalProps) {
+ return (
+ <>
+
+
+ {text}
+
+ {" "}
+
+
+
+
+ >
+ );
+}
diff --git a/packages/status-react/src/components/Modals/EditModal.tsx b/packages/status-react/src/components/Modals/EditModal.tsx
new file mode 100644
index 00000000..e6b24df5
--- /dev/null
+++ b/packages/status-react/src/components/Modals/EditModal.tsx
@@ -0,0 +1,164 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { buttonStyles } from "../Buttons/buttonStyle";
+import { ChannelLogo } from "../Channels/ChannelIcon";
+import { inputStyles } from "../Form/inputStyles";
+import { AddIcon } from "../Icons/AddIcon";
+import { textMediumStyles } from "../Text";
+
+import { Modal } from "./Modal";
+import {
+ AddWrapper,
+ ButtonSection,
+ Heading,
+ Hint,
+ Section,
+} from "./ModalStyle";
+
+export const EditModalName = "editModal";
+
+export const EditModal = () => {
+ const { activeChannel, changeGroupChatName } = useMessengerContext();
+ const { setModal } = useModal(EditModalName);
+
+ const [groupName, setGroupName] = useState("");
+ const [image, setImage] = useState("");
+
+ const handleChange = (e: React.FormEvent) => {
+ if (e.currentTarget?.files?.length) {
+ setImage(URL.createObjectURL(e.currentTarget.files[0]));
+ }
+ };
+
+ const handleUpload = () => {
+ if (activeChannel) {
+ if (image) {
+ activeChannel.icon = image; // Need function to send image to waku
+ setImage("");
+ }
+ if (groupName) {
+ changeGroupChatName(groupName, activeChannel.id);
+ setGroupName("");
+ }
+ setModal(false);
+ }
+ };
+
+ return (
+
+
+ Edit group name and image
+
+
+
+
+
+
+ {groupName.length}/30
+
+
+ setGroupName(e.currentTarget.value)}
+ />
+
+
+
+
+ {!activeChannel?.icon &&
+ !image &&
+ activeChannel?.name?.slice(0, 1)?.toUpperCase()}
+ {image && }
+
+
+
+
+
+
+
+
+ Save changes
+
+
+ );
+};
+
+const NameSection = styled.div`
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 16px;
+`;
+
+const LabelGroup = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+const Label = styled.p`
+ color: ${({ theme }) => theme.primary};
+ padding: 10px 0;
+
+ ${textMediumStyles}
+`;
+
+const NameInput = styled.input`
+ padding: 14px 70px 14px 8px;
+
+ ${inputStyles}
+`;
+
+const LogoSection = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-bottom: 8px;
+`;
+
+const GroupLogo = styled(ChannelLogo)`
+ width: 128px;
+ height: 128px;
+ font-weight: bold;
+ font-size: 80px;
+ position: relative;
+ align-self: center;
+ margin-right: 0;
+`;
+
+const LogoPreview = styled.img`
+ width: 128px;
+ height: 128px;
+ border-radius: 50%;
+`;
+
+const AddPictureInputWrapper = styled(AddWrapper)`
+ top: 0;
+ right: 8px;
+`;
+
+const AddPictureInput = styled.input`
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 40px;
+ height: 40px;
+ opacity: 0;
+ z-index: 2;
+ cursor: pointer;
+`;
+
+const SaveBtn = styled.button`
+ padding: 11px 24px;
+
+ ${buttonStyles}
+`;
diff --git a/packages/status-react/src/components/Modals/LeavingModal.tsx b/packages/status-react/src/components/Modals/LeavingModal.tsx
new file mode 100644
index 00000000..16a02c12
--- /dev/null
+++ b/packages/status-react/src/components/Modals/LeavingModal.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { ButtonNo } from "../Buttons/buttonStyle";
+
+import { Modal } from "./Modal";
+import { ButtonSection, Heading, Section, Text } from "./ModalStyle";
+
+export const LeavingModalName = "LeavingModal";
+
+export const LeavingModal = () => {
+ const { setModal } = useModal(LeavingModalName);
+ const { activeChannel, removeChannel } = useMessengerContext();
+
+ if (activeChannel)
+ return (
+
+
+
+ {activeChannel.type === "dm" ? "Delete chat" : "Leave group"}
+
+
+
+
+ Are you sure you want to{" "}
+ {activeChannel.type === "dm"
+ ? "delete this chat"
+ : "leave this group"}
+ ?
+
+
+
+ {
+ removeChannel(activeChannel.id);
+ setModal(false);
+ }}
+ >
+ {activeChannel.type === "dm" ? "Delete" : "Leave"}
+
+
+
+ );
+ else {
+ return null;
+ }
+};
diff --git a/packages/status-react/src/components/Modals/LinkModal.tsx b/packages/status-react/src/components/Modals/LinkModal.tsx
new file mode 100644
index 00000000..6c260bc8
--- /dev/null
+++ b/packages/status-react/src/components/Modals/LinkModal.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useModal } from "../../contexts/modalProvider";
+import { ButtonNo, ButtonYes } from "../Buttons/buttonStyle";
+import { textMediumStyles } from "../Text";
+
+import { Modal } from "./Modal";
+import { ButtonSection, Heading, Section } from "./ModalStyle";
+
+export const LinkModalName = "LinkModal";
+
+interface LinkModalProps {
+ link: string;
+}
+
+export const LinkModal = ({ link }: LinkModalProps) => {
+ const { setModal } = useModal(LinkModalName);
+ return (
+
+
+ Are you sure you want to visit this website?
+
+
+
+ setModal(false)}>No
+ {
+ window?.open(link, "_blank", "noopener")?.focus();
+ setModal(false);
+ }}
+ >
+ Yes, take me there
+
+
+
+ );
+};
+
+const Link = styled.a`
+ text-decoration: none;
+ word-break: break-all;
+ color: ${({ theme }) => theme.primary};
+
+ ${textMediumStyles}
+`;
diff --git a/packages/status-react/src/components/Modals/LogoutModal.tsx b/packages/status-react/src/components/Modals/LogoutModal.tsx
new file mode 100644
index 00000000..4e0bcf99
--- /dev/null
+++ b/packages/status-react/src/components/Modals/LogoutModal.tsx
@@ -0,0 +1,100 @@
+import React from "react";
+import styled from "styled-components";
+
+import {
+ useSetIdentity,
+ useSetNikcname,
+ useUserPublicKey,
+} from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { ButtonNo, ButtonYes } from "../Buttons/buttonStyle";
+import { UserLogo } from "../Members/UserLogo";
+
+import { Modal } from "./Modal";
+import { ButtonSection, Heading, Section, Text } from "./ModalStyle";
+import {
+ EmojiKey,
+ UserAddress,
+ UserAddressWrapper,
+ UserName,
+ UserNameWrapper,
+} from "./ProfileModal";
+
+export const LogoutModalName = "LogoutModal";
+
+export const LogoutModal = () => {
+ const { setModal } = useModal(LogoutModalName);
+ const logout = useSetIdentity();
+ const setNickname = useSetNikcname();
+ const userPK = useUserPublicKey();
+ const { nickname } = useMessengerContext();
+
+ if (userPK) {
+ return (
+
+
+
+ Do you want to disconnect your profile?
+
+
+
+ {" "}
+ {nickname}
+
+
+
+
+ {" "}
+ Chatkey: {userPK.slice(0, 10)}...
+ {userPK.slice(-3)}{" "}
+
+
+ 🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱
+
+
+
+ {
+ setModal(false);
+ logout(undefined);
+ setNickname(undefined);
+ }}
+ >
+ Disconnect
+
+ {
+ setModal(false);
+ }}
+ >
+ Stay Connected
+
+
+
+ );
+ }
+
+ return null;
+};
+
+const UserSection = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin: 8px 0;
+`;
diff --git a/packages/status-react/src/components/Modals/Modal.tsx b/packages/status-react/src/components/Modals/Modal.tsx
new file mode 100644
index 00000000..e86d07f4
--- /dev/null
+++ b/packages/status-react/src/components/Modals/Modal.tsx
@@ -0,0 +1,112 @@
+import React, { ReactNode, useCallback, useEffect } from "react";
+import { createPortal } from "react-dom";
+import styled from "styled-components";
+
+import { useModal } from "../../contexts/modalProvider";
+import { CrossIcon } from "../Icons/CrossIcon";
+
+export interface BasicModalProps {
+ name: string;
+ className?: string;
+}
+
+export interface ModalProps extends BasicModalProps {
+ children: ReactNode;
+}
+
+export const Modal = ({ name, children, className }: ModalProps) => {
+ const { isVisible, setModal } = useModal(name);
+
+ const listenKeyboard = useCallback(
+ (event: KeyboardEvent) => {
+ if (event.key === "Escape" || event.keyCode === 27) {
+ setModal(false);
+ }
+ },
+ [setModal]
+ );
+
+ useEffect(() => {
+ if (isVisible) {
+ window.addEventListener("keydown", listenKeyboard, true);
+ return () => {
+ window.removeEventListener("keydown", listenKeyboard, true);
+ };
+ }
+ }, [isVisible, listenKeyboard]);
+
+ if (!isVisible) return null;
+
+ const element = document.getElementById("modal-root");
+
+ if (element) {
+ return createPortal(
+
+ setModal(false)} />
+
+ setModal(false)} className={className}>
+
+
+ {children}
+
+ ,
+ element
+ );
+ }
+ return null;
+};
+
+const ModalView = styled.div`
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 9999;
+`;
+
+const ModalBody = styled.div`
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ max-width: 480px;
+ width: 100%;
+ transform: translate(-50%, -50%);
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ border-radius: 8px;
+ overflow-y: auto;
+
+ &.picture {
+ max-width: 820px;
+ border-radius: 0;
+ }
+
+ &.wide {
+ max-width: 640px;
+ }
+`;
+
+const ModalOverlay = styled.div`
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ background: ${({ theme }) => theme.primary};
+ opacity: 0.4;
+`;
+
+const CloseButton = styled.button`
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ padding: 10px;
+
+ &.picture {
+ display: none;
+ }
+`;
diff --git a/packages/status-react/src/components/Modals/ModalStyle.tsx b/packages/status-react/src/components/Modals/ModalStyle.tsx
new file mode 100644
index 00000000..690808ef
--- /dev/null
+++ b/packages/status-react/src/components/Modals/ModalStyle.tsx
@@ -0,0 +1,85 @@
+import styled from "styled-components";
+
+import { buttonStyles } from "../Buttons/buttonStyle";
+import { textMediumStyles } from "../Text";
+
+export const Section = styled.div`
+ padding: 16px;
+
+ & + & {
+ border-top: 1px solid ${({ theme }) => theme.border};
+ }
+`;
+
+export const MiddleSection = styled(Section)`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+export const Heading = styled.p`
+ color: ${({ theme }) => theme.primary};
+ font-weight: bold;
+ font-size: 17px;
+ line-height: 24px;
+`;
+
+export const Text = styled.p`
+ color: ${({ theme }) => theme.primary};
+
+ ${textMediumStyles}
+`;
+
+export const Btn = styled.button`
+ padding: 11px 24px;
+ margin-left: 8px;
+ ${buttonStyles}
+
+ &:disabled {
+ background: ${({ theme }) => theme.border};
+ color: ${({ theme }) => theme.secondary};
+ }
+`;
+
+export const BackBtn = styled(Btn)`
+ position: absolute;
+ left: 16px;
+ top: 16px;
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ padding: 8px;
+ margin-left: 0;
+
+ & > svg {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+`;
+
+export const ButtonSection = styled(Section)`
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ position: relative;
+`;
+
+export const Hint = styled.p`
+ color: ${({ theme }) => theme.secondary};
+ font-size: 12px;
+ line-height: 16px;
+`;
+
+export const AddWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ width: 40px;
+ height: 40px;
+ background: ${({ theme }) => theme.tertiary};
+ border-radius: 50%;
+`;
+
+export const QRWrapper = styled.div`
+ margin: 30px 0;
+`;
diff --git a/packages/status-react/src/components/Modals/PictureModal.tsx b/packages/status-react/src/components/Modals/PictureModal.tsx
new file mode 100644
index 00000000..6e863fe1
--- /dev/null
+++ b/packages/status-react/src/components/Modals/PictureModal.tsx
@@ -0,0 +1,31 @@
+import React from "react";
+import styled from "styled-components";
+
+import { Modal } from "./Modal";
+
+export const PictureModalName = "PictureModal" as const;
+
+export interface PictureModalProps {
+ image: string;
+}
+
+export const PictureModal = ({ image }: PictureModalProps) => {
+ return (
+
+
+
+
+
+ );
+};
+
+const ModalImageWrapper = styled.div`
+ display: flex;
+ max-width: 820px;
+ max-height: 820px;
+`;
+
+const ModalImage = styled.img`
+ width: 100%;
+ height: 100%;
+`;
diff --git a/packages/status-react/src/components/Modals/ProfileFoundModal.tsx b/packages/status-react/src/components/Modals/ProfileFoundModal.tsx
new file mode 100644
index 00000000..d943656b
--- /dev/null
+++ b/packages/status-react/src/components/Modals/ProfileFoundModal.tsx
@@ -0,0 +1,129 @@
+import { Identity, utils } from "@status-im/core";
+import React, { useEffect, useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { useNickname, useSetIdentity } from "../../contexts/identityProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { decryptIdentity, loadEncryptedIdentity } from "../../utils";
+import { buttonTransparentStyles } from "../Buttons/buttonStyle";
+import { UserLogo } from "../Members/UserLogo";
+import { textMediumStyles } from "../Text";
+
+import { Modal } from "./Modal";
+import {
+ Btn,
+ ButtonSection,
+ Heading,
+ MiddleSection,
+ Section,
+ Text,
+} from "./ModalStyle";
+import {
+ EmojiKey,
+ UserAddress,
+ UserAddressWrapper,
+ UserName,
+} from "./ProfileModal";
+import { UserCreationModalName } from "./UserCreationModal";
+
+export const ProfileFoundModalName = "ProfileFoundModal";
+
+export function ProfileFoundModal() {
+ const { setModal } = useModal(ProfileFoundModalName);
+ const { setModal: setCreationModal } = useModal(UserCreationModalName);
+
+ const setIdentity = useSetIdentity();
+ const encryptedIdentity = useMemo(() => loadEncryptedIdentity(), []);
+ const nickname = useNickname();
+
+ const [decryptedIdentity, setDecryptedIdentity] = useState<
+ Identity | undefined
+ >(undefined);
+
+ useEffect(() => {
+ if (encryptedIdentity)
+ (async () => {
+ setDecryptedIdentity(
+ await decryptIdentity(encryptedIdentity, "noPassword")
+ );
+ })();
+ }, [encryptedIdentity]);
+
+ if (decryptedIdentity) {
+ return (
+
+
+ Throwaway Profile found
+
+
+
+
+ {nickname}
+
+
+
+ {" "}
+ Chatkey: {decryptedIdentity.privateKey.slice(0, 10)}...
+ {decryptedIdentity.privateKey.slice(-3)}{" "}
+
+
+ 🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱
+
+
+ Throwaway Profile is found in your local browser’s cache. Would you
+ like to load it and use it?{" "}
+
+
+
+ {
+ setCreationModal(true);
+ setModal(false);
+ }}
+ >
+ Skip
+
+ {
+ setIdentity(decryptedIdentity);
+ setModal(false);
+ }}
+ >
+ Load Throwaway Profile
+
+
+
+ );
+ } else {
+ return null;
+ }
+}
+
+const Logo = styled(UserLogo)`
+ margin-bottom: 8px;
+`;
+
+const Name = styled(UserName)`
+ margin-bottom: 8px;
+`;
+
+const EmojiKeyBlock = styled(EmojiKey)`
+ margin-bottom: 24px;
+`;
+
+const SkipBtn = styled.button`
+ ${buttonTransparentStyles}
+ ${textMediumStyles}
+`;
diff --git a/packages/status-react/src/components/Modals/ProfileModal.tsx b/packages/status-react/src/components/Modals/ProfileModal.tsx
new file mode 100644
index 00000000..b10f14c5
--- /dev/null
+++ b/packages/status-react/src/components/Modals/ProfileModal.tsx
@@ -0,0 +1,416 @@
+import React, { useEffect, useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { useToasts } from "../../contexts/toastProvider";
+import { copy } from "../../utils";
+import { buttonStyles } from "../Buttons/buttonStyle";
+import {
+ ClearBtn,
+ inputStyles,
+ NameInput,
+ NameInputWrapper,
+} from "../Form/inputStyles";
+import { ClearSvgFull } from "../Icons/ClearIconFull";
+import { CopyIcon } from "../Icons/CopyIcon";
+import { EditIcon } from "../Icons/EditIcon";
+import { LeftIcon } from "../Icons/LeftIcon";
+import { UntrustworthIcon } from "../Icons/UntrustworthIcon";
+import { UserIcon } from "../Icons/UserIcon";
+import { textMediumStyles, textSmallStyles } from "../Text";
+
+import { Modal } from "./Modal";
+import {
+ BackBtn,
+ Btn,
+ ButtonSection,
+ Heading,
+ Hint,
+ Section,
+} from "./ModalStyle";
+
+export const ProfileModalName = "profileModal" as const;
+
+export type ProfileModalProps = {
+ id: string;
+ image?: string;
+ renamingState?: boolean;
+ requestState?: boolean;
+};
+
+export const ProfileModal = () => {
+ const { props } = useModal(ProfileModalName);
+ const { id, image, renamingState, requestState } = useMemo(
+ () => (props ? props : { id: "" }),
+ [props]
+ );
+
+ const { setToasts } = useToasts();
+ const { setModal } = useModal(ProfileModalName);
+
+ const userPK = useUserPublicKey();
+ const isUser = useMemo(() => {
+ if (userPK) {
+ return id === userPK;
+ } else {
+ return false;
+ }
+ }, [id, userPK]);
+
+ const [renaming, setRenaming] = useState(renamingState ?? false);
+
+ useEffect(() => {
+ setRenaming(renamingState ?? false);
+ }, [renamingState]);
+
+ const [request, setRequest] = useState("");
+ const [requestCreation, setRequestCreation] = useState(requestState ?? false);
+
+ useEffect(() => {
+ setRequestCreation(requestState ?? false);
+ }, [requestState]);
+
+ const { contacts, contactsDispatch } = useMessengerContext();
+ const contact = useMemo(() => contacts[id], [id, contacts]);
+ const [customNameInput, setCustomNameInput] = useState("");
+
+ if (!contact) return null;
+ return (
+
+
+ {contact.trueName}’s Profile
+
+
+
+
+ {image ? (
+
+ ) : (
+
+ )}
+
+
+ {contact?.customName ?? contact.trueName}
+
+ {contact.isUntrustworthy && }
+ {!renaming && (
+
+ )}
+
+ {contact?.customName && (
+ {contact.trueName}
+ )}
+
+ {renaming ? (
+
+ setCustomNameInput(e.currentTarget.value)}
+ />
+ {customNameInput && (
+ {
+ contactsDispatch({
+ type: "setCustomName",
+ payload: { id, customName: undefined },
+ });
+ setCustomNameInput("");
+ }}
+ >
+
+
+ )}
+
+ ) : (
+ <>
+
+ {requestCreation ? (
+
+ {id.slice(0, 10)}...{id.slice(-3)}
+
+ ) : (
+ <>
+
+ Chatkey: {id.slice(0, 30)}
+
+
+ copy(id)}>
+
+
+ >
+ )}
+
+
+ 🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱
+ {" "}
+ >
+ )}
+ {requestCreation && (
+
+ {request.length}/280
+ setRequest(e.currentTarget.value)}
+ required
+ autoFocus
+ />
+
+ )}
+
+
+ {renaming ? (
+ <>
+ setRenaming(false)}>
+
+
+ {
+ contactsDispatch({
+ type: "setCustomName",
+ payload: { id, customName: customNameInput },
+ });
+ setRenaming(false);
+ }}
+ >
+ Apply nickname
+
+ >
+ ) : requestCreation ? (
+ <>
+ setRequestCreation(false)}>
+
+
+ {
+ setToasts((prev) => [
+ ...prev,
+ {
+ id: id + request,
+ type: "confirmation",
+ text: "Contact Request Sent",
+ },
+ ]),
+ setRequestCreation(false),
+ setModal(false),
+ setRequest("");
+ }}
+ >
+ Send Contact Request
+
+ >
+ ) : (
+ <>
+ {!contact.isFriend && !isUser && (
+ {
+ contactsDispatch({ type: "toggleBlocked", payload: { id } });
+ }}
+ >
+ {contact.blocked ? "Unblock" : "Block"}
+
+ )}
+ {contact.isFriend && (
+
+ contactsDispatch({
+ type: "setIsFriend",
+ payload: { id, isFriend: false },
+ })
+ }
+ >
+ Remove Contact
+
+ )}
+
+ contactsDispatch({ type: "toggleTrustworthy", payload: { id } })
+ }
+ >
+ {contact.isUntrustworthy
+ ? "Remove Untrustworthy Mark"
+ : "Mark as Untrustworthy"}
+
+ {!contact.isFriend && (
+ setRequestCreation(true)}>
+ Send Contact Request
+
+ )}
+ >
+ )}
+
+
+ );
+};
+
+const ProfileSection = styled(Section)`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+const NameSection = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ margin-bottom: 16px;
+
+ &.small {
+ margin-bottom: 0;
+ }
+`;
+
+const ProfileIcon = styled.div`
+ width: 80px;
+ height: 80px;
+ display: flex;
+ justify-content: center;
+ align-items: end;
+ border-radius: 50%;
+ background-color: #bcbdff;
+ background-size: contain;
+ background-position: center;
+ flex-shrink: 0;
+ position: relative;
+ cursor: pointer;
+
+ &.small {
+ width: 64px;
+ height: 64px;
+ }
+`;
+
+export const UserNameWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-top: 4px;
+
+ & > svg {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &.logout {
+ margin: 8px 0;
+ }
+`;
+
+export const UserName = styled.p`
+ color: ${({ theme }) => theme.primary};
+ font-weight: bold;
+ font-size: 22px;
+ line-height: 30px;
+ letter-spacing: -0.2px;
+ margin-right: 8px;
+
+ &.small {
+ font-size: 17px;
+ line-height: 24px;
+ margin-right: 0;
+ }
+`;
+
+const UserTrueName = styled.p`
+ color: ${({ theme }) => theme.primary};
+ font-size: 12px;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ margin-top: 8px;
+`;
+
+export const UserAddressWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-bottom: 24px;
+
+ &.small {
+ margin-bottom: 8px;
+ }
+`;
+
+export const UserAddress = styled.p`
+ display: flex;
+ letter-spacing: 1px;
+ margin-right: 8px;
+ color: ${({ theme }) => theme.secondary};
+
+ ${textMediumStyles}
+
+ &.small {
+ margin-right: 0;
+
+ ${textSmallStyles}
+ }
+`;
+export const EmojiKey = styled.div`
+ width: 116px;
+ gap: 8px;
+ font-size: 15px;
+ line-height: 14px;
+ letter-spacing: 0.2px;
+
+ &.small {
+ width: 83px;
+ ${textSmallStyles}
+ }
+`;
+
+const ProfileBtn = styled.button`
+ padding: 11px 24px;
+ ${buttonStyles}
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ border: 1px solid ${({ theme }) => theme.border};
+ margin-left: 8px;
+
+ &.red {
+ color: ${({ theme }) => theme.redColor};
+ }
+
+ &.red:hover {
+ background: ${({ theme }) => theme.buttonNoBgHover};
+ }
+`;
+
+const CopyButton = styled.button`
+ & > svg {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+`;
+
+const RequestSection = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ margin: 16px 0;
+`;
+
+const RequestInput = styled.textarea`
+ width: 100%;
+ height: 152px;
+ padding: 10px 16px;
+ resize: none;
+ margin-top: 16px;
+ font-family: "Inter";
+
+ ${inputStyles}
+`;
diff --git a/packages/status-react/src/components/Modals/SizeLimitModal.tsx b/packages/status-react/src/components/Modals/SizeLimitModal.tsx
new file mode 100644
index 00000000..1127559c
--- /dev/null
+++ b/packages/status-react/src/components/Modals/SizeLimitModal.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+
+import { useModal } from "../../contexts/modalProvider";
+
+import { Modal } from "./Modal";
+
+export const SizeLimitModalName = "SizeLimitModal";
+
+export function SizeLimitModal() {
+ const { setModal } = useModal(SizeLimitModalName);
+
+ return (
+
+ setModal(false)} style={{ padding: "20px" }}>
+ File size must be less than 1MB
+
+
+ );
+}
diff --git a/packages/status-react/src/components/Modals/StatusModal.tsx b/packages/status-react/src/components/Modals/StatusModal.tsx
new file mode 100644
index 00000000..e6fb2840
--- /dev/null
+++ b/packages/status-react/src/components/Modals/StatusModal.tsx
@@ -0,0 +1,89 @@
+import QRCode from "qrcode.react";
+import React, { useState } from "react";
+import styled from "styled-components";
+
+import { buttonStyles } from "../Buttons/buttonStyle";
+import { LoginInstructions } from "../Form/LoginInstructions";
+import { PasteInput } from "../Form/PasteInput";
+
+import { Modal } from "./Modal";
+import { Heading, MiddleSection, Section } from "./ModalStyle";
+
+export const StatusModalName = "StatusModal";
+
+export enum StatusModalState {
+ Mobile,
+ Desktop,
+}
+
+export function StatusModal() {
+ const [modalState, setModalState] = useState(
+ StatusModalState.Mobile
+ );
+
+ const mobileFlow = modalState === StatusModalState.Mobile;
+ const desktopFlow = modalState === StatusModalState.Desktop;
+
+ const switchModalState = (state: StatusModalState) => {
+ setModalState((prev) => (prev === state ? StatusModalState.Mobile : state));
+ };
+ return (
+
+
+ Sync with Status profile
+
+
+
+ switchModalState(StatusModalState.Mobile)}
+ >
+ From mobile
+
+ switchModalState(StatusModalState.Desktop)}
+ >
+ From desktop
+
+
+
+ {mobileFlow && }
+
+ {desktopFlow && }
+
+
+
+
+ );
+}
+
+const MiddleSectionStatus = styled(MiddleSection)`
+ height: 514px;
+`;
+
+const Switch = styled.div`
+ display: flex;
+ align-items: center;
+ margin-bottom: 32px;
+`;
+
+const SwitchBtn = styled.button`
+ ${buttonStyles}
+ width: 159px;
+ padding: 7px 0;
+ text-align: center;
+ color: ${({ theme }) => theme.tertiary};
+ background: ${({ theme }) => theme.buttonBg};
+ position: relative;
+
+ &.active {
+ background: ${({ theme }) => theme.tertiary};
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+ z-index: 10000;
+ }
+`;
+
+const SwitchBtnMobile = styled(SwitchBtn)`
+ margin-left: -8px;
+`;
diff --git a/packages/status-react/src/components/Modals/UserCreationModal.tsx b/packages/status-react/src/components/Modals/UserCreationModal.tsx
new file mode 100644
index 00000000..b327578d
--- /dev/null
+++ b/packages/status-react/src/components/Modals/UserCreationModal.tsx
@@ -0,0 +1,213 @@
+import { Identity } from "@status-im/core";
+import React, { useState } from "react";
+import styled from "styled-components";
+
+import {
+ useSetIdentity,
+ useSetNikcname,
+ useUserPublicKey,
+ useWalletIdentity,
+} from "../../contexts/identityProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { useNameError } from "../../hooks/useNameError";
+import { Contact } from "../../models/Contact";
+import { saveIdentity } from "../../utils";
+import { NameError } from "../Form/NameError";
+import { ClearBtn, NameInput, NameInputWrapper } from "../Form/inputStyles";
+import { AddIcon } from "../Icons/AddIcon";
+import { ChainIcon } from "../Icons/ChainIcon";
+import { ClearSvgFull } from "../Icons/ClearIconFull";
+import { LeftIcon } from "../Icons/LeftIcon";
+import { UserLogo } from "../Members/UserLogo";
+
+import { AgreementModalName } from "./AgreementModal";
+import { Modal } from "./Modal";
+import {
+ AddWrapper,
+ BackBtn,
+ Btn,
+ ButtonSection,
+ Heading,
+ Hint,
+ Section,
+ Text,
+} from "./ModalStyle";
+import { EmojiKey, UserAddress } from "./ProfileModal";
+
+export const UserCreationModalName = "UserCreationModal";
+
+export function UserCreationModal() {
+ const walletIdentity = useWalletIdentity();
+ const userPK = useUserPublicKey();
+ const setIdentity = useSetIdentity();
+ const setNickname = useSetNikcname();
+
+ const [customNameInput, setCustomNameInput] = useState("");
+ const error = useNameError(customNameInput);
+ const [nextStep, setNextStep] = useState(false);
+ const { setModal } = useModal(UserCreationModalName);
+ const { setModal: setAgreementModal } = useModal(AgreementModalName);
+
+ return (
+
+
+ Create a Status Profile
+
+
+ {nextStep ? (
+ Your emojihash and identicon ring
+ ) : (
+ Your profile
+ )}
+ {nextStep ? (
+
+ {" "}
+ This set of emojis and coloured ring around your avatar are unique
+ and represent your chat key, so your friends can easily distinguish
+ you from potential impersonators.
+
+ ) : (
+
+ Longer and unusual names are better as they are
less likely
+ to be used by someone else.
+
+ )}
+
+
+
+ {!nextStep && (
+
+
+
+ )}
+
+ {!nextStep && (
+
+ setCustomNameInput(e.currentTarget.value)}
+ maxLength={24}
+ />
+ {customNameInput && (
+ setCustomNameInput("")}>
+
+
+ )}
+
+ )}
+
+
+
+ {nextStep && userPK && (
+ <>
+
+ {" "}
+ Chatkey: {userPK.slice(0, 10)}...
+ {userPK.slice(-3)}{" "}
+
+
+
+
+
+
+ 🎩🍞🥑🦍🌈📡💅🏻♣️🔔⛸👵🅱
+
+
+ >
+ )}
+
+
+ setModal(false)}>
+
+
+ {
+ if (nextStep) {
+ setModal(false);
+ setAgreementModal(true);
+ } else {
+ const identity = walletIdentity || Identity.generate();
+ setNickname(customNameInput);
+ setIdentity(identity);
+ !walletIdentity && saveIdentity(identity, "noPassword");
+ setNextStep(true);
+ }
+ }}
+ disabled={!customNameInput || error !== 0}
+ >
+ Next
+
+
+
+ );
+}
+
+const MiddleSection = styled(Section)`
+ height: 420px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ &.initial {
+ padding: 32px;
+ }
+`;
+
+const Title = styled(Text)`
+ font-weight: bold;
+ font-size: 22px;
+ line-height: 30px;
+ letter-spacing: -0.2px;
+ margin-bottom: 16px;
+`;
+
+const StyledHint = styled(Hint)`
+ font-size: 15px;
+ line-height: 22px;
+ margin-bottom: 32px;
+ text-align: center;
+`;
+
+const LogoWrapper = styled.div`
+ position: relative;
+ display: flex;
+ margin-bottom: 32px;
+`;
+
+const AddIconWrapper = styled(AddWrapper)`
+ top: 0;
+ right: -50%;
+ transform: translateX(-50%);
+`;
+
+const ChainIcons = styled.div`
+ width: 104px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin: 16px 0;
+`;
+
+const UserAttributes = styled.div`
+ width: 200px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 32px;
+`;
diff --git a/packages/status-react/src/components/Modals/UserCreationStartModal.tsx b/packages/status-react/src/components/Modals/UserCreationStartModal.tsx
new file mode 100644
index 00000000..404ba391
--- /dev/null
+++ b/packages/status-react/src/components/Modals/UserCreationStartModal.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import styled from "styled-components";
+
+import { UserCreationButtons } from "../UserCreation/UserCreationButtons";
+
+import { Modal } from "./Modal";
+import { Heading, Section } from "./ModalStyle";
+
+export const UserCreationStartModalName = "UserCreationStartModal";
+
+export const UserCreationStartModal = () => {
+ return (
+
+
+ Jump into the discussion
+
+
+
+
+
+ );
+};
+
+const MiddleSection = styled(Section)`
+ padding: 48px 0;
+`;
diff --git a/packages/status-react/src/components/Modals/WalletConnectModal.tsx b/packages/status-react/src/components/Modals/WalletConnectModal.tsx
new file mode 100644
index 00000000..0bd0b145
--- /dev/null
+++ b/packages/status-react/src/components/Modals/WalletConnectModal.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+
+import { ConnectModal } from "./ConnectModal";
+import { Modal } from "./Modal";
+
+export const WalletConnectModalName = "WalletConnectModal";
+
+export function WalletConnectModal() {
+ return (
+
+
+
+ );
+}
diff --git a/packages/status-react/src/components/Modals/WalletModal.tsx b/packages/status-react/src/components/Modals/WalletModal.tsx
new file mode 100644
index 00000000..a730a371
--- /dev/null
+++ b/packages/status-react/src/components/Modals/WalletModal.tsx
@@ -0,0 +1,164 @@
+import { Identity, genPrivateKeyWithEntropy } from "@status-im/core";
+import React, { useCallback } from "react";
+import styled from "styled-components";
+
+import { useConfig } from "../../contexts/configProvider";
+import {
+ useSetIdentity,
+ useSetWalletIdentity,
+} from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useModal } from "../../contexts/modalProvider";
+import { CoinbaseLogo } from "../Icons/CoinbaseLogo";
+import { MetamaskLogo } from "../Icons/MetamaskLogo";
+import { WalletConnectLogo } from "../Icons/WalletConnectLogo";
+
+import { CoinbaseModalName } from "./CoinbaseModal";
+import { Modal } from "./Modal";
+import { Heading, MiddleSection, Section, Text } from "./ModalStyle";
+import { UserCreationModalName } from "./UserCreationModal";
+import { WalletConnectModalName } from "./WalletConnectModal";
+
+export const WalletModalName = "WalletModal";
+
+export function WalletModal() {
+ const { setModal } = useModal(WalletModalName);
+ const setIdentity = useSetIdentity();
+ const setWalletIdentity = useSetWalletIdentity();
+ const { setModal: setUserCreationModal } = useModal(UserCreationModalName);
+ const { setModal: setWalleConnectModal } = useModal(WalletConnectModalName);
+ const { setModal: setCoinbaseModal } = useModal(CoinbaseModalName);
+ const { messenger } = useMessengerContext();
+ const { dappUrl } = useConfig();
+
+ const handleMetamaskClick = useCallback(async () => {
+ const ethereum = (window as any)?.ethereum as any | undefined;
+ if (document.location.origin !== dappUrl) {
+ alert("You are not signing in from correct url!");
+ return;
+ }
+ if (ethereum && messenger) {
+ try {
+ if (ethereum?.isMetaMask) {
+ const [account] = await ethereum.request({
+ method: "eth_requestAccounts",
+ });
+
+ const msgParams = JSON.stringify({
+ domain: {
+ chainId: 1,
+ name: window.location.origin,
+ version: "1",
+ },
+ message: {
+ action: "Status CommunityChatRoom Key",
+ onlySignOn: dappUrl,
+ message:
+ "This signature will be used to decrypt chat communications; check that the 'onlySignOn' property of this message matches the current website address.",
+ },
+ primaryType: "Mail",
+ types: {
+ EIP712Domain: [
+ { name: "name", type: "string" },
+ { name: "version", type: "string" },
+ { name: "chainId", type: "uint256" },
+ ],
+ Mail: [
+ { name: "action", type: "string" },
+ { name: "onlySignOn", type: "string" },
+ { name: "message", type: "string" },
+ ],
+ },
+ });
+
+ const params = [account, msgParams];
+ const method = "eth_signTypedData_v4";
+
+ const signature = await ethereum.request({
+ method,
+ params,
+ from: account,
+ });
+ const privateKey = genPrivateKeyWithEntropy(signature);
+
+ const loadedIdentity = new Identity(privateKey);
+
+ const userInNetwork = await messenger.checkIfUserInWakuNetwork(
+ loadedIdentity.publicKey
+ );
+
+ if (userInNetwork) {
+ setIdentity(loadedIdentity);
+ } else {
+ setWalletIdentity(loadedIdentity);
+ setUserCreationModal(true);
+ }
+ setModal(false);
+ return;
+ }
+ } catch {
+ alert("Error");
+ }
+ }
+ alert("Metamask not found");
+ }, [
+ messenger,
+ dappUrl,
+ setIdentity,
+ setModal,
+ setWalletIdentity,
+ setUserCreationModal,
+ ]);
+
+ return (
+
+
+ Connect an Ethereum Wallet
+
+
+ Choose a way to chat using your Ethereum address.
+
+ (setModal(false), setWalleConnectModal(true))}>
+ WalletConnect
+
+
+ (setModal(false), setCoinbaseModal(true))}>
+ Coinbase Wallet
+
+
+
+ MetaMask
+
+
+
+
+
+ );
+}
+
+const MiddleSectionWallet = styled(MiddleSection)`
+ align-items: stretch;
+`;
+
+const Wallets = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 16px;
+`;
+
+const Wallet = styled.div`
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+ padding: 12px 16px;
+ border: 1px solid ${({ theme }) => theme.skeletonDark};
+ border-radius: 8px;
+ cursor: pointer;
+
+ &:hover {
+ background: ${({ theme }) => theme.buttonBgHover};
+ }
+`;
diff --git a/packages/status-react/src/components/NarrowMode/NarrowChannels.tsx b/packages/status-react/src/components/NarrowMode/NarrowChannels.tsx
new file mode 100644
index 00000000..2dae6253
--- /dev/null
+++ b/packages/status-react/src/components/NarrowMode/NarrowChannels.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+
+import { Channels } from "../Channels/Channels";
+
+import { ListWrapper, NarrowTopbar } from "./NarrowTopbar";
+
+interface NarrowChannelsProps {
+ setShowChannels: (val: boolean) => void;
+}
+
+export function NarrowChannels({ setShowChannels }: NarrowChannelsProps) {
+ return (
+
+ setShowChannels(false)} />
+ setShowChannels(false)} />
+
+ );
+}
diff --git a/packages/status-react/src/components/NarrowMode/NarrowMembers.tsx b/packages/status-react/src/components/NarrowMode/NarrowMembers.tsx
new file mode 100644
index 00000000..47e44871
--- /dev/null
+++ b/packages/status-react/src/components/NarrowMode/NarrowMembers.tsx
@@ -0,0 +1,28 @@
+import React, { useMemo } from "react";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { MembersList } from "../Members/MembersList";
+
+import { ListWrapper, NarrowTopbar } from "./NarrowTopbar";
+
+interface NarrowMembersProps {
+ switchShowMembersList: () => void;
+}
+
+export function NarrowMembers({ switchShowMembersList }: NarrowMembersProps) {
+ const { activeChannel } = useMessengerContext();
+ const listName = useMemo(
+ () =>
+ activeChannel && activeChannel?.type === "group"
+ ? "Group members"
+ : "Community members",
+ [activeChannel]
+ );
+
+ return (
+
+
+
+
+ );
+}
diff --git a/packages/status-react/src/components/NarrowMode/NarrowTopbar.tsx b/packages/status-react/src/components/NarrowMode/NarrowTopbar.tsx
new file mode 100644
index 00000000..f49fc3e9
--- /dev/null
+++ b/packages/status-react/src/components/NarrowMode/NarrowTopbar.tsx
@@ -0,0 +1,59 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { BackButton } from "../Buttons/BackButton";
+
+interface NarrowTopbarProps {
+ list: string;
+ onBtnClick: () => void;
+}
+
+export function NarrowTopbar({ list, onBtnClick }: NarrowTopbarProps) {
+ const { communityData, activeChannel } = useMessengerContext();
+ return (
+
+
+
+ {list}
+
+ {activeChannel?.type === "group"
+ ? activeChannel.name
+ : communityData?.name}
+
+
+
+ );
+}
+
+const TopbarWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ background-color: ${({ theme }) => theme.bodyBackgroundColor};
+ margin-bottom: 16px;
+ position: relative;
+`;
+
+const HeadingWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ text-align: center;
+`;
+
+const Heading = styled.p`
+ font-weight: 500;
+ color: ${({ theme }) => theme.primary};
+`;
+
+const SubHeading = styled.p`
+ font-weight: 500;
+ color: ${({ theme }) => theme.secondary};
+`;
+
+export const ListWrapper = styled.div`
+ padding: 16px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ overflow: auto;
+ flex: 1;
+`;
diff --git a/packages/status-react/src/components/Reactions/ReactionButton.tsx b/packages/status-react/src/components/Reactions/ReactionButton.tsx
new file mode 100644
index 00000000..6e41d7e7
--- /dev/null
+++ b/packages/status-react/src/components/Reactions/ReactionButton.tsx
@@ -0,0 +1,90 @@
+import { BaseEmoji } from "emoji-mart";
+import React, { useRef, useState } from "react";
+import styled from "styled-components";
+
+import { useClickOutside } from "../../hooks/useClickOutside";
+import { Tooltip } from "../Form/Tooltip";
+import { ReactionSvg } from "../Icons/ReactionIcon";
+
+import { ReactionPicker } from "./ReactionPicker";
+
+interface ReactionButtonProps {
+ className?: string;
+ messageReactions: BaseEmoji[];
+ setMessageReactions: React.Dispatch>;
+}
+
+export function ReactionButton({
+ className,
+ messageReactions,
+ setMessageReactions,
+}: ReactionButtonProps) {
+ const ref = useRef(null);
+ useClickOutside(ref, () => setShowReactions(false));
+
+ const [showReactions, setShowReactions] = useState(false);
+
+ return (
+
+ {showReactions && (
+
+ )}
+ setShowReactions(!showReactions)}
+ className={className}
+ >
+
+ {!className && !showReactions && }
+
+
+ );
+}
+
+const Wrapper = styled.div`
+ position: relative;
+`;
+
+export const ReactionBtn = styled.button`
+ width: 32px;
+ height: 32px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 8px;
+ align-self: center;
+ position: relative;
+
+ &:hover {
+ background: ${({ theme }) => theme.buttonBgHover};
+ }
+
+ &.red:hover {
+ background: ${({ theme }) => theme.buttonNoBgHover};
+ }
+
+ &:hover > svg {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &.red:hover > svg {
+ fill: ${({ theme }) => theme.redColor};
+ }
+
+ &:hover > div {
+ visibility: visible;
+ }
+
+ &.small {
+ width: 18px;
+ height: 18px;
+ padding: 0;
+
+ &:hover {
+ background: inherit;
+ }
+ }
+`;
diff --git a/packages/status-react/src/components/Reactions/ReactionPicker.tsx b/packages/status-react/src/components/Reactions/ReactionPicker.tsx
new file mode 100644
index 00000000..95b9c4d9
--- /dev/null
+++ b/packages/status-react/src/components/Reactions/ReactionPicker.tsx
@@ -0,0 +1,108 @@
+import { BaseEmoji, Emoji, getEmojiDataFromNative } from "emoji-mart";
+import data from "emoji-mart/data/all.json";
+import React, { useCallback } from "react";
+import styled from "styled-components";
+
+const emojiHeart = getEmojiDataFromNative("❤️", "twitter", data);
+const emojiLike = getEmojiDataFromNative("👍", "twitter", data);
+const emojiDislike = getEmojiDataFromNative("👎", "twitter", data);
+const emojiLaughing = getEmojiDataFromNative("😆", "twitter", data);
+const emojiDisappointed = getEmojiDataFromNative("😥", "twitter", data);
+const emojiRage = getEmojiDataFromNative("😡", "twitter", data);
+
+export const emojiArr = [
+ emojiHeart,
+ emojiLike,
+ emojiDislike,
+ emojiLaughing,
+ emojiDisappointed,
+ emojiRage,
+];
+
+interface ReactionPickerProps {
+ className?: string;
+ messageReactions: BaseEmoji[];
+ setMessageReactions: React.Dispatch>;
+}
+
+export function ReactionPicker({
+ className,
+ messageReactions,
+ setMessageReactions,
+}: ReactionPickerProps) {
+ const handleReaction = useCallback(
+ (emoji: BaseEmoji) => {
+ messageReactions.find((e) => e === emoji)
+ ? setMessageReactions((prev) => prev.filter((e) => e != emoji))
+ : setMessageReactions((prev) => [...prev, emoji]);
+ },
+ [messageReactions, setMessageReactions]
+ );
+
+ return (
+
+ {emojiArr.map((emoji) => (
+ handleReaction(emoji)}
+ className={`${messageReactions.includes(emoji) && "chosen"}`}
+ menuMode={className === "menu"}
+ >
+ {" "}
+
+
+ ))}
+
+ );
+}
+
+const Wrapper = styled.div`
+ width: 266px;
+ display: flex;
+ justify-content: space-between;
+ position: absolute;
+ right: -34px;
+ top: -60px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08);
+ border-radius: 16px 16px 4px 16px;
+ padding: 8px;
+
+ &.small {
+ right: unset;
+ left: -100px;
+ transform: none;
+ border-radius: 16px 16px 16px 4px;
+ }
+
+ &.menu {
+ width: 100%;
+ position: static;
+ box-shadow: unset;
+ border: none;
+ padding: 0;
+ }
+`;
+
+export const EmojiBtn = styled.button<{ menuMode: boolean }>`
+ width: ${({ menuMode }) => (menuMode ? "24px" : "40px")};
+ height: ${({ menuMode }) => (menuMode ? "24px" : "40px")};
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 8px;
+
+ &:hover {
+ background: ${({ theme }) => theme.inputColor};
+ }
+
+ &.chosen {
+ background: ${({ theme }) => theme.reactionBg};
+ border: 1px solid ${({ theme }) => theme.tertiary};
+ }
+`;
diff --git a/packages/status-react/src/components/Reactions/Reactions.tsx b/packages/status-react/src/components/Reactions/Reactions.tsx
new file mode 100644
index 00000000..2b83d8ae
--- /dev/null
+++ b/packages/status-react/src/components/Reactions/Reactions.tsx
@@ -0,0 +1,89 @@
+import { BaseEmoji } from "emoji-mart";
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useUserPublicKey } from "../../contexts/identityProvider";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { Reply } from "../../hooks/useReply";
+import { ChatMessage } from "../../models/ChatMessage";
+import { Tooltip } from "../Form/Tooltip";
+import { DeleteIcon } from "../Icons/DeleteIcon";
+import { EditIcon } from "../Icons/EditIcon";
+import { PinIcon } from "../Icons/PinIcon";
+import { ReplySvg } from "../Icons/ReplyIcon";
+
+import { ReactionBtn, ReactionButton } from "./ReactionButton";
+
+interface ReactionsProps {
+ message: ChatMessage;
+ setReply: (val: Reply | undefined) => void;
+ messageReactions: BaseEmoji[];
+ setMessageReactions: React.Dispatch>;
+}
+
+export function Reactions({
+ message,
+ setReply,
+ messageReactions,
+ setMessageReactions,
+}: ReactionsProps) {
+ const userPK = useUserPublicKey();
+ const { activeChannel } = useMessengerContext();
+
+ const userMessage = useMemo(
+ () => !!userPK && message.sender === userPK,
+ [userPK, message]
+ );
+
+ return (
+
+
+
+ setReply({
+ sender: message.sender,
+ content: message.content,
+ image: message.image,
+ id: message.id,
+ })
+ }
+ >
+
+
+
+ {userMessage && (
+
+
+
+
+ )}
+ {activeChannel?.type !== "channel" && (
+
+
+
+
+ )}
+ {userMessage && (
+
+
+
+
+ )}
+
+ );
+}
+
+const Wrapper = styled.div`
+ display: flex;
+ position: absolute;
+ right: 20px;
+ top: -18px;
+ box-shadow: 0px 4px 12px rgba(0, 34, 51, 0.08);
+ border-radius: 8px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ padding: 2px;
+ visibility: hidden;
+`;
diff --git a/packages/status-react/src/components/SearchBlock.tsx b/packages/status-react/src/components/SearchBlock.tsx
new file mode 100644
index 00000000..7b9dd0ee
--- /dev/null
+++ b/packages/status-react/src/components/SearchBlock.tsx
@@ -0,0 +1,78 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useMessengerContext } from "../contexts/messengerProvider";
+
+import { ContactsList } from "./Chat/ChatCreation";
+import { Member } from "./Members/Member";
+
+interface SearchBlockProps {
+ query: string;
+ discludeList: string[];
+ onClick: (member: string) => void;
+ onBotttom?: boolean;
+}
+
+export const SearchBlock = ({
+ query,
+ discludeList,
+ onClick,
+ onBotttom,
+}: SearchBlockProps) => {
+ const { contacts } = useMessengerContext();
+
+ const searchList = useMemo(() => {
+ return Object.values(contacts)
+ .filter(
+ (member) =>
+ member.id.includes(query) ||
+ member?.customName?.includes(query) ||
+ member.trueName.includes(query)
+ )
+ .filter((member) => !discludeList.includes(member.id));
+ }, [query, discludeList, contacts]);
+
+ if (searchList.length === 0 || !query) {
+ return null;
+ }
+ return (
+
+
+ {searchList.map((member) => (
+
+ onClick(member.id)} />
+
+ ))}
+
+
+ );
+};
+
+const SearchContacts = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 360px;
+ padding: 8px;
+ background-color: ${({ theme }) => theme.bodyBackgroundColor};
+ box-shadow: 0px 2px 4px rgba(0, 34, 51, 0.16),
+ 0px 4px 12px rgba(0, 34, 51, 0.08);
+ border-radius: 8px;
+ position: absolute;
+ left: 0;
+ max-height: 200px;
+ overflow: auto;
+`;
+
+const SearchContact = styled.div`
+ width: 340px;
+ display: flex;
+ align-items: center;
+ padding: 12px 12px 0 16px;
+ border-radius: 8px;
+
+ &:hover {
+ background: ${({ theme }) => theme.inputColor};
+ }
+`;
diff --git a/packages/status-react/src/components/Skeleton/CommunitySkeleton.tsx b/packages/status-react/src/components/Skeleton/CommunitySkeleton.tsx
new file mode 100644
index 00000000..f48c6691
--- /dev/null
+++ b/packages/status-react/src/components/Skeleton/CommunitySkeleton.tsx
@@ -0,0 +1,29 @@
+import React from "react";
+import styled from "styled-components";
+
+import { Column } from "../CommunityIdentity";
+
+import { Skeleton } from "./Skeleton";
+
+export const CommunitySkeleton = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const LogoSkeleton = styled(Skeleton)`
+ border-radius: 50%;
+ margin-right: 8px;
+ flex-shrink: 0;
+`;
+
+const Loading = styled.div`
+ display: flex;
+ padding: 0 0 0 10px;
+`;
diff --git a/packages/status-react/src/components/Skeleton/Loading.tsx b/packages/status-react/src/components/Skeleton/Loading.tsx
new file mode 100644
index 00000000..c15a2200
--- /dev/null
+++ b/packages/status-react/src/components/Skeleton/Loading.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import styled from "styled-components";
+
+import { LoadingIcon } from "../Icons/LoadingIcon";
+import { textSmallStyles } from "../Text";
+
+export const Loading = () => {
+ return (
+
+
+ Loading messages...
+
+ );
+};
+
+const LoadingBlock = styled.div`
+ display: flex;
+ align-items: center;
+ position: absolute;
+ left: 50%;
+ bottom: -35px;
+ transform: translateX(-50%);
+ padding: 4px 5px 4px 7px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ color: ${({ theme }) => theme.primary};
+ box-shadow: ${({ theme }) => theme.shadow};
+ border-radius: 8px;
+ z-index: 2;
+`;
+
+const LoadingText = styled.p`
+ color: ${({ theme }) => theme.primary};
+ margin-left: 8px;
+ font-weight: 500;
+
+ ${textSmallStyles}
+`;
diff --git a/packages/status-react/src/components/Skeleton/LoadingSkeleton.tsx b/packages/status-react/src/components/Skeleton/LoadingSkeleton.tsx
new file mode 100644
index 00000000..7cade447
--- /dev/null
+++ b/packages/status-react/src/components/Skeleton/LoadingSkeleton.tsx
@@ -0,0 +1,55 @@
+import React from "react";
+import styled from "styled-components";
+
+import { MessageSkeleton } from "./MessageSkeleton";
+import { Skeleton } from "./Skeleton";
+
+export const LoadingSkeleton = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const Loading = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ height: calc(100% - 44px);
+ padding: 8px 16px 0;
+ overflow: auto;
+`;
diff --git a/packages/status-react/src/components/Skeleton/MessageSkeleton.tsx b/packages/status-react/src/components/Skeleton/MessageSkeleton.tsx
new file mode 100644
index 00000000..b960c85f
--- /dev/null
+++ b/packages/status-react/src/components/Skeleton/MessageSkeleton.tsx
@@ -0,0 +1,58 @@
+import React, { ReactNode } from "react";
+import styled from "styled-components";
+
+import { Skeleton } from "./Skeleton";
+
+interface MessageSkeletonProps {
+ children: ReactNode;
+}
+
+export const MessageSkeleton = ({ children }: MessageSkeletonProps) => {
+ return (
+
+
+
+
+
+
+
+ {children}
+
+
+ );
+};
+
+const MessageWrapper = styled.div`
+ display: flex;
+ padding: 8px 0;
+ margin-bottom: 8px;
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+`;
+
+const MessageHeaderWrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+const MessageBodyWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+`;
+
+const AvatarSkeleton = styled(Skeleton)`
+ border-radius: 50%;
+ margin-right: 8px;
+`;
+
+const UserNameSkeleton = styled(Skeleton)`
+ margin-right: 4px;
+`;
+
+const TimeSkeleton = styled(Skeleton)`
+ margin-right: 4px;
+`;
diff --git a/packages/status-react/src/components/Skeleton/Skeleton.tsx b/packages/status-react/src/components/Skeleton/Skeleton.tsx
new file mode 100644
index 00000000..63da25ad
--- /dev/null
+++ b/packages/status-react/src/components/Skeleton/Skeleton.tsx
@@ -0,0 +1,46 @@
+import styled, { keyframes } from "styled-components";
+
+interface SkeletonProps {
+ width?: string;
+ height?: string;
+ borderRadius?: string;
+}
+
+const waveKeyframe = keyframes`
+ 0% {
+ transform: translateX(-100%);
+ }
+ 50% {
+ transform: translateX(100%);
+ }
+ 100% {
+ transform: translateX(100%);
+ }
+`;
+
+export const Skeleton = styled.div`
+ position: relative;
+ display: inline-block;
+ width: ${({ width }) => width || "100%"};
+ height: ${({ height }) => height || "22px"};
+ background: ${({ theme }) => theme.skeletonDark};
+ border-radius: ${({ borderRadius }) => borderRadius || "8px"};
+ margin-bottom: 5px;
+ overflow: hidden;
+
+ &::after {
+ animation: ${waveKeyframe} 1.6s linear 0.5s infinite;
+ background: linear-gradient(
+ 90deg,
+ ${({ theme }) => theme.skeletonLight} 0%,
+ ${({ theme }) => theme.skeletonDark} 100%
+ );
+ content: "";
+ position: absolute;
+ transform: translateX(-100%);
+ bottom: 0;
+ left: 0;
+ right: 0;
+ top: 0;
+ }
+`;
diff --git a/packages/status-react/src/components/Text.tsx b/packages/status-react/src/components/Text.tsx
new file mode 100644
index 00000000..aeefa04f
--- /dev/null
+++ b/packages/status-react/src/components/Text.tsx
@@ -0,0 +1,11 @@
+import { css } from "styled-components";
+
+export const textSmallStyles = css`
+ font-size: 13px;
+ line-height: 18px;
+`;
+
+export const textMediumStyles = css`
+ font-size: 15px;
+ line-height: 22px;
+`;
diff --git a/packages/status-react/src/components/ToastMessages/ToastMessage.tsx b/packages/status-react/src/components/ToastMessages/ToastMessage.tsx
new file mode 100644
index 00000000..adb5c9f9
--- /dev/null
+++ b/packages/status-react/src/components/ToastMessages/ToastMessage.tsx
@@ -0,0 +1,128 @@
+import React from "react";
+import styled, { keyframes } from "styled-components";
+
+import { useToasts } from "../../contexts/toastProvider";
+import { Toast } from "../../models/Toast";
+import { Column } from "../CommunityIdentity";
+import { CheckIcon } from "../Icons/CheckIcon";
+import { CommunityIcon } from "../Icons/CommunityIcon";
+import { CrossIcon } from "../Icons/CrossIcon";
+import { ProfileIcon } from "../Icons/ProfileIcon";
+import { textSmallStyles } from "../Text";
+
+export function AnimationToastMessage() {
+ return keyframes`
+ 0% {
+ opacity: 0;
+ transform: translateY(-100%); }
+ 100% {
+ opacity: 1;
+ transform: translateY(0); }
+`;
+}
+
+type ToastMessageProps = {
+ toast: Toast;
+};
+
+export function ToastMessage({ toast }: ToastMessageProps) {
+ const { setToasts } = useToasts();
+
+ const closeToast = () => {
+ setToasts((prev) => prev.filter((e) => e != toast));
+ };
+
+ return (
+
+
+ {toast.type === "confirmation" && (
+
+
+
+ )}
+ {toast.type === "incoming" && (
+
+
+
+ )}
+ {(toast.type === "approvement" || toast.type === "rejection") && (
+
+
+
+ )}
+
+ {toast.text}
+ {toast.request && {toast.request}}
+
+
+
+
+
+
+ );
+}
+
+const ToastWrapper = styled.div`
+ width: 343px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ margin-top: 8px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ box-shadow: ${({ theme }) => theme.shadow};
+ border-radius: 8px;
+ animation: ${AnimationToastMessage} 2s ease;
+`;
+
+const ToastBlock = styled.div`
+ display: flex;
+ align-items: center;
+ color: ${({ theme }) => theme.primary};
+`;
+
+const ToastText = styled.p`
+ font-weight: 500;
+ ${textSmallStyles};
+`;
+
+const ToastRequest = styled(ToastText)`
+ width: 243px;
+ color: ${({ theme }) => theme.secondary};
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+`;
+
+const IconWrapper = styled.div`
+ width: 32px;
+ height: 32px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 50%;
+ margin-right: 12px;
+
+ &.green {
+ background: ${({ theme }) => theme.greenBg};
+ }
+
+ &.blue {
+ background: ${({ theme }) => theme.blueBg};
+ }
+
+ &.red {
+ background: ${({ theme }) => theme.buttonNoBg};
+ }
+`;
+
+const CloseButton = styled.button`
+ width: 32px;
+ height: 32px;
+`;
diff --git a/packages/status-react/src/components/ToastMessages/ToastMessageList.tsx b/packages/status-react/src/components/ToastMessages/ToastMessageList.tsx
new file mode 100644
index 00000000..a16e8a25
--- /dev/null
+++ b/packages/status-react/src/components/ToastMessages/ToastMessageList.tsx
@@ -0,0 +1,29 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useToasts } from "../../contexts/toastProvider";
+
+import { ToastMessage } from "./ToastMessage";
+
+export function ToastMessageList() {
+ const { toasts } = useToasts();
+
+ return (
+
+ {toasts.map((toast) => (
+
+ ))}
+
+ );
+}
+
+const ToastsWrapper = styled.div`
+ position: absolute;
+ bottom: 56px;
+ right: 16px;
+ width: 343px;
+ display: flex;
+ flex-direction: column-reverse;
+ align-items: center;
+ z-index: 999;
+`;
diff --git a/packages/status-react/src/components/UserCreation/UserCreation.tsx b/packages/status-react/src/components/UserCreation/UserCreation.tsx
new file mode 100644
index 00000000..4207998e
--- /dev/null
+++ b/packages/status-react/src/components/UserCreation/UserCreation.tsx
@@ -0,0 +1,45 @@
+import React from "react";
+import styled from "styled-components";
+
+import { useNarrow } from "../../contexts/narrowProvider";
+import { ColorChatIcon } from "../Icons/ColorChatIcon";
+
+import { UserCreationButtons } from "./UserCreationButtons";
+
+interface UserCreationProps {
+ permission: boolean;
+}
+
+export function UserCreation({ permission }: UserCreationProps) {
+ const narrow = useNarrow();
+
+ if (!narrow) {
+ return (
+
+
+ Want to jump into the discussion?
+
+
+ );
+ } else {
+ return null;
+ }
+}
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ flex: 1;
+ background-color: ${({ theme }) => theme.sectionBackgroundColor};
+`;
+
+const TitleWrapper = styled.div`
+ font-weight: bold;
+ font-size: 17px;
+ line-height: 24px;
+ text-align: center;
+ margin: 24px 0;
+ color: ${({ theme }) => theme.primary};
+`;
diff --git a/packages/status-react/src/components/UserCreation/UserCreationButtons.tsx b/packages/status-react/src/components/UserCreation/UserCreationButtons.tsx
new file mode 100644
index 00000000..daec9217
--- /dev/null
+++ b/packages/status-react/src/components/UserCreation/UserCreationButtons.tsx
@@ -0,0 +1,85 @@
+import React, { useMemo } from "react";
+import styled from "styled-components";
+
+import { useModal } from "../../contexts/modalProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { loadEncryptedIdentity } from "../../utils";
+import { buttonStyles, buttonTransparentStyles } from "../Buttons/buttonStyle";
+import { ProfileFoundModalName } from "../Modals/ProfileFoundModal";
+import { StatusModalName } from "../Modals/StatusModal";
+import { UserCreationModalName } from "../Modals/UserCreationModal";
+import { UserCreationStartModalName } from "../Modals/UserCreationStartModal";
+import { WalletModalName } from "../Modals/WalletModal";
+import { textSmallStyles } from "../Text";
+
+interface UserCreationProps {
+ permission: boolean;
+}
+
+export function UserCreationButtons({ permission }: UserCreationProps) {
+ const narrow = useNarrow();
+ const { setModal } = useModal(UserCreationModalName);
+ const { setModal: setStatusModal } = useModal(StatusModalName);
+ const { setModal: setWalletModal } = useModal(WalletModalName);
+ const { setModal: setProfileFoundModal } = useModal(ProfileFoundModalName);
+ const { setModal: setCreationStartModal } = useModal(
+ UserCreationStartModalName
+ );
+
+ const encryptedIdentity = useMemo(() => loadEncryptedIdentity(), []);
+
+ return (
+
+ {
+ setStatusModal(true);
+ setCreationStartModal(false);
+ }}
+ className={`${narrow && "narrow"}`}
+ >
+ Sync with Status profile
+
+ {
+ setWalletModal(true);
+ setCreationStartModal(false);
+ }}
+ className={`${narrow && "narrow"}`}
+ >
+ Connect Ethereum Wallet
+
+ {permission && (
+ {
+ encryptedIdentity ? setProfileFoundModal(true) : setModal(true);
+ setCreationStartModal(false);
+ }}
+ >
+ Use a throwaway profile
+
+ )}
+
+ );
+}
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+`;
+
+const LoginBtn = styled.button`
+ ${buttonStyles}
+ ${textSmallStyles}
+ padding: 10px 12px;
+ margin-bottom: 16px;
+
+ &.narrow {
+ margin-bottom: 32px;
+ }
+`;
+
+const ThrowAwayButton = styled.button`
+ ${buttonTransparentStyles}
+`;
diff --git a/packages/status-react/src/contexts/chatStateProvider.tsx b/packages/status-react/src/contexts/chatStateProvider.tsx
new file mode 100644
index 00000000..44b9bba2
--- /dev/null
+++ b/packages/status-react/src/contexts/chatStateProvider.tsx
@@ -0,0 +1,25 @@
+import React, { createContext, useContext, useState } from "react";
+
+export enum ChatState {
+ ChatCreation,
+ ChatBody,
+}
+
+type ChatStateContextType = [
+ ChatState,
+ React.Dispatch>
+];
+
+const ChatStateContext = createContext([
+ ChatState.ChatBody,
+ () => undefined,
+]);
+
+export function useChatState() {
+ return useContext(ChatStateContext);
+}
+
+export function ChatStateProvider({ children }: { children: React.ReactNode }) {
+ const state = useState(ChatState.ChatBody);
+ return ;
+}
diff --git a/packages/status-react/src/contexts/configProvider.tsx b/packages/status-react/src/contexts/configProvider.tsx
new file mode 100644
index 00000000..50c1b395
--- /dev/null
+++ b/packages/status-react/src/contexts/configProvider.tsx
@@ -0,0 +1,24 @@
+import React, { createContext, useContext } from "react";
+
+export type ConfigType = {
+ environment: string;
+ dappUrl: string;
+};
+
+const ConfigContext = createContext({
+ environment: "production",
+ dappUrl: "",
+});
+
+export function useConfig() {
+ return useContext(ConfigContext);
+}
+
+type ConfigProviderProps = {
+ children: React.ReactNode;
+ config: ConfigType;
+};
+
+export function ConfigProvider({ children, config }: ConfigProviderProps) {
+ return ;
+}
diff --git a/packages/status-react/src/contexts/fetchMetadataProvider.tsx b/packages/status-react/src/contexts/fetchMetadataProvider.tsx
new file mode 100644
index 00000000..c96fc4f4
--- /dev/null
+++ b/packages/status-react/src/contexts/fetchMetadataProvider.tsx
@@ -0,0 +1,23 @@
+import React, { createContext, useContext } from "react";
+
+const FetchMetadataContext = createContext<
+ ((link: string) => Promise) | undefined
+>(undefined);
+
+export function useFetchMetadata() {
+ return useContext(FetchMetadataContext);
+}
+
+interface FetchMetadataProviderProps {
+ children: React.ReactNode;
+ fetchMetadata?: (link: string) => Promise;
+}
+
+export function FetchMetadataProvider({
+ children,
+ fetchMetadata,
+}: FetchMetadataProviderProps) {
+ return (
+
+ );
+}
diff --git a/packages/status-react/src/contexts/identityProvider.tsx b/packages/status-react/src/contexts/identityProvider.tsx
new file mode 100644
index 00000000..19f32a7e
--- /dev/null
+++ b/packages/status-react/src/contexts/identityProvider.tsx
@@ -0,0 +1,79 @@
+import { Identity, bufToHex } from "@status-im/core";
+import React, { createContext, useContext, useMemo, useState } from "react";
+
+const IdentityContext = createContext<{
+ identity: Identity | undefined;
+ setIdentity: React.Dispatch>;
+ publicKey: string | undefined;
+ walletIdentity: Identity | undefined;
+ setWalletIdentity: React.Dispatch>;
+ nickname: string | undefined;
+ setNickname: React.Dispatch>;
+}>({
+ identity: undefined,
+ setIdentity: () => undefined,
+ publicKey: undefined,
+ walletIdentity: undefined,
+ setWalletIdentity: () => undefined,
+ nickname: undefined,
+ setNickname: () => undefined,
+});
+
+export function useIdentity() {
+ return useContext(IdentityContext).identity;
+}
+
+export function useUserPublicKey() {
+ return useContext(IdentityContext).publicKey;
+}
+
+export function useSetIdentity() {
+ return useContext(IdentityContext).setIdentity;
+}
+
+export function useWalletIdentity() {
+ return useContext(IdentityContext).walletIdentity;
+}
+
+export function useSetWalletIdentity() {
+ return useContext(IdentityContext).setWalletIdentity;
+}
+
+export function useNickname() {
+ return useContext(IdentityContext).nickname;
+}
+
+export function useSetNikcname() {
+ return useContext(IdentityContext).setNickname;
+}
+
+interface IdentityProviderProps {
+ children: React.ReactNode;
+}
+
+export function IdentityProvider({ children }: IdentityProviderProps) {
+ const [identity, setIdentity] = useState(undefined);
+ const publicKey = useMemo(
+ () => (identity ? bufToHex(identity.publicKey) : undefined),
+ [identity]
+ );
+ const [walletIdentity, setWalletIdentity] = useState(
+ undefined
+ );
+ const [nickname, setNickname] = useState(undefined);
+
+ return (
+
+ );
+}
diff --git a/packages/status-react/src/contexts/messengerProvider.tsx b/packages/status-react/src/contexts/messengerProvider.tsx
new file mode 100644
index 00000000..08678e83
--- /dev/null
+++ b/packages/status-react/src/contexts/messengerProvider.tsx
@@ -0,0 +1,50 @@
+import React, { createContext, useContext } from "react";
+
+import { MessengerType, useMessenger } from "../hooks/messenger/useMessenger";
+
+import { useIdentity, useNickname } from "./identityProvider";
+
+const MessengerContext = createContext({
+ messenger: undefined,
+ messages: [],
+ sendMessage: async () => undefined,
+ notifications: {},
+ clearNotifications: () => undefined,
+ mentions: {},
+ clearMentions: () => undefined,
+ loadPrevDay: async () => undefined,
+ loadingMessages: false,
+ loadingMessenger: true,
+ communityData: undefined,
+ contacts: {},
+ contactsDispatch: () => undefined,
+ addContact: () => undefined,
+ activeChannel: undefined,
+ channels: {},
+ channelsDispatch: () => undefined,
+ removeChannel: () => undefined,
+ createGroupChat: () => undefined,
+ changeGroupChatName: () => undefined,
+ addMembers: () => undefined,
+ nickname: undefined,
+ subscriptionsDispatch: () => undefined,
+});
+
+export function useMessengerContext() {
+ return useContext(MessengerContext);
+}
+
+interface MessengerProviderProps {
+ communityKey: string | undefined;
+ children: React.ReactNode;
+}
+
+export function MessengerProvider({
+ communityKey,
+ children,
+}: MessengerProviderProps) {
+ const identity = useIdentity();
+ const nickname = useNickname();
+ const messenger = useMessenger(communityKey, identity, nickname);
+ return ;
+}
diff --git a/packages/status-react/src/contexts/modalProvider.tsx b/packages/status-react/src/contexts/modalProvider.tsx
new file mode 100644
index 00000000..69dee0d8
--- /dev/null
+++ b/packages/status-react/src/contexts/modalProvider.tsx
@@ -0,0 +1,63 @@
+import React, {
+ createContext,
+ useCallback,
+ useContext,
+ useMemo,
+ useState,
+} from "react";
+
+import {
+ ProfileModalName,
+ ProfileModalProps,
+} from "../components/Modals/ProfileModal";
+
+type TypeMap = {
+ [ProfileModalName]?: ProfileModalProps;
+};
+
+type ModalsState = TypeMap & {
+ [name: string]: boolean | undefined;
+};
+
+type ModalContextType = [
+ state: ModalsState,
+ setState: React.Dispatch>
+];
+
+const ModalContext = createContext([{}, () => undefined]);
+
+export function useModal(name: T) {
+ const [modals, setModals] = useContext(ModalContext);
+
+ const setModal = useCallback(
+ (state: T extends keyof TypeMap ? TypeMap[T] | false : boolean) => {
+ setModals((prev) => {
+ if (!state) {
+ return {
+ ...prev,
+ [name]: undefined,
+ };
+ }
+ return {
+ ...prev,
+ [name]: state,
+ };
+ });
+ },
+ [name, setModals]
+ );
+ const isVisible = useMemo(() => !!modals?.[name], [modals, name]);
+
+ const props = useMemo(() => modals?.[name], [modals, name]);
+
+ return { isVisible, setModal, props };
+}
+
+interface IdentityProviderProps {
+ children: React.ReactNode;
+}
+
+export function ModalProvider({ children }: IdentityProviderProps) {
+ const modalState = useState({});
+ return ;
+}
diff --git a/packages/status-react/src/contexts/narrowProvider.tsx b/packages/status-react/src/contexts/narrowProvider.tsx
new file mode 100644
index 00000000..6def64a3
--- /dev/null
+++ b/packages/status-react/src/contexts/narrowProvider.tsx
@@ -0,0 +1,29 @@
+import React, { createContext, useContext } from "react";
+
+import { useRefBreak } from "../hooks/useRefBreak";
+
+const NarrowContext = createContext<{ narrow: boolean; low: boolean }>({
+ narrow: false,
+ low: false,
+});
+
+export function useNarrow() {
+ const { narrow } = useContext(NarrowContext);
+ return narrow;
+}
+
+export function useLow() {
+ const { low } = useContext(NarrowContext);
+ return low;
+}
+
+interface NarrowProviderProps {
+ children: React.ReactNode;
+ myRef: React.RefObject;
+}
+
+export function NarrowProvider({ children, myRef }: NarrowProviderProps) {
+ const narrow = useRefBreak(myRef?.current?.offsetWidth ?? 0, 736);
+ const low = useRefBreak(myRef?.current?.offsetHeight ?? 0, 465);
+ return ;
+}
diff --git a/packages/status-react/src/contexts/scrollProvider.tsx b/packages/status-react/src/contexts/scrollProvider.tsx
new file mode 100644
index 00000000..3e8b8540
--- /dev/null
+++ b/packages/status-react/src/contexts/scrollProvider.tsx
@@ -0,0 +1,70 @@
+import React, {
+ createContext,
+ useCallback,
+ useContext,
+ useEffect,
+ useState,
+} from "react";
+
+import { useMessengerContext } from "../contexts/messengerProvider";
+import { ChatMessage } from "../models/ChatMessage";
+
+const ScrollContext = createContext<
+ (msg: ChatMessage, channelId?: string) => void
+>(() => undefined);
+
+export function useScrollToMessage() {
+ return useContext(ScrollContext);
+}
+
+interface ScrollProviderProps {
+ children: React.ReactNode;
+}
+
+export function ScrollProvider({ children }: ScrollProviderProps) {
+ const scrollToDivId = useCallback((id: string) => {
+ const quoteDiv = document.getElementById(id);
+ if (quoteDiv) {
+ quoteDiv.scrollIntoView({
+ behavior: "smooth",
+ block: "center",
+ inline: "center",
+ });
+ quoteDiv.style.background = "lightblue";
+ quoteDiv.style.transition = "background-color 1000ms linear";
+ window.setTimeout(() => {
+ quoteDiv.style.background = "";
+ window.setTimeout(() => {
+ quoteDiv.style.transition = "";
+ }, 1000);
+ }, 1000);
+ }
+ }, []);
+
+ const { activeChannel, channelsDispatch } = useMessengerContext();
+ const [scrollToMessage, setScrollToMessage] = useState("");
+ const [messageChannel, setMessageChannel] = useState("");
+
+ useEffect(() => {
+ if (scrollToMessage && messageChannel) {
+ if (activeChannel?.id === messageChannel) {
+ scrollToDivId(scrollToMessage);
+ setScrollToMessage("");
+ setMessageChannel("");
+ }
+ }
+ }, [activeChannel, scrollToMessage, messageChannel, scrollToDivId]);
+ const scroll = useCallback(
+ (msg: ChatMessage, channelId?: string) => {
+ if (!channelId || activeChannel?.id === channelId) {
+ scrollToDivId(msg.id);
+ } else {
+ setMessageChannel(channelId);
+ setScrollToMessage(msg.id);
+ channelsDispatch({ type: "ChangeActive", payload: channelId });
+ }
+ },
+ [scrollToDivId, channelsDispatch, activeChannel]
+ );
+ return ;
+}
diff --git a/packages/status-react/src/contexts/toastProvider.tsx b/packages/status-react/src/contexts/toastProvider.tsx
new file mode 100644
index 00000000..06eeb627
--- /dev/null
+++ b/packages/status-react/src/contexts/toastProvider.tsx
@@ -0,0 +1,26 @@
+import React, { createContext, useContext, useState } from "react";
+
+import { Toast } from "../models/Toast";
+
+const ToastContext = createContext<{
+ toasts: Toast[];
+ setToasts: React.Dispatch>;
+}>({
+ toasts: [],
+ setToasts: () => undefined,
+});
+
+export function useToasts() {
+ return useContext(ToastContext);
+}
+
+interface ToastProviderProps {
+ children: React.ReactNode;
+}
+
+export function ToastProvider({ children }: ToastProviderProps) {
+ const [toasts, setToasts] = useState([]);
+ return (
+
+ );
+}
diff --git a/packages/status-react/src/groupChatComponents/GroupChat.tsx b/packages/status-react/src/groupChatComponents/GroupChat.tsx
new file mode 100644
index 00000000..6c7d8f45
--- /dev/null
+++ b/packages/status-react/src/groupChatComponents/GroupChat.tsx
@@ -0,0 +1,58 @@
+import React, { useRef } from "react";
+import { ThemeProvider } from "styled-components";
+import styled from "styled-components";
+
+import { ConfigType } from "..";
+import { ChatStateProvider } from "../contexts/chatStateProvider";
+import { ConfigProvider } from "../contexts/configProvider";
+import { FetchMetadataProvider } from "../contexts/fetchMetadataProvider";
+import { IdentityProvider } from "../contexts/identityProvider";
+import { MessengerProvider } from "../contexts/messengerProvider";
+import { ModalProvider } from "../contexts/modalProvider";
+import { NarrowProvider } from "../contexts/narrowProvider";
+import { ToastProvider } from "../contexts/toastProvider";
+import { Metadata } from "../models/Metadata";
+import { GlobalStyle } from "../styles/GlobalStyle";
+import { Theme } from "../styles/themes";
+
+import { GroupChatRoom } from "./GroupChatRoom";
+
+interface GroupChatProps {
+ theme: Theme;
+ config: ConfigType;
+ fetchMetadata?: (url: string) => Promise;
+}
+
+export function GroupChat({ theme, config, fetchMetadata }: GroupChatProps) {
+ const ref = useRef(null);
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const Wrapper = styled.div`
+ height: 100%;
+ overflow: hidden;
+`;
diff --git a/packages/status-react/src/groupChatComponents/GroupChat/GroupChatBody.tsx b/packages/status-react/src/groupChatComponents/GroupChat/GroupChatBody.tsx
new file mode 100644
index 00000000..5d0cc3e1
--- /dev/null
+++ b/packages/status-react/src/groupChatComponents/GroupChat/GroupChatBody.tsx
@@ -0,0 +1,182 @@
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { ChatCreation } from "../../components/Chat/ChatCreation";
+import { ChatInput } from "../../components/Chat/ChatInput";
+import {
+ ChatTopbar,
+ ChatTopbarLoading,
+} from "../../components/Chat/ChatTopbar";
+import { TokenRequirement } from "../../components/Form/TokenRequirement";
+import { MessagesList } from "../../components/Messages/MessagesList";
+import { NarrowChannels } from "../../components/NarrowMode/NarrowChannels";
+import { NarrowMembers } from "../../components/NarrowMode/NarrowMembers";
+import { LoadingSkeleton } from "../../components/Skeleton/LoadingSkeleton";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+import { useNarrow } from "../../contexts/narrowProvider";
+import { Reply } from "../../hooks/useReply";
+import { ChannelData } from "../../models/ChannelData";
+
+export enum ChatBodyState {
+ Chat,
+ Channels,
+ Members,
+}
+
+function ChatBodyLoading() {
+ const narrow = useNarrow();
+ return (
+
+
+
+
+ undefined} />
+
+
+ );
+}
+
+type ChatBodyContentProps = {
+ showState: ChatBodyState;
+ switchShowState: (state: ChatBodyState) => void;
+ channel: ChannelData;
+};
+
+function ChatBodyContent({
+ showState,
+ switchShowState,
+ channel,
+}: ChatBodyContentProps) {
+ const [reply, setReply] = useState(undefined);
+
+ switch (showState) {
+ case ChatBodyState.Chat:
+ return (
+ <>
+
+
+ >
+ );
+ case ChatBodyState.Channels:
+ return (
+ switchShowState(ChatBodyState.Channels)}
+ />
+ );
+ case ChatBodyState.Members:
+ return (
+ switchShowState(ChatBodyState.Members)}
+ />
+ );
+ }
+}
+
+interface GroupChatBodyProps {
+ onClick: () => void;
+ showMembers: boolean;
+ permission: boolean;
+ editGroup: boolean;
+ setEditGroup: React.Dispatch>;
+}
+
+export function GroupChatBody({
+ onClick,
+ showMembers,
+ permission,
+ editGroup,
+ setEditGroup,
+}: GroupChatBodyProps) {
+ const { activeChannel, loadingMessenger } = useMessengerContext();
+
+ const narrow = useNarrow();
+ const className = useMemo(() => (narrow ? "narrow" : ""), [narrow]);
+
+ const [showState, setShowState] = useState(ChatBodyState.Chat);
+ const switchShowState = useCallback(
+ (state: ChatBodyState) => {
+ if (narrow) {
+ setShowState((prev) => (prev === state ? ChatBodyState.Chat : state));
+ }
+ },
+ [narrow]
+ );
+
+ useEffect(() => {
+ if (!narrow) {
+ setShowState(ChatBodyState.Chat);
+ }
+ }, [narrow]);
+
+ if (!loadingMessenger && activeChannel) {
+ return (
+
+
+ {editGroup ? (
+
+ ) : (
+
+ )}
+
+
+ {!permission && (
+
+
+
+ )}
+
+ );
+ }
+
+ return ;
+}
+
+export const Wrapper = styled.div`
+ width: 61%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ height: 100%;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ position: relative;
+
+ &.narrow {
+ width: 100%;
+ }
+`;
+
+const ChatBodyWrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+`;
+
+const BluredWrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: flex-end;
+ justify-content: center;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ background: ${({ theme }) => theme.bodyBackgroundGradient};
+ backdrop-filter: blur(4px);
+ z-index: 2;
+`;
diff --git a/packages/status-react/src/groupChatComponents/GroupChatRoom.tsx b/packages/status-react/src/groupChatComponents/GroupChatRoom.tsx
new file mode 100644
index 00000000..b6f09af2
--- /dev/null
+++ b/packages/status-react/src/groupChatComponents/GroupChatRoom.tsx
@@ -0,0 +1,90 @@
+import React, { useState } from "react";
+import styled from "styled-components";
+
+import { Channels } from "../components/Channels/Channels";
+import { ChatCreation } from "../components/Chat/ChatCreation";
+import { AgreementModal } from "../components/Modals/AgreementModal";
+import { CoinbaseModal } from "../components/Modals/CoinbaseModal";
+import { EditModal } from "../components/Modals/EditModal";
+import { LeavingModal } from "../components/Modals/LeavingModal";
+import { LogoutModal } from "../components/Modals/LogoutModal";
+import { ProfileFoundModal } from "../components/Modals/ProfileFoundModal";
+import { ProfileModal } from "../components/Modals/ProfileModal";
+import { StatusModal } from "../components/Modals/StatusModal";
+import { UserCreationModal } from "../components/Modals/UserCreationModal";
+import { UserCreationStartModal } from "../components/Modals/UserCreationStartModal";
+import { WalletConnectModal } from "../components/Modals/WalletConnectModal";
+import { WalletModal } from "../components/Modals/WalletModal";
+import { ToastMessageList } from "../components/ToastMessages/ToastMessageList";
+import { ChatState, useChatState } from "../contexts/chatStateProvider";
+import { useNarrow } from "../contexts/narrowProvider";
+
+import { GroupChatBody } from "./GroupChat/GroupChatBody";
+import { GroupMembers } from "./GroupMembers/GroupMembers";
+
+function Modals() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export function GroupChatRoom() {
+ const [state] = useChatState();
+ const [showMembers, setShowMembers] = useState(false);
+ const [editGroup, setEditGroup] = useState(false);
+ const narrow = useNarrow();
+ return (
+
+ {!narrow && (
+
+
+
+ )}
+ {state === ChatState.ChatBody && (
+ setShowMembers(!showMembers)}
+ showMembers={showMembers}
+ permission={true}
+ editGroup={editGroup}
+ setEditGroup={setEditGroup}
+ />
+ )}
+ {showMembers && !narrow && state === ChatState.ChatBody && (
+
+ )}
+ {state === ChatState.ChatCreation && }
+
+
+
+ );
+}
+
+const ChatWrapper = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ position: relative;
+`;
+
+const ChannelsWrapper = styled.div`
+ width: 21%;
+ height: 100%;
+ min-width: 250px;
+ background-color: ${({ theme }) => theme.sectionBackgroundColor};
+ padding: 10px 16px;
+ display: flex;
+ flex-direction: column;
+`;
diff --git a/packages/status-react/src/groupChatComponents/GroupMembers/GroupMembers.tsx b/packages/status-react/src/groupChatComponents/GroupMembers/GroupMembers.tsx
new file mode 100644
index 00000000..dd4fd4a4
--- /dev/null
+++ b/packages/status-react/src/groupChatComponents/GroupMembers/GroupMembers.tsx
@@ -0,0 +1,49 @@
+import React, { useMemo, useState } from "react";
+import styled from "styled-components";
+
+import { MembersList } from "../../components/Members/MembersList";
+import { useMessengerContext } from "../../contexts/messengerProvider";
+
+export function GroupMembers() {
+ const { addContact, activeChannel } = useMessengerContext();
+ const heading = useMemo(
+ () =>
+ activeChannel && activeChannel?.type === "group"
+ ? "Group members"
+ : "Members",
+ [activeChannel]
+ );
+ const [newUserInput, setNewUserInput] = useState("");
+ return (
+ <>
+
+ {heading}
+
+ setNewUserInput(e.target.value)}
+ />
+
+
+ >
+ );
+}
+
+const MembersWrapper = styled.div`
+ width: 18%;
+ height: 100%;
+ min-width: 164px;
+ display: flex;
+ flex-direction: column;
+ background-color: ${({ theme }) => theme.sectionBackgroundColor};
+ padding: 16px;
+ overflow-y: scroll;
+`;
+
+const MemberHeading = styled.h2`
+ font-weight: 500;
+ font-size: 15px;
+ line-height: 22px;
+ color: ${({ theme }) => theme.primary};
+ margin-bottom: 16px;
+`;
diff --git a/packages/status-react/src/hooks/messenger/useChannelsReducer.ts b/packages/status-react/src/hooks/messenger/useChannelsReducer.ts
new file mode 100644
index 00000000..728a8f31
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useChannelsReducer.ts
@@ -0,0 +1,79 @@
+import { useReducer } from "react";
+
+import { ChannelData, ChannelsData } from "../../models/ChannelData";
+
+export type ChannelsState = {
+ channels: ChannelsData;
+ activeChannel: ChannelData;
+};
+
+export type ChannelAction =
+ | { type: "AddChannel"; payload: ChannelData }
+ | { type: "UpdateActive"; payload: ChannelData }
+ | { type: "ChangeActive"; payload: string }
+ | { type: "ToggleMuted"; payload: string }
+ | { type: "RemoveChannel"; payload: string };
+
+function channelReducer(
+ state: ChannelsState,
+ action: ChannelAction
+): ChannelsState {
+ switch (action.type) {
+ case "AddChannel": {
+ const channels = {
+ ...state.channels,
+ [action.payload.id]: action.payload,
+ };
+ return { channels, activeChannel: action.payload };
+ }
+ case "UpdateActive": {
+ const activeChannel = state.activeChannel;
+ if (activeChannel) {
+ return {
+ channels: { ...state.channels, [activeChannel.id]: action.payload },
+ activeChannel: action.payload,
+ };
+ }
+ return state;
+ }
+ case "ChangeActive": {
+ const newActive = state.channels[action.payload];
+ if (newActive) {
+ return { ...state, activeChannel: newActive };
+ }
+ return state;
+ }
+ case "ToggleMuted": {
+ const channel = state.channels[action.payload];
+ if (channel) {
+ const updatedChannel: ChannelData = {
+ ...channel,
+ isMuted: !channel.isMuted,
+ };
+ return {
+ channels: { ...state.channels, [channel.id]: updatedChannel },
+ activeChannel: updatedChannel,
+ };
+ }
+ return state;
+ }
+ case "RemoveChannel": {
+ const channelsCopy = { ...state.channels };
+ delete channelsCopy[action.payload];
+ let newActive = { id: "", name: "", type: "channel" } as ChannelData;
+ if (Object.values(channelsCopy).length > 0) {
+ newActive = Object.values(channelsCopy)[0];
+ }
+ return { channels: channelsCopy, activeChannel: newActive };
+ }
+ default:
+ throw new Error();
+ }
+}
+
+export function useChannelsReducer() {
+ return useReducer(channelReducer, {
+ channels: {},
+ activeChannel: { id: "", name: "", type: "channel" },
+ } as ChannelsState);
+}
diff --git a/packages/status-react/src/hooks/messenger/useContacts.ts b/packages/status-react/src/hooks/messenger/useContacts.ts
new file mode 100644
index 00000000..c32cd60c
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useContacts.ts
@@ -0,0 +1,126 @@
+import {
+ Contacts as ContactsClass,
+ Identity,
+ Messenger,
+ bufToHex
+} from "@status-im/core";
+import { useMemo, useReducer, useState } from "react";
+
+import { Contacts } from "../../models/Contact";
+
+export type ContactsAction =
+ | { type: "updateOnline"; payload: { id: string; clock: number } }
+ | { type: "setTrueName"; payload: { id: string; trueName: string } }
+ | {
+ type: "setCustomName";
+ payload: { id: string; customName: string | undefined };
+ }
+ | {
+ type: "setIsUntrustworthy";
+ payload: { id: string; isUntrustworthy: boolean };
+ }
+ | { type: "setIsFriend"; payload: { id: string; isFriend: boolean } }
+ | { type: "setBlocked"; payload: { id: string; blocked: boolean } }
+ | { type: "toggleBlocked"; payload: { id: string } }
+ | { type: "toggleTrustworthy"; payload: { id: string } };
+
+function contactsReducer(state: Contacts, action: ContactsAction): Contacts {
+ const id = action.payload.id;
+ const prev = state[id];
+
+ switch (action.type) {
+ case "updateOnline": {
+ const now = Date.now();
+ const clock = action.payload.clock;
+ if (prev) {
+ return { ...state, [id]: { ...prev, online: clock > now - 301000 } };
+ }
+ return { ...state, [id]: { id, trueName: id.slice(0, 10) } };
+ }
+ case "setTrueName": {
+ const trueName = action.payload.trueName;
+ if (prev) {
+ return { ...state, [id]: { ...prev, trueName } };
+ }
+ return { ...state, [id]: { id, trueName } };
+ }
+ case "setCustomName": {
+ const customName = action.payload.customName;
+ if (prev) {
+ return { ...state, [id]: { ...prev, customName } };
+ }
+ return state;
+ }
+ case "setIsUntrustworthy": {
+ const isUntrustworthy = action.payload.isUntrustworthy;
+ if (prev) {
+ return { ...state, [id]: { ...prev, isUntrustworthy } };
+ }
+ return state;
+ }
+ case "setIsFriend": {
+ const isFriend = action.payload.isFriend;
+ if (prev) {
+ return { ...state, [id]: { ...prev, isFriend } };
+ }
+ return state;
+ }
+ case "setBlocked": {
+ const blocked = action.payload.blocked;
+ if (prev) {
+ return { ...state, [id]: { ...prev, blocked } };
+ }
+ return state;
+ }
+ case "toggleBlocked": {
+ if (prev) {
+ return { ...state, [id]: { ...prev, blocked: !prev.blocked } };
+ }
+ return state;
+ }
+ case "toggleTrustworthy": {
+ if (prev) {
+ return {
+ ...state,
+ [id]: { ...prev, isUntrustworthy: !prev.isUntrustworthy },
+ };
+ }
+ return state;
+ }
+ default:
+ throw new Error();
+ }
+}
+
+export function useContacts(
+ messenger: Messenger | undefined,
+ identity: Identity | undefined,
+ newNickname: string | undefined
+) {
+ const [nickname, setNickname] = useState(undefined);
+ const [contacts, contactsDispatch] = useReducer(contactsReducer, {});
+
+ const contactsClass = useMemo(() => {
+ if (messenger && messenger.identity === identity) {
+ const newContacts = new ContactsClass(
+ identity,
+ messenger.waku,
+ (id, clock) =>
+ contactsDispatch({ type: "updateOnline", payload: { id, clock } }),
+ (id, nickname) => {
+ if (identity?.publicKey && id === bufToHex(identity.publicKey)) {
+ setNickname(nickname);
+ }
+ contactsDispatch({
+ type: "setTrueName",
+ payload: { id, trueName: nickname },
+ });
+ },
+ newNickname
+ );
+ return newContacts;
+ }
+ }, [messenger, identity, newNickname]);
+
+ return { contacts, contactsDispatch, contactsClass, nickname };
+}
diff --git a/packages/status-react/src/hooks/messenger/useGroupChats.ts b/packages/status-react/src/hooks/messenger/useGroupChats.ts
new file mode 100644
index 00000000..ec381c90
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useGroupChats.ts
@@ -0,0 +1,132 @@
+import {
+ Contacts as ContactsClass,
+ GroupChat,
+ GroupChats,
+ Identity,
+ Messenger,
+ ChatMessage as StatusChatMessage,
+} from "@status-im/core";
+import { useCallback, useMemo } from "react";
+
+import { ChannelData } from "../../models/ChannelData";
+import { ChatMessage } from "../../models/ChatMessage";
+import { Contact } from "../../models/Contact";
+import { uintToImgUrl } from "../../utils";
+
+import { ChannelAction } from "./useChannelsReducer";
+
+const contactFromId = (member: string): Contact => {
+ return {
+ blocked: false,
+ id: member,
+ isUntrustworthy: false,
+ online: false,
+ trueName: member,
+ };
+};
+
+export function useGroupChats(
+ messenger: Messenger | undefined,
+ identity: Identity | undefined,
+ dispatch: (action: ChannelAction) => void,
+ addChatMessage: (newMessage: ChatMessage | undefined, id: string) => void,
+ contactsClass: ContactsClass | undefined
+) {
+ const groupChat = useMemo(() => {
+ if (messenger && identity && contactsClass) {
+ const addChat = (chat: GroupChat) => {
+ const members = chat.members
+ .map(member => member.id)
+ .map(contactFromId);
+ const channel: ChannelData =
+ chat.members.length > 2
+ ? {
+ id: chat.chatId,
+ name: chat.name ?? chat.chatId.slice(0, 10),
+ type: "group",
+ description: `${chat.members.length} members`,
+ members,
+ }
+ : {
+ id: chat.chatId,
+ name: chat.members[0].id,
+ type: "dm",
+ description: `Chatkey: ${chat.members[0].id}`,
+ members,
+ };
+ chat.members.forEach(member => contactsClass.addContact(member.id));
+ dispatch({ type: "AddChannel", payload: channel });
+ };
+ const removeChat = (chat: GroupChat) => {
+ dispatch({ type: "RemoveChannel", payload: chat.chatId });
+ };
+ const handleMessage = (msg: StatusChatMessage, sender: string) => {
+ let image: string | undefined = undefined;
+ if (msg.image) {
+ image = uintToImgUrl(msg.image.payload);
+ }
+ addChatMessage(
+ new ChatMessage(
+ msg.text ?? "",
+ new Date(msg.clock ?? 0),
+ sender,
+ image,
+ msg.responseTo
+ ),
+ msg.chatId
+ );
+ };
+ return new GroupChats(
+ identity,
+ messenger.waku,
+ addChat,
+ removeChat,
+ handleMessage
+ );
+ }
+ }, [messenger, identity, contactsClass, addChatMessage, dispatch]);
+
+ const createGroupChat = useCallback(
+ (members: string[]) => {
+ if (groupChat) {
+ groupChat.createGroupChat(members);
+ }
+ },
+ [groupChat]
+ );
+
+ const changeGroupChatName = useCallback(
+ (name: string, chatId: string) => {
+ if (groupChat) {
+ groupChat.changeChatName(chatId, name);
+ }
+ },
+ [groupChat]
+ );
+
+ const removeChannel = useCallback(
+ (channelId: string) => {
+ if (groupChat) {
+ groupChat.quitChat(channelId);
+ }
+ },
+ [groupChat]
+ );
+
+ const addMembers = useCallback(
+ (members: string[], chatId: string) => {
+ if (groupChat) {
+ groupChat.addMembers(chatId, members);
+ }
+ },
+ [groupChat]
+ );
+
+ return {
+ createGroupChat,
+ removeChannel,
+ groupChat,
+ changeGroupChatName,
+ addMembers,
+ };
+}
diff --git a/packages/status-react/src/hooks/messenger/useLoadPrevDay.ts b/packages/status-react/src/hooks/messenger/useLoadPrevDay.ts
new file mode 100644
index 00000000..6fa7094d
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useLoadPrevDay.ts
@@ -0,0 +1,70 @@
+import { GroupChats, Messenger } from "@status-im/core";
+import { useCallback, useEffect, useRef, useState } from "react";
+
+const _MS_PER_DAY = 1000 * 60 * 60 * 24;
+
+export function useLoadPrevDay(
+ chatId: string,
+ messenger: Messenger | undefined,
+ groupChats?: GroupChats
+) {
+ const loadingPreviousMessages = useRef<{
+ [chatId: string]: boolean;
+ }>({});
+ const lastLoadTime = useRef<{
+ [chatId: string]: Date;
+ }>({});
+ const [loadingMessages, setLoadingMessages] = useState(false);
+
+ useEffect(() => {
+ if (chatId) {
+ setLoadingMessages(loadingPreviousMessages.current[chatId]);
+ }
+ }, [chatId]);
+
+ const loadPrevDay = useCallback(
+ async (id: string, groupChat?: boolean) => {
+ if (messenger && id) {
+ const endTime = lastLoadTime.current[id] ?? new Date();
+ const startTime = new Date(endTime.getTime() - _MS_PER_DAY * 5);
+ const timeDiff = Math.floor(
+ (new Date().getTime() - endTime.getTime()) / _MS_PER_DAY
+ );
+ if (timeDiff < 28) {
+ if (!loadingPreviousMessages.current[id]) {
+ loadingPreviousMessages.current[id] = true;
+ setLoadingMessages(true);
+ let amountOfMessages = 0;
+ let failed = true;
+ try {
+ if (groupChat && groupChats) {
+ amountOfMessages = await groupChats.retrievePreviousMessages(
+ id,
+ startTime,
+ endTime
+ );
+ } else {
+ amountOfMessages = await messenger.retrievePreviousMessages(
+ id,
+ startTime,
+ endTime
+ );
+ }
+ lastLoadTime.current[id] = startTime;
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ loadingPreviousMessages.current[id] = false;
+ setLoadingMessages(false);
+ if (amountOfMessages === 0 && !failed) {
+ loadPrevDay(id, groupChat);
+ }
+ }
+ }
+ }
+ },
+ [messenger, groupChats]
+ );
+ return { loadingMessages, loadPrevDay };
+}
diff --git a/packages/status-react/src/hooks/messenger/useMessages.ts b/packages/status-react/src/hooks/messenger/useMessages.ts
new file mode 100644
index 00000000..b3b7d92b
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useMessages.ts
@@ -0,0 +1,93 @@
+import {
+ ApplicationMetadataMessage,
+ Contacts,
+ Identity,
+ bufToHex
+} from "@status-im/core";
+import { useCallback, useMemo, useState } from "react";
+
+import { ChatMessage } from "../../models/ChatMessage";
+import { binarySetInsert } from "../../utils";
+
+import { useNotifications } from "./useNotifications";
+
+export function useMessages(
+ chatId: string,
+ identity: Identity | undefined,
+ subscriptions: React.MutableRefObject<
+ ((msg: ChatMessage, id: string) => void)[]
+ >,
+ contacts?: Contacts
+) {
+ const [messages, setMessages] = useState<{ [chatId: string]: ChatMessage[] }>(
+ {}
+ );
+ const { notifications, incNotification, clearNotifications } =
+ useNotifications();
+
+ const {
+ notifications: mentions,
+ incNotification: incMentions,
+ clearNotifications: clearMentions,
+ } = useNotifications();
+
+ const addChatMessage = useCallback(
+ (newMessage: ChatMessage | undefined, id: string) => {
+ if (newMessage) {
+ contacts?.addContact(newMessage.sender);
+ setMessages(prev => {
+ if (newMessage.responseTo && prev[id]) {
+ newMessage.quote = prev[id].find(
+ msg => msg.id === newMessage.responseTo
+ );
+ }
+ return {
+ ...prev,
+ [id]: binarySetInsert(
+ prev?.[id] ?? [],
+ newMessage,
+ (a, b) => a.date < b.date,
+ (a, b) => a.date.getTime() === b.date.getTime()
+ ),
+ };
+ });
+ subscriptions.current.forEach(subscription =>
+ subscription(newMessage, id)
+ );
+ incNotification(id);
+ if (
+ identity &&
+ newMessage.content.includes(`@${bufToHex(identity.publicKey)}`)
+ ) {
+ incMentions(id);
+ }
+ }
+ },
+ [contacts, identity, subscriptions, incMentions, incNotification]
+ );
+
+ const addMessage = useCallback(
+ (msg: ApplicationMetadataMessage, id: string, date: Date) => {
+ const newMessage = ChatMessage.fromMetadataMessage(msg, date);
+ addChatMessage(newMessage, id);
+ },
+ [addChatMessage]
+ );
+
+ const activeMessages = useMemo(() => {
+ if (messages?.[chatId]) {
+ return [...messages[chatId]];
+ }
+ return [];
+ }, [messages, chatId]);
+
+ return {
+ messages: activeMessages,
+ addMessage,
+ notifications,
+ clearNotifications,
+ mentions,
+ clearMentions,
+ addChatMessage,
+ };
+}
diff --git a/packages/status-react/src/hooks/messenger/useMessenger.ts b/packages/status-react/src/hooks/messenger/useMessenger.ts
new file mode 100644
index 00000000..85e50643
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useMessenger.ts
@@ -0,0 +1,358 @@
+// import { StoreCodec } from "js-waku";
+import {
+ ApplicationMetadataMessage,
+ Community,
+ Contacts as ContactsClass,
+ Identity,
+ Messenger,
+} from "@status-im/core";
+import {
+ useCallback,
+ useEffect,
+ useMemo,
+ useReducer,
+ useRef,
+ useState,
+} from "react";
+
+import { useConfig } from "../../contexts/configProvider";
+import { ChannelData, ChannelsData } from "../../models/ChannelData";
+import { ChatMessage } from "../../models/ChatMessage";
+import { CommunityData } from "../../models/CommunityData";
+import { Contacts } from "../../models/Contact";
+import { createCommunity } from "../../utils/createCommunity";
+import { createMessenger } from "../../utils/createMessenger";
+import { uintToImgUrl } from "../../utils/uintToImgUrl";
+
+import { ChannelAction, useChannelsReducer } from "./useChannelsReducer";
+import { ContactsAction, useContacts } from "./useContacts";
+import { useGroupChats } from "./useGroupChats";
+import { useLoadPrevDay } from "./useLoadPrevDay";
+import { useMessages } from "./useMessages";
+
+export type MessengerType = {
+ messenger: Messenger | undefined;
+ messages: ChatMessage[];
+ sendMessage: (
+ messageText?: string | undefined,
+ image?: Uint8Array | undefined,
+ responseTo?: string
+ ) => Promise;
+ notifications: { [chatId: string]: number };
+ clearNotifications: (id: string) => void;
+ mentions: { [chatId: string]: number };
+ clearMentions: (id: string) => void;
+ loadPrevDay: (id: string, groupChat?: boolean) => Promise;
+ loadingMessages: boolean;
+ loadingMessenger: boolean;
+ communityData: CommunityData | undefined;
+ contacts: Contacts;
+ contactsDispatch: (action: ContactsAction) => void;
+ addContact: (publicKey: string) => void;
+ channels: ChannelsData;
+ channelsDispatch: (action: ChannelAction) => void;
+ removeChannel: (channelId: string) => void;
+ activeChannel: ChannelData | undefined;
+ createGroupChat: (members: string[]) => void;
+ changeGroupChatName: (name: string, chatId: string) => void;
+ addMembers: (members: string[], chatId: string) => void;
+ nickname: string | undefined;
+ subscriptionsDispatch: (action: SubscriptionAction) => void;
+};
+
+function useCreateMessenger(identity: Identity | undefined) {
+ const { environment } = useConfig();
+ const [messenger, setMessenger] = useState(undefined);
+ useEffect(() => {
+ createMessenger(identity, environment).then(e => {
+ setMessenger(e);
+ });
+ }, [identity, environment]);
+
+ return messenger;
+}
+
+function useCreateCommunity(
+ messenger: Messenger | undefined,
+ identity: Identity | undefined,
+ communityKey: string | undefined,
+ addMessage: (msg: ApplicationMetadataMessage, id: string, date: Date) => void,
+ contactsClass: ContactsClass | undefined
+) {
+ const [community, setCommunity] = useState(undefined);
+
+ useEffect(() => {
+ if (
+ messenger &&
+ communityKey &&
+ contactsClass &&
+ addMessage &&
+ messenger.identity === identity
+ ) {
+ createCommunity(communityKey, addMessage, messenger).then(comm => {
+ setCommunity(comm);
+ });
+ }
+ }, [messenger, communityKey, addMessage, contactsClass, identity]);
+
+ const communityData = useMemo(() => {
+ if (community?.description) {
+ const membersList = Object.keys(community.description.proto.members);
+
+ if (contactsClass) {
+ membersList.forEach(contactsClass.addContact, contactsClass);
+ }
+
+ return {
+ id: community.publicKeyStr,
+ name: community.description.identity?.displayName ?? "",
+ icon: uintToImgUrl(
+ community.description?.identity?.images?.thumbnail?.payload ??
+ new Uint8Array()
+ ),
+ members: membersList.length,
+ membersList,
+ description: community.description.identity?.description ?? "",
+ };
+ } else {
+ return undefined;
+ }
+ }, [community, contactsClass]);
+
+ return { community, communityData };
+}
+
+type Subscriptions = {
+ [id: string]: (msg: ChatMessage, id: string) => void;
+};
+
+type SubscriptionAction =
+ | {
+ type: "addSubscription";
+ payload: {
+ name: string;
+ subFunction: (msg: ChatMessage, id: string) => void;
+ };
+ }
+ | { type: "removeSubscription"; payload: { name: string } };
+
+function subscriptionReducer(
+ state: Subscriptions,
+ action: SubscriptionAction
+): Subscriptions {
+ switch (action.type) {
+ case "addSubscription": {
+ if (state[action.payload.name]) {
+ throw new Error("Subscription already exists");
+ }
+ return { ...state, [action.payload.name]: action.payload.subFunction };
+ }
+ case "removeSubscription": {
+ if (state[action.payload.name]) {
+ const newState = { ...state };
+ delete newState[action.payload.name];
+ return newState;
+ }
+ return state;
+ }
+ default:
+ throw new Error("Wrong subscription action type");
+ }
+}
+
+export function useMessenger(
+ communityKey: string | undefined,
+ identity: Identity | undefined,
+ newNickname: string | undefined
+) {
+ const [subscriptions, subscriptionsDispatch] = useReducer(
+ subscriptionReducer,
+ {}
+ );
+ const subList = useRef<((msg: ChatMessage, id: string) => void)[]>([]);
+ useEffect(() => {
+ subList.current = Object.values(subscriptions);
+ }, [subscriptions]);
+
+ const [channelsState, channelsDispatch] = useChannelsReducer();
+ const messenger = useCreateMessenger(identity);
+ const { contacts, contactsDispatch, contactsClass, nickname } = useContacts(
+ messenger,
+ identity,
+ newNickname
+ );
+
+ const addContact = useCallback(
+ (publicKey: string) => {
+ if (contactsClass) {
+ contactsClass.addContact(publicKey);
+ }
+ },
+ [contactsClass]
+ );
+
+ const {
+ addChatMessage,
+ addMessage,
+ clearNotifications,
+ notifications,
+ messages,
+ mentions,
+ clearMentions,
+ } = useMessages(
+ channelsState?.activeChannel?.id,
+ identity,
+ subList,
+ contactsClass
+ );
+
+ const { community, communityData } = useCreateCommunity(
+ messenger,
+ identity,
+ communityKey,
+ addMessage,
+ contactsClass
+ );
+
+ useEffect(() => {
+ if (community?.chats) {
+ for (const chat of community.chats.values()) {
+ channelsDispatch({
+ type: "AddChannel",
+ payload: {
+ id: chat.id,
+ name: chat.communityChat?.identity?.displayName ?? "",
+ description: chat.communityChat?.identity?.description ?? "",
+ type: "channel",
+ },
+ });
+ }
+ }
+ }, [community, channelsDispatch]);
+
+ useEffect(() => {
+ Object.values(channelsState.channels)
+ .filter(channel => channel.type === "dm")
+ .forEach(channel => {
+ const contact = contacts?.[channel?.members?.[1]?.id ?? ""];
+ if (
+ contact &&
+ channel.name !== (contact?.customName ?? contact.trueName)
+ ) {
+ channelsDispatch({
+ type: "AddChannel",
+ payload: {
+ ...channel,
+ name: contact?.customName ?? contact.trueName,
+ },
+ });
+ }
+ });
+ }, [contacts, channelsState.channels, channelsDispatch]);
+
+ const {
+ groupChat,
+ removeChannel,
+ createGroupChat,
+ changeGroupChatName,
+ addMembers,
+ } = useGroupChats(
+ messenger,
+ identity,
+ channelsDispatch,
+ addChatMessage,
+ contactsClass
+ );
+
+ const { loadPrevDay, loadingMessages } = useLoadPrevDay(
+ channelsState.activeChannel.id,
+ messenger,
+ groupChat
+ );
+
+ useEffect(() => {
+ if (messenger && community?.chats) {
+ Array.from(community?.chats.values()).forEach(({ id }) =>
+ loadPrevDay(id)
+ );
+ }
+ }, [messenger, community, loadPrevDay]);
+
+ const sendMessage = useCallback(
+ async (messageText?: string, image?: Uint8Array, responseTo?: string) => {
+ let content;
+ if (messageText) {
+ content = {
+ text: messageText,
+ contentType: 0,
+ };
+ }
+ if (image) {
+ content = {
+ image,
+ imageType: 1,
+ contentType: 2,
+ };
+ }
+ if (content) {
+ if (channelsState.activeChannel.type !== "channel") {
+ await groupChat?.sendMessage(
+ channelsState.activeChannel.id,
+ content,
+ responseTo
+ );
+ } else {
+ await messenger?.sendMessage(
+ channelsState.activeChannel.id,
+ content,
+ responseTo
+ );
+ }
+ }
+ },
+ [messenger, groupChat, channelsState.activeChannel]
+ );
+
+ useEffect(() => {
+ if (channelsState.activeChannel) {
+ if (notifications[channelsState.activeChannel.id] > 0) {
+ clearNotifications(channelsState.activeChannel.id);
+ clearMentions(channelsState.activeChannel.id);
+ }
+ }
+ }, [notifications, channelsState, clearNotifications, clearMentions]);
+
+ const loadingMessenger = useMemo(() => {
+ return Boolean(
+ (communityKey && !communityData) ||
+ !messenger ||
+ (communityKey && !channelsState.activeChannel.id)
+ );
+ }, [communityData, messenger, channelsState, communityKey]);
+
+ return {
+ messenger,
+ messages,
+ sendMessage,
+ notifications,
+ clearNotifications,
+ loadPrevDay,
+ loadingMessages,
+ loadingMessenger,
+ communityData,
+ contacts,
+ contactsDispatch,
+ addContact,
+ channels: channelsState.channels,
+ channelsDispatch,
+ removeChannel,
+ activeChannel: channelsState.activeChannel,
+ mentions,
+ clearMentions,
+ createGroupChat,
+ changeGroupChatName,
+ addMembers,
+ nickname,
+ subscriptionsDispatch,
+ };
+}
diff --git a/packages/status-react/src/hooks/messenger/useNotifications.ts b/packages/status-react/src/hooks/messenger/useNotifications.ts
new file mode 100644
index 00000000..8e9b6093
--- /dev/null
+++ b/packages/status-react/src/hooks/messenger/useNotifications.ts
@@ -0,0 +1,24 @@
+import { useCallback, useState } from "react";
+
+export function useNotifications() {
+ const [notifications, setNotifications] = useState<{
+ [chatId: string]: number;
+ }>({});
+ const incNotification = useCallback((id: string) => {
+ setNotifications((prevNotifications) => {
+ return {
+ ...prevNotifications,
+ [id]: (prevNotifications?.[id] ?? 0) + 1,
+ };
+ });
+ }, []);
+ const clearNotifications = useCallback((id: string) => {
+ setNotifications((prevNotifications) => {
+ return {
+ ...prevNotifications,
+ [id]: 0,
+ };
+ });
+ }, []);
+ return { notifications, incNotification, clearNotifications };
+}
diff --git a/packages/status-react/src/hooks/useActivities.ts b/packages/status-react/src/hooks/useActivities.ts
new file mode 100644
index 00000000..c66c3e0f
--- /dev/null
+++ b/packages/status-react/src/hooks/useActivities.ts
@@ -0,0 +1,115 @@
+import { useEffect, useMemo, useReducer } from "react";
+
+import { useUserPublicKey } from "../contexts/identityProvider";
+import { useMessengerContext } from "../contexts/messengerProvider";
+import { Activities, Activity, ActivityStatus } from "../models/Activity";
+import { ChatMessage } from "../models/ChatMessage";
+
+export type ActivityAction =
+ | { type: "addActivity"; payload: Activity }
+ | { type: "removeActivity"; payload: "string" }
+ | { type: "setAsRead"; payload: string }
+ | { type: "setAllAsRead" }
+ | { type: "setStatus"; payload: { id: string; status: ActivityStatus } };
+
+function activityReducer(
+ state: Activities,
+ action: ActivityAction
+): Activities {
+ switch (action.type) {
+ case "setStatus": {
+ const activity = state[action.payload.id];
+ if (activity && "status" in activity) {
+ activity.status = action.payload.status;
+ activity.isRead = true;
+ return { ...state, [activity.id]: activity };
+ }
+ return state;
+ }
+ case "setAsRead": {
+ const activity = state[action.payload];
+ if (activity) {
+ activity.isRead = true;
+ return { ...state, [activity.id]: activity };
+ }
+ return state;
+ }
+ case "setAllAsRead": {
+ return Object.entries(state).reduce((prev, curr) => {
+ const activity = curr[1];
+ activity.isRead = true;
+ return { ...prev, [curr[0]]: activity };
+ }, {});
+ }
+ case "addActivity": {
+ return { ...state, [action.payload.id]: action.payload };
+ }
+ case "removeActivity": {
+ if (state[action.payload]) {
+ const newState = { ...state };
+ delete newState[action.payload];
+ return newState;
+ } else {
+ return state;
+ }
+ }
+ default:
+ throw new Error("Wrong activity reducer type");
+ }
+}
+
+export function useActivities() {
+ const [activitiesObj, dispatch] = useReducer(activityReducer, {});
+ const activities = useMemo(
+ () => Object.values(activitiesObj),
+ [activitiesObj]
+ );
+ const userPK = useUserPublicKey();
+ const { subscriptionsDispatch, channels } = useMessengerContext();
+
+ useEffect(() => {
+ if (userPK) {
+ const subscribeFunction = (message: ChatMessage, id: string) => {
+ if (message.quote && message.quote.sender === userPK) {
+ const newActivity: Activity = {
+ id: message.date.getTime().toString() + message.content,
+ type: "reply",
+ date: message.date,
+ user: message.sender,
+ message: message,
+ channel: channels[id],
+ quote: message.quote,
+ };
+ dispatch({ type: "addActivity", payload: newActivity });
+ }
+
+ const split = message.content.split(" ");
+ const userMentioned = split.some(
+ (fragment) => fragment.startsWith("@") && fragment.slice(1) == userPK
+ );
+ if (userMentioned) {
+ const newActivity: Activity = {
+ id: message.date.getTime().toString() + message.content,
+ type: "mention",
+ date: message.date,
+ user: message.sender,
+ message: message,
+ channel: channels[id],
+ };
+ dispatch({ type: "addActivity", payload: newActivity });
+ }
+ };
+ subscriptionsDispatch({
+ type: "addSubscription",
+ payload: { name: "activityCenter", subFunction: subscribeFunction },
+ });
+ }
+ return () =>
+ subscriptionsDispatch({
+ type: "removeSubscription",
+ payload: { name: "activityCenter" },
+ });
+ }, [subscriptionsDispatch, userPK, channels]);
+
+ return { activities, activityDispatch: dispatch };
+}
diff --git a/packages/status-react/src/hooks/useChatScrollHandle.ts b/packages/status-react/src/hooks/useChatScrollHandle.ts
new file mode 100644
index 00000000..5100a3f2
--- /dev/null
+++ b/packages/status-react/src/hooks/useChatScrollHandle.ts
@@ -0,0 +1,55 @@
+import { useEffect, useState } from "react";
+
+import { useMessengerContext } from "../contexts/messengerProvider";
+import { ChatMessage } from "../models/ChatMessage";
+
+export function useChatScrollHandle(
+ messages: ChatMessage[],
+ ref: React.RefObject
+) {
+ const { loadPrevDay, loadingMessages, activeChannel } = useMessengerContext();
+ const [scrollOnBot, setScrollOnBot] = useState(true);
+
+ useEffect(() => {
+ if (ref && ref.current && scrollOnBot) {
+ ref.current.scrollTop = ref.current.scrollHeight;
+ }
+ }, [messages.length, scrollOnBot, ref]);
+
+ useEffect(() => {
+ if (activeChannel) {
+ if (
+ (ref?.current?.clientHeight ?? 0) >= (ref?.current?.scrollHeight ?? 0)
+ ) {
+ setScrollOnBot(true);
+ loadPrevDay(activeChannel.id, activeChannel.type !== "channel");
+ }
+ }
+ }, [messages.length, activeChannel, loadPrevDay, setScrollOnBot, ref]);
+
+ useEffect(() => {
+ const currentRef = ref.current;
+ const setScroll = () => {
+ if (ref?.current && activeChannel) {
+ if (ref.current.scrollTop <= 0) {
+ loadPrevDay(activeChannel.id, activeChannel.type !== "channel");
+ }
+ if (
+ ref.current.scrollTop + ref.current.clientHeight ==
+ ref.current.scrollHeight
+ ) {
+ if (scrollOnBot === false) {
+ setScrollOnBot(true);
+ }
+ } else {
+ if (scrollOnBot === true) {
+ setScrollOnBot(false);
+ }
+ }
+ }
+ };
+ currentRef?.addEventListener("scroll", setScroll);
+ return () => currentRef?.removeEventListener("scroll", setScroll);
+ }, [ref, scrollOnBot, activeChannel, loadPrevDay]);
+ return loadingMessages;
+}
diff --git a/packages/status-react/src/hooks/useClickOutside.ts b/packages/status-react/src/hooks/useClickOutside.ts
new file mode 100644
index 00000000..686913b9
--- /dev/null
+++ b/packages/status-react/src/hooks/useClickOutside.ts
@@ -0,0 +1,23 @@
+import { RefObject, useCallback, useEffect } from "react";
+
+export const useClickOutside = (
+ ref: RefObject,
+ callback: () => void
+) => {
+ const handleClick = useCallback(
+ (e: MouseEvent) => {
+ if (ref.current && !ref.current.contains(e.target as HTMLInputElement)) {
+ callback();
+ }
+ },
+ [ref, callback]
+ );
+
+ useEffect(() => {
+ document.addEventListener("mousedown", handleClick);
+
+ return () => {
+ document.removeEventListener("mousedown", handleClick);
+ };
+ }, [handleClick]);
+};
diff --git a/packages/status-react/src/hooks/useClickPosition.ts b/packages/status-react/src/hooks/useClickPosition.ts
new file mode 100644
index 00000000..e97b4206
--- /dev/null
+++ b/packages/status-react/src/hooks/useClickPosition.ts
@@ -0,0 +1,30 @@
+import { RefObject, useCallback, useEffect, useState } from "react";
+
+export const useClickPosition = (ref: RefObject) => {
+ const [topPosition, setTopPosition] = useState(0);
+ const [leftPosition, setLeftPosition] = useState(0);
+
+ const getPosition = useCallback(
+ (e: MouseEvent) => {
+ if (ref.current) {
+ const target = e.target as HTMLImageElement;
+ const imgTarget = target.tagName === "IMG";
+ const rect = ref.current.getBoundingClientRect();
+ const x = ref.current.clientWidth - e.clientX < 180 ? 180 : 0;
+ setLeftPosition(imgTarget ? -200 : e.clientX - rect.left - x);
+ setTopPosition(imgTarget ? 0 : e.clientY - rect.top);
+ }
+ },
+ [setTopPosition, setLeftPosition, ref]
+ );
+
+ useEffect(() => {
+ document.addEventListener("contextmenu", getPosition);
+
+ return () => {
+ document.removeEventListener("contextmenu", getPosition);
+ };
+ });
+
+ return { topPosition, leftPosition };
+};
diff --git a/packages/status-react/src/hooks/useContextMenu.ts b/packages/status-react/src/hooks/useContextMenu.ts
new file mode 100644
index 00000000..e3d6fa68
--- /dev/null
+++ b/packages/status-react/src/hooks/useContextMenu.ts
@@ -0,0 +1,27 @@
+import { useCallback, useEffect, useState } from "react";
+
+export const useContextMenu = (elementId: string) => {
+ const [showMenu, setShowMenu] = useState(false);
+
+ const handleContextMenu = useCallback(
+ (event) => {
+ event.preventDefault();
+ setShowMenu(true);
+ },
+ [setShowMenu]
+ );
+
+ useEffect(() => {
+ const element = document.getElementById(elementId) || document;
+
+ element.addEventListener("contextmenu", handleContextMenu);
+ document.addEventListener("click", () => setShowMenu(false));
+ return () => {
+ element.removeEventListener("contextmenu", handleContextMenu);
+ document.removeEventListener("click", () => setShowMenu(false));
+ setShowMenu(false);
+ };
+ }, [elementId, handleContextMenu]);
+
+ return { showMenu, setShowMenu };
+};
diff --git a/packages/status-react/src/hooks/useNameError.tsx b/packages/status-react/src/hooks/useNameError.tsx
new file mode 100644
index 00000000..ecd37b91
--- /dev/null
+++ b/packages/status-react/src/hooks/useNameError.tsx
@@ -0,0 +1,40 @@
+import { useMemo } from "react";
+
+import { useMessengerContext } from "../contexts/messengerProvider";
+
+export enum NameErrors {
+ NoError = 0,
+ NameExists = 1,
+ BadCharacters = 2,
+ EndingWithEth = 3,
+ TooLong = 4,
+}
+
+export function useNameError(name: string) {
+ const { contacts } = useMessengerContext();
+
+ const error = useMemo(() => {
+ const RegName = new RegExp("^[a-z0-9_-]+$");
+ if (name === "") {
+ return NameErrors.NoError;
+ }
+ const nameExists = Object.values(contacts).find(
+ (contact) => contact.trueName === name
+ );
+ if (nameExists) {
+ return NameErrors.NameExists;
+ }
+ if (!name.match(RegName)) {
+ return NameErrors.BadCharacters;
+ }
+ if (name.slice(-4) === "_eth" || name.slice(-4) === "-eth") {
+ return NameErrors.EndingWithEth;
+ }
+ if (name.length >= 24) {
+ return NameErrors.TooLong;
+ }
+ return NameErrors.NoError;
+ }, [name, contacts]);
+
+ return error;
+}
diff --git a/packages/status-react/src/hooks/useRefBreak.ts b/packages/status-react/src/hooks/useRefBreak.ts
new file mode 100644
index 00000000..0c983120
--- /dev/null
+++ b/packages/status-react/src/hooks/useRefBreak.ts
@@ -0,0 +1,26 @@
+import { useEffect, useState } from "react";
+
+export function useRefBreak(dimension: number, sizeThreshold: number) {
+ const [widthBreak, setWidthBreak] = useState(dimension < sizeThreshold);
+
+ useEffect(() => {
+ const checkDimensions = () => {
+ if (dimension && dimension < sizeThreshold && dimension > 0) {
+ if (widthBreak === false) {
+ setWidthBreak(true);
+ }
+ } else {
+ if (widthBreak === true) {
+ setWidthBreak(false);
+ }
+ }
+ };
+ checkDimensions();
+ window.addEventListener("resize", checkDimensions);
+ return () => {
+ window.removeEventListener("resize", checkDimensions);
+ };
+ }, [dimension, widthBreak, sizeThreshold]);
+
+ return widthBreak;
+}
diff --git a/packages/status-react/src/hooks/useReply.ts b/packages/status-react/src/hooks/useReply.ts
new file mode 100644
index 00000000..fb76a530
--- /dev/null
+++ b/packages/status-react/src/hooks/useReply.ts
@@ -0,0 +1,6 @@
+export type Reply = {
+ sender: string;
+ content: string;
+ image?: string;
+ id: string;
+};
diff --git a/packages/status-react/src/index.ts b/packages/status-react/src/index.ts
new file mode 100644
index 00000000..66b3f67f
--- /dev/null
+++ b/packages/status-react/src/index.ts
@@ -0,0 +1,6 @@
+import { CommunityChat } from "./components/CommunityChat";
+import { ConfigType } from "./contexts/configProvider";
+import { GroupChat } from "./groupChatComponents/GroupChat";
+import { darkTheme, lightTheme } from "./styles/themes";
+
+export { CommunityChat, GroupChat, lightTheme, darkTheme, ConfigType };
diff --git a/packages/status-react/src/models/Activity.ts b/packages/status-react/src/models/Activity.ts
new file mode 100644
index 00000000..8df01491
--- /dev/null
+++ b/packages/status-react/src/models/Activity.ts
@@ -0,0 +1,49 @@
+import { ChannelData } from "./ChannelData";
+import { ChatMessage } from "./ChatMessage";
+import { CommunityData } from "./CommunityData";
+
+export type ActivityStatus = "sent" | "accepted" | "declined" | "blocked";
+
+export type Activity =
+ | {
+ id: string;
+ type: "mention";
+ date: Date;
+ user: string;
+ message: ChatMessage;
+ channel: ChannelData;
+ isRead?: boolean;
+ }
+ | {
+ id: string;
+ type: "reply";
+ date: Date;
+ user: string;
+ message: ChatMessage;
+ channel: ChannelData;
+ quote: ChatMessage;
+ isRead?: boolean;
+ }
+ | {
+ id: string;
+ type: "request";
+ date: Date;
+ user: string;
+ isRead?: boolean;
+ request: string;
+ requestType: "outcome" | "income";
+ status: ActivityStatus;
+ }
+ | {
+ id: string;
+ type: "invitation";
+ isRead?: boolean;
+ date: Date;
+ user: string;
+ status: ActivityStatus;
+ invitation?: CommunityData;
+ };
+
+export type Activities = {
+ [id: string]: Activity;
+};
diff --git a/packages/status-react/src/models/ChannelData.ts b/packages/status-react/src/models/ChannelData.ts
new file mode 100644
index 00000000..d2ce2c4e
--- /dev/null
+++ b/packages/status-react/src/models/ChannelData.ts
@@ -0,0 +1,15 @@
+import { Contact } from "./Contact";
+
+export type ChannelData = {
+ id: string;
+ name: string;
+ type: "channel" | "dm" | "group";
+ description?: string;
+ icon?: string;
+ isMuted?: boolean;
+ members?: Contact[];
+};
+
+export type ChannelsData = {
+ [id: string]: ChannelData;
+};
diff --git a/packages/status-react/src/models/ChatMessage.ts b/packages/status-react/src/models/ChatMessage.ts
new file mode 100644
index 00000000..1e17adad
--- /dev/null
+++ b/packages/status-react/src/models/ChatMessage.ts
@@ -0,0 +1,56 @@
+import { ApplicationMetadataMessage, bufToHex } from "@status-im/core";
+import { keccak256 } from "js-sha3";
+
+import { uintToImgUrl } from "../utils";
+
+export class ChatMessage {
+ content: string;
+ date: Date;
+ sender: string;
+ image?: string;
+ responseTo?: string;
+ quote?: ChatMessage;
+ id: string;
+
+ constructor(
+ content: string,
+ date: Date,
+ sender: string,
+ image?: string,
+ responseTo?: string
+ ) {
+ this.content = content;
+ this.date = date;
+ this.sender = sender;
+ this.image = image;
+ this.responseTo = responseTo;
+ this.id = keccak256(date.getTime().toString() + content);
+ }
+
+ public static fromMetadataMessage(
+ msg: ApplicationMetadataMessage,
+ date: Date
+ ) {
+ if (
+ msg.signer &&
+ (msg.chatMessage?.text || msg.chatMessage?.image) &&
+ msg.chatMessage.clock
+ ) {
+ const content = msg.chatMessage.text ?? "";
+ let image: string | undefined = undefined;
+ if (msg.chatMessage?.image) {
+ image = uintToImgUrl(msg.chatMessage?.image.payload);
+ }
+ const sender = bufToHex(msg.signer);
+ return new ChatMessage(
+ content,
+ date,
+ sender,
+ image,
+ msg.chatMessage.responseTo
+ );
+ } else {
+ return undefined;
+ }
+ }
+}
diff --git a/packages/status-react/src/models/CommunityData.ts b/packages/status-react/src/models/CommunityData.ts
new file mode 100644
index 00000000..6ebefd83
--- /dev/null
+++ b/packages/status-react/src/models/CommunityData.ts
@@ -0,0 +1,8 @@
+export type CommunityData = {
+ id: string;
+ name: string;
+ icon: string;
+ members: number;
+ membersList: string[];
+ description: string;
+};
diff --git a/packages/status-react/src/models/Contact.ts b/packages/status-react/src/models/Contact.ts
new file mode 100644
index 00000000..79047b9b
--- /dev/null
+++ b/packages/status-react/src/models/Contact.ts
@@ -0,0 +1,13 @@
+export type Contact = {
+ id: string;
+ online?: boolean;
+ trueName: string;
+ customName?: string;
+ isUntrustworthy?: boolean;
+ blocked?: boolean;
+ isFriend?: boolean;
+};
+
+export type Contacts = {
+ [id: string]: Contact;
+};
diff --git a/packages/status-react/src/models/Metadata.ts b/packages/status-react/src/models/Metadata.ts
new file mode 100644
index 00000000..a24aa18b
--- /dev/null
+++ b/packages/status-react/src/models/Metadata.ts
@@ -0,0 +1,5 @@
+export interface Metadata {
+ "og:site_name": string;
+ "og:title": string;
+ "og:image": string;
+}
diff --git a/packages/status-react/src/models/Toast.ts b/packages/status-react/src/models/Toast.ts
new file mode 100644
index 00000000..706cccf0
--- /dev/null
+++ b/packages/status-react/src/models/Toast.ts
@@ -0,0 +1,6 @@
+export type Toast = {
+ id: string;
+ type: "confirmation" | "incoming" | "approvement" | "rejection";
+ text: string;
+ request?: string;
+};
diff --git a/packages/status-react/src/styles/GlobalStyle.tsx b/packages/status-react/src/styles/GlobalStyle.tsx
new file mode 100644
index 00000000..f707d420
--- /dev/null
+++ b/packages/status-react/src/styles/GlobalStyle.tsx
@@ -0,0 +1,159 @@
+import { createGlobalStyle } from "styled-components";
+
+export const GlobalStyle = createGlobalStyle`
+ * {
+ box-sizing: border-box;
+ -webkit-font-smoothing: antialiased;
+
+ &::-webkit-scrollbar {
+ width: 0;
+ }
+ }
+
+ body,
+ html {
+ margin: 0;
+ font-family: 'Inter', sans-serif;
+ font-size: 15px;
+ line-height: 22px;
+ }
+
+ html,
+ body,
+ div,
+ span,
+ applet,
+ object,
+ iframe,
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6,
+ p,
+ blockquote,
+ pre,
+ a,
+ abbr,
+ acronym,
+ address,
+ big,
+ cite,
+ code,
+ del,
+ dfn,
+ em,
+ img,
+ ins,
+ kbd,
+ q,
+ s,
+ samp,
+ small,
+ strike,
+ strong,
+ sub,
+ sup,
+ tt,
+ var,
+ b,
+ u,
+ i,
+ center,
+ dl,
+ dt,
+ dd,
+ ol,
+ ul,
+ li,
+ fieldset,
+ form,
+ label,
+ legend,
+ table,
+ caption,
+ tbody,
+ tfoot,
+ thead,
+ tr,
+ th,
+ td,
+ article,
+ aside,
+ canvas,
+ details,
+ embed,
+ figure,
+ figcaption,
+ footer,
+ header,
+ hgroup,
+ menu,
+ nav,
+ output,
+ ruby,
+ section,
+ summary,
+ time,
+ mark,
+ audio,
+ video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ vertical-align: baseline;
+ }
+
+ article,
+ aside,
+ details,
+ figcaption,
+ figure,
+ footer,
+ header,
+ hgroup,
+ menu,
+ nav,
+ section {
+ display: block;
+ }
+
+ body {
+ line-height: 147%;
+ }
+
+ ol,
+ ul {
+ list-style: none;
+ }
+
+ blockquote,
+ q {
+ quotes: none;
+ }
+
+ blockquote:before,
+ blockquote:after,
+ q:before,
+ q:after {
+ content: '';
+ content: none;
+ }
+
+ table {
+ border-collapse: collapse;
+ border-spacing: 0;
+ }
+
+ button {
+ border: none;
+ background: none;
+ cursor: pointer;
+ }
+
+ a {
+ text-decoration: none;
+ cursor: pointer;
+ }
+`;
diff --git a/packages/status-react/src/styles/themes.ts b/packages/status-react/src/styles/themes.ts
new file mode 100644
index 00000000..98234da1
--- /dev/null
+++ b/packages/status-react/src/styles/themes.ts
@@ -0,0 +1,107 @@
+export type Theme = {
+ primary: string;
+ secondary: string;
+ tertiary: string;
+ bodyBackgroundColor: string;
+ sectionBackgroundColor: string;
+ bodyBackgroundGradient: string;
+ guestNameColor: string;
+ iconColor: string;
+ iconUserColor: string;
+ iconTextColor: string;
+ logoColor: string;
+ activeChannelBackground: string;
+ notificationColor: string;
+ inputColor: string;
+ border: string;
+ buttonBg: string;
+ buttonBgHover: string;
+ buttonNoBg: string;
+ buttonNoBgHover: string;
+ skeletonLight: string;
+ skeletonDark: string;
+ redColor: string;
+ greenColor: string;
+ greenBg: string;
+ mentionColor: string;
+ mentionHover: string;
+ mentionBg: string;
+ mentionBgHover: string;
+ shadow: string;
+ reactionBg: string;
+ blueBg: string;
+};
+
+export const lightTheme: Theme = {
+ primary: "#000",
+ secondary: "#939BA1",
+ tertiary: "#4360DF",
+ bodyBackgroundColor: "#fff",
+ sectionBackgroundColor: "#F6F8FA",
+ bodyBackgroundGradient:
+ "linear-gradient(0deg, #FFFFFF 50%, rgba(255, 255, 255, 0) 102.57%)",
+ guestNameColor: "#887AF9",
+ iconColor: "#D37EF4",
+ iconUserColor: "#717199",
+ iconTextColor: "rgba(255, 255, 255, 0.7)",
+ logoColor: "#51D0F0",
+ activeChannelBackground: "#E9EDF1",
+ notificationColor: "#4360DF",
+ inputColor: "#EEF2F5",
+ border: "#EEF2F5",
+ buttonBg: "rgba(67, 96, 223, 0.1)",
+ buttonBgHover: "rgba(67, 96, 223, 0.2)",
+ buttonNoBg: "rgba(255, 45, 85, 0.1)",
+ buttonNoBgHover: "rgba(255, 45, 85, 0.2)",
+ skeletonLight: "#F6F8FA",
+ skeletonDark: "#E9EDF1",
+ redColor: "#FF2D55",
+ greenColor: "#4EBC60",
+ greenBg: "rgba(78, 188, 96, 0.1)",
+ mentionColor: "#0DA4C9",
+ mentionHover: "#BDE7F2",
+ mentionBg: "#E5F8FD",
+ mentionBgHover: "#D4F3FA",
+ shadow:
+ "0px 2px 4px rgba(0, 34, 51, 0.16), 0px 4px 12px rgba(0, 34, 51, 0.08)",
+ reactionBg: "#eceffc",
+ blueBg: "rgba(67, 96, 223, 0.1)",
+};
+
+export const darkTheme: Theme = {
+ primary: "#fff",
+ secondary: "#909090",
+ tertiary: "#88B0FF",
+ bodyBackgroundColor: "#000",
+ sectionBackgroundColor: "#252525",
+ bodyBackgroundGradient:
+ "linear-gradient(0deg, #000 50%, rgba(255, 255, 255, 0) 102.57%)",
+ guestNameColor: "#887AF9",
+ iconColor: "#D37EF4",
+ iconUserColor: "#717199",
+ logoColor: "#51D0F0",
+ iconTextColor: "rgba(0, 0, 0, 0.7)",
+ activeChannelBackground: "#2C2C2C",
+ notificationColor: "#887AF9",
+ inputColor: "#373737",
+ border: "#373737",
+ buttonBg: "rgba(134, 158, 255, 0.2)",
+ buttonBgHover: "rgba(67, 96, 223, 0.3)",
+ buttonNoBg: "rgba(255, 92, 123, 0.2)",
+ buttonNoBgHover: "rgba(255, 45, 85, 0.3)",
+ skeletonLight: "#2E2F31",
+ skeletonDark: "#141414",
+ redColor: "#FF5C7B",
+ greenColor: "#60C370",
+ greenBg: "rgba(96, 195, 112, 0.2)",
+ mentionColor: "#51D0F0",
+ mentionHover: "#004E60",
+ mentionBg: "#004050",
+ mentionBgHover: "#002D39",
+ shadow:
+ "0px 2px 4px rgba(0, 34, 51, 0.16), 0px 4px 12px rgba(0, 34, 51, 0.08)",
+ reactionBg: "#373737",
+ blueBg: "rgba(134, 158, 255, 0.3)",
+};
+
+export default { lightTheme, darkTheme };
diff --git a/packages/status-react/src/utils/binarySetInsert.ts b/packages/status-react/src/utils/binarySetInsert.ts
new file mode 100644
index 00000000..de163844
--- /dev/null
+++ b/packages/status-react/src/utils/binarySetInsert.ts
@@ -0,0 +1,21 @@
+export function binarySetInsert(
+ arr: T[],
+ val: T,
+ compFunc: (a: T, b: T) => boolean,
+ eqFunc: (a: T, b: T) => boolean
+) {
+ let low = 0;
+ let high = arr.length;
+ while (low < high) {
+ const mid = (low + high) >> 1;
+ if (compFunc(arr[mid], val)) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
+ }
+ if (arr.length === low || !eqFunc(arr[low], val)) {
+ arr.splice(low, 0, val);
+ }
+ return arr;
+}
diff --git a/packages/status-react/src/utils/copy.ts b/packages/status-react/src/utils/copy.ts
new file mode 100644
index 00000000..6a9ccc48
--- /dev/null
+++ b/packages/status-react/src/utils/copy.ts
@@ -0,0 +1,5 @@
+export const copy = (text: string) => {
+ navigator.clipboard.writeText(text).catch((error) => {
+ console.log(error);
+ });
+};
diff --git a/packages/status-react/src/utils/copyImg.ts b/packages/status-react/src/utils/copyImg.ts
new file mode 100644
index 00000000..89d66009
--- /dev/null
+++ b/packages/status-react/src/utils/copyImg.ts
@@ -0,0 +1,18 @@
+const copyToClipboard = async (pngBlob: any) => {
+ try {
+ await navigator.clipboard.write([
+ new ClipboardItem({
+ [pngBlob.type]: pngBlob,
+ }),
+ ]);
+ } catch (error) {
+ console.error(error);
+ }
+};
+
+//Images are already converted to png by useMessenger when received
+export const copyImg = async (image: string) => {
+ const img = await fetch(image);
+ const imgBlob = await img.blob();
+ return copyToClipboard(imgBlob);
+};
diff --git a/packages/status-react/src/utils/createCommunity.ts b/packages/status-react/src/utils/createCommunity.ts
new file mode 100644
index 00000000..b6adfac6
--- /dev/null
+++ b/packages/status-react/src/utils/createCommunity.ts
@@ -0,0 +1,22 @@
+import { Community, Messenger, ApplicationMetadataMessage } from "@status-im/core";
+
+export async function createCommunity(
+ communityKey: string,
+ addMessage: (msg: ApplicationMetadataMessage, id: string, date: Date) => void,
+ messenger: Messenger
+) {
+ const community = await Community.instantiateCommunity(
+ communityKey,
+ messenger.waku
+ );
+ await Promise.all(
+ Array.from(community.chats.values()).map(async chat => {
+ await messenger.joinChat(chat);
+ messenger.addObserver(
+ (msg, date) => addMessage(msg, chat.id, date),
+ chat.id
+ );
+ })
+ );
+ return community;
+}
diff --git a/packages/status-react/src/utils/createMessenger.ts b/packages/status-react/src/utils/createMessenger.ts
new file mode 100644
index 00000000..303b500c
--- /dev/null
+++ b/packages/status-react/src/utils/createMessenger.ts
@@ -0,0 +1,38 @@
+import { Identity, Messenger } from "@status-im/core";
+import { getNodesFromHostedJson } from "js-waku";
+import { Protocols } from "js-waku/build/main/lib/waku";
+
+function createWakuOptions(env: string) {
+ let bootstrap: any = { default: true };
+ if (env === "test") {
+ bootstrap = {
+ getPeers: getNodesFromHostedJson.bind({}, [
+ "fleets",
+ "wakuv2.test",
+ "waku-websocket",
+ ]),
+ };
+ }
+ return {
+ bootstrap,
+ libp2p: {
+ config: {
+ pubsub: {
+ enabled: true,
+ emitSelf: true,
+ },
+ },
+ },
+ };
+}
+
+export async function createMessenger(
+ identity: Identity | undefined,
+ env: string
+) {
+ const WAKU_OPTIONS = createWakuOptions(env);
+ const messenger = await Messenger.create(identity, WAKU_OPTIONS);
+ await messenger.waku.waitForRemotePeer([Protocols.Store]);
+
+ return messenger;
+}
diff --git a/packages/status-react/src/utils/downloadImg.ts b/packages/status-react/src/utils/downloadImg.ts
new file mode 100644
index 00000000..9b23f9f7
--- /dev/null
+++ b/packages/status-react/src/utils/downloadImg.ts
@@ -0,0 +1,10 @@
+export const downloadImg = async (image: string) => {
+ try {
+ const a = document.createElement("a");
+ a.download = `${image.split("/").pop()}.png`;
+ a.href = image;
+ a.click();
+ } catch {
+ return;
+ }
+};
diff --git a/packages/status-react/src/utils/equalDate.ts b/packages/status-react/src/utils/equalDate.ts
new file mode 100644
index 00000000..02ac9824
--- /dev/null
+++ b/packages/status-react/src/utils/equalDate.ts
@@ -0,0 +1,7 @@
+export function equalDate(a: Date, b: Date) {
+ return (
+ a.getDate() === b.getDate() &&
+ a.getMonth() === b.getMonth() &&
+ a.getFullYear() === b.getFullYear()
+ );
+}
diff --git a/packages/status-react/src/utils/identityStorage.ts b/packages/status-react/src/utils/identityStorage.ts
new file mode 100644
index 00000000..b0490a45
--- /dev/null
+++ b/packages/status-react/src/utils/identityStorage.ts
@@ -0,0 +1,79 @@
+import { Identity, bufToHex, hexToBuf } from "@status-im/core";
+
+export async function saveIdentity(identity: Identity, password: string) {
+ const salt = window.crypto.getRandomValues(new Uint8Array(16));
+ const wrapKey = await getWrapKey(password, salt);
+
+ const iv = window.crypto.getRandomValues(new Uint8Array(12));
+ const cipher = await window.crypto.subtle.encrypt(
+ {
+ name: "AES-GCM",
+ iv: iv,
+ },
+ wrapKey,
+ identity.privateKey
+ );
+
+ const data = {
+ salt: bufToHex(salt),
+ iv: bufToHex(iv),
+ cipher: bufToHex(cipher),
+ };
+
+ localStorage.setItem("cipherIdentity", JSON.stringify(data));
+}
+
+export function loadEncryptedIdentity(): string | null {
+ return localStorage.getItem("cipherIdentity");
+}
+
+async function getWrapKey(password: string, salt: Uint8Array) {
+ const enc = new TextEncoder();
+ const keyMaterial = await window.crypto.subtle.importKey(
+ "raw",
+ enc.encode(password),
+ { name: "PBKDF2" },
+ false,
+ ["deriveBits", "deriveKey"]
+ );
+ return await window.crypto.subtle.deriveKey(
+ {
+ name: "PBKDF2",
+ salt,
+ iterations: 100000,
+ hash: "SHA-256",
+ },
+ keyMaterial,
+ { name: "AES-GCM", length: 256 },
+ true,
+ ["encrypt", "decrypt"]
+ );
+}
+
+export async function decryptIdentity(
+ encryptedIdentity: string,
+ password: string
+): Promise {
+ const data = JSON.parse(encryptedIdentity);
+
+ const salt = hexToBuf(data.salt);
+ const iv = hexToBuf(data.iv);
+ const cipherKeyPair = hexToBuf(data.cipher);
+
+ const key = await getWrapKey(password, salt);
+
+ try {
+ const decrypted = await window.crypto.subtle.decrypt(
+ {
+ name: "AES-GCM",
+ iv: iv,
+ },
+ key,
+ cipherKeyPair
+ );
+
+ return new Identity(new Uint8Array(decrypted));
+ } catch (e) {
+ return;
+ }
+}
diff --git a/packages/status-react/src/utils/index.ts b/packages/status-react/src/utils/index.ts
new file mode 100644
index 00000000..9b50e9aa
--- /dev/null
+++ b/packages/status-react/src/utils/index.ts
@@ -0,0 +1,12 @@
+export { binarySetInsert } from "./binarySetInsert";
+export { copy } from "./copy";
+export { copyImg } from "./copyImg";
+export { downloadImg } from "./downloadImg";
+export {
+ saveIdentity,
+ loadEncryptedIdentity,
+ decryptIdentity,
+} from "./identityStorage";
+export { reduceString } from "./reduceString";
+export { uintToImgUrl } from "./uintToImgUrl";
+export { equalDate } from "./equalDate";
diff --git a/packages/status-react/src/utils/paste.ts b/packages/status-react/src/utils/paste.ts
new file mode 100644
index 00000000..ba171a10
--- /dev/null
+++ b/packages/status-react/src/utils/paste.ts
@@ -0,0 +1,9 @@
+export const paste = (elementId: string) => {
+ navigator.clipboard
+ .readText()
+ .then(
+ (clipText) =>
+ ((document.getElementById(elementId)).value =
+ clipText)
+ );
+};
diff --git a/packages/status-react/src/utils/reduceString.ts b/packages/status-react/src/utils/reduceString.ts
new file mode 100644
index 00000000..595eba49
--- /dev/null
+++ b/packages/status-react/src/utils/reduceString.ts
@@ -0,0 +1,9 @@
+export const reduceString = (
+ string: string,
+ limitBefore: number,
+ limitAfter: number
+) => {
+ return `${string.substring(0, limitBefore)}...${string.substring(
+ string.length - limitAfter
+ )}`;
+};
diff --git a/packages/status-react/src/utils/uintToImgUrl.ts b/packages/status-react/src/utils/uintToImgUrl.ts
new file mode 100644
index 00000000..d1774aee
--- /dev/null
+++ b/packages/status-react/src/utils/uintToImgUrl.ts
@@ -0,0 +1,4 @@
+export function uintToImgUrl(img: Uint8Array) {
+ const blob = new Blob([img], { type: "image/png" });
+ return URL.createObjectURL(blob);
+}
diff --git a/packages/status-react/tsconfig.json b/packages/status-react/tsconfig.json
new file mode 100644
index 00000000..416708b4
--- /dev/null
+++ b/packages/status-react/tsconfig.json
@@ -0,0 +1,48 @@
+{
+ "compilerOptions": {
+ "target": "es6",
+ "jsx": "react",
+ "outDir": "dist",
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "declaration": true,
+ "sourceMap": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "composite": true,
+ "strict": true /* Enable all strict type-checking options. */,
+
+ /* Strict Type-Checking Options */
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "strictPropertyInitialization": true,
+ "noImplicitThis": true,
+ "alwaysStrict": true,
+
+ /* Additional Checks */
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": false /* to set at a later stage */,
+ "noFallthroughCasesInSwitch": true,
+ "forceConsistentCasingInFileNames": true,
+
+ /* Debugging Options */
+ "traceResolution": false,
+ "listEmittedFiles": false,
+ "listFiles": false,
+ "pretty": true,
+
+ // Due to broken types in indirect dependencies
+ "skipLibCheck": true,
+ "typeRoots": [
+ "./node_modules/@types",
+ "./src/types",
+ "../../node_modules/@types"
+ ]
+ },
+ "include": ["src"],
+ "exclude": ["node_modules/**"],
+ "types": ["mocha"],
+ "compileOnSave": false
+}
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 00000000..c0f1b516
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,9025 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/code-frame@7.12.11":
+ version "7.12.11"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
+ integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
+ dependencies:
+ "@babel/highlight" "^7.10.4"
+
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
+ integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
+ dependencies:
+ "@babel/highlight" "^7.16.7"
+
+"@babel/generator@^7.17.3":
+ version "7.17.3"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200"
+ integrity sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==
+ dependencies:
+ "@babel/types" "^7.17.0"
+ jsesc "^2.5.1"
+ source-map "^0.5.0"
+
+"@babel/helper-annotate-as-pure@^7.16.0":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862"
+ integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-environment-visitor@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7"
+ integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-function-name@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f"
+ integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==
+ dependencies:
+ "@babel/helper-get-function-arity" "^7.16.7"
+ "@babel/template" "^7.16.7"
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-get-function-arity@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419"
+ integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-hoist-variables@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246"
+ integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
+ integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-split-export-declaration@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b"
+ integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-validator-identifier@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
+ integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
+
+"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7":
+ version "7.16.10"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88"
+ integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.16.7"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
+"@babel/parser@^7.16.7", "@babel/parser@^7.17.3":
+ version "7.17.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0"
+ integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==
+
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5":
+ version "7.17.2"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
+ integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
+"@babel/template@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
+ integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
+ dependencies:
+ "@babel/code-frame" "^7.16.7"
+ "@babel/parser" "^7.16.7"
+ "@babel/types" "^7.16.7"
+
+"@babel/traverse@^7.4.5":
+ version "7.17.3"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57"
+ integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==
+ dependencies:
+ "@babel/code-frame" "^7.16.7"
+ "@babel/generator" "^7.17.3"
+ "@babel/helper-environment-visitor" "^7.16.7"
+ "@babel/helper-function-name" "^7.16.7"
+ "@babel/helper-hoist-variables" "^7.16.7"
+ "@babel/helper-split-export-declaration" "^7.16.7"
+ "@babel/parser" "^7.17.3"
+ "@babel/types" "^7.17.0"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
+"@babel/types@^7.16.7", "@babel/types@^7.17.0":
+ version "7.17.0"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b"
+ integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.16.7"
+ to-fast-properties "^2.0.0"
+
+"@chainsafe/libp2p-noise@^5.0.0":
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-noise/-/libp2p-noise-5.0.2.tgz#1fe7ae2cf453a9fbb2bd982b6941d6f866ed025f"
+ integrity sha512-hpxHl3bxHN2fgpmjP2zkC2Lq3ajA349WxI7U2aBuskkq3Pd+aUmSlVjM8pyN+5Dr5+yHuayqCgMUxq3AeOM7Zw==
+ dependencies:
+ "@stablelib/chacha20poly1305" "^1.0.1"
+ "@stablelib/hkdf" "^1.0.1"
+ "@stablelib/sha256" "^1.0.1"
+ "@stablelib/x25519" "^1.0.1"
+ bl "^5.0.0"
+ debug "^4.3.1"
+ it-buffer "^0.1.3"
+ it-length-prefixed "^5.0.3"
+ it-pair "^1.0.0"
+ it-pb-rpc "^0.2.0"
+ it-pipe "^1.1.0"
+ peer-id "^0.16.0"
+ protobufjs "^6.11.2"
+ uint8arrays "^3.0.0"
+
+"@cspotcode/source-map-consumer@0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
+ integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
+
+"@cspotcode/source-map-support@0.7.0":
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
+ integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
+ dependencies:
+ "@cspotcode/source-map-consumer" "0.8.0"
+
+"@discoveryjs/json-ext@^0.5.0":
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
+ integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==
+
+"@emotion/is-prop-valid@^0.8.8":
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
+ integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
+ dependencies:
+ "@emotion/memoize" "0.7.4"
+
+"@emotion/memoize@0.7.4":
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
+ integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
+
+"@emotion/stylis@^0.8.4":
+ version "0.8.5"
+ resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
+ integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
+
+"@emotion/unitless@^0.7.4":
+ version "0.7.5"
+ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
+ integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
+
+"@eslint/eslintrc@^0.4.3":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
+ integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
+ dependencies:
+ ajv "^6.12.4"
+ debug "^4.1.1"
+ espree "^7.3.0"
+ globals "^13.9.0"
+ ignore "^4.0.6"
+ import-fresh "^3.2.1"
+ js-yaml "^3.13.1"
+ minimatch "^3.0.4"
+ strip-json-comments "^3.1.1"
+
+"@hcaptcha/react-hcaptcha@^1.0.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.1.0.tgz#ca770c9fc1f456e3c6b057bedf01a94693b2ec96"
+ integrity sha512-+0JYxSFkZaHMOJ91YD9PUNiCUZhG5d9BzVAIye4vAWMyXzfD4b8Dx7EwAVUf1qfbf8KVCa33QwoTRt6EKfDDSA==
+
+"@humanwhocodes/config-array@^0.5.0":
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
+ integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.0"
+ debug "^4.1.1"
+ minimatch "^3.0.4"
+
+"@humanwhocodes/object-schema@^1.2.0":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
+ integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+
+"@jest/types@^24.9.0":
+ version "24.9.0"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
+ integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^1.1.1"
+ "@types/yargs" "^13.0.0"
+
+"@leichtgewicht/ip-codec@^2.0.1", "@leichtgewicht/ip-codec@^2.0.2":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0"
+ integrity sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==
+
+"@motrix/nat-api@^0.3.1":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/@motrix/nat-api/-/nat-api-0.3.2.tgz#a1164e25b1401279e2170666b0df3455812e7e1e"
+ integrity sha512-T3LSHnEUULbSU1o1zCZZ1ul8l8Jm98f0fz/0BeF7DhNvrV63YllLCD4vUR9hFZWu/+WTIVPnbH8dBK5Ckuveuw==
+ dependencies:
+ async "^3.2.0"
+ debug "^4.3.1"
+ default-gateway "^6.0.3"
+ request "^2.88.2"
+ unordered-array-remove "^1.0.2"
+ xml2js "^0.4.23"
+
+"@multiformats/base-x@^4.0.1":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@multiformats/base-x/-/base-x-4.0.1.tgz#95ff0fa58711789d53aefb2590a8b7a4e715d121"
+ integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==
+
+"@noble/ed25519@^1.5.1":
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.6.0.tgz#b55f7c9e532b478bf1d7c4f609e1f3a37850b583"
+ integrity sha512-UKju89WV37IUALIMfKhKW3psO8AqmrE/GvH6QbPKjzolQ98zM7WmGUeY+xdIgSf5tqPFf75ZCYMgym6E9Jsw3Q==
+
+"@noble/secp256k1@^1.3.0":
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.5.5.tgz#315ab5745509d1a8c8e90d0bdf59823ccf9bcfc3"
+ integrity sha512-sZ1W6gQzYnu45wPrWx8D3kwI2/U29VYTx9OjbDAd7jwRItJ0cSTMPRL/C8AWZFn9kWFLQGqEXVEE86w4Z8LpIQ==
+
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
+ dependencies:
+ "@nodelib/fs.stat" "2.0.5"
+ run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
+
+"@nodelib/fs.walk@^1.2.3":
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
+ dependencies:
+ "@nodelib/fs.scandir" "2.1.5"
+ fastq "^1.6.0"
+
+"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
+ integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
+
+"@protobufjs/base64@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
+ integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
+
+"@protobufjs/codegen@^2.0.4":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
+ integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
+
+"@protobufjs/eventemitter@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
+ integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
+
+"@protobufjs/fetch@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
+ integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
+ dependencies:
+ "@protobufjs/aspromise" "^1.1.1"
+ "@protobufjs/inquire" "^1.1.0"
+
+"@protobufjs/float@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
+ integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
+
+"@protobufjs/inquire@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
+ integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
+
+"@protobufjs/path@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
+ integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
+
+"@protobufjs/pool@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
+ integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
+
+"@protobufjs/utf8@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
+ integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
+
+"@sindresorhus/is@^0.14.0":
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
+ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
+
+"@stablelib/aead@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3"
+ integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==
+
+"@stablelib/binary@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f"
+ integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==
+ dependencies:
+ "@stablelib/int" "^1.0.1"
+
+"@stablelib/bytes@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8"
+ integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==
+
+"@stablelib/chacha20poly1305@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee"
+ integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA==
+ dependencies:
+ "@stablelib/aead" "^1.0.1"
+ "@stablelib/binary" "^1.0.1"
+ "@stablelib/chacha" "^1.0.1"
+ "@stablelib/constant-time" "^1.0.1"
+ "@stablelib/poly1305" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/chacha@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371"
+ integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg==
+ dependencies:
+ "@stablelib/binary" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/constant-time@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35"
+ integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==
+
+"@stablelib/hash@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5"
+ integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==
+
+"@stablelib/hkdf@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d"
+ integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g==
+ dependencies:
+ "@stablelib/hash" "^1.0.1"
+ "@stablelib/hmac" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/hmac@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec"
+ integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA==
+ dependencies:
+ "@stablelib/constant-time" "^1.0.1"
+ "@stablelib/hash" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/int@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008"
+ integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==
+
+"@stablelib/keyagreement@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f"
+ integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==
+ dependencies:
+ "@stablelib/bytes" "^1.0.1"
+
+"@stablelib/poly1305@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc"
+ integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==
+ dependencies:
+ "@stablelib/constant-time" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/random@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.1.tgz#4357a00cb1249d484a9a71e6054bc7b8324a7009"
+ integrity sha512-zOh+JHX3XG9MSfIB0LZl/YwPP9w3o6WBiJkZvjPoKKu5LKFW4OLV71vMxWp9qG5T43NaWyn0QQTWgqCdO+yOBQ==
+ dependencies:
+ "@stablelib/binary" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/sha256@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f"
+ integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ==
+ dependencies:
+ "@stablelib/binary" "^1.0.1"
+ "@stablelib/hash" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@stablelib/wipe@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36"
+ integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==
+
+"@stablelib/x25519@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.1.tgz#bcd6132ac4dd94f28f1479e228c85b3468d6ed27"
+ integrity sha512-nmyUI2ZArxYDh1PhdoSCPEtlTYE0DYugp2qqx8OtjrX3Hmh7boIlDsD0X71ihAxzxqJf3TyQqN/p58ToWhnp+Q==
+ dependencies:
+ "@stablelib/keyagreement" "^1.0.1"
+ "@stablelib/random" "^1.0.1"
+ "@stablelib/wipe" "^1.0.1"
+
+"@szmarczak/http-timer@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
+ integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
+ dependencies:
+ defer-to-connect "^1.0.1"
+
+"@testing-library/react-hooks@^7.0.1":
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0"
+ integrity sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+ "@types/react" ">=16.9.0"
+ "@types/react-dom" ">=16.9.0"
+ "@types/react-test-renderer" ">=16.9.0"
+ react-error-boundary "^3.1.0"
+
+"@tootallnate/once@1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
+ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
+
+"@tsconfig/node10@^1.0.7":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
+ integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==
+
+"@tsconfig/node12@^1.0.7":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c"
+ integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==
+
+"@tsconfig/node14@^1.0.0":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2"
+ integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==
+
+"@tsconfig/node16@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
+ integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
+
+"@types/bn.js@*", "@types/bn.js@^5.1.0":
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68"
+ integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==
+ dependencies:
+ "@types/node" "*"
+
+"@types/chai@^4.2.21", "@types/chai@^4.2.22":
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.0.tgz#23509ebc1fa32f1b4d50d6a66c4032d5b8eaabdc"
+ integrity sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==
+
+"@types/debug@^4.1.5":
+ version "4.1.7"
+ resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
+ integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==
+ dependencies:
+ "@types/ms" "*"
+
+"@types/dns-packet@^5.2.0":
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/@types/dns-packet/-/dns-packet-5.2.4.tgz#0de4ee48f900a62b014ce61a3c9ab5d33dc06b0d"
+ integrity sha512-OAruArypdNxR/tzbmrtoyEuXeNTLaZCpO19BXaNC10T5ACIbvjmvhmV2RDEy2eLc3w8IjK7SY3cvUCcAW+sfoQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/elliptic@^6.4.14":
+ version "6.4.14"
+ resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.14.tgz#7bbaad60567a588c1f08b10893453e6b9b4de48e"
+ integrity sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ==
+ dependencies:
+ "@types/bn.js" "*"
+
+"@types/emoji-mart@^3.0.6":
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/@types/emoji-mart/-/emoji-mart-3.0.9.tgz#2f7ef5d9ec194f28029c46c81a5fc1e5b0efa73c"
+ integrity sha512-qdBo/2Y8MXaJ/2spKjDZocuq79GpnOhkwMHnK2GnVFa8WYFgfA+ei6sil3aeWQPCreOKIx9ogPpR5+7MaOqYAA==
+ dependencies:
+ "@types/react" "*"
+
+"@types/eslint-scope@^3.7.3":
+ version "3.7.3"
+ resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224"
+ integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==
+ dependencies:
+ "@types/eslint" "*"
+ "@types/estree" "*"
+
+"@types/eslint@*":
+ version "8.4.1"
+ resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304"
+ integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==
+ dependencies:
+ "@types/estree" "*"
+ "@types/json-schema" "*"
+
+"@types/estree@*", "@types/estree@^0.0.51":
+ version "0.0.51"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
+ integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
+
+"@types/glob@^7.1.1":
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
+ integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
+ dependencies:
+ "@types/minimatch" "*"
+ "@types/node" "*"
+
+"@types/hcaptcha__react-hcaptcha@^0.1.5":
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/@types/hcaptcha__react-hcaptcha/-/hcaptcha__react-hcaptcha-0.1.5.tgz#c531629fb7b017b255b2255718561a7ae5eb1d4c"
+ integrity sha512-HWSerODPnawycJmDj1Moveu4Q6oWj+fWMOhlEMUQeUHOH+Fn7RF2k1WU0Odksweg0FPR4Q1gjD7iwmgymr1N5w==
+ dependencies:
+ "@types/react" "*"
+
+"@types/history@^4.7.11":
+ version "4.7.11"
+ resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
+ integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
+
+"@types/hoist-non-react-statics@*":
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
+ integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
+ dependencies:
+ "@types/react" "*"
+ hoist-non-react-statics "^3.3.0"
+
+"@types/html-minifier-terser@^6.0.0":
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
+ integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==
+
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44"
+ integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==
+
+"@types/istanbul-lib-report@*":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
+ integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
+ dependencies:
+ "@types/istanbul-lib-coverage" "*"
+
+"@types/istanbul-reports@^1.1.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2"
+ integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==
+ dependencies:
+ "@types/istanbul-lib-coverage" "*"
+ "@types/istanbul-lib-report" "*"
+
+"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8":
+ version "7.0.9"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
+ integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
+
+"@types/json5@^0.0.29":
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
+ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+
+"@types/long@^4.0.1":
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
+ integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
+
+"@types/minimatch@*", "@types/minimatch@^3.0.4":
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
+ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
+
+"@types/mocha@^9.0.0":
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.0.tgz#baf17ab2cca3fcce2d322ebc30454bff487efad5"
+ integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==
+
+"@types/ms@*":
+ version "0.7.31"
+ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
+ integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
+
+"@types/node@*", "@types/node@>=13.7.0":
+ version "17.0.19"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.19.tgz#726171367f404bfbe8512ba608a09ebad810c7e6"
+ integrity sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==
+
+"@types/node@^16.4.12", "@types/node@^16.9.6":
+ version "16.11.25"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.25.tgz#bb812b58bacbd060ce85921250d8b4ca553cd4a2"
+ integrity sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==
+
+"@types/object-hash@^1.3.0":
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/@types/object-hash/-/object-hash-1.3.4.tgz#079ba142be65833293673254831b5e3e847fe58b"
+ integrity sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==
+
+"@types/parse-json@^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
+ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
+
+"@types/pbkdf2@^3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1"
+ integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/prop-types@*":
+ version "15.7.4"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
+ integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
+
+"@types/qrcode.react@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.2.tgz#f892432cc41b5dac52e3ca8873b717c8bfea6002"
+ integrity sha512-I9Oq5Cjlkgy3Tw7krCnCXLw2/zMhizkTere49OOcta23tkvH0xBTP0yInimTh0gstLRtb8Ki9NZVujE5UI6ffQ==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react-dom@>=16.9.0", "@types/react-dom@^17.0.9":
+ version "17.0.11"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.11.tgz#e1eadc3c5e86bdb5f7684e00274ae228e7bcc466"
+ integrity sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react-router-dom@^5.1.8":
+ version "5.3.3"
+ resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
+ integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==
+ dependencies:
+ "@types/history" "^4.7.11"
+ "@types/react" "*"
+ "@types/react-router" "*"
+
+"@types/react-router@*", "@types/react-router@^5.1.16":
+ version "5.1.18"
+ resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.18.tgz#c8851884b60bc23733500d86c1266e1cfbbd9ef3"
+ integrity sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g==
+ dependencies:
+ "@types/history" "^4.7.11"
+ "@types/react" "*"
+
+"@types/react-test-renderer@>=16.9.0":
+ version "17.0.1"
+ resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b"
+ integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*", "@types/react@>=16.9.0", "@types/react@^17.0.15", "@types/react@^17.0.16":
+ version "17.0.39"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce"
+ integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/retry@^0.12.0":
+ version "0.12.1"
+ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065"
+ integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==
+
+"@types/scheduler@*":
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
+ integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
+
+"@types/secp256k1@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c"
+ integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==
+ dependencies:
+ "@types/node" "*"
+
+"@types/styled-components@^5.1.12":
+ version "5.1.23"
+ resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.23.tgz#11e5740047f292b42a042c60c0ef16b58d5adef6"
+ integrity sha512-zt8oQGU6XB4LH1Xpq169YnAVmt22+swzHJvyKMyTZu/z8+afvgKjjg0s79aAodgNSf36ZOEG6DyVAW/JhLH2Nw==
+ dependencies:
+ "@types/hoist-non-react-statics" "*"
+ "@types/react" "*"
+ csstype "^3.0.2"
+
+"@types/uuid@^8.3.3":
+ version "8.3.4"
+ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc"
+ integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==
+
+"@types/yargs-parser@*":
+ version "20.2.1"
+ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
+ integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==
+
+"@types/yargs@^13.0.0":
+ version "13.0.12"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.12.tgz#d895a88c703b78af0465a9de88aa92c61430b092"
+ integrity sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==
+ dependencies:
+ "@types/yargs-parser" "*"
+
+"@typescript-eslint/eslint-plugin@^4.29.0", "@typescript-eslint/eslint-plugin@^4.31.1":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276"
+ integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==
+ dependencies:
+ "@typescript-eslint/experimental-utils" "4.33.0"
+ "@typescript-eslint/scope-manager" "4.33.0"
+ debug "^4.3.1"
+ functional-red-black-tree "^1.0.1"
+ ignore "^5.1.8"
+ regexpp "^3.1.0"
+ semver "^7.3.5"
+ tsutils "^3.21.0"
+
+"@typescript-eslint/experimental-utils@4.33.0", "@typescript-eslint/experimental-utils@^4.9.1":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd"
+ integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==
+ dependencies:
+ "@types/json-schema" "^7.0.7"
+ "@typescript-eslint/scope-manager" "4.33.0"
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/typescript-estree" "4.33.0"
+ eslint-scope "^5.1.1"
+ eslint-utils "^3.0.0"
+
+"@typescript-eslint/parser@^4.29.0", "@typescript-eslint/parser@^4.31.1":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899"
+ integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==
+ dependencies:
+ "@typescript-eslint/scope-manager" "4.33.0"
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/typescript-estree" "4.33.0"
+ debug "^4.3.1"
+
+"@typescript-eslint/scope-manager@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3"
+ integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==
+ dependencies:
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/visitor-keys" "4.33.0"
+
+"@typescript-eslint/types@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72"
+ integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==
+
+"@typescript-eslint/typescript-estree@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609"
+ integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==
+ dependencies:
+ "@typescript-eslint/types" "4.33.0"
+ "@typescript-eslint/visitor-keys" "4.33.0"
+ debug "^4.3.1"
+ globby "^11.0.3"
+ is-glob "^4.0.1"
+ semver "^7.3.5"
+ tsutils "^3.21.0"
+
+"@typescript-eslint/visitor-keys@4.33.0":
+ version "4.33.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd"
+ integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==
+ dependencies:
+ "@typescript-eslint/types" "4.33.0"
+ eslint-visitor-keys "^2.0.0"
+
+"@ungap/promise-all-settled@1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
+ integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
+
+"@vascosantos/moving-average@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@vascosantos/moving-average/-/moving-average-1.1.0.tgz#8d5793b09b2d6021ba5e620c6a0f876c20db7eaa"
+ integrity sha512-MVEJ4vWAPNbrGLjz7ITnHYg+YXZ6ijAqtH5/cHwSoCpbvuJ98aLXwFfPKAUfZpJMQR5uXB58UJajbY130IRF/w==
+
+"@webassemblyjs/ast@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
+ integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==
+ dependencies:
+ "@webassemblyjs/helper-numbers" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+
+"@webassemblyjs/floating-point-hex-parser@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f"
+ integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==
+
+"@webassemblyjs/helper-api-error@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16"
+ integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==
+
+"@webassemblyjs/helper-buffer@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5"
+ integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==
+
+"@webassemblyjs/helper-numbers@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae"
+ integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==
+ dependencies:
+ "@webassemblyjs/floating-point-hex-parser" "1.11.1"
+ "@webassemblyjs/helper-api-error" "1.11.1"
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/helper-wasm-bytecode@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1"
+ integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==
+
+"@webassemblyjs/helper-wasm-section@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a"
+ integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+
+"@webassemblyjs/ieee754@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614"
+ integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==
+ dependencies:
+ "@xtuc/ieee754" "^1.2.0"
+
+"@webassemblyjs/leb128@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5"
+ integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==
+ dependencies:
+ "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/utf8@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff"
+ integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==
+
+"@webassemblyjs/wasm-edit@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6"
+ integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/helper-wasm-section" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+ "@webassemblyjs/wasm-opt" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+ "@webassemblyjs/wast-printer" "1.11.1"
+
+"@webassemblyjs/wasm-gen@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76"
+ integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/ieee754" "1.11.1"
+ "@webassemblyjs/leb128" "1.11.1"
+ "@webassemblyjs/utf8" "1.11.1"
+
+"@webassemblyjs/wasm-opt@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2"
+ integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+
+"@webassemblyjs/wasm-parser@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199"
+ integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-api-error" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/ieee754" "1.11.1"
+ "@webassemblyjs/leb128" "1.11.1"
+ "@webassemblyjs/utf8" "1.11.1"
+
+"@webassemblyjs/wast-printer@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0"
+ integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@xtuc/long" "4.2.2"
+
+"@webpack-cli/configtest@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356"
+ integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==
+
+"@webpack-cli/info@^1.4.1":
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea"
+ integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==
+ dependencies:
+ envinfo "^7.7.3"
+
+"@webpack-cli/serve@^1.6.1":
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe"
+ integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==
+
+"@xtuc/ieee754@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
+ integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
+
+"@xtuc/long@4.2.2":
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
+ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
+
+abab@^2.0.3, abab@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
+ integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==
+
+abbrev@1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
+ integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
+
+abort-controller@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
+ integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
+ dependencies:
+ event-target-shim "^5.0.0"
+
+abortable-iterator@^3.0.0, abortable-iterator@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/abortable-iterator/-/abortable-iterator-3.0.2.tgz#6f5af0f36e86db4607fc95251bffe2dee261d6a2"
+ integrity sha512-qVP8HFfTpUQI2F+f1tpTriKDIZ4XrmwCrBCrQeRKO7DKWF3kgoT6NXiNDv2krrGcHxPwmI63eGQiec81sEaWIw==
+ dependencies:
+ get-iterator "^1.0.2"
+
+accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
+ integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
+ dependencies:
+ mime-types "~2.1.34"
+ negotiator "0.6.3"
+
+acorn-globals@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
+ integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==
+ dependencies:
+ acorn "^7.1.1"
+ acorn-walk "^7.1.1"
+
+acorn-import-assertions@^1.7.6:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9"
+ integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==
+
+acorn-jsx@^5.3.1:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
+acorn-walk@^7.1.1:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
+ integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
+
+acorn-walk@^8.1.1:
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
+ integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
+
+acorn@^7.1.1, acorn@^7.4.0:
+ version "7.4.1"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
+ integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
+
+acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0:
+ version "8.7.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
+ integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
+
+agent-base@6:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
+ integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
+ dependencies:
+ debug "4"
+
+aggregate-error@^3.0.0, aggregate-error@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
+ integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
+ dependencies:
+ clean-stack "^2.0.0"
+ indent-string "^4.0.0"
+
+ajv-errors@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
+ integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
+
+ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
+ version "3.5.2"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
+ integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
+
+ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
+ version "6.12.6"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
+ integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
+
+ajv@^8.0.1:
+ version "8.10.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d"
+ integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+ uri-js "^4.2.2"
+
+ansi-align@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
+ integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==
+ dependencies:
+ string-width "^4.1.0"
+
+ansi-colors@4.1.1, ansi-colors@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
+ integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
+
+ansi-colors@^3.0.0:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"
+ integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==
+
+ansi-html-community@0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41"
+ integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+ integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
+
+ansi-regex@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
+ integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^3.2.0, ansi-styles@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+ integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+ dependencies:
+ color-convert "^1.9.0"
+
+ansi-styles@^4.0.0, ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+any-signal@^2.1.0, any-signal@^2.1.1:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/any-signal/-/any-signal-2.1.2.tgz#8d48270de0605f8b218cf9abe8e9c6a0e7418102"
+ integrity sha512-B+rDnWasMi/eWcajPcCWSlYc7muXOrcYrqgyzcdKisl2H/WTlQ0gip1KyQfr0ZlxJdsuWCj/LWwQm7fhyhRfIQ==
+ dependencies:
+ abort-controller "^3.0.0"
+ native-abort-controller "^1.0.3"
+
+any-signal@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/any-signal/-/any-signal-3.0.0.tgz#4f6ee491e5cdda9e9a544f50fdf1d14be40535b6"
+ integrity sha512-l1H1GEkGGIXVGfCtvq8N68YI7gHajmfzRdKhmb8sGyAQpLCblirLa8eB09j4uKaiwe7vodAChocUf7AT3mYq5g==
+
+anymatch@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
+ integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==
+ dependencies:
+ micromatch "^3.1.4"
+ normalize-path "^2.1.1"
+
+anymatch@~3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
+ integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
+ dependencies:
+ normalize-path "^3.0.0"
+ picomatch "^2.0.4"
+
+arg@^4.1.0:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
+ integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
+
+argparse@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+ integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
+ dependencies:
+ sprintf-js "~1.0.2"
+
+argparse@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+ integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
+arr-diff@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
+ integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=
+
+arr-flatten@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
+ integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==
+
+arr-union@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
+ integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
+
+array-flatten@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+ integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
+
+array-flatten@^2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
+ integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
+
+array-includes@^3.1.3, array-includes@^3.1.4:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9"
+ integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+ get-intrinsic "^1.1.1"
+ is-string "^1.0.7"
+
+array-union@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+ integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
+ dependencies:
+ array-uniq "^1.0.1"
+
+array-union@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
+ integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+
+array-uniq@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+ integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
+
+array-unique@^0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
+ integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
+
+array.prototype.flat@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
+ integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.0"
+
+array.prototype.flatmap@^1.2.4, array.prototype.flatmap@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446"
+ integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.0"
+
+asn1.js@^5.0.1, asn1.js@^5.2.0:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
+ integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
+ dependencies:
+ bn.js "^4.0.0"
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+ safer-buffer "^2.1.0"
+
+asn1@~0.2.3:
+ version "0.2.6"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
+ integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
+ dependencies:
+ safer-buffer "~2.1.0"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+ integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+
+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==
+ dependencies:
+ es6-object-assign "^1.1.0"
+ is-nan "^1.2.1"
+ object-is "^1.0.1"
+ util "^0.12.0"
+
+assertion-error@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
+ integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
+
+assign-symbols@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
+ integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
+
+astral-regex@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
+ integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
+
+async-each@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
+ integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
+
+async-limiter@~1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
+ integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
+
+async@^2.6.2:
+ version "2.6.3"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
+ integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
+ dependencies:
+ lodash "^4.17.14"
+
+async@^3.2.0:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
+ integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+ integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+
+at-least-node@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
+ integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
+
+atob@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
+ integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
+
+available-typed-arrays@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
+ integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
+
+aws-sign2@~0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+ integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
+
+aws4@^1.8.0:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
+ integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
+
+axios@^0.21.1:
+ version "0.21.4"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
+ integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
+ dependencies:
+ follow-redirects "^1.14.0"
+
+"babel-plugin-styled-components@>= 1.12.0":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.4.tgz#2ee2574e4044f2e6dea443111aa2f3219271b181"
+ integrity sha512-qOQpu/f0cLzn6qUZ9BlIM693fMsBQt+QGbij0uHLd27FMzd2VMf0mBPr7r3CETzulXlNsHXVw5khzhnrvmPU/g==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.16.0"
+ "@babel/helper-module-imports" "^7.16.0"
+ babel-plugin-syntax-jsx "^6.18.0"
+ lodash "^4.17.11"
+ picomatch "^2.3.0"
+
+babel-plugin-syntax-jsx@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+ integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
+
+balanced-match@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+base64-js@^1.3.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
+ integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+
+base64url@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
+ integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
+
+base@^0.11.1:
+ version "0.11.2"
+ resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
+ integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==
+ dependencies:
+ cache-base "^1.0.1"
+ class-utils "^0.3.5"
+ component-emitter "^1.2.1"
+ define-property "^1.0.0"
+ isobject "^3.0.1"
+ mixin-deep "^1.2.0"
+ pascalcase "^0.1.1"
+
+batch@0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
+ integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
+ integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
+ dependencies:
+ tweetnacl "^0.14.3"
+
+big.js@^5.2.2:
+ version "5.2.2"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
+ integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
+
+bigint-buffer@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442"
+ integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==
+ dependencies:
+ bindings "^1.3.0"
+
+bignumber.js@^9.0.1:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673"
+ integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==
+
+binary-extensions@^1.0.0:
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
+ integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==
+
+binary-extensions@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
+ integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+
+bindings@^1.3.0, bindings@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
+ integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
+ dependencies:
+ file-uri-to-path "1.0.0"
+
+bl@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-5.0.0.tgz#6928804a41e9da9034868e1c50ca88f21f57aea2"
+ integrity sha512-8vxFNZ0pflFfi0WXA3WQXlj6CaMEwsmh63I1CNp0q+wWv8sD0ARx1KovSQd0l2GkwrMIOyedq0EF1FxI+RCZLQ==
+ dependencies:
+ buffer "^6.0.3"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
+
+bluebird@^3.5.1:
+ version "3.7.2"
+ resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
+ integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
+
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
+ version "4.12.0"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
+ integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
+
+bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
+ integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
+
+body-parser@1.19.2:
+ version "1.19.2"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e"
+ integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==
+ dependencies:
+ bytes "3.1.2"
+ content-type "~1.0.4"
+ debug "2.6.9"
+ depd "~1.1.2"
+ http-errors "1.8.1"
+ iconv-lite "0.4.24"
+ on-finished "~2.3.0"
+ qs "6.9.7"
+ raw-body "2.4.3"
+ type-is "~1.6.18"
+
+bonjour@^3.5.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5"
+ integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU=
+ dependencies:
+ array-flatten "^2.1.0"
+ deep-equal "^1.0.1"
+ dns-equal "^1.0.0"
+ dns-txt "^2.0.2"
+ multicast-dns "^6.0.1"
+ multicast-dns-service-types "^1.1.0"
+
+boolbase@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+ integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
+
+boxen@^5.0.0:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50"
+ integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==
+ dependencies:
+ ansi-align "^3.0.0"
+ camelcase "^6.2.0"
+ chalk "^4.1.0"
+ cli-boxes "^2.2.1"
+ string-width "^4.2.2"
+ type-fest "^0.20.2"
+ widest-line "^3.1.0"
+ wrap-ansi "^7.0.0"
+
+brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+ integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+braces@^2.3.1, braces@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
+ integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
+ dependencies:
+ arr-flatten "^1.1.0"
+ array-unique "^0.3.2"
+ extend-shallow "^2.0.1"
+ fill-range "^4.0.0"
+ isobject "^3.0.1"
+ repeat-element "^1.1.2"
+ snapdragon "^0.8.1"
+ snapdragon-node "^2.0.1"
+ split-string "^3.0.2"
+ to-regex "^3.0.1"
+
+braces@^3.0.1, braces@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+ integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+ dependencies:
+ fill-range "^7.0.1"
+
+brorand@^1.0.1, brorand@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+ integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+
+browser-process-hrtime@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
+ integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
+
+browser-stdout@1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
+ integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
+
+browserify-aes@^1.0.0, browserify-aes@^1.0.4:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
+ integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
+ dependencies:
+ buffer-xor "^1.0.3"
+ cipher-base "^1.0.0"
+ create-hash "^1.1.0"
+ evp_bytestokey "^1.0.3"
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+browserify-cipher@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
+ integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
+ dependencies:
+ browserify-aes "^1.0.4"
+ browserify-des "^1.0.0"
+ evp_bytestokey "^1.0.0"
+
+browserify-des@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
+ integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
+ dependencies:
+ cipher-base "^1.0.1"
+ des.js "^1.0.0"
+ inherits "^2.0.1"
+ safe-buffer "^5.1.2"
+
+browserify-rsa@^4.0.0, browserify-rsa@^4.0.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d"
+ integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==
+ dependencies:
+ bn.js "^5.0.0"
+ randombytes "^2.0.1"
+
+browserify-sign@^4.0.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3"
+ integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==
+ dependencies:
+ bn.js "^5.1.1"
+ browserify-rsa "^4.0.1"
+ create-hash "^1.2.0"
+ create-hmac "^1.1.7"
+ elliptic "^6.5.3"
+ inherits "^2.0.4"
+ parse-asn1 "^5.1.5"
+ readable-stream "^3.6.0"
+ safe-buffer "^5.2.0"
+
+browserify-zlib@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
+ integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
+ dependencies:
+ pako "~1.0.5"
+
+browserslist@^4.14.5:
+ version "4.19.3"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.3.tgz#29b7caad327ecf2859485f696f9604214bedd383"
+ integrity sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==
+ dependencies:
+ caniuse-lite "^1.0.30001312"
+ electron-to-chromium "^1.4.71"
+ escalade "^3.1.1"
+ node-releases "^2.0.2"
+ picocolors "^1.0.0"
+
+buffer-from@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
+buffer-indexof@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
+ integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
+
+buffer-xor@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
+ integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
+
+buffer@^6.0.1, buffer@^6.0.3:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
+ integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
+ dependencies:
+ base64-js "^1.3.1"
+ ieee754 "^1.2.1"
+
+builtin-status-codes@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
+ integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
+
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+ integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
+
+bytes@3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
+ integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
+
+cache-base@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
+ integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==
+ dependencies:
+ collection-visit "^1.0.0"
+ component-emitter "^1.2.1"
+ get-value "^2.0.6"
+ has-value "^1.0.0"
+ isobject "^3.0.1"
+ set-value "^2.0.0"
+ to-object-path "^0.3.0"
+ union-value "^1.0.0"
+ unset-value "^1.0.0"
+
+cacheable-request@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
+ integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
+ dependencies:
+ clone-response "^1.0.2"
+ get-stream "^5.1.0"
+ http-cache-semantics "^4.0.0"
+ keyv "^3.0.0"
+ lowercase-keys "^2.0.0"
+ normalize-url "^4.1.0"
+ responselike "^1.0.2"
+
+call-bind@^1.0.0, call-bind@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
+ integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
+ dependencies:
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
+
+callsites@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
+ integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+
+camel-case@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
+ integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
+ dependencies:
+ pascal-case "^3.1.2"
+ tslib "^2.0.3"
+
+camelcase@^5.0.0:
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
+ integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+
+camelcase@^6.0.0, camelcase@^6.2.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
+ integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
+
+camelize@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
+ integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
+
+caniuse-lite@^1.0.30001312:
+ version "1.0.30001312"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f"
+ integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==
+
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+ integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+
+chai@^4.3.4:
+ version "4.3.6"
+ resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c"
+ integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==
+ dependencies:
+ assertion-error "^1.1.0"
+ check-error "^1.0.2"
+ deep-eql "^3.0.1"
+ get-func-name "^2.0.0"
+ loupe "^2.3.1"
+ pathval "^1.1.1"
+ type-detect "^4.0.5"
+
+chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+ dependencies:
+ ansi-styles "^3.2.1"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.3.0"
+
+chalk@^4.0.0, chalk@^4.1.0:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+check-error@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
+ integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
+
+chokidar@3.5.3, chokidar@^3.4.2, chokidar@^3.5.2:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
+ integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+chokidar@^2.1.8:
+ version "2.1.8"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
+ integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==
+ dependencies:
+ anymatch "^2.0.0"
+ async-each "^1.0.1"
+ braces "^2.3.2"
+ glob-parent "^3.1.0"
+ inherits "^2.0.3"
+ is-binary-path "^1.0.0"
+ is-glob "^4.0.0"
+ normalize-path "^3.0.0"
+ path-is-absolute "^1.0.0"
+ readdirp "^2.2.1"
+ upath "^1.1.1"
+ optionalDependencies:
+ fsevents "^1.2.7"
+
+chrome-trace-event@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
+ integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
+
+ci-info@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
+ integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+
+cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
+ integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+class-is@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825"
+ integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==
+
+class-utils@^0.3.5:
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
+ integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==
+ dependencies:
+ arr-union "^3.1.0"
+ define-property "^0.2.5"
+ isobject "^3.0.0"
+ static-extend "^0.1.1"
+
+clean-css@^5.2.2:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.4.tgz#982b058f8581adb2ae062520808fb2429bd487a4"
+ integrity sha512-nKseG8wCzEuji/4yrgM/5cthL9oTDc5UOQyFMvW/Q53oP6gLH690o1NbuTh6Y18nujr7BxlsFuS7gXLnLzKJGg==
+ dependencies:
+ source-map "~0.6.0"
+
+clean-stack@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
+ integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
+
+cli-boxes@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
+ integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
+
+cliui@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
+ integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
+ dependencies:
+ string-width "^3.1.0"
+ strip-ansi "^5.2.0"
+ wrap-ansi "^5.1.0"
+
+cliui@^7.0.2:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
+ integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.0"
+ wrap-ansi "^7.0.0"
+
+clone-deep@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
+ integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
+ dependencies:
+ is-plain-object "^2.0.4"
+ kind-of "^6.0.2"
+ shallow-clone "^3.0.0"
+
+clone-response@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
+ integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
+ dependencies:
+ mimic-response "^1.0.0"
+
+collection-visit@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
+ integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=
+ dependencies:
+ map-visit "^1.0.0"
+ object-visit "^1.0.0"
+
+color-convert@^1.9.0:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+ integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+ dependencies:
+ color-name "1.1.3"
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+ integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+colorette@^2.0.14:
+ version "2.0.16"
+ resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
+ integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
+
+combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
+ integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
+ dependencies:
+ delayed-stream "~1.0.0"
+
+commander@^2.20.0:
+ version "2.20.3"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
+ integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+
+commander@^7.0.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
+ integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
+
+commander@^8.3.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
+ integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
+
+component-emitter@^1.2.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
+ integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
+
+compressible@~2.0.16:
+ version "2.0.18"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
+ integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
+ dependencies:
+ mime-db ">= 1.43.0 < 2"
+
+compression@^1.7.4:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
+ integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
+ dependencies:
+ accepts "~1.3.5"
+ bytes "3.0.0"
+ compressible "~2.0.16"
+ debug "2.6.9"
+ on-headers "~1.0.2"
+ safe-buffer "5.1.2"
+ vary "~1.1.2"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+ integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+
+configstore@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
+ integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==
+ dependencies:
+ dot-prop "^5.2.0"
+ graceful-fs "^4.1.2"
+ make-dir "^3.0.0"
+ unique-string "^2.0.0"
+ write-file-atomic "^3.0.0"
+ xdg-basedir "^4.0.0"
+
+connect-history-api-fallback@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
+ integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
+
+content-disposition@0.5.4:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
+ integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
+ dependencies:
+ safe-buffer "5.2.1"
+
+content-type@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+ integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
+
+cookie-signature@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
+ integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
+
+cookie@0.4.2:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
+ integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
+
+copy-descriptor@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
+ integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
+
+copyfiles@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
+ integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==
+ dependencies:
+ glob "^7.0.5"
+ minimatch "^3.0.3"
+ mkdirp "^1.0.4"
+ noms "0.0.0"
+ through2 "^2.0.1"
+ untildify "^4.0.0"
+ yargs "^16.1.0"
+
+core-util-is@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+ integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+
+core-util-is@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
+cosmiconfig@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
+ integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==
+ dependencies:
+ "@types/parse-json" "^4.0.0"
+ import-fresh "^3.1.0"
+ parse-json "^5.0.0"
+ path-type "^4.0.0"
+ yaml "^1.7.2"
+
+create-ecdh@^4.0.0:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
+ integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==
+ dependencies:
+ bn.js "^4.1.0"
+ elliptic "^6.5.3"
+
+create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
+ integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
+ dependencies:
+ cipher-base "^1.0.1"
+ inherits "^2.0.1"
+ md5.js "^1.3.4"
+ ripemd160 "^2.0.1"
+ sha.js "^2.4.0"
+
+create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
+ integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
+ dependencies:
+ cipher-base "^1.0.3"
+ create-hash "^1.1.0"
+ inherits "^2.0.1"
+ ripemd160 "^2.0.0"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+
+create-require@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
+ integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+
+cross-spawn@^6.0.0, cross-spawn@^6.0.5:
+ version "6.0.5"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
+ integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
+ dependencies:
+ nice-try "^1.0.4"
+ path-key "^2.0.1"
+ semver "^5.5.0"
+ shebang-command "^1.2.0"
+ which "^1.2.9"
+
+cross-spawn@^7.0.2, cross-spawn@^7.0.3:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
+ integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
+crypto-browserify@^3.12.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
+ integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
+ dependencies:
+ browserify-cipher "^1.0.0"
+ browserify-sign "^4.0.0"
+ create-ecdh "^4.0.0"
+ create-hash "^1.1.0"
+ create-hmac "^1.1.0"
+ diffie-hellman "^5.0.0"
+ inherits "^2.0.1"
+ pbkdf2 "^3.0.3"
+ public-encrypt "^4.0.0"
+ randombytes "^2.0.0"
+ randomfill "^1.0.3"
+
+crypto-random-string@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
+ integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
+
+css-color-keywords@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
+ integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
+
+css-loader@^6.3.0:
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.6.0.tgz#c792ad5510bd1712618b49381bd0310574fafbd3"
+ integrity sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg==
+ dependencies:
+ icss-utils "^5.1.0"
+ postcss "^8.4.5"
+ postcss-modules-extract-imports "^3.0.0"
+ postcss-modules-local-by-default "^4.0.0"
+ postcss-modules-scope "^3.0.0"
+ postcss-modules-values "^4.0.0"
+ postcss-value-parser "^4.2.0"
+ semver "^7.3.5"
+
+css-select@^4.1.3:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd"
+ integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==
+ dependencies:
+ boolbase "^1.0.0"
+ css-what "^5.1.0"
+ domhandler "^4.3.0"
+ domutils "^2.8.0"
+ nth-check "^2.0.1"
+
+css-to-react-native@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
+ integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
+ dependencies:
+ camelize "^1.0.0"
+ css-color-keywords "^1.0.0"
+ postcss-value-parser "^4.0.2"
+
+css-what@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
+ integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
+
+cssesc@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
+ integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+
+cssom@^0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
+ integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
+
+cssom@~0.3.6:
+ version "0.3.8"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
+ integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
+
+cssstyle@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852"
+ integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==
+ dependencies:
+ cssom "~0.3.6"
+
+csstype@^3.0.2:
+ version "3.0.10"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5"
+ integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
+ dependencies:
+ assert-plus "^1.0.0"
+
+data-urls@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
+ integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
+ dependencies:
+ abab "^2.0.3"
+ whatwg-mimetype "^2.3.0"
+ whatwg-url "^8.0.0"
+
+dataloader@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8"
+ integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==
+
+debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
+ version "2.6.9"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
+ integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+ dependencies:
+ ms "2.0.0"
+
+debug@4, debug@4.3.3, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.0, debug@^4.3.1:
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
+ integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
+ dependencies:
+ ms "2.1.2"
+
+debug@^3.1.1, debug@^3.2.6, debug@^3.2.7:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
+ integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
+ dependencies:
+ ms "^2.1.1"
+
+decamelize@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+ integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+
+decamelize@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
+ integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
+
+decimal.js@^10.2.1:
+ version "10.3.1"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
+ integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
+
+decode-uri-component@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+ integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
+
+decompress-response@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
+ integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
+ dependencies:
+ mimic-response "^1.0.0"
+
+deep-eql@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
+ integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
+ dependencies:
+ type-detect "^4.0.0"
+
+deep-equal@^1.0.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
+ integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
+ dependencies:
+ is-arguments "^1.0.4"
+ is-date-object "^1.0.1"
+ is-regex "^1.0.4"
+ object-is "^1.0.1"
+ object-keys "^1.1.1"
+ regexp.prototype.flags "^1.2.0"
+
+deep-extend@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
+ integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
+
+deep-is@^0.1.3, deep-is@~0.1.3:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
+ integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
+
+deepmerge@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
+ integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
+
+default-gateway@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
+ integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==
+ dependencies:
+ execa "^1.0.0"
+ ip-regex "^2.1.0"
+
+default-gateway@^6.0.3:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71"
+ integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==
+ dependencies:
+ execa "^5.0.0"
+
+defer-to-connect@^1.0.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
+ integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
+
+define-properties@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
+ integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
+ dependencies:
+ object-keys "^1.0.12"
+
+define-property@^0.2.5:
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
+ integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=
+ dependencies:
+ is-descriptor "^0.1.0"
+
+define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
+ integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY=
+ dependencies:
+ is-descriptor "^1.0.0"
+
+define-property@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d"
+ integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==
+ dependencies:
+ is-descriptor "^1.0.2"
+ isobject "^3.0.1"
+
+del@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
+ integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==
+ dependencies:
+ "@types/glob" "^7.1.1"
+ globby "^6.1.0"
+ is-path-cwd "^2.0.0"
+ is-path-in-cwd "^2.0.0"
+ p-map "^2.0.0"
+ pify "^4.0.1"
+ rimraf "^2.6.3"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+ integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+
+denque@^1.5.0:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
+ integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
+
+depd@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+ integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
+
+des.js@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
+ integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==
+ dependencies:
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+
+destroy@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+ integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
+
+detect-node@^2.0.4:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
+ integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
+
+diff@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
+ integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
+
+diff@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
+ integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+
+diffie-hellman@^5.0.0:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
+ integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
+ dependencies:
+ bn.js "^4.1.0"
+ miller-rabin "^4.0.0"
+ randombytes "^2.0.0"
+
+dir-glob@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
+ integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+ dependencies:
+ path-type "^4.0.0"
+
+dns-equal@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
+ integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
+
+dns-over-http-resolver@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/dns-over-http-resolver/-/dns-over-http-resolver-1.2.3.tgz#194d5e140a42153f55bb79ac5a64dd2768c36af9"
+ integrity sha512-miDiVSI6KSNbi4SVifzO/reD8rMnxgrlnkrlkugOLQpWQTe2qMdHsZp5DmfKjxNE+/T3VAAYLQUZMv9SMr6+AA==
+ dependencies:
+ debug "^4.3.1"
+ native-fetch "^3.0.0"
+ receptacle "^1.3.2"
+
+dns-packet@^1.3.1:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f"
+ integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==
+ dependencies:
+ ip "^1.1.0"
+ safe-buffer "^5.0.1"
+
+dns-packet@^5.2.4, dns-packet@^5.3.0:
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.3.1.tgz#eb94413789daec0f0ebe2fcc230bdc9d7c91b43d"
+ integrity sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==
+ dependencies:
+ "@leichtgewicht/ip-codec" "^2.0.1"
+
+dns-query@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/dns-query/-/dns-query-0.8.0.tgz#e64f2d96d0f18783c1f8d1a6ca33a77050599a76"
+ integrity sha512-Gx3jYhdj9oLMZFieinpwpTFK0c2Q+teV53Se1+l4AbcWLPMUCBACu7qcj0IqTWwnpasWl8Gwgxeqw2RjoCwIoA==
+ dependencies:
+ "@leichtgewicht/ip-codec" "^2.0.2"
+ "@types/dns-packet" "^5.2.0"
+ dns-packet "^5.3.0"
+ dns-socket "^4.2.2"
+
+dns-socket@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/dns-socket/-/dns-socket-4.2.2.tgz#58b0186ec053ea0731feb06783c7eeac4b95b616"
+ integrity sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==
+ dependencies:
+ dns-packet "^5.2.4"
+
+dns-txt@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6"
+ integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=
+ dependencies:
+ buffer-indexof "^1.0.0"
+
+doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
+ integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
+ dependencies:
+ esutils "^2.0.2"
+
+doctrine@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
+ integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
+ dependencies:
+ esutils "^2.0.2"
+
+dom-converter@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
+ integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==
+ dependencies:
+ utila "~0.4"
+
+dom-serializer@^1.0.1:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
+ integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.2.0"
+ entities "^2.0.0"
+
+domelementtype@^2.0.1, domelementtype@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
+ integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
+
+domexception@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
+ integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
+ dependencies:
+ webidl-conversions "^5.0.0"
+
+domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626"
+ integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==
+ dependencies:
+ domelementtype "^2.2.0"
+
+domutils@^2.5.2, domutils@^2.8.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
+ integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
+ dependencies:
+ dom-serializer "^1.0.1"
+ domelementtype "^2.2.0"
+ domhandler "^4.2.0"
+
+dot-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
+ integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
+ dependencies:
+ no-case "^3.0.4"
+ tslib "^2.0.3"
+
+dot-prop@^5.2.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
+ integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
+ dependencies:
+ is-obj "^2.0.0"
+
+duplexer3@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
+ integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
+
+ecc-jsbn@~0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
+ integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
+ dependencies:
+ jsbn "~0.1.0"
+ safer-buffer "^2.1.0"
+
+ecies-geth@^1.5.2, ecies-geth@^1.5.3:
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/ecies-geth/-/ecies-geth-1.6.3.tgz#7b58434b6d7a4d93d1c54b5abe8974b5e911004a"
+ integrity sha512-RAZs5p0MZLGWXt3weAHjefnWzJwTDvMw8GizSHhPNM8HkGDkRnOjbJtN613BD+/EOPaTP5j7bwwd83WhJq+5Ew==
+ dependencies:
+ elliptic "^6.5.4"
+ secp256k1 "^4.0.3"
+
+ee-first@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
+ integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
+
+electron-fetch@^1.7.2:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/electron-fetch/-/electron-fetch-1.7.4.tgz#af975ab92a14798bfaa025f88dcd2e54a7b0b769"
+ integrity sha512-+fBLXEy4CJWQ5bz8dyaeSG1hD6JJ15kBZyj3eh24pIVrd3hLM47H/umffrdQfS6GZ0falF0g9JT9f3Rs6AVUhw==
+ dependencies:
+ encoding "^0.1.13"
+
+electron-to-chromium@^1.4.71:
+ version "1.4.71"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz#17056914465da0890ce00351a3b946fd4cd51ff6"
+ integrity sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==
+
+elliptic@^6.5.3, elliptic@^6.5.4:
+ version "6.5.4"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
+ integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
+ dependencies:
+ bn.js "^4.11.9"
+ brorand "^1.1.0"
+ hash.js "^1.0.0"
+ hmac-drbg "^1.0.1"
+ inherits "^2.0.4"
+ minimalistic-assert "^1.0.1"
+ minimalistic-crypto-utils "^1.0.1"
+
+emoji-mart@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-3.0.1.tgz#9ce86706e02aea0506345f98464814a662ca54c6"
+ integrity sha512-sxpmMKxqLvcscu6mFn9ITHeZNkGzIvD0BSNFE/LJESPbCA8s1jM6bCDPjWbV31xHq7JXaxgpHxLB54RCbBZSlg==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ prop-types "^15.6.0"
+
+emoji-regex@^7.0.1:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
+ integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
+
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
+emojis-list@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
+ integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
+
+encodeurl@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
+ integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
+
+encoding@^0.1.13:
+ version "0.1.13"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
+ integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
+ dependencies:
+ iconv-lite "^0.6.2"
+
+end-of-stream@^1.1.0:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
+ integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
+ dependencies:
+ once "^1.4.0"
+
+enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3:
+ version "5.9.0"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz#49ac24953ac8452ed8fed2ef1340fc8e043667ee"
+ integrity sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.2.0"
+
+enquirer@^2.3.5:
+ version "2.3.6"
+ resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
+ integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
+ dependencies:
+ ansi-colors "^4.1.1"
+
+entities@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
+ integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
+
+envinfo@^7.7.3:
+ version "7.8.1"
+ resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
+ integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==
+
+err-code@^3.0.0, err-code@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920"
+ integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==
+
+errno@^0.1.3:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
+ integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
+ dependencies:
+ prr "~1.0.1"
+
+error-ex@^1.3.1:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
+ integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
+ dependencies:
+ is-arrayish "^0.2.1"
+
+es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19.1:
+ version "1.19.1"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
+ integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
+ dependencies:
+ call-bind "^1.0.2"
+ es-to-primitive "^1.2.1"
+ function-bind "^1.1.1"
+ get-intrinsic "^1.1.1"
+ get-symbol-description "^1.0.0"
+ has "^1.0.3"
+ has-symbols "^1.0.2"
+ internal-slot "^1.0.3"
+ is-callable "^1.2.4"
+ is-negative-zero "^2.0.1"
+ is-regex "^1.1.4"
+ is-shared-array-buffer "^1.0.1"
+ is-string "^1.0.7"
+ is-weakref "^1.0.1"
+ object-inspect "^1.11.0"
+ object-keys "^1.1.1"
+ object.assign "^4.1.2"
+ string.prototype.trimend "^1.0.4"
+ string.prototype.trimstart "^1.0.4"
+ unbox-primitive "^1.0.1"
+
+es-module-lexer@^0.9.0:
+ version "0.9.3"
+ resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
+ integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
+
+es-to-primitive@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
+ integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
+ dependencies:
+ is-callable "^1.1.4"
+ 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 sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
+
+es6-promisify@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-7.0.0.tgz#9a710008dd6a4ab75a89e280bad787bfb749927b"
+ integrity sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q==
+
+esbuild-android-arm64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz#c89b3c50b4f47668dcbeb0b34ee4615258818e71"
+ integrity sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==
+
+esbuild-darwin-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz#1c131e8cb133ed935ca32f824349a117c896a15b"
+ integrity sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==
+
+esbuild-darwin-arm64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz#3c6245a50109dd84953f53d7833bd3b4f0e8c6fa"
+ integrity sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==
+
+esbuild-freebsd-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz#0cdc54e72d3dd9cd992f9c2960055e68a7f8650c"
+ integrity sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==
+
+esbuild-freebsd-arm64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz#1d11faed3a0c429e99b7dddef84103eb509788b2"
+ integrity sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==
+
+esbuild-linux-32@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz#fd9f033fc27dcab61100cb1eb1c936893a68c841"
+ integrity sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==
+
+esbuild-linux-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz#c04c438514f1359ecb1529205d0c836d4165f198"
+ integrity sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==
+
+esbuild-linux-arm64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz#d1b3ab2988ab0734886eb9e811726f7db099ab96"
+ integrity sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==
+
+esbuild-linux-arm@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz#df7558b6a5076f5eb9fd387c8704f768b61d97fb"
+ integrity sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==
+
+esbuild-linux-mips64le@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz#bb4c47fccc9493d460ffeb1f88e8a97a98a14f8b"
+ integrity sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==
+
+esbuild-linux-ppc64le@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz#a332dbc8a1b4e30cfe1261bfaa5cef57c9c8c02a"
+ integrity sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==
+
+esbuild-linux-riscv64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz#85675f3f931f5cd7cfb238fd82f77a62ffcb6d86"
+ integrity sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==
+
+esbuild-linux-s390x@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz#a526282a696e6d846f4c628f5315475518c0c0f0"
+ integrity sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==
+
+esbuild-loader@^2.15.1:
+ version "2.18.0"
+ resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-2.18.0.tgz#7b9548578ab954574fd94655693d22aa5ec74120"
+ integrity sha512-AKqxM3bI+gvGPV8o6NAhR+cBxVO8+dh+O0OXBHIXXwuSGumckbPWHzZ17subjBGI2YEGyJ1STH7Haj8aCrwL/w==
+ dependencies:
+ esbuild "^0.14.6"
+ joycon "^3.0.1"
+ json5 "^2.2.0"
+ loader-utils "^2.0.0"
+ tapable "^2.2.0"
+ webpack-sources "^2.2.0"
+
+esbuild-netbsd-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz#8e456605694719aa1be4be266d6cd569c06dfaf5"
+ integrity sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==
+
+esbuild-openbsd-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz#f2fc51714b4ddabc86e4eb30ca101dd325db2f7d"
+ integrity sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==
+
+esbuild-sunos-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz#a408f33ea20e215909e20173a0fd78b1aaad1f8e"
+ integrity sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==
+
+esbuild-windows-32@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz#b9005bbff54dac3975ff355d5de2b5e37165d128"
+ integrity sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==
+
+esbuild-windows-64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz#2b5a99befeaca6aefdad32d738b945730a60a060"
+ integrity sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==
+
+esbuild-windows-arm64@0.14.23:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz#edc560bbadb097eb45fc235aeacb942cb94a38c0"
+ integrity sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==
+
+esbuild@^0.14.6:
+ version "0.14.23"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.23.tgz#95e842cb22bc0c7d82c140adc16788aac91469fe"
+ integrity sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==
+ optionalDependencies:
+ esbuild-android-arm64 "0.14.23"
+ esbuild-darwin-64 "0.14.23"
+ esbuild-darwin-arm64 "0.14.23"
+ esbuild-freebsd-64 "0.14.23"
+ esbuild-freebsd-arm64 "0.14.23"
+ esbuild-linux-32 "0.14.23"
+ esbuild-linux-64 "0.14.23"
+ esbuild-linux-arm "0.14.23"
+ esbuild-linux-arm64 "0.14.23"
+ esbuild-linux-mips64le "0.14.23"
+ esbuild-linux-ppc64le "0.14.23"
+ esbuild-linux-riscv64 "0.14.23"
+ esbuild-linux-s390x "0.14.23"
+ esbuild-netbsd-64 "0.14.23"
+ esbuild-openbsd-64 "0.14.23"
+ esbuild-sunos-64 "0.14.23"
+ esbuild-windows-32 "0.14.23"
+ esbuild-windows-64 "0.14.23"
+ esbuild-windows-arm64 "0.14.23"
+
+escalade@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
+ integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+
+escape-goat@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
+ integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
+
+escape-html@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+ integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
+
+escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
+escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+ integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+
+escodegen@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
+ integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==
+ dependencies:
+ esprima "^4.0.1"
+ estraverse "^5.2.0"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.6.1"
+
+eslint-config-prettier@^8.3.0:
+ version "8.4.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.4.0.tgz#8e6d17c7436649e98c4c2189868562921ef563de"
+ integrity sha512-CFotdUcMY18nGRo5KGsnNxpznzhkopOcOo0InID+sgQssPrzjvsyKZPvOgymTFeHrFuC3Tzdf2YndhXtULK9Iw==
+
+eslint-import-resolver-node@^0.3.6:
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
+ integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
+ dependencies:
+ debug "^3.2.7"
+ resolve "^1.20.0"
+
+eslint-module-utils@^2.7.2:
+ version "2.7.3"
+ resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee"
+ integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==
+ dependencies:
+ debug "^3.2.7"
+ find-up "^2.1.0"
+
+eslint-plugin-eslint-comments@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa"
+ integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ ignore "^5.0.5"
+
+eslint-plugin-functional@^3.7.0:
+ version "3.7.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-functional/-/eslint-plugin-functional-3.7.2.tgz#c90325dddfa822fab27419375084d12158f05da1"
+ integrity sha512-BuWPOeE0nuXYlZjObYOHnYf7G3iG+sysxw84I579MsrH+hy5XdXb2sdabmXQ5z7eFGCg2/DWNbZ/yz5GAgtcUg==
+ dependencies:
+ "@typescript-eslint/experimental-utils" "^4.9.1"
+ array.prototype.flatmap "^1.2.4"
+ deepmerge "^4.2.2"
+ escape-string-regexp "^4.0.0"
+ object.fromentries "^2.0.3"
+
+eslint-plugin-hooks@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-hooks/-/eslint-plugin-hooks-0.2.0.tgz#a6339b4afc9d37501c08b1c15589eafa94e7f076"
+ integrity sha512-02x4B/LEtmM+i92OBau/1qqdo3NgfCS/5xUj4TPmjpZedVGeEVbRRE+pb8by6VTThsn+DiI+AK4lH78XfAFJmQ==
+ dependencies:
+ requireindex "~1.2.0"
+
+eslint-plugin-import@^2.24.2:
+ version "2.25.4"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1"
+ integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==
+ dependencies:
+ array-includes "^3.1.4"
+ array.prototype.flat "^1.2.5"
+ debug "^2.6.9"
+ doctrine "^2.1.0"
+ eslint-import-resolver-node "^0.3.6"
+ eslint-module-utils "^2.7.2"
+ has "^1.0.3"
+ is-core-module "^2.8.0"
+ is-glob "^4.0.3"
+ minimatch "^3.0.4"
+ object.values "^1.1.5"
+ resolve "^1.20.0"
+ tsconfig-paths "^3.12.0"
+
+eslint-plugin-react-hooks@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
+ integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==
+
+eslint-plugin-react@^7.24.0:
+ version "7.28.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz#8f3ff450677571a659ce76efc6d80b6a525adbdf"
+ integrity sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==
+ dependencies:
+ array-includes "^3.1.4"
+ array.prototype.flatmap "^1.2.5"
+ doctrine "^2.1.0"
+ estraverse "^5.3.0"
+ jsx-ast-utils "^2.4.1 || ^3.0.0"
+ minimatch "^3.0.4"
+ object.entries "^1.1.5"
+ object.fromentries "^2.0.5"
+ object.hasown "^1.1.0"
+ object.values "^1.1.5"
+ prop-types "^15.7.2"
+ resolve "^2.0.0-next.3"
+ semver "^6.3.0"
+ string.prototype.matchall "^4.0.6"
+
+eslint-scope@5.1.1, eslint-scope@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
+ integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^4.1.1"
+
+eslint-utils@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
+ integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
+ dependencies:
+ eslint-visitor-keys "^1.1.0"
+
+eslint-utils@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
+ integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
+ dependencies:
+ eslint-visitor-keys "^2.0.0"
+
+eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
+ integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
+
+eslint-visitor-keys@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
+ integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
+
+eslint@^7.32.0:
+ version "7.32.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
+ integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
+ dependencies:
+ "@babel/code-frame" "7.12.11"
+ "@eslint/eslintrc" "^0.4.3"
+ "@humanwhocodes/config-array" "^0.5.0"
+ ajv "^6.10.0"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.2"
+ debug "^4.0.1"
+ doctrine "^3.0.0"
+ enquirer "^2.3.5"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^5.1.1"
+ eslint-utils "^2.1.0"
+ eslint-visitor-keys "^2.0.0"
+ espree "^7.3.1"
+ esquery "^1.4.0"
+ esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
+ functional-red-black-tree "^1.0.1"
+ glob-parent "^5.1.2"
+ globals "^13.6.0"
+ ignore "^4.0.6"
+ import-fresh "^3.0.0"
+ imurmurhash "^0.1.4"
+ is-glob "^4.0.0"
+ js-yaml "^3.13.1"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ levn "^0.4.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.0.4"
+ natural-compare "^1.4.0"
+ optionator "^0.9.1"
+ progress "^2.0.0"
+ regexpp "^3.1.0"
+ semver "^7.2.1"
+ strip-ansi "^6.0.0"
+ strip-json-comments "^3.1.0"
+ table "^6.0.9"
+ text-table "^0.2.0"
+ v8-compile-cache "^2.0.3"
+
+espree@^7.3.0, espree@^7.3.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
+ integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
+ dependencies:
+ acorn "^7.4.0"
+ acorn-jsx "^5.3.1"
+ eslint-visitor-keys "^1.3.0"
+
+esprima@^4.0.0, esprima@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
+ integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+
+esquery@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
+ integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
+ dependencies:
+ estraverse "^5.1.0"
+
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+ dependencies:
+ estraverse "^5.2.0"
+
+estraverse@^4.1.1:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
+ integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+
+estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+
+esutils@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
+ integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
+etag@~1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
+ integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
+
+event-iterator@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/event-iterator/-/event-iterator-2.0.0.tgz#10f06740cc1e9fd6bc575f334c2bc1ae9d2dbf62"
+ integrity sha512-KGft0ldl31BZVV//jj+IAIGCxkvvUkkON+ScH6zfoX+l+omX6001ggyRSpI0Io2Hlro0ThXotswCtfzS8UkIiQ==
+
+event-target-shim@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
+ integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
+
+eventemitter3@^4.0.0, eventemitter3@^4.0.4:
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
+ integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
+
+events@^3.2.0, events@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
+ integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
+
+eventsource@^1.0.7:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf"
+ integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==
+ dependencies:
+ original "^1.0.0"
+
+evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
+ integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
+ dependencies:
+ md5.js "^1.3.4"
+ safe-buffer "^5.1.1"
+
+execa@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
+ integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
+ dependencies:
+ cross-spawn "^6.0.0"
+ get-stream "^4.0.0"
+ is-stream "^1.1.0"
+ npm-run-path "^2.0.0"
+ p-finally "^1.0.0"
+ signal-exit "^3.0.0"
+ strip-eof "^1.0.0"
+
+execa@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.0"
+ human-signals "^2.1.0"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.1"
+ onetime "^5.1.2"
+ signal-exit "^3.0.3"
+ strip-final-newline "^2.0.0"
+
+expand-brackets@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
+ integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI=
+ dependencies:
+ debug "^2.3.3"
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ posix-character-classes "^0.1.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+express@^4.17.1:
+ version "4.17.3"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1"
+ integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==
+ dependencies:
+ accepts "~1.3.8"
+ array-flatten "1.1.1"
+ body-parser "1.19.2"
+ content-disposition "0.5.4"
+ content-type "~1.0.4"
+ cookie "0.4.2"
+ cookie-signature "1.0.6"
+ debug "2.6.9"
+ depd "~1.1.2"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ finalhandler "~1.1.2"
+ fresh "0.5.2"
+ merge-descriptors "1.0.1"
+ methods "~1.1.2"
+ on-finished "~2.3.0"
+ parseurl "~1.3.3"
+ path-to-regexp "0.1.7"
+ proxy-addr "~2.0.7"
+ qs "6.9.7"
+ range-parser "~1.2.1"
+ safe-buffer "5.2.1"
+ send "0.17.2"
+ serve-static "1.14.2"
+ setprototypeof "1.2.0"
+ statuses "~1.5.0"
+ type-is "~1.6.18"
+ utils-merge "1.0.1"
+ vary "~1.1.2"
+
+extend-shallow@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
+ integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=
+ dependencies:
+ is-extendable "^0.1.0"
+
+extend-shallow@^3.0.0, extend-shallow@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
+ integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=
+ dependencies:
+ assign-symbols "^1.0.0"
+ is-extendable "^1.0.1"
+
+extend@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
+ integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+
+extglob@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
+ integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==
+ dependencies:
+ array-unique "^0.3.2"
+ define-property "^1.0.0"
+ expand-brackets "^2.1.4"
+ extend-shallow "^2.0.1"
+ fragment-cache "^0.2.1"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+extsprintf@1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+ integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
+
+extsprintf@^1.2.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
+ integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
+
+fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+ integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
+fast-fifo@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.1.0.tgz#17d1a3646880b9891dfa0c54e69c5fef33cad779"
+ integrity sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==
+
+fast-glob@^3.2.9:
+ version "3.2.11"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
+ integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
+fast-json-stable-stringify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
+ integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+
+fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+ integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
+
+fastest-levenshtein@^1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
+ integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
+
+fastq@^1.6.0:
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
+ integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
+ dependencies:
+ reusify "^1.0.4"
+
+faye-websocket@^0.11.3:
+ version "0.11.4"
+ resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da"
+ integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==
+ dependencies:
+ websocket-driver ">=0.5.1"
+
+file-entry-cache@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
+ integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
+ dependencies:
+ flat-cache "^3.0.4"
+
+file-loader@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d"
+ integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==
+ dependencies:
+ loader-utils "^2.0.0"
+ schema-utils "^3.0.0"
+
+file-uri-to-path@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
+ integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
+
+fill-range@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
+ integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-number "^3.0.0"
+ repeat-string "^1.6.1"
+ to-regex-range "^2.1.0"
+
+fill-range@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+ integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+ dependencies:
+ to-regex-range "^5.0.1"
+
+finalhandler@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
+ integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
+ dependencies:
+ debug "2.6.9"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ on-finished "~2.3.0"
+ parseurl "~1.3.3"
+ statuses "~1.5.0"
+ unpipe "~1.0.0"
+
+find-up@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
+ integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+ dependencies:
+ locate-path "^6.0.0"
+ path-exists "^4.0.0"
+
+find-up@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
+ integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
+ dependencies:
+ locate-path "^2.0.0"
+
+find-up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
+ integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
+ dependencies:
+ locate-path "^3.0.0"
+
+find-up@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
+ integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+ dependencies:
+ locate-path "^5.0.0"
+ path-exists "^4.0.0"
+
+flat-cache@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
+ integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
+ dependencies:
+ flatted "^3.1.0"
+ rimraf "^3.0.2"
+
+flat@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
+ integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
+
+flatted@^3.1.0:
+ version "3.2.5"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3"
+ integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
+
+follow-redirects@^1.0.0, follow-redirects@^1.14.0:
+ version "1.14.9"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
+ integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
+
+for-in@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
+ integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
+
+foreach@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
+ integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k=
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+ integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+
+fork-ts-checker-webpack-plugin@^6.3.1:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.0.tgz#0282b335fa495a97e167f69018f566ea7d2a2b5e"
+ integrity sha512-cS178Y+xxtIjEUorcHddKS7yCMlrDPV31mt47blKKRfMd70Kxu5xruAFE2o9sDY6wVC5deuob/u/alD04YYHnw==
+ dependencies:
+ "@babel/code-frame" "^7.8.3"
+ "@types/json-schema" "^7.0.5"
+ chalk "^4.1.0"
+ chokidar "^3.4.2"
+ cosmiconfig "^6.0.0"
+ deepmerge "^4.2.2"
+ fs-extra "^9.0.0"
+ glob "^7.1.6"
+ memfs "^3.1.2"
+ minimatch "^3.0.4"
+ schema-utils "2.7.0"
+ semver "^7.3.2"
+ tapable "^1.0.0"
+
+form-data@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
+ integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.8"
+ mime-types "^2.1.12"
+
+form-data@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
+ integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.6"
+ mime-types "^2.1.12"
+
+forwarded@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
+ integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
+
+fragment-cache@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
+ integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=
+ dependencies:
+ map-cache "^0.2.2"
+
+fresh@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+ integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
+
+fs-extra@^9.0.0:
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
+ integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
+ dependencies:
+ at-least-node "^1.0.0"
+ graceful-fs "^4.2.0"
+ jsonfile "^6.0.1"
+ universalify "^2.0.0"
+
+fs-monkey@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3"
+ integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+ integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
+
+fsevents@^1.2.7:
+ version "1.2.13"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38"
+ integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==
+ dependencies:
+ bindings "^1.5.0"
+ nan "^2.12.1"
+
+fsevents@~2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+
+function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+ integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
+functional-red-black-tree@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+ integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+
+get-caller-file@^2.0.1, get-caller-file@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
+ integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+
+get-func-name@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
+ integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
+
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
+ integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
+ dependencies:
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-symbols "^1.0.1"
+
+get-iterator@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-1.0.2.tgz#cd747c02b4c084461fac14f48f6b45a80ed25c82"
+ integrity sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==
+
+get-stream@^4.0.0, get-stream@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
+ integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
+ dependencies:
+ pump "^3.0.0"
+
+get-stream@^5.1.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
+ integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
+ dependencies:
+ pump "^3.0.0"
+
+get-stream@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
+ integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
+
+get-symbol-description@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6"
+ integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.1"
+
+get-value@^2.0.3, get-value@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
+ integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
+
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
+ dependencies:
+ assert-plus "^1.0.0"
+
+glob-parent@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
+ integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=
+ dependencies:
+ is-glob "^3.1.0"
+ path-dirname "^1.0.0"
+
+glob-parent@^5.1.2, glob-parent@~5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+ dependencies:
+ is-glob "^4.0.1"
+
+glob-to-regexp@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
+ integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
+
+glob@7.2.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
+ integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
+ 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-dirs@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686"
+ integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==
+ dependencies:
+ ini "2.0.0"
+
+globals@^11.1.0:
+ version "11.12.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
+ integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+
+globals@^13.6.0, globals@^13.9.0:
+ version "13.12.1"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb"
+ integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==
+ dependencies:
+ type-fest "^0.20.2"
+
+globby@^11.0.3:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
+ integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
+ dependencies:
+ array-union "^2.1.0"
+ dir-glob "^3.0.1"
+ fast-glob "^3.2.9"
+ ignore "^5.2.0"
+ merge2 "^1.4.1"
+ slash "^3.0.0"
+
+globby@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
+ integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
+ dependencies:
+ array-union "^1.0.1"
+ glob "^7.0.3"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+got@^9.6.0:
+ version "9.6.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
+ integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
+ dependencies:
+ "@sindresorhus/is" "^0.14.0"
+ "@szmarczak/http-timer" "^1.1.2"
+ cacheable-request "^6.0.0"
+ decompress-response "^3.3.0"
+ duplexer3 "^0.1.4"
+ get-stream "^4.1.0"
+ lowercase-keys "^1.0.1"
+ mimic-response "^1.0.1"
+ p-cancelable "^1.0.0"
+ to-readable-stream "^1.0.0"
+ url-parse-lax "^3.0.0"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
+ version "4.2.9"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
+ integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
+
+growl@1.10.5:
+ version "1.10.5"
+ resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
+ integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
+
+handle-thing@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
+ integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
+
+har-schema@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+ integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
+
+har-validator@~5.1.3:
+ version "5.1.5"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
+ integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
+ dependencies:
+ ajv "^6.12.3"
+ har-schema "^2.0.0"
+
+has-bigints@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
+ integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
+
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+ integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+has-symbols@^1.0.1, has-symbols@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
+ integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
+
+has-tostringtag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
+ integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
+ dependencies:
+ has-symbols "^1.0.2"
+
+has-value@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
+ integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=
+ dependencies:
+ get-value "^2.0.3"
+ has-values "^0.1.4"
+ isobject "^2.0.0"
+
+has-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177"
+ integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=
+ dependencies:
+ get-value "^2.0.6"
+ has-values "^1.0.0"
+ isobject "^3.0.0"
+
+has-values@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
+ integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E=
+
+has-values@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f"
+ integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=
+ dependencies:
+ is-number "^3.0.0"
+ kind-of "^4.0.0"
+
+has-yarn@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
+ integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
+
+has@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
+ integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+ dependencies:
+ function-bind "^1.1.1"
+
+hash-base@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
+ integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
+ dependencies:
+ inherits "^2.0.4"
+ readable-stream "^3.6.0"
+ safe-buffer "^5.2.0"
+
+hash.js@^1.0.0, hash.js@^1.0.3:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
+ integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
+ dependencies:
+ inherits "^2.0.3"
+ minimalistic-assert "^1.0.1"
+
+hashlru@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/hashlru/-/hashlru-2.3.0.tgz#5dc15928b3f6961a2056416bb3a4910216fdfb51"
+ integrity sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==
+
+he@1.2.0, he@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
+ integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+
+hi-base32@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.1.tgz#1279f2ddae2673219ea5870c2121d2a33132857e"
+ integrity sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==
+
+history@^4.9.0:
+ version "4.10.1"
+ resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
+ integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
+ dependencies:
+ "@babel/runtime" "^7.1.2"
+ loose-envify "^1.2.0"
+ resolve-pathname "^3.0.0"
+ tiny-invariant "^1.0.2"
+ tiny-warning "^1.0.0"
+ value-equal "^1.0.1"
+
+hmac-drbg@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
+ integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
+ dependencies:
+ hash.js "^1.0.3"
+ minimalistic-assert "^1.0.0"
+ minimalistic-crypto-utils "^1.0.1"
+
+hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
+hosted-git-info@^2.1.4:
+ version "2.8.9"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
+ integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
+
+hpack.js@^2.1.6:
+ version "2.1.6"
+ resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
+ integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=
+ dependencies:
+ inherits "^2.0.1"
+ obuf "^1.0.0"
+ readable-stream "^2.0.1"
+ wbuf "^1.1.0"
+
+html-encoding-sniffer@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
+ integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
+ dependencies:
+ whatwg-encoding "^1.0.5"
+
+html-entities@^1.3.1:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc"
+ integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==
+
+html-entities@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488"
+ integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==
+
+html-minifier-terser@^6.0.2:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab"
+ integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==
+ dependencies:
+ camel-case "^4.1.2"
+ clean-css "^5.2.2"
+ commander "^8.3.0"
+ he "^1.2.0"
+ param-case "^3.0.4"
+ relateurl "^0.2.7"
+ terser "^5.10.0"
+
+html-webpack-plugin@^5.3.2:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50"
+ integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==
+ dependencies:
+ "@types/html-minifier-terser" "^6.0.0"
+ html-minifier-terser "^6.0.2"
+ lodash "^4.17.21"
+ pretty-error "^4.0.0"
+ tapable "^2.0.0"
+
+htmlparser2@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
+ integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.0.0"
+ domutils "^2.5.2"
+ entities "^2.0.0"
+
+http-cache-semantics@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
+ integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
+
+http-deceiver@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
+ integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
+
+http-errors@1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
+ integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
+ dependencies:
+ depd "~1.1.2"
+ inherits "2.0.4"
+ setprototypeof "1.2.0"
+ statuses ">= 1.5.0 < 2"
+ toidentifier "1.0.1"
+
+http-errors@~1.6.2:
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
+ integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
+ dependencies:
+ depd "~1.1.2"
+ inherits "2.0.3"
+ setprototypeof "1.1.0"
+ statuses ">= 1.4.0 < 2"
+
+http-parser-js@>=0.5.1:
+ version "0.5.5"
+ resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5"
+ integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==
+
+http-proxy-agent@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
+ integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==
+ dependencies:
+ "@tootallnate/once" "1"
+ agent-base "6"
+ debug "4"
+
+http-proxy-middleware@0.19.1:
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
+ integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==
+ dependencies:
+ http-proxy "^1.17.0"
+ is-glob "^4.0.0"
+ lodash "^4.17.11"
+ micromatch "^3.1.10"
+
+http-proxy@^1.17.0:
+ version "1.18.1"
+ resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
+ integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
+ dependencies:
+ eventemitter3 "^4.0.0"
+ follow-redirects "^1.0.0"
+ requires-port "^1.0.0"
+
+http-signature@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+ integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
+ dependencies:
+ assert-plus "^1.0.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+https-browserify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
+ integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
+
+https-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
+ integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
+ dependencies:
+ agent-base "6"
+ debug "4"
+
+human-signals@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
+ integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+
+iconv-lite@0.4.24:
+ version "0.4.24"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
+ integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
+iconv-lite@^0.6.2, iconv-lite@^0.6.3:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
+ integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3.0.0"
+
+icss-utils@^5.0.0, icss-utils@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
+ integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
+
+ieee754@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
+ integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
+
+ignore-by-default@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
+ integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
+
+ignore@^4.0.6:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
+ integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
+
+ignore@^5.0.5, ignore@^5.1.8, ignore@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
+ integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
+
+import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
+ integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
+ dependencies:
+ parent-module "^1.0.0"
+ resolve-from "^4.0.0"
+
+import-lazy@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
+ integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
+
+import-local@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
+ integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==
+ dependencies:
+ pkg-dir "^3.0.0"
+ resolve-cwd "^2.0.0"
+
+import-local@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"
+ integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
+ dependencies:
+ pkg-dir "^4.2.0"
+ resolve-cwd "^3.0.0"
+
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+ integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+
+indent-string@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
+ integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+inherits@2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+ integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
+
+ini@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5"
+ integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==
+
+ini@~1.3.0:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
+ integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
+
+interface-datastore@^5.1.1:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-5.2.0.tgz#9341b13a8babbfb23961ca7c732c0263f85e5007"
+ integrity sha512-nthO4C4BMJM2j9x/mT2KFa/g/sbcY8yf9j/kOBgli3u5mq9ZdPvQyDxi0OhKzr4JmoM81OYh5xcFjyebquqwvA==
+ dependencies:
+ err-code "^3.0.1"
+ interface-store "^1.0.2"
+ ipfs-utils "^8.1.2"
+ it-all "^1.0.2"
+ it-drain "^1.0.1"
+ it-filter "^1.0.2"
+ it-take "^1.0.1"
+ nanoid "^3.0.2"
+ uint8arrays "^3.0.0"
+
+interface-store@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-1.0.2.tgz#1ebd6cbbae387039a3a2de0cae665da52474800f"
+ integrity sha512-rUBLYsgoWwxuUpnQoSUr+DR/3dH3reVeIu5aOHFZK31lAexmb++kR6ZECNRgrx6WvoaM3Akdo0A7TDrqgCzZaQ==
+
+internal-ip@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907"
+ integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==
+ dependencies:
+ default-gateway "^4.2.0"
+ ipaddr.js "^1.9.0"
+
+internal-slot@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
+ integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==
+ dependencies:
+ get-intrinsic "^1.1.0"
+ has "^1.0.3"
+ side-channel "^1.0.4"
+
+interpret@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
+ integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
+
+ip-address@^8.0.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-8.1.0.tgz#1fe9b4509b51ff7d2fbbef4d3d26994d9915a459"
+ integrity sha512-Wz91gZKpNKoXtqvY8ScarKYwhXoK4r/b5QuT+uywe/azv0/nUCo7Bh0IRRI7F9DHR06kJNWtzMGLIbXavngbKA==
+ dependencies:
+ jsbn "1.1.0"
+ sprintf-js "1.1.2"
+
+ip-regex@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
+ integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
+
+ip-regex@^4.0.0, ip-regex@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
+ integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
+
+ip@^1.1.0, ip@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
+ integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
+
+ipaddr.js@1.9.1, ipaddr.js@^1.9.0:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
+ integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+
+ipaddr.js@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0"
+ integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==
+
+ipfs-utils@^8.1.2:
+ version "8.1.6"
+ resolved "https://registry.yarnpkg.com/ipfs-utils/-/ipfs-utils-8.1.6.tgz#431cb1711e3b666fbc7e4ff830c758e2527da308"
+ integrity sha512-V/cwb6113DrDhrjDTWImA6+zmJbpdbUkxdxmEQO7it8ykV76bBmzU1ZXSM0QR0qxGy9VW8dkUlPAC2K10VgSmw==
+ dependencies:
+ abort-controller "^3.0.0"
+ any-signal "^2.1.0"
+ buffer "^6.0.1"
+ electron-fetch "^1.7.2"
+ err-code "^3.0.1"
+ is-electron "^2.2.0"
+ iso-url "^1.1.5"
+ it-glob "~0.0.11"
+ it-to-stream "^1.0.0"
+ merge-options "^3.0.4"
+ nanoid "^3.1.20"
+ native-abort-controller "^1.0.3"
+ native-fetch "^3.0.0"
+ node-fetch "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz"
+ react-native-fetch-api "^2.0.0"
+ stream-to-it "^0.2.2"
+
+ipfs-utils@^9.0.1:
+ version "9.0.4"
+ resolved "https://registry.yarnpkg.com/ipfs-utils/-/ipfs-utils-9.0.4.tgz#364be777e73ac86956b8f7cbee89f3b09510884b"
+ integrity sha512-cfLKk004KLoEWJhBx4zg3mCro6mkiNhyGIlT7OZX9zxO1UqvLWpvW7cSZ1b1fbUIZ8qI7X2B7PeKlXC7jSfZ7g==
+ dependencies:
+ any-signal "^3.0.0"
+ buffer "^6.0.1"
+ electron-fetch "^1.7.2"
+ err-code "^3.0.1"
+ is-electron "^2.2.0"
+ iso-url "^1.1.5"
+ it-glob "^1.0.1"
+ it-to-stream "^1.0.0"
+ merge-options "^3.0.4"
+ nanoid "^3.1.20"
+ native-fetch "^3.0.0"
+ node-fetch "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz"
+ react-native-fetch-api "^2.0.0"
+ stream-to-it "^0.2.2"
+
+is-absolute-url@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698"
+ integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==
+
+is-accessor-descriptor@^0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
+ integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=
+ dependencies:
+ kind-of "^3.0.2"
+
+is-accessor-descriptor@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
+ integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==
+ dependencies:
+ kind-of "^6.0.0"
+
+is-arguments@^1.0.4:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
+ integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+ integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+
+is-bigint@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
+ integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==
+ dependencies:
+ has-bigints "^1.0.1"
+
+is-binary-path@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
+ integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=
+ dependencies:
+ binary-extensions "^1.0.0"
+
+is-binary-path@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
+ integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+ dependencies:
+ binary-extensions "^2.0.0"
+
+is-boolean-object@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
+ integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-buffer@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+ integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
+
+is-callable@^1.1.4, is-callable@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
+ integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
+
+is-ci@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
+ integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
+ dependencies:
+ ci-info "^2.0.0"
+
+is-core-module@^2.2.0, is-core-module@^2.8.0, is-core-module@^2.8.1:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
+ integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==
+ dependencies:
+ has "^1.0.3"
+
+is-data-descriptor@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
+ integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=
+ dependencies:
+ kind-of "^3.0.2"
+
+is-data-descriptor@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
+ integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==
+ dependencies:
+ kind-of "^6.0.0"
+
+is-date-object@^1.0.1:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
+ integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-descriptor@^0.1.0:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
+ integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==
+ dependencies:
+ is-accessor-descriptor "^0.1.6"
+ is-data-descriptor "^0.1.4"
+ kind-of "^5.0.0"
+
+is-descriptor@^1.0.0, is-descriptor@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
+ integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==
+ dependencies:
+ is-accessor-descriptor "^1.0.0"
+ is-data-descriptor "^1.0.0"
+ kind-of "^6.0.2"
+
+is-electron@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.1.tgz#751b1dd8a74907422faa5c35aaa0cf66d98086e9"
+ integrity sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw==
+
+is-extendable@^0.1.0, is-extendable@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+ integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=
+
+is-extendable@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
+ integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==
+ dependencies:
+ is-plain-object "^2.0.4"
+
+is-extglob@^2.1.0, is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+ integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+
+is-fullwidth-code-point@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+ integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
+
+is-fullwidth-code-point@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+ integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
+is-generator-function@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
+ integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-glob@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
+ integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=
+ dependencies:
+ is-extglob "^2.1.0"
+
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+ dependencies:
+ is-extglob "^2.1.1"
+
+is-installed-globally@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
+ integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==
+ dependencies:
+ global-dirs "^3.0.0"
+ is-path-inside "^3.0.2"
+
+is-ip@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8"
+ integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==
+ dependencies:
+ ip-regex "^4.0.0"
+
+is-loopback-addr@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-loopback-addr/-/is-loopback-addr-1.0.1.tgz#d4adf50d12d53100da62a397c61d6c83fe40aab9"
+ integrity sha512-DhWU/kqY7X2F6KrrVTu7mHlbd2Pbo4D1YkAzasBMjQs6lJAoefxaA6m6CpSX0K6pjt9D0b9PNFI5zduy/vzOYw==
+
+is-nan@^1.2.1:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d"
+ integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+
+is-negative-zero@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
+ integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
+
+is-npm@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8"
+ integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==
+
+is-number-object@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0"
+ integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-number@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
+ integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=
+ dependencies:
+ kind-of "^3.0.2"
+
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-obj@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
+ integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
+
+is-path-cwd@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
+ integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
+
+is-path-in-cwd@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb"
+ integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==
+ dependencies:
+ is-path-inside "^2.1.0"
+
+is-path-inside@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2"
+ integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==
+ dependencies:
+ path-is-inside "^1.0.2"
+
+is-path-inside@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
+ integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+
+is-plain-obj@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
+ integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
+
+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"
+ integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
+ dependencies:
+ isobject "^3.0.1"
+
+is-potential-custom-element-name@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
+ integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
+
+is-regex@^1.0.4, is-regex@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
+ integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-shared-array-buffer@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
+ integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
+
+is-stream@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+ integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+
+is-stream@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+
+is-string@^1.0.5, is-string@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
+ integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-symbol@^1.0.2, is-symbol@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
+ integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
+ dependencies:
+ has-symbols "^1.0.2"
+
+is-typed-array@^1.1.3, is-typed-array@^1.1.7:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79"
+ integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==
+ dependencies:
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ es-abstract "^1.18.5"
+ foreach "^2.0.5"
+ has-tostringtag "^1.0.0"
+
+is-typedarray@^1.0.0, is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+ integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+
+is-unicode-supported@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
+ integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
+
+is-weakref@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
+ integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
+ dependencies:
+ call-bind "^1.0.2"
+
+is-windows@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
+ integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
+
+is-wsl@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
+ integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
+
+is-yarn-global@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
+ integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
+
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+ integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
+
+isarray@1.0.0, isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+ integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+ integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+
+iso-random-stream@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/iso-random-stream/-/iso-random-stream-2.0.2.tgz#a24f77c34cfdad9d398707d522a6a0cc640ff27d"
+ integrity sha512-yJvs+Nnelic1L2vH2JzWvvPQFA4r7kSTnpST/+LkAQjSz0hos2oqLD+qIVi9Qk38Hoe7mNDt3j0S27R58MVjLQ==
+ dependencies:
+ events "^3.3.0"
+ readable-stream "^3.4.0"
+
+iso-url@^1.1.2, iso-url@^1.1.5:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-1.2.1.tgz#db96a49d8d9a64a1c889fc07cc525d093afb1811"
+ integrity sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng==
+
+isobject@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+ integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=
+ dependencies:
+ isarray "1.0.0"
+
+isobject@^3.0.0, isobject@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
+ integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
+
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+ integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+
+it-all@^1.0.2, it-all@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/it-all/-/it-all-1.0.6.tgz#852557355367606295c4c3b7eff0136f07749335"
+ integrity sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==
+
+it-buffer@^0.1.2, it-buffer@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/it-buffer/-/it-buffer-0.1.3.tgz#efebef1cc35a6133cb9558e759345d4f17b3e1d0"
+ integrity sha512-9a2/9SYVwG7bcn3tpRDR4bXbtuMLXnDK48KVC+GXiQg97ZOOdWz2nIITBsOQ19b+gj01Rw8RNwtiLDLI8P8oiQ==
+ dependencies:
+ bl "^5.0.0"
+ buffer "^6.0.3"
+
+it-concat@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/it-concat/-/it-concat-2.0.0.tgz#b4dc02aeb7365bada05b247c1ee50f3bbc147419"
+ integrity sha512-jchrEB3fHlUENWkVJRmbFJ1A7gcjJDmwiolQsHhVC14DpUIbX8fgr3SOC7XNE5OoUUQNL6/RaMCPChkPemyQUw==
+ dependencies:
+ bl "^5.0.0"
+
+it-drain@^1.0.1, it-drain@^1.0.3:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/it-drain/-/it-drain-1.0.5.tgz#0466d4e286b37bcd32599d4e99b37a87cb8cfdf6"
+ integrity sha512-r/GjkiW1bZswC04TNmUnLxa6uovme7KKwPhc+cb1hHU65E3AByypHH6Pm91WHuvqfFsm+9ws0kPtDBV3/8vmIg==
+
+it-filter@^1.0.1, it-filter@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/it-filter/-/it-filter-1.0.3.tgz#66ea0cc4bf84af71bebd353c05a9c5735fcba751"
+ integrity sha512-EI3HpzUrKjTH01miLHWmhNWy3Xpbx4OXMXltgrNprL5lDpF3giVpHIouFpr5l+evXw6aOfxhnt01BIB+4VQA+w==
+
+it-first@^1.0.4, it-first@^1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/it-first/-/it-first-1.0.7.tgz#a4bef40da8be21667f7d23e44dae652f5ccd7ab1"
+ integrity sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g==
+
+it-glob@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/it-glob/-/it-glob-1.0.2.tgz#bab9b04d6aaac42884502f3a0bfee84c7a29e15e"
+ integrity sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==
+ dependencies:
+ "@types/minimatch" "^3.0.4"
+ minimatch "^3.0.4"
+
+it-glob@~0.0.11:
+ version "0.0.14"
+ resolved "https://registry.yarnpkg.com/it-glob/-/it-glob-0.0.14.tgz#24f5e7fa48f9698ce7dd410355f327470c91eb90"
+ integrity sha512-TKKzs9CglbsihSpcwJPXN5DBUssu4akRzPlp8QJRCoLrKoaOpyY2V1qDlxx+UMivn0i114YyTd4AawWl7eqIdw==
+ dependencies:
+ "@types/minimatch" "^3.0.4"
+ minimatch "^3.0.4"
+
+it-handshake@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/it-handshake/-/it-handshake-2.0.0.tgz#97671f33c13c47218a3df8a8d92de565a075b28c"
+ integrity sha512-K4q+mz8aLlCK3vTjtgNdHC9c/JbuOATsfogarjMsLcBZC5vYfKbX3Gq3AWcCdjIsIrPqzTlhPKSxl64LJkrt2w==
+ dependencies:
+ it-pushable "^1.4.0"
+ it-reader "^3.0.0"
+ p-defer "^3.0.0"
+
+it-length-prefixed@^5.0.0, it-length-prefixed@^5.0.2, it-length-prefixed@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/it-length-prefixed/-/it-length-prefixed-5.0.3.tgz#77fbd99b89aa6cdd79fad62c962423b413db7045"
+ integrity sha512-b+jDHLcnOnPDQN79ronmzF5jeBjdJsy0ce2O6i6X4J5tnaO8Fd146ZA/tMbzaLlKnTpXa0eKtofpYhumXGENeg==
+ dependencies:
+ bl "^5.0.0"
+ buffer "^6.0.3"
+ varint "^6.0.0"
+
+it-map@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/it-map/-/it-map-1.0.6.tgz#6aa547e363eedcf8d4f69d8484b450bc13c9882c"
+ integrity sha512-XT4/RM6UHIFG9IobGlQPFQUrlEKkU4eBUFG3qhWhfAdh1JfF2x11ShCrKCdmZ0OiZppPfoLuzcfA4cey6q3UAQ==
+
+it-merge@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/it-merge/-/it-merge-1.0.4.tgz#81c8d427b389b1cd039c25015edb804cd1a60545"
+ integrity sha512-DcL6GksTD2HQ7+5/q3JznXaLNfwjyG3/bObaF98da+oHfUiPmdo64oJlT9J8R8G5sJRU7thwaY5zxoAKCn7FJw==
+ dependencies:
+ it-pushable "^1.4.0"
+
+it-pair@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/it-pair/-/it-pair-1.0.0.tgz#b1add81f49af16a10b2939dbef7b1974fae87d6a"
+ integrity sha512-9raOiDu5OAuDOahtMtapKQDrQTxBfzlzrNcB6o7JARHkt+7Bb1dMkW/TpYdAjBJE77KH3e2zGzwpGUP9tXbLww==
+ dependencies:
+ get-iterator "^1.0.2"
+
+it-pb-rpc@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/it-pb-rpc/-/it-pb-rpc-0.2.0.tgz#9247489e73e4a7d382d63a74778c1c3308bd9297"
+ integrity sha512-Rojodsa6yxSTZDqVVF9HXKsISoHtlLNOL0P6b/7oCswiscbjCpt1IB78BxRDHpFL3tg8jFPMNDTP3v6ZjrMf9w==
+ dependencies:
+ it-handshake "^2.0.0"
+ it-length-prefixed "^5.0.3"
+
+it-pipe@^1.0.1, it-pipe@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/it-pipe/-/it-pipe-1.1.0.tgz#f5964c6bb785dd776f11a62d1e75964787ab95ce"
+ integrity sha512-lF0/3qTVeth13TOnHVs0BTFaziwQF7m5Gg+E6JV0BXcLKutC92YjSi7bASgkPOXaLEb+YvNZrPorGMBIJvZfxg==
+
+it-pushable@^1.4.0, it-pushable@^1.4.1, it-pushable@^1.4.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-1.4.2.tgz#fb127a53ec99b35a3a455a775abc85ab193c220b"
+ integrity sha512-vVPu0CGRsTI8eCfhMknA7KIBqqGFolbRx+1mbQ6XuZ7YCz995Qj7L4XUviwClFunisDq96FdxzF5FnAbw15afg==
+ dependencies:
+ fast-fifo "^1.0.0"
+
+it-reader@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/it-reader/-/it-reader-3.0.0.tgz#56596c7742ec7c63b7f7998f6bfa3f712e333d0e"
+ integrity sha512-NxR40odATeaBmSefn6Xn43DplYvn2KtEKQzn4jrTRuPYXMky5M4e+KQ7aTJh0k0vkytLyeenGO1I1GXlGm4laQ==
+ dependencies:
+ bl "^5.0.0"
+
+it-take@^1.0.0, it-take@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/it-take/-/it-take-1.0.2.tgz#b5f1570014db7c3454897898b69bb7ac9c3bffc1"
+ integrity sha512-u7I6qhhxH7pSevcYNaMECtkvZW365ARqAIt9K+xjdK1B2WUDEjQSfETkOCT8bxFq/59LqrN3cMLUtTgmDBaygw==
+
+it-to-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/it-to-stream/-/it-to-stream-1.0.0.tgz#6c47f91d5b5df28bda9334c52782ef8e97fe3a4a"
+ integrity sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA==
+ dependencies:
+ buffer "^6.0.3"
+ fast-fifo "^1.0.0"
+ get-iterator "^1.0.2"
+ p-defer "^3.0.0"
+ p-fifo "^1.0.0"
+ readable-stream "^3.6.0"
+
+it-ws@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/it-ws/-/it-ws-4.0.0.tgz#2e5ef0bcd857c1a898cc32c176ab6cac8f8306ea"
+ integrity sha512-XmTzpMkevc6rUboy73r0CCNhciMmL/Yxir9O6FujRwdrjysztqLBQ1Xkr4CpY2m7BVSCObKotaCWJeZ29lOXRA==
+ dependencies:
+ buffer "^6.0.3"
+ event-iterator "^2.0.0"
+ iso-url "^1.1.2"
+ ws "^7.3.1"
+
+jest-changed-files@^24.9.0:
+ version "24.9.0"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039"
+ integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==
+ dependencies:
+ "@jest/types" "^24.9.0"
+ execa "^1.0.0"
+ throat "^4.0.0"
+
+jest-worker@^27.4.5:
+ version "27.5.1"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
+ integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==
+ dependencies:
+ "@types/node" "*"
+ merge-stream "^2.0.0"
+ supports-color "^8.0.0"
+
+joycon@^3.0.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03"
+ integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==
+
+js-sha3@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
+ integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
+
+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+js-waku@^0.16.0:
+ version "0.16.0"
+ resolved "https://registry.yarnpkg.com/js-waku/-/js-waku-0.16.0.tgz#2c426a90417564ab6e28a2d75cd735a6ea4fdc4a"
+ integrity sha512-7ngwKoFtUzCY/aUBTpH/HoU8a47hS+AKdckqC1WArI22wTF5OBDayLXozD1m9MYCViF/CuRqDR7RdvoJz0VBFQ==
+ dependencies:
+ "@chainsafe/libp2p-noise" "^5.0.0"
+ axios "^0.21.1"
+ base64url "^3.0.1"
+ bigint-buffer "^1.1.5"
+ debug "^4.3.1"
+ dns-query "^0.8.0"
+ ecies-geth "^1.5.2"
+ hi-base32 "^0.5.1"
+ it-concat "^2.0.0"
+ it-length-prefixed "^5.0.2"
+ js-sha3 "^0.8.0"
+ libp2p "^0.32.4"
+ libp2p-bootstrap "^0.14.0"
+ libp2p-gossipsub "^0.12.1"
+ libp2p-mplex "^0.10.4"
+ libp2p-websockets "^0.16.1"
+ multiaddr "^10.0.1"
+ multihashes "^4.0.3"
+ protobufjs "^6.8.8"
+ rlp "^2.2.7"
+ secp256k1 "^4.0.2"
+ uuid "^8.3.2"
+
+js-yaml@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+ integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+ dependencies:
+ argparse "^2.0.1"
+
+js-yaml@^3.13.1:
+ version "3.14.1"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
+ integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
+jsbn@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
+ integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA=
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+ integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+
+jsdom-global@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9"
+ integrity sha1-a9KZwTsMRiay2iwDk81DhdYGrLk=
+
+jsdom@^16.7.0:
+ version "16.7.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
+ integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
+ dependencies:
+ abab "^2.0.5"
+ acorn "^8.2.4"
+ acorn-globals "^6.0.0"
+ cssom "^0.4.4"
+ cssstyle "^2.3.0"
+ data-urls "^2.0.0"
+ decimal.js "^10.2.1"
+ domexception "^2.0.1"
+ escodegen "^2.0.0"
+ form-data "^3.0.0"
+ html-encoding-sniffer "^2.0.1"
+ http-proxy-agent "^4.0.1"
+ https-proxy-agent "^5.0.0"
+ is-potential-custom-element-name "^1.0.1"
+ nwsapi "^2.2.0"
+ parse5 "6.0.1"
+ saxes "^5.0.1"
+ symbol-tree "^3.2.4"
+ tough-cookie "^4.0.0"
+ w3c-hr-time "^1.0.2"
+ w3c-xmlserializer "^2.0.0"
+ webidl-conversions "^6.1.0"
+ whatwg-encoding "^1.0.5"
+ whatwg-mimetype "^2.3.0"
+ whatwg-url "^8.5.0"
+ ws "^7.4.6"
+ xml-name-validator "^3.0.0"
+
+jsesc@^2.5.1:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
+ integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+
+json-buffer@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
+ integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
+
+json-parse-better-errors@^1.0.1, 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"
+ integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
+
+json-parse-even-better-errors@^2.3.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
+ integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+
+json-schema-traverse@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+ integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+
+json-schema-traverse@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
+json-schema@0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
+ integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
+
+json-stable-stringify-without-jsonify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
+ integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+ integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
+
+json3@^3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
+ integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
+
+json5@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
+ integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+ dependencies:
+ minimist "^1.2.0"
+
+json5@^2.1.2, json5@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
+ integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
+ dependencies:
+ minimist "^1.2.5"
+
+jsonfile@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
+ integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
+ dependencies:
+ universalify "^2.0.0"
+ optionalDependencies:
+ graceful-fs "^4.1.6"
+
+jsprim@^1.2.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
+ integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.3.0"
+ json-schema "0.4.0"
+ verror "1.10.0"
+
+"jsx-ast-utils@^2.4.1 || ^3.0.0":
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b"
+ integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==
+ dependencies:
+ array-includes "^3.1.3"
+ object.assign "^4.1.2"
+
+keypair@^1.0.1, keypair@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/keypair/-/keypair-1.0.4.tgz#a749a45f388593f3950f18b3757d32a93bd8ce83"
+ integrity sha512-zwhgOhhniaL7oxMgUMKKw5219PWWABMO+dgMnzJOQ2/5L3XJtTJGhW2PEXlxXj9zaccdReZJZ83+4NPhVfNVDg==
+
+keyv@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
+ integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
+ dependencies:
+ json-buffer "3.0.0"
+
+killable@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
+ integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==
+
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
+ integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
+ dependencies:
+ is-buffer "^1.1.5"
+
+kind-of@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
+ integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc=
+ dependencies:
+ is-buffer "^1.1.5"
+
+kind-of@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
+ integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
+
+kind-of@^6.0.0, kind-of@^6.0.2:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
+ integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+
+latest-version@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face"
+ integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==
+ dependencies:
+ package-json "^6.3.0"
+
+levn@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
+ integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+ dependencies:
+ prelude-ls "^1.2.1"
+ type-check "~0.4.0"
+
+levn@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+ integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
+ dependencies:
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+
+libp2p-bootstrap@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/libp2p-bootstrap/-/libp2p-bootstrap-0.14.0.tgz#820cc2d259a4710c660d239c5e2043384a1317b2"
+ integrity sha512-j3slZo5nOdA8wVlav8dRZeAXutZ7psz/f10DLoIEX/EFif7uU5oZfIYvjbVGo3ZDl+VQLo2tR0m1lV0westQ3g==
+ dependencies:
+ debug "^4.3.1"
+ mafmt "^10.0.0"
+ multiaddr "^10.0.0"
+ peer-id "^0.16.0"
+
+libp2p-crypto@^0.19.4:
+ version "0.19.7"
+ resolved "https://registry.yarnpkg.com/libp2p-crypto/-/libp2p-crypto-0.19.7.tgz#e96a95bd430e672a695209fe0fbd2bcbd348bc35"
+ integrity sha512-Qb5o/3WFKF2j6mYSt4UBPyi2kbKl3jYV0podBJoJCw70DlpM5Xc+oh3fFY9ToSunu8aSQQ5GY8nutjXgX/uGRA==
+ dependencies:
+ err-code "^3.0.1"
+ is-typedarray "^1.0.0"
+ iso-random-stream "^2.0.0"
+ keypair "^1.0.1"
+ multiformats "^9.4.5"
+ node-forge "^0.10.0"
+ pem-jwk "^2.0.0"
+ protobufjs "^6.11.2"
+ secp256k1 "^4.0.0"
+ uint8arrays "^3.0.0"
+ ursa-optional "^0.10.1"
+
+libp2p-crypto@^0.20.0:
+ version "0.20.0"
+ resolved "https://registry.yarnpkg.com/libp2p-crypto/-/libp2p-crypto-0.20.0.tgz#3881ccff5f1f51f48c74050d685535fb1a728488"
+ integrity sha512-WgIW9rYcWaO/5j2T6NW3R6Q46yvp2ZfFErqRMbi4/pOTL3T7+OROYpL/1iWVksWkXyurU/t2qFsIijWMxR5C4Q==
+ dependencies:
+ err-code "^3.0.1"
+ iso-random-stream "^2.0.0"
+ keypair "^1.0.4"
+ multiformats "^9.4.5"
+ noble-ed25519 "^1.2.6"
+ noble-secp256k1 "^1.2.10"
+ node-forge "^0.10.0"
+ pem-jwk "^2.0.0"
+ protobufjs "^6.11.2"
+ uint8arrays "^3.0.0"
+ ursa-optional "^0.10.1"
+
+libp2p-crypto@^0.21.0:
+ version "0.21.2"
+ resolved "https://registry.yarnpkg.com/libp2p-crypto/-/libp2p-crypto-0.21.2.tgz#7f9875436f24ca3887b077210b217b702bd72916"
+ integrity sha512-EXFrhSpiHtJ+/L8xXDvQNK5VjUMG51u878jzZcaT5XhuN/zFg6PWJFnl/qB2Y2j7eMWnvCRP7Kp+ua2H36cG4g==
+ dependencies:
+ "@noble/ed25519" "^1.5.1"
+ "@noble/secp256k1" "^1.3.0"
+ err-code "^3.0.1"
+ iso-random-stream "^2.0.0"
+ multiformats "^9.4.5"
+ node-forge "^1.2.1"
+ protobufjs "^6.11.2"
+ uint8arrays "^3.0.0"
+
+libp2p-gossipsub@^0.12.1:
+ version "0.12.3"
+ resolved "https://registry.yarnpkg.com/libp2p-gossipsub/-/libp2p-gossipsub-0.12.3.tgz#28c34166e927670ae47609c0df7577d749a74345"
+ integrity sha512-Oyjt1jGoQm4t/L6t+NUToQPP5kwTailzFrzTnNTVSfKi8WCUty2ua2ttnq3ZEG4rUxlGDgqmOQoI6bfmjdvRNw==
+ dependencies:
+ "@types/debug" "^4.1.5"
+ debug "^4.3.1"
+ denque "^1.5.0"
+ err-code "^3.0.1"
+ it-pipe "^1.1.0"
+ libp2p-interfaces "^2.0.1"
+ peer-id "^0.16.0"
+ protobufjs "^6.11.2"
+ time-cache "^0.3.0"
+ uint8arrays "^3.0.0"
+
+libp2p-interfaces@^1.0.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/libp2p-interfaces/-/libp2p-interfaces-1.3.1.tgz#193dccffefd709b24f689bc7ac2e3bb67299f90b"
+ integrity sha512-Bh991Nv2KT/jZ7DjPd/zqhk8cCtkHl6OWw8lyK7wBX7Aj3/ezGwjoDABJzKgt1lbvcgCeQIbzPiIbaKj4DUI4w==
+ dependencies:
+ abort-controller "^3.0.0"
+ abortable-iterator "^3.0.0"
+ debug "^4.3.1"
+ err-code "^3.0.1"
+ it-length-prefixed "^5.0.2"
+ it-pipe "^1.1.0"
+ it-pushable "^1.4.2"
+ libp2p-crypto "^0.20.0"
+ multiaddr "^10.0.0"
+ multiformats "^9.1.2"
+ p-queue "^6.6.2"
+ peer-id "^0.15.4"
+ protobufjs "^6.10.2"
+ uint8arrays "^3.0.0"
+
+libp2p-interfaces@^2.0.1:
+ version "2.0.9"
+ resolved "https://registry.yarnpkg.com/libp2p-interfaces/-/libp2p-interfaces-2.0.9.tgz#ae3995a07ee885355972c02bc5359fd9f0c2c88f"
+ integrity sha512-KYPYBy7dprcc9cy9PdoJyljs//Gb7A1448jNl/egfxIETKZl4uvYK66l4lzLtKB3AblIxATB8BFWEY/ph86QIA==
+ dependencies:
+ abortable-iterator "^3.0.0"
+ debug "^4.3.1"
+ err-code "^3.0.1"
+ it-length-prefixed "^5.0.2"
+ it-pipe "^1.1.0"
+ it-pushable "^1.4.2"
+ libp2p-crypto "^0.21.0"
+ multiaddr "^10.0.0"
+ multiformats "^9.1.2"
+ p-queue "^6.6.2"
+ peer-id "^0.16.0"
+ protobufjs "^6.10.2"
+ uint8arrays "^3.0.0"
+
+libp2p-mplex@^0.10.4:
+ version "0.10.7"
+ resolved "https://registry.yarnpkg.com/libp2p-mplex/-/libp2p-mplex-0.10.7.tgz#2d62e85087964f9cf973173042e40f72b7ca0398"
+ integrity sha512-21VV0DZWuOsHgitWy1GZD1M/kki3a/hVoAJ5QC48p01JNSK5W8gxRiZtq7cCGJ/xNpbQxvMlMtS5eq8CFRlysg==
+ dependencies:
+ abortable-iterator "^3.0.2"
+ bl "^5.0.0"
+ debug "^4.3.1"
+ err-code "^3.0.1"
+ it-pipe "^1.1.0"
+ it-pushable "^1.4.1"
+ varint "^6.0.0"
+
+libp2p-utils@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/libp2p-utils/-/libp2p-utils-0.4.1.tgz#260405434c376db8a1d9023867373b99b81c657f"
+ integrity sha512-kq/US2unamiyY+YwP47dO1uqpAdcbdYI2Fzi9JIEhjfPBaD1MR/uyQ/YP7ABthl3EaxAjIQYd1TVp85d6QKAtQ==
+ dependencies:
+ abortable-iterator "^3.0.0"
+ debug "^4.3.0"
+ err-code "^3.0.1"
+ ip-address "^8.0.0"
+ is-loopback-addr "^1.0.0"
+ multiaddr "^10.0.0"
+ private-ip "^2.1.1"
+
+libp2p-websockets@^0.16.1:
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/libp2p-websockets/-/libp2p-websockets-0.16.2.tgz#4eca653b3ae9593d3dd5dd467a58aed03cc92e3a"
+ integrity sha512-QGfo8jX1Ks16yi8C67CCyMW7k9cfCYiQ0lzKVJBud0fV3ymbMO2L8gzU6iXUUZTHILo8ka26zKhwQ4lmUMI+nA==
+ dependencies:
+ abortable-iterator "^3.0.0"
+ class-is "^1.1.0"
+ debug "^4.3.1"
+ err-code "^3.0.1"
+ ipfs-utils "^9.0.1"
+ it-ws "^4.0.0"
+ libp2p-utils "^0.4.0"
+ mafmt "^10.0.0"
+ multiaddr "^10.0.0"
+ multiaddr-to-uri "^8.0.0"
+ p-defer "^3.0.0"
+ p-timeout "^4.1.0"
+
+libp2p@^0.32.4:
+ version "0.32.5"
+ resolved "https://registry.yarnpkg.com/libp2p/-/libp2p-0.32.5.tgz#e5ecf4d82d3b90683f4b1ef5e2374b044c85dda1"
+ integrity sha512-G21yQUdq4LaGDvjMi3ySmcx1cESl8ZsTG1BAfjzjx65DsZJKQ5GPZlamcv+Rwppk3OIplWoRnCu6gam/fI//bw==
+ dependencies:
+ "@motrix/nat-api" "^0.3.1"
+ "@vascosantos/moving-average" "^1.1.0"
+ abort-controller "^3.0.0"
+ abortable-iterator "^3.0.0"
+ aggregate-error "^3.1.0"
+ any-signal "^2.1.1"
+ bignumber.js "^9.0.1"
+ class-is "^1.1.0"
+ debug "^4.3.1"
+ err-code "^3.0.0"
+ es6-promisify "^7.0.0"
+ events "^3.3.0"
+ hashlru "^2.3.0"
+ interface-datastore "^5.1.1"
+ it-all "^1.0.4"
+ it-buffer "^0.1.2"
+ it-drain "^1.0.3"
+ it-filter "^1.0.1"
+ it-first "^1.0.4"
+ it-handshake "^2.0.0"
+ it-length-prefixed "^5.0.2"
+ it-map "^1.0.4"
+ it-merge "^1.0.0"
+ it-pipe "^1.1.0"
+ it-take "^1.0.0"
+ libp2p-crypto "^0.19.4"
+ libp2p-interfaces "^1.0.0"
+ libp2p-utils "^0.4.0"
+ mafmt "^10.0.0"
+ merge-options "^3.0.4"
+ multiaddr "^10.0.0"
+ multiformats "^9.0.0"
+ multistream-select "^2.0.0"
+ mutable-proxy "^1.0.0"
+ node-forge "^0.10.0"
+ p-any "^3.0.0"
+ p-fifo "^1.0.0"
+ p-retry "^4.4.0"
+ p-settle "^4.1.1"
+ peer-id "^0.15.0"
+ private-ip "^2.1.0"
+ protobufjs "^6.10.2"
+ retimer "^3.0.0"
+ sanitize-filename "^1.6.3"
+ set-delayed-interval "^1.0.0"
+ streaming-iterables "^6.0.0"
+ timeout-abort-controller "^1.1.1"
+ uint8arrays "^3.0.0"
+ varint "^6.0.0"
+ wherearewe "^1.0.0"
+ xsalsa20 "^1.1.0"
+
+lines-and-columns@^1.1.6:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
+ integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
+
+load-json-file@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
+ integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs=
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^4.0.0"
+ pify "^3.0.0"
+ strip-bom "^3.0.0"
+
+loader-runner@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
+ integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
+
+loader-utils@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
+ integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
+ dependencies:
+ big.js "^5.2.2"
+ emojis-list "^3.0.0"
+ json5 "^2.1.2"
+
+locate-path@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
+ integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
+ dependencies:
+ p-locate "^2.0.0"
+ path-exists "^3.0.0"
+
+locate-path@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
+ integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
+ dependencies:
+ p-locate "^3.0.0"
+ path-exists "^3.0.0"
+
+locate-path@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
+ integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
+ dependencies:
+ p-locate "^4.1.0"
+
+locate-path@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
+ integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+ dependencies:
+ p-locate "^5.0.0"
+
+lodash.merge@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+
+lodash.throttle@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
+ integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
+
+lodash.truncate@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
+ integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
+
+lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+log-symbols@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
+ integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
+ dependencies:
+ chalk "^4.1.0"
+ is-unicode-supported "^0.1.0"
+
+loglevel@^1.6.8:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114"
+ integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==
+
+long@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
+ integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
+
+loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
+loupe@^2.3.1:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3"
+ integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==
+ dependencies:
+ get-func-name "^2.0.0"
+
+lower-case@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
+ integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
+ dependencies:
+ tslib "^2.0.3"
+
+lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
+ integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
+
+lowercase-keys@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
+ integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
+
+lru-cache@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
+ integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+ dependencies:
+ yallist "^4.0.0"
+
+mafmt@^10.0.0:
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/mafmt/-/mafmt-10.0.0.tgz#431726f16e51090b32ada621c402acbdb64fce9c"
+ integrity sha512-K1bziJOXcnepfztu+2Xy9FLKVLaFMDuspmiyJIYRxnO0WOxFSV7XKSdMxMrVZxcvg1+YjlTIvSGTImUHU2k4Aw==
+ dependencies:
+ multiaddr "^10.0.0"
+
+make-dir@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
+ integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
+ dependencies:
+ semver "^6.0.0"
+
+make-error@^1.1.1:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
+ integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+
+map-cache@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
+ integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
+
+map-visit@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
+ integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=
+ dependencies:
+ object-visit "^1.0.0"
+
+md5.js@^1.3.4:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
+ integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
+ dependencies:
+ hash-base "^3.0.0"
+ inherits "^2.0.1"
+ safe-buffer "^5.1.2"
+
+media-typer@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
+ integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
+
+memfs@^3.1.2:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305"
+ integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==
+ dependencies:
+ fs-monkey "1.0.3"
+
+memory-fs@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
+ integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
+ dependencies:
+ errno "^0.1.3"
+ readable-stream "^2.0.1"
+
+memorystream@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
+ integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=
+
+merge-descriptors@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+ integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
+
+merge-options@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7"
+ integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==
+ dependencies:
+ is-plain-obj "^2.1.0"
+
+merge-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
+ integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+
+merge2@^1.3.0, merge2@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
+ integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+methods@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+ integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
+
+micromatch@^3.1.10, micromatch@^3.1.4:
+ version "3.1.10"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
+ integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
+ dependencies:
+ arr-diff "^4.0.0"
+ array-unique "^0.3.2"
+ braces "^2.3.1"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ extglob "^2.0.4"
+ fragment-cache "^0.2.1"
+ kind-of "^6.0.2"
+ nanomatch "^1.2.9"
+ object.pick "^1.3.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.2"
+
+micromatch@^4.0.0, micromatch@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
+ integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+ dependencies:
+ braces "^3.0.1"
+ picomatch "^2.2.3"
+
+miller-rabin@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
+ integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
+ dependencies:
+ bn.js "^4.0.0"
+ brorand "^1.0.1"
+
+mime-db@1.51.0:
+ version "1.51.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
+ integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
+
+"mime-db@>= 1.43.0 < 2":
+ version "1.52.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
+mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
+ version "2.1.34"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
+ integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
+ dependencies:
+ mime-db "1.51.0"
+
+mime@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+ integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
+
+mime@^2.4.4:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
+ integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
+
+mimic-fn@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
+ integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
+mimic-response@^1.0.0, mimic-response@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
+ integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
+
+mini-create-react-context@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e"
+ integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
+ dependencies:
+ "@babel/runtime" "^7.12.1"
+ tiny-warning "^1.0.3"
+
+minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
+ integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
+
+minimalistic-crypto-utils@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
+ integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
+
+minimatch@3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+ integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimatch@^3.0.3, minimatch@^3.0.4:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
+ integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimist@^1.2.0, minimist@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+ integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+
+mixin-deep@^1.2.0:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
+ integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==
+ dependencies:
+ for-in "^1.0.2"
+ is-extendable "^1.0.1"
+
+mkdirp@^0.5.1, mkdirp@^0.5.5:
+ version "0.5.5"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
+ integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
+ dependencies:
+ minimist "^1.2.5"
+
+mkdirp@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
+ integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+
+mocha@^9.0.3, mocha@^9.1.1:
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e"
+ integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==
+ dependencies:
+ "@ungap/promise-all-settled" "1.1.2"
+ ansi-colors "4.1.1"
+ browser-stdout "1.3.1"
+ chokidar "3.5.3"
+ debug "4.3.3"
+ diff "5.0.0"
+ escape-string-regexp "4.0.0"
+ find-up "5.0.0"
+ glob "7.2.0"
+ growl "1.10.5"
+ he "1.2.0"
+ js-yaml "4.1.0"
+ log-symbols "4.1.0"
+ minimatch "3.0.4"
+ ms "2.1.3"
+ nanoid "3.2.0"
+ serialize-javascript "6.0.0"
+ strip-json-comments "3.1.1"
+ supports-color "8.1.1"
+ which "2.0.2"
+ workerpool "6.2.0"
+ yargs "16.2.0"
+ yargs-parser "20.2.4"
+ yargs-unparser "2.0.0"
+
+ms@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+ integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+
+ms@2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+ integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+ms@2.1.3, ms@^2.1.1:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+multiaddr-to-uri@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/multiaddr-to-uri/-/multiaddr-to-uri-8.0.0.tgz#65efe4b1f9de5f6b681aa42ff36a7c8db7625e58"
+ integrity sha512-dq4p/vsOOUdVEd1J1gl+R2GFrXJQH8yjLtz4hodqdVbieg39LvBOdMQRdQnfbg5LSM/q1BYNVf5CBbwZFFqBgA==
+ dependencies:
+ multiaddr "^10.0.0"
+
+multiaddr@^10.0.0, multiaddr@^10.0.1:
+ version "10.0.1"
+ resolved "https://registry.yarnpkg.com/multiaddr/-/multiaddr-10.0.1.tgz#0d15848871370860a4d266bb44d93b3dac5d90ef"
+ integrity sha512-G5upNcGzEGuTHkzxezPrrD6CaIHR9uo+7MwqhNVcXTs33IInon4y7nMiGxl2CY5hG7chvYQUQhz5V52/Qe3cbg==
+ dependencies:
+ dns-over-http-resolver "^1.2.3"
+ err-code "^3.0.1"
+ is-ip "^3.1.0"
+ multiformats "^9.4.5"
+ uint8arrays "^3.0.0"
+ varint "^6.0.0"
+
+multibase@^4.0.1:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.6.tgz#6e624341483d6123ca1ede956208cb821b440559"
+ integrity sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==
+ dependencies:
+ "@multiformats/base-x" "^4.0.1"
+
+multicast-dns-service-types@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
+ integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=
+
+multicast-dns@^6.0.1:
+ version "6.2.3"
+ resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229"
+ integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==
+ dependencies:
+ dns-packet "^1.3.1"
+ thunky "^1.0.2"
+
+multiformats@^9.0.0, multiformats@^9.1.2, multiformats@^9.4.2, multiformats@^9.4.5:
+ version "9.6.4"
+ resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.6.4.tgz#5dce1f11a407dbb69aa612cb7e5076069bb759ca"
+ integrity sha512-fCCB6XMrr6CqJiHNjfFNGT0v//dxOBMrOMqUIzpPc/mmITweLEyhvMpY9bF+jZ9z3vaMAau5E8B68DW77QMXkg==
+
+multihashes@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-4.0.3.tgz#426610539cd2551edbf533adeac4c06b3b90fb05"
+ integrity sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==
+ dependencies:
+ multibase "^4.0.1"
+ uint8arrays "^3.0.0"
+ varint "^5.0.2"
+
+multistream-select@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/multistream-select/-/multistream-select-2.0.1.tgz#120608d54c146762d16d1df5919a2f0326a78527"
+ integrity sha512-ziVNT/vux0uUElP4OKNMVr0afU/X6PciAmT2UJNolhzhSLXIwFAaYfmLajD8NoZ+DsBQ1bp0zZ2nMVPF+FhClA==
+ dependencies:
+ bl "^5.0.0"
+ debug "^4.1.1"
+ err-code "^3.0.1"
+ it-first "^1.0.6"
+ it-handshake "^2.0.0"
+ it-length-prefixed "^5.0.0"
+ it-pipe "^1.0.1"
+ it-reader "^3.0.0"
+ p-defer "^3.0.0"
+ uint8arrays "^3.0.0"
+
+mutable-proxy@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/mutable-proxy/-/mutable-proxy-1.0.0.tgz#3c6e6f9304c2e5a4751bb65b5a66677de9bcf3c8"
+ integrity sha512-4OvNRr1DJpy2QuDUV74m+BWZ//n4gG4bmd21MzDSPqHEidIDWqwyOjcadU1LBMO3vXYGurVKjfBrxrSQIHFu9A==
+
+nan@^2.12.1, nan@^2.14.2:
+ version "2.15.0"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
+ integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
+
+nanoid@3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
+ integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
+
+nanoid@^3.0.2, nanoid@^3.1.20, nanoid@^3.2.0:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
+ integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
+
+nanomatch@^1.2.9:
+ version "1.2.13"
+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
+ integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==
+ dependencies:
+ arr-diff "^4.0.0"
+ array-unique "^0.3.2"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ fragment-cache "^0.2.1"
+ is-windows "^1.0.2"
+ kind-of "^6.0.2"
+ object.pick "^1.3.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+native-abort-controller@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/native-abort-controller/-/native-abort-controller-1.0.4.tgz#39920155cc0c18209ff93af5bc90be856143f251"
+ integrity sha512-zp8yev7nxczDJMoP6pDxyD20IU0T22eX8VwN2ztDccKvSZhRaV33yP1BGwKSZfXuqWUzsXopVFjBdau9OOAwMQ==
+
+native-fetch@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/native-fetch/-/native-fetch-3.0.0.tgz#06ccdd70e79e171c365c75117959cf4fe14a09bb"
+ integrity sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==
+
+natural-compare@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+ integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
+
+negotiator@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
+ integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
+
+neo-async@^2.6.2:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
+ integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+
+netmask@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
+ integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
+
+nice-try@^1.0.4:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
+ integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
+
+no-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
+ integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
+ dependencies:
+ lower-case "^2.0.2"
+ tslib "^2.0.3"
+
+noble-ed25519@^1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/noble-ed25519/-/noble-ed25519-1.2.6.tgz#a55b75c61da000498abb43ffd81caaa370bfed22"
+ integrity sha512-zfnWqg9FVMp8CnzUpAjbt1nDXpDjCvxYiCXdnW1mY8zQHw/6twUlkFm14VPdojVzc0kcd+i9zT79+26GcNbsuQ==
+
+noble-secp256k1@^1.2.10:
+ version "1.2.14"
+ resolved "https://registry.yarnpkg.com/noble-secp256k1/-/noble-secp256k1-1.2.14.tgz#39429c941d51211ca40161569cee03e61d72599e"
+ integrity sha512-GSCXyoZBUaaPwVWdYncMEmzlSUjF9J/YeEHpklYJCyg8wPuJP3NzDx0BkiwArzINkdX2HJHvUJhL6vVWPOQQcg==
+
+node-addon-api@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32"
+ integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
+
+node-fetch@^2.6.0:
+ version "2.6.7"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
+ integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
+ dependencies:
+ whatwg-url "^5.0.0"
+
+"node-fetch@https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz":
+ version "2.6.7"
+ uid "1b5d62978f2ed07b99444f64f0df39f960a6d34d"
+ resolved "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz#1b5d62978f2ed07b99444f64f0df39f960a6d34d"
+
+node-forge@^0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
+ integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
+
+node-forge@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c"
+ integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==
+
+node-gyp-build@^4.2.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
+ integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
+
+node-releases@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
+ integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
+
+nodemon@^2.0.7:
+ version "2.0.15"
+ resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e"
+ integrity sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==
+ dependencies:
+ chokidar "^3.5.2"
+ debug "^3.2.7"
+ ignore-by-default "^1.0.1"
+ minimatch "^3.0.4"
+ pstree.remy "^1.1.8"
+ semver "^5.7.1"
+ supports-color "^5.5.0"
+ touch "^3.1.0"
+ undefsafe "^2.0.5"
+ update-notifier "^5.1.0"
+
+noms@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859"
+ integrity sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "~1.0.31"
+
+nopt@~1.0.10:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
+ integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=
+ dependencies:
+ abbrev "1"
+
+normalize-package-data@^2.3.2:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
+ integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
+ dependencies:
+ hosted-git-info "^2.1.4"
+ resolve "^1.10.0"
+ semver "2 || 3 || 4 || 5"
+ validate-npm-package-license "^3.0.1"
+
+normalize-path@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
+ integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=
+ dependencies:
+ remove-trailing-separator "^1.0.1"
+
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+ integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
+normalize-url@^4.1.0:
+ version "4.5.1"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
+ integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
+
+npm-run-all@^4.1.5:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
+ integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
+ dependencies:
+ ansi-styles "^3.2.1"
+ chalk "^2.4.1"
+ cross-spawn "^6.0.5"
+ memorystream "^0.3.1"
+ minimatch "^3.0.4"
+ pidtree "^0.3.0"
+ read-pkg "^3.0.0"
+ shell-quote "^1.6.1"
+ string.prototype.padend "^3.0.0"
+
+npm-run-path@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
+ integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
+ dependencies:
+ path-key "^2.0.0"
+
+npm-run-path@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
+ integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
+ dependencies:
+ path-key "^3.0.0"
+
+npm-watch@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/npm-watch/-/npm-watch-0.11.0.tgz#d052d9832ad2923dcf937a35aff0c2db678a8a2e"
+ integrity sha512-wAOd0moNX2kSA2FNvt8+7ORwYaJpQ1ZoWjUYdb1bBCxq4nkWuU0IiJa9VpVxrj5Ks+FGXQd62OC/Bjk0aSr+dg==
+ dependencies:
+ nodemon "^2.0.7"
+ through2 "^4.0.2"
+
+nth-check@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2"
+ integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
+ dependencies:
+ boolbase "^1.0.0"
+
+nwsapi@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
+ integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
+
+oauth-sign@~0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
+ integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
+
+object-assign@^4.0.1, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+ integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
+
+object-copy@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
+ integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw=
+ dependencies:
+ copy-descriptor "^0.1.0"
+ define-property "^0.2.5"
+ kind-of "^3.0.3"
+
+object-hash@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
+ integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
+
+object-inspect@^1.11.0, object-inspect@^1.9.0:
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
+ integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
+
+object-is@^1.0.1:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
+ integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+
+object-keys@^1.0.12, object-keys@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
+ integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
+
+object-visit@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
+ integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=
+ dependencies:
+ isobject "^3.0.0"
+
+object.assign@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
+ integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ has-symbols "^1.0.1"
+ object-keys "^1.1.1"
+
+object.entries@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
+ integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+object.fromentries@^2.0.3, object.fromentries@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
+ integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+object.hasown@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5"
+ integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+object.pick@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
+ integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=
+ dependencies:
+ isobject "^3.0.1"
+
+object.values@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
+ integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+obuf@^1.0.0, obuf@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
+ integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
+
+on-finished@~2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
+ integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
+ dependencies:
+ ee-first "1.1.1"
+
+on-headers@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
+ integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
+
+once@^1.3.0, once@^1.3.1, once@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+ dependencies:
+ wrappy "1"
+
+onetime@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
+ integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
+ dependencies:
+ mimic-fn "^2.1.0"
+
+opn@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
+ integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==
+ dependencies:
+ is-wsl "^1.1.0"
+
+optionator@^0.8.1:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
+ integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
+ dependencies:
+ deep-is "~0.1.3"
+ fast-levenshtein "~2.0.6"
+ levn "~0.3.0"
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+ word-wrap "~1.2.3"
+
+optionator@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
+ integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
+ dependencies:
+ deep-is "^0.1.3"
+ fast-levenshtein "^2.0.6"
+ levn "^0.4.1"
+ prelude-ls "^1.2.1"
+ type-check "^0.4.0"
+ word-wrap "^1.2.3"
+
+original@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
+ integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==
+ dependencies:
+ url-parse "^1.4.3"
+
+p-any@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/p-any/-/p-any-3.0.0.tgz#79847aeed70b5d3a10ea625296c0c3d2e90a87b9"
+ integrity sha512-5rqbqfsRWNb0sukt0awwgJMlaep+8jV45S15SKKB34z4UuzjcofIfnriCBhWjZP2jbVtjt9yRl7buB6RlKsu9w==
+ dependencies:
+ p-cancelable "^2.0.0"
+ p-some "^5.0.0"
+
+p-cancelable@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
+ integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
+
+p-cancelable@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
+ integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
+
+p-defer@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83"
+ integrity sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==
+
+p-fifo@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-fifo/-/p-fifo-1.0.0.tgz#e29d5cf17c239ba87f51dde98c1d26a9cfe20a63"
+ integrity sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==
+ dependencies:
+ fast-fifo "^1.0.0"
+ p-defer "^3.0.0"
+
+p-finally@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+ integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
+
+p-limit@^1.1.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
+ integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
+ dependencies:
+ p-try "^1.0.0"
+
+p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.2:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
+ integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+ dependencies:
+ p-try "^2.0.0"
+
+p-limit@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+ integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+ dependencies:
+ yocto-queue "^0.1.0"
+
+p-locate@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
+ integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
+ dependencies:
+ p-limit "^1.1.0"
+
+p-locate@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
+ integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
+ dependencies:
+ p-limit "^2.0.0"
+
+p-locate@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
+ integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
+ dependencies:
+ p-limit "^2.2.0"
+
+p-locate@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
+ integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+ dependencies:
+ p-limit "^3.0.2"
+
+p-map@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
+ integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
+
+p-queue@^6.6.2:
+ version "6.6.2"
+ resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426"
+ integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==
+ dependencies:
+ eventemitter3 "^4.0.4"
+ p-timeout "^3.2.0"
+
+p-reflect@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/p-reflect/-/p-reflect-2.1.0.tgz#5d67c7b3c577c4e780b9451fc9129675bd99fe67"
+ integrity sha512-paHV8NUz8zDHu5lhr/ngGWQiW067DK/+IbJ+RfZ4k+s8y4EKyYCz8pGYWjxCg35eHztpJAt+NUgvN4L+GCbPlg==
+
+p-retry@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328"
+ integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==
+ dependencies:
+ retry "^0.12.0"
+
+p-retry@^4.4.0:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c"
+ integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==
+ dependencies:
+ "@types/retry" "^0.12.0"
+ retry "^0.13.1"
+
+p-settle@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/p-settle/-/p-settle-4.1.1.tgz#37fbceb2b02c9efc28658fc8d36949922266035f"
+ integrity sha512-6THGh13mt3gypcNMm0ADqVNCcYa3BK6DWsuJWFCuEKP1rpY+OKGp7gaZwVmLspmic01+fsg/fN57MfvDzZ/PuQ==
+ dependencies:
+ p-limit "^2.2.2"
+ p-reflect "^2.1.0"
+
+p-some@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/p-some/-/p-some-5.0.0.tgz#8b730c74b4fe5169d7264a240ad010b6ebc686a4"
+ integrity sha512-Js5XZxo6vHjB9NOYAzWDYAIyyiPvva0DWESAIWIK7uhSpGsyg5FwUPxipU/SOQx5x9EqhOh545d1jo6cVkitig==
+ dependencies:
+ aggregate-error "^3.0.0"
+ p-cancelable "^2.0.0"
+
+p-timeout@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe"
+ integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==
+ dependencies:
+ p-finally "^1.0.0"
+
+p-timeout@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-4.1.0.tgz#788253c0452ab0ffecf18a62dff94ff1bd09ca0a"
+ integrity sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==
+
+p-try@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+ integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
+
+p-try@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
+ integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+
+package-json@^6.3.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
+ integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
+ dependencies:
+ got "^9.6.0"
+ registry-auth-token "^4.0.0"
+ registry-url "^5.0.0"
+ semver "^6.2.0"
+
+pako@~1.0.5:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
+ integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
+
+param-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
+ integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
+ dependencies:
+ dot-case "^3.0.4"
+ tslib "^2.0.3"
+
+parent-module@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
+ integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
+ dependencies:
+ callsites "^3.0.0"
+
+parse-asn1@^5.0.0, parse-asn1@^5.1.5:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4"
+ integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==
+ dependencies:
+ asn1.js "^5.2.0"
+ browserify-aes "^1.0.0"
+ evp_bytestokey "^1.0.0"
+ pbkdf2 "^3.0.3"
+ safe-buffer "^5.1.1"
+
+parse-json@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+ integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
+ dependencies:
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+
+parse-json@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
+ integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ error-ex "^1.3.1"
+ json-parse-even-better-errors "^2.3.0"
+ lines-and-columns "^1.1.6"
+
+parse5@6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
+ integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
+
+parseurl@~1.3.2, parseurl@~1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
+ integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
+
+pascal-case@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb"
+ integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==
+ dependencies:
+ no-case "^3.0.4"
+ tslib "^2.0.3"
+
+pascalcase@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
+ integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
+
+path-dirname@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
+ integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
+
+path-exists@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
+ integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+ integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
+
+path-is-inside@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
+ integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
+
+path-key@^2.0.0, path-key@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
+ integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
+
+path-key@^3.0.0, path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-parse@^1.0.6, path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+path-to-regexp@0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
+ integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
+
+path-to-regexp@^1.7.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
+ integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
+ dependencies:
+ isarray "0.0.1"
+
+path-type@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
+ integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
+ dependencies:
+ pify "^3.0.0"
+
+path-type@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
+ integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+
+pathval@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
+ integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
+
+pbkdf2@^3.0.3, pbkdf2@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
+ integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==
+ dependencies:
+ create-hash "^1.1.2"
+ create-hmac "^1.1.4"
+ ripemd160 "^2.0.1"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+
+peer-id@^0.15.0, peer-id@^0.15.4:
+ version "0.15.4"
+ resolved "https://registry.yarnpkg.com/peer-id/-/peer-id-0.15.4.tgz#ae55e0dfb41d261266c051b4df4885a18d76b33d"
+ integrity sha512-MDoBIMZYwQIAHaZQUwsIcvoFgdbIl5GtZMwSkXpIYvc5v0TSDv+u8WsTKrKt2Vv28tHFFDJQdVzu3T4qTPzK+w==
+ dependencies:
+ class-is "^1.1.0"
+ libp2p-crypto "^0.20.0"
+ minimist "^1.2.5"
+ multiformats "^9.4.5"
+ protobufjs "^6.10.2"
+ uint8arrays "^3.0.0"
+
+peer-id@^0.16.0:
+ version "0.16.0"
+ resolved "https://registry.yarnpkg.com/peer-id/-/peer-id-0.16.0.tgz#0913062cfa4378707fe69c949b5720b3efadbf32"
+ integrity sha512-EmL7FurFUduU9m1PS9cfJ5TAuCvxKQ7DKpfx3Yj6IKWyBRtosriFuOag/l3ni/dtPgPLwiA4R9IvpL7hsDLJuQ==
+ dependencies:
+ class-is "^1.1.0"
+ libp2p-crypto "^0.21.0"
+ multiformats "^9.4.5"
+ protobufjs "^6.10.2"
+ uint8arrays "^3.0.0"
+
+pem-jwk@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/pem-jwk/-/pem-jwk-2.0.0.tgz#1c5bb264612fc391340907f5c1de60c06d22f085"
+ integrity sha512-rFxu7rVoHgQ5H9YsP50dDWf0rHjreVA2z0yPiWr5WdH/UHb29hKtF7h6l8vNd1cbYR1t0QL+JKhW55a2ZV4KtA==
+ dependencies:
+ asn1.js "^5.0.1"
+
+performance-now@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+ integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+
+picocolors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
+ integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+pidtree@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a"
+ integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==
+
+pify@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+ integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
+
+pify@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
+ integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
+
+pify@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
+ integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
+
+pinkie-promise@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+ integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
+
+pkg-dir@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
+ integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==
+ dependencies:
+ find-up "^3.0.0"
+
+pkg-dir@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
+ integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
+ dependencies:
+ find-up "^4.0.0"
+
+portfinder@^1.0.26:
+ version "1.0.28"
+ resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
+ integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==
+ dependencies:
+ async "^2.6.2"
+ debug "^3.1.1"
+ mkdirp "^0.5.5"
+
+posix-character-classes@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
+ integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
+
+postcss-modules-extract-imports@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d"
+ integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==
+
+postcss-modules-local-by-default@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c"
+ integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==
+ dependencies:
+ icss-utils "^5.0.0"
+ postcss-selector-parser "^6.0.2"
+ postcss-value-parser "^4.1.0"
+
+postcss-modules-scope@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06"
+ integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==
+ dependencies:
+ postcss-selector-parser "^6.0.4"
+
+postcss-modules-values@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c"
+ integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==
+ dependencies:
+ icss-utils "^5.0.0"
+
+postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
+ version "6.0.9"
+ resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f"
+ integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==
+ dependencies:
+ cssesc "^3.0.0"
+ util-deprecate "^1.0.2"
+
+postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
+ integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
+
+postcss@^8.4.5:
+ version "8.4.6"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1"
+ integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==
+ dependencies:
+ nanoid "^3.2.0"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.2"
+
+prelude-ls@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
+ integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+
+prelude-ls@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+ integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
+
+prepend-http@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
+ integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
+
+prettier@^2.3.2, prettier@^2.4.0, prettier@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
+ integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==
+
+pretty-error@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6"
+ integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==
+ dependencies:
+ lodash "^4.17.20"
+ renderkid "^3.0.0"
+
+private-ip@^2.1.0, private-ip@^2.1.1:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.3.tgz#1e80ff8443e5ac78f555631aec3ea6ff027fa6aa"
+ integrity sha512-5zyFfekIVUOTVbL92hc8LJOtE/gyGHeREHkJ2yTyByP8Q2YZVoBqLg3EfYLeF0oVvGqtaEX2t2Qovja0/gStXw==
+ dependencies:
+ ip-regex "^4.3.0"
+ ipaddr.js "^2.0.1"
+ is-ip "^3.1.0"
+ netmask "^2.0.2"
+
+process-nextick-args@~2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
+ integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+
+process@^0.11.10:
+ version "0.11.10"
+ resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
+ integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
+
+progress@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
+ integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
+
+prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
+ version "15.8.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+ integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.13.1"
+
+protobufjs@^6.10.2, protobufjs@^6.11.2, protobufjs@^6.8.8:
+ version "6.11.2"
+ resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b"
+ integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==
+ dependencies:
+ "@protobufjs/aspromise" "^1.1.2"
+ "@protobufjs/base64" "^1.1.2"
+ "@protobufjs/codegen" "^2.0.4"
+ "@protobufjs/eventemitter" "^1.1.0"
+ "@protobufjs/fetch" "^1.1.0"
+ "@protobufjs/float" "^1.0.2"
+ "@protobufjs/inquire" "^1.1.0"
+ "@protobufjs/path" "^1.1.2"
+ "@protobufjs/pool" "^1.1.0"
+ "@protobufjs/utf8" "^1.1.0"
+ "@types/long" "^4.0.1"
+ "@types/node" ">=13.7.0"
+ long "^4.0.0"
+
+proxy-addr@~2.0.7:
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
+ integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
+ dependencies:
+ forwarded "0.2.0"
+ ipaddr.js "1.9.1"
+
+prr@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
+ integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
+
+psl@^1.1.28, psl@^1.1.33:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
+ integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
+
+pstree.remy@^1.1.8:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
+ integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
+
+public-encrypt@^4.0.0:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
+ integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
+ dependencies:
+ bn.js "^4.1.0"
+ browserify-rsa "^4.0.0"
+ create-hash "^1.1.0"
+ parse-asn1 "^5.0.0"
+ randombytes "^2.0.1"
+ safe-buffer "^5.1.2"
+
+pump@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
+ integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
+punycode@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
+ integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
+
+punycode@^2.1.0, punycode@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+ integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+
+pupa@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62"
+ integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==
+ dependencies:
+ escape-goat "^2.0.0"
+
+qr.js@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
+ integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
+
+qrcode.react@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.1.tgz#2834bb50e5e275ffe5af6906eff15391fe9e38a5"
+ integrity sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg==
+ dependencies:
+ loose-envify "^1.4.0"
+ prop-types "^15.6.0"
+ qr.js "0.0.0"
+
+qs@6.9.7:
+ version "6.9.7"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe"
+ integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
+
+qs@~6.5.2:
+ version "6.5.3"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
+ integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
+
+querystring@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
+ integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
+
+querystringify@^2.1.1:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
+ integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
+
+queue-microtask@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
+ integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
+ dependencies:
+ safe-buffer "^5.1.0"
+
+randomfill@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
+ integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
+ dependencies:
+ randombytes "^2.0.5"
+ safe-buffer "^5.1.0"
+
+range-parser@^1.2.1, range-parser@~1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
+ integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
+
+raw-body@2.4.3:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c"
+ integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==
+ dependencies:
+ bytes "3.1.2"
+ http-errors "1.8.1"
+ iconv-lite "0.4.24"
+ unpipe "1.0.0"
+
+rc@^1.2.8:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
+ integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
+ dependencies:
+ deep-extend "^0.6.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~2.0.1"
+
+react-dom@^17.0.2:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
+ integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ scheduler "^0.20.2"
+
+react-error-boundary@^3.1.0:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
+ integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+
+react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
+ version "16.13.1"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+ integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
+react-is@^17.0.2:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
+ integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+
+react-native-fetch-api@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/react-native-fetch-api/-/react-native-fetch-api-2.0.0.tgz#c4af188b4fce3f3eaf1f1ff4e61dae1a00d4ffa0"
+ integrity sha512-GOA8tc1EVYLnHvma/TU9VTgLOyralO7eATRuCDchQveXW9Fr9vXygyq9iwqmM7YRZ8qRJfEt9xOS7OYMdJvRFw==
+ dependencies:
+ p-defer "^3.0.0"
+
+react-router-dom@^5.2.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363"
+ integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==
+ dependencies:
+ "@babel/runtime" "^7.12.13"
+ history "^4.9.0"
+ loose-envify "^1.3.1"
+ prop-types "^15.6.2"
+ react-router "5.2.1"
+ tiny-invariant "^1.0.2"
+ tiny-warning "^1.0.0"
+
+react-router@5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d"
+ integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==
+ dependencies:
+ "@babel/runtime" "^7.12.13"
+ history "^4.9.0"
+ hoist-non-react-statics "^3.1.0"
+ loose-envify "^1.3.1"
+ mini-create-react-context "^0.4.0"
+ path-to-regexp "^1.7.0"
+ prop-types "^15.6.2"
+ react-is "^16.6.0"
+ tiny-invariant "^1.0.2"
+ tiny-warning "^1.0.0"
+
+react@^17.0.2:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
+ integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
+read-pkg@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
+ integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=
+ dependencies:
+ load-json-file "^4.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^3.0.0"
+
+readable-stream@3, readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
+ integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
+readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@~2.3.6:
+ version "2.3.7"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
+ integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
+readable-stream@~1.0.31:
+ version "1.0.34"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+ integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
+readdirp@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
+ integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
+ dependencies:
+ graceful-fs "^4.1.11"
+ micromatch "^3.1.10"
+ readable-stream "^2.0.2"
+
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
+
+receptacle@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/receptacle/-/receptacle-1.3.2.tgz#a7994c7efafc7a01d0e2041839dab6c4951360d2"
+ integrity sha512-HrsFvqZZheusncQRiEE7GatOAETrARKV/lnfYicIm8lbvp/JQOdADOfhjBd2DajvoszEyxSM6RlAAIZgEoeu/A==
+ dependencies:
+ ms "^2.1.1"
+
+rechoir@^0.7.0:
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686"
+ integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==
+ dependencies:
+ resolve "^1.9.0"
+
+regenerator-runtime@^0.13.4:
+ version "0.13.9"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
+ integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
+
+regex-not@^1.0.0, regex-not@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
+ integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==
+ dependencies:
+ extend-shallow "^3.0.2"
+ safe-regex "^1.1.0"
+
+regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307"
+ integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+
+regexpp@^3.1.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
+ integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
+
+registry-auth-token@^4.0.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250"
+ integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==
+ dependencies:
+ rc "^1.2.8"
+
+registry-url@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009"
+ integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==
+ dependencies:
+ rc "^1.2.8"
+
+relateurl@^0.2.7:
+ version "0.2.7"
+ resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
+ integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
+
+remove-trailing-separator@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
+ integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
+
+renderkid@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a"
+ integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==
+ dependencies:
+ css-select "^4.1.3"
+ dom-converter "^0.2.0"
+ htmlparser2 "^6.1.0"
+ lodash "^4.17.21"
+ strip-ansi "^6.0.1"
+
+repeat-element@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9"
+ integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==
+
+repeat-string@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+ integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
+
+request@^2.88.2:
+ version "2.88.2"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
+ integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
+ dependencies:
+ aws-sign2 "~0.7.0"
+ aws4 "^1.8.0"
+ caseless "~0.12.0"
+ combined-stream "~1.0.6"
+ extend "~3.0.2"
+ forever-agent "~0.6.1"
+ form-data "~2.3.2"
+ har-validator "~5.1.3"
+ http-signature "~1.2.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.19"
+ oauth-sign "~0.9.0"
+ performance-now "^2.1.0"
+ qs "~6.5.2"
+ safe-buffer "^5.1.2"
+ tough-cookie "~2.5.0"
+ tunnel-agent "^0.6.0"
+ uuid "^3.3.2"
+
+require-directory@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+ integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
+
+require-from-string@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
+ integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+
+require-main-filename@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
+ integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
+
+requireindex@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef"
+ integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==
+
+requires-port@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+ integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
+
+resolve-cwd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+ integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=
+ dependencies:
+ resolve-from "^3.0.0"
+
+resolve-cwd@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
+ integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
+ dependencies:
+ resolve-from "^5.0.0"
+
+resolve-from@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
+ integrity sha1-six699nWiBvItuZTM17rywoYh0g=
+
+resolve-from@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
+ integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
+
+resolve-from@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
+ integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
+
+resolve-pathname@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
+ integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
+
+resolve-url@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
+ integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
+
+resolve@^1.10.0, resolve@^1.20.0, resolve@^1.9.0:
+ version "1.22.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
+ integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
+ dependencies:
+ is-core-module "^2.8.1"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+resolve@^2.0.0-next.3:
+ version "2.0.0-next.3"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"
+ integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==
+ dependencies:
+ is-core-module "^2.2.0"
+ path-parse "^1.0.6"
+
+responselike@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
+ integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
+ dependencies:
+ lowercase-keys "^1.0.0"
+
+ret@~0.1.10:
+ version "0.1.15"
+ resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
+ integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
+
+retimer@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/retimer/-/retimer-2.0.0.tgz#e8bd68c5e5a8ec2f49ccb5c636db84c04063bbca"
+ integrity sha512-KLXY85WkEq2V2bKex/LOO1ViXVn2KGYe4PYysAdYdjmraYIUsVkXu8O4am+8+5UbaaGl1qho4aqAAPHNQ4GSbg==
+
+retimer@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/retimer/-/retimer-3.0.0.tgz#98b751b1feaf1af13eb0228f8ea68b8f9da530df"
+ integrity sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==
+
+retry@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
+ integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
+
+retry@^0.13.1:
+ version "0.13.1"
+ resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
+ integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==
+
+reusify@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
+ integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+
+rimraf@^2.6.3:
+ version "2.7.1"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
+ integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
+ dependencies:
+ glob "^7.1.3"
+
+rimraf@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+ dependencies:
+ glob "^7.1.3"
+
+ripemd160@^2.0.0, ripemd160@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
+ integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
+ dependencies:
+ hash-base "^3.0.0"
+ inherits "^2.0.1"
+
+rlp@^2.2.7:
+ version "2.2.7"
+ resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf"
+ integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==
+ dependencies:
+ bn.js "^5.2.0"
+
+run-parallel@^1.1.9:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
+ integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+ dependencies:
+ queue-microtask "^1.2.2"
+
+safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+ integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
+safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+safe-regex@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e"
+ integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4=
+ dependencies:
+ ret "~0.1.10"
+
+"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+
+sanitize-filename@^1.6.3:
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378"
+ integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==
+ dependencies:
+ truncate-utf8-bytes "^1.0.0"
+
+sax@>=0.6.0:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+ integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
+
+saxes@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
+ integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==
+ dependencies:
+ xmlchars "^2.2.0"
+
+scheduler@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
+ integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
+schema-utils@2.7.0:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
+ integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
+ dependencies:
+ "@types/json-schema" "^7.0.4"
+ ajv "^6.12.2"
+ ajv-keywords "^3.4.1"
+
+schema-utils@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
+ integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==
+ dependencies:
+ ajv "^6.1.0"
+ ajv-errors "^1.0.0"
+ ajv-keywords "^3.1.0"
+
+schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
+ integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
+ dependencies:
+ "@types/json-schema" "^7.0.8"
+ ajv "^6.12.5"
+ ajv-keywords "^3.5.2"
+
+secp256k1@^4.0.0, secp256k1@^4.0.2, secp256k1@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303"
+ integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==
+ dependencies:
+ elliptic "^6.5.4"
+ node-addon-api "^2.0.0"
+ node-gyp-build "^4.2.0"
+
+select-hose@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
+ integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
+
+selfsigned@^1.10.8:
+ version "1.10.14"
+ resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574"
+ integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==
+ dependencies:
+ node-forge "^0.10.0"
+
+semver-diff@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
+ integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==
+ dependencies:
+ semver "^6.3.0"
+
+"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.7.1:
+ version "5.7.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
+ integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+
+semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
+semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
+ version "7.3.5"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
+ integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
+ dependencies:
+ lru-cache "^6.0.0"
+
+send@0.17.2:
+ version "0.17.2"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820"
+ integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==
+ dependencies:
+ debug "2.6.9"
+ depd "~1.1.2"
+ destroy "~1.0.4"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ fresh "0.5.2"
+ http-errors "1.8.1"
+ mime "1.6.0"
+ ms "2.1.3"
+ on-finished "~2.3.0"
+ range-parser "~1.2.1"
+ statuses "~1.5.0"
+
+serialize-javascript@6.0.0, serialize-javascript@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
+ integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
+ dependencies:
+ randombytes "^2.1.0"
+
+serve-index@^1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
+ integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
+ dependencies:
+ accepts "~1.3.4"
+ batch "0.6.1"
+ debug "2.6.9"
+ escape-html "~1.0.3"
+ http-errors "~1.6.2"
+ mime-types "~2.1.17"
+ parseurl "~1.3.2"
+
+serve-static@1.14.2:
+ version "1.14.2"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa"
+ integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==
+ dependencies:
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ parseurl "~1.3.3"
+ send "0.17.2"
+
+set-blocking@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+ integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
+
+set-delayed-interval@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/set-delayed-interval/-/set-delayed-interval-1.0.0.tgz#1f7c065780a365f10250f8a80e2be10175ea0388"
+ integrity sha512-29fhAwuZlLcuBnW/EwxvLcg2D3ELX+VBDNhnavs3YYkab72qmrcSeQNVdzl8EcPPahGQXhBM6MKdPLCQGMDakw==
+
+set-value@^2.0.0, set-value@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
+ integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-extendable "^0.1.1"
+ is-plain-object "^2.0.3"
+ split-string "^3.0.1"
+
+setprototypeof@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
+ integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
+
+setprototypeof@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
+ integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
+
+sha.js@^2.4.0, sha.js@^2.4.8:
+ version "2.4.11"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
+ integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+shallow-clone@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
+ integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
+ dependencies:
+ kind-of "^6.0.2"
+
+shallowequal@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
+ integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
+
+shebang-command@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+ integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
+ dependencies:
+ shebang-regex "^1.0.0"
+
+shebang-command@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+ dependencies:
+ shebang-regex "^3.0.0"
+
+shebang-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+ integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
+
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+shell-quote@^1.6.1:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123"
+ integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==
+
+side-channel@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
+ integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
+ dependencies:
+ call-bind "^1.0.0"
+ get-intrinsic "^1.0.2"
+ object-inspect "^1.9.0"
+
+signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
+ version "3.0.7"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
+ integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
+slash@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
+ integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+
+slice-ansi@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
+ integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==
+ dependencies:
+ ansi-styles "^4.0.0"
+ astral-regex "^2.0.0"
+ is-fullwidth-code-point "^3.0.0"
+
+snapdragon-node@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
+ integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==
+ dependencies:
+ define-property "^1.0.0"
+ isobject "^3.0.0"
+ snapdragon-util "^3.0.1"
+
+snapdragon-util@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
+ integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==
+ dependencies:
+ kind-of "^3.2.0"
+
+snapdragon@^0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d"
+ integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==
+ dependencies:
+ base "^0.11.1"
+ debug "^2.2.0"
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ map-cache "^0.2.2"
+ source-map "^0.5.6"
+ source-map-resolve "^0.5.0"
+ use "^3.1.0"
+
+sockjs-client@^1.5.0:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.2.tgz#4bc48c2da9ce4769f19dc723396b50f5c12330a3"
+ integrity sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==
+ dependencies:
+ debug "^3.2.6"
+ eventsource "^1.0.7"
+ faye-websocket "^0.11.3"
+ inherits "^2.0.4"
+ json3 "^3.3.3"
+ url-parse "^1.5.3"
+
+sockjs@^0.3.21:
+ version "0.3.24"
+ resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce"
+ integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==
+ dependencies:
+ faye-websocket "^0.11.3"
+ uuid "^8.3.2"
+ websocket-driver "^0.7.4"
+
+source-list-map@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
+ integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
+
+source-map-js@^1.0.1, source-map-js@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
+source-map-loader@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d"
+ integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA==
+ dependencies:
+ abab "^2.0.5"
+ iconv-lite "^0.6.3"
+ source-map-js "^1.0.1"
+
+source-map-resolve@^0.5.0:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
+ integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==
+ dependencies:
+ atob "^2.1.2"
+ decode-uri-component "^0.2.0"
+ resolve-url "^0.2.1"
+ source-map-url "^0.4.0"
+ urix "^0.1.0"
+
+source-map-support@~0.5.20:
+ version "0.5.21"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+ integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
+source-map-url@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
+ integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
+
+source-map@^0.5.0, source-map@^0.5.6:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+ integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
+
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+source-map@~0.7.2:
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
+ integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
+
+spdx-correct@^3.0.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
+ integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
+ dependencies:
+ spdx-expression-parse "^3.0.0"
+ spdx-license-ids "^3.0.0"
+
+spdx-exceptions@^2.1.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
+ integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
+
+spdx-expression-parse@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
+ integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
+ dependencies:
+ spdx-exceptions "^2.1.0"
+ spdx-license-ids "^3.0.0"
+
+spdx-license-ids@^3.0.0:
+ version "3.0.11"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95"
+ integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==
+
+spdy-transport@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31"
+ integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==
+ dependencies:
+ debug "^4.1.0"
+ detect-node "^2.0.4"
+ hpack.js "^2.1.6"
+ obuf "^1.1.2"
+ readable-stream "^3.0.6"
+ wbuf "^1.7.3"
+
+spdy@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b"
+ integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==
+ dependencies:
+ debug "^4.1.0"
+ handle-thing "^2.0.0"
+ http-deceiver "^1.2.7"
+ select-hose "^2.0.0"
+ spdy-transport "^3.0.0"
+
+split-string@^3.0.1, split-string@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
+ integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==
+ dependencies:
+ extend-shallow "^3.0.0"
+
+split@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
+ integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
+ dependencies:
+ through "2"
+
+sprintf-js@1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
+ integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
+
+sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+ integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+
+sshpk@^1.7.0:
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
+ integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ bcrypt-pbkdf "^1.0.0"
+ dashdash "^1.12.0"
+ ecc-jsbn "~0.1.1"
+ getpass "^0.1.1"
+ jsbn "~0.1.0"
+ safer-buffer "^2.0.2"
+ tweetnacl "~0.14.0"
+
+static-extend@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
+ integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=
+ dependencies:
+ define-property "^0.2.5"
+ object-copy "^0.1.0"
+
+"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
+ integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
+
+stream-browserify@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f"
+ integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==
+ dependencies:
+ inherits "~2.0.4"
+ readable-stream "^3.5.0"
+
+stream-http@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5"
+ integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==
+ dependencies:
+ builtin-status-codes "^3.0.0"
+ inherits "^2.0.4"
+ readable-stream "^3.6.0"
+ xtend "^4.0.2"
+
+stream-to-it@^0.2.2:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/stream-to-it/-/stream-to-it-0.2.4.tgz#d2fd7bfbd4a899b4c0d6a7e6a533723af5749bd0"
+ integrity sha512-4vEbkSs83OahpmBybNJXlJd7d6/RxzkkSdT3I0mnGt79Xd2Kk+e1JqbvAvsQfCeKj3aKb0QIWkyK3/n0j506vQ==
+ dependencies:
+ get-iterator "^1.0.2"
+
+streaming-iterables@^6.0.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/streaming-iterables/-/streaming-iterables-6.2.0.tgz#e8079bc56272335b287e2f13274602fbef008e56"
+ integrity sha512-3AYC8oB60WyD1ic7uHmN/vm2oRGzRnQ3XFBl/bFMDi1q1+nc5/vjMmiE4vroIya3jG59t87VpyAj/iXYxyw9AA==
+
+string-width@^3.0.0, string-width@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
+ integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
+ dependencies:
+ emoji-regex "^7.0.1"
+ is-fullwidth-code-point "^2.0.0"
+ strip-ansi "^5.1.0"
+
+string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+string.prototype.matchall@^4.0.6:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa"
+ integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+ get-intrinsic "^1.1.1"
+ has-symbols "^1.0.2"
+ internal-slot "^1.0.3"
+ regexp.prototype.flags "^1.3.1"
+ side-channel "^1.0.4"
+
+string.prototype.padend@^3.0.0:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1"
+ integrity sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+string.prototype.trimend@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80"
+ integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+
+string.prototype.trimstart@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed"
+ integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+ integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
+
+string_decoder@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
+ integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+ dependencies:
+ safe-buffer "~5.1.0"
+
+strip-ansi@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
+ integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
+ dependencies:
+ ansi-regex "^4.1.0"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+ integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
+
+strip-eof@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
+ integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
+
+strip-final-newline@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
+ integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+
+strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+ integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
+strip-json-comments@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+ integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
+
+style-loader@^3.3.0:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575"
+ integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==
+
+styled-components@^5.3.1:
+ version "5.3.3"
+ resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743"
+ integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
+ dependencies:
+ "@babel/helper-module-imports" "^7.0.0"
+ "@babel/traverse" "^7.4.5"
+ "@emotion/is-prop-valid" "^0.8.8"
+ "@emotion/stylis" "^0.8.4"
+ "@emotion/unitless" "^0.7.4"
+ babel-plugin-styled-components ">= 1.12.0"
+ css-to-react-native "^3.0.0"
+ hoist-non-react-statics "^3.0.0"
+ shallowequal "^1.1.0"
+ supports-color "^5.5.0"
+
+supports-color@8.1.1, supports-color@^8.0.0:
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-color@^5.3.0, supports-color@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+ dependencies:
+ has-flag "^3.0.0"
+
+supports-color@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
+ integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
+ dependencies:
+ has-flag "^3.0.0"
+
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
+symbol-tree@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
+ integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
+
+table@^6.0.9:
+ version "6.8.0"
+ resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca"
+ integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==
+ dependencies:
+ ajv "^8.0.1"
+ lodash.truncate "^4.4.2"
+ slice-ansi "^4.0.0"
+ string-width "^4.2.3"
+ strip-ansi "^6.0.1"
+
+tapable@^1.0.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
+ integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
+
+tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
+ integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+
+terser-webpack-plugin@^5.1.3:
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54"
+ integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==
+ dependencies:
+ jest-worker "^27.4.5"
+ schema-utils "^3.1.1"
+ serialize-javascript "^6.0.0"
+ source-map "^0.6.1"
+ terser "^5.7.2"
+
+terser@^5.10.0, terser@^5.7.2:
+ version "5.11.0"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.11.0.tgz#2da5506c02e12cd8799947f30ce9c5b760be000f"
+ integrity sha512-uCA9DLanzzWSsN1UirKwylhhRz3aKPInlfmpGfw8VN6jHsAtu8HJtIpeeHHK23rxnE/cDc+yvmq5wqkIC6Kn0A==
+ dependencies:
+ acorn "^8.5.0"
+ commander "^2.20.0"
+ source-map "~0.7.2"
+ source-map-support "~0.5.20"
+
+text-table@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+ integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+
+throat@^4.0.0, throat@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
+ integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=
+
+through2@^2.0.1:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
+ integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
+ dependencies:
+ readable-stream "~2.3.6"
+ xtend "~4.0.1"
+
+through2@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764"
+ integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==
+ dependencies:
+ readable-stream "3"
+
+through@2:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+
+thunky@^1.0.2:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
+ integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
+
+time-cache@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/time-cache/-/time-cache-0.3.0.tgz#ed0dfcf0fda45cdc95fbd601fda830ebf1bd5d8b"
+ integrity sha1-7Q388P2kXNyV+9YB/agw6/G9XYs=
+ dependencies:
+ lodash.throttle "^4.1.1"
+
+timeout-abort-controller@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/timeout-abort-controller/-/timeout-abort-controller-1.1.1.tgz#2c3c3c66f13c783237987673c276cbd7a9762f29"
+ integrity sha512-BsF9i3NAJag6T0ZEjki9j654zoafI2X6ayuNd6Tp8+Ul6Tr5s4jo973qFeiWrRSweqvskC+AHDKUmIW4b7pdhQ==
+ dependencies:
+ abort-controller "^3.0.0"
+ retimer "^2.0.0"
+
+tiny-invariant@^1.0.2:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
+ integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
+
+tiny-warning@^1.0.0, tiny-warning@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
+ integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
+
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+ integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
+
+to-object-path@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
+ integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=
+ dependencies:
+ kind-of "^3.0.2"
+
+to-readable-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
+ integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
+
+to-regex-range@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
+ integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=
+ dependencies:
+ is-number "^3.0.0"
+ repeat-string "^1.6.1"
+
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+ dependencies:
+ is-number "^7.0.0"
+
+to-regex@^3.0.1, to-regex@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
+ integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==
+ dependencies:
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ regex-not "^1.0.2"
+ safe-regex "^1.1.0"
+
+toidentifier@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
+ integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
+
+touch@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
+ integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==
+ dependencies:
+ nopt "~1.0.10"
+
+tough-cookie@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
+ integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==
+ dependencies:
+ psl "^1.1.33"
+ punycode "^2.1.1"
+ universalify "^0.1.2"
+
+tough-cookie@~2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
+ integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
+ dependencies:
+ psl "^1.1.28"
+ punycode "^2.1.1"
+
+tr46@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
+ integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==
+ dependencies:
+ punycode "^2.1.1"
+
+tr46@~0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+ integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
+
+truncate-utf8-bytes@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b"
+ integrity sha1-QFkjkJWS1W94pYGENLC3hInKXys=
+ dependencies:
+ utf8-byte-length "^1.0.1"
+
+ts-loader@^9.2.5:
+ version "9.2.6"
+ resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74"
+ integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==
+ dependencies:
+ chalk "^4.1.0"
+ enhanced-resolve "^5.0.0"
+ micromatch "^4.0.0"
+ semver "^7.3.4"
+
+ts-node@^10.1.0, ts-node@^10.2.1:
+ version "10.5.0"
+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.5.0.tgz#618bef5854c1fbbedf5e31465cbb224a1d524ef9"
+ integrity sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==
+ dependencies:
+ "@cspotcode/source-map-support" "0.7.0"
+ "@tsconfig/node10" "^1.0.7"
+ "@tsconfig/node12" "^1.0.7"
+ "@tsconfig/node14" "^1.0.0"
+ "@tsconfig/node16" "^1.0.2"
+ acorn "^8.4.1"
+ acorn-walk "^8.1.1"
+ arg "^4.1.0"
+ create-require "^1.1.0"
+ diff "^4.0.1"
+ make-error "^1.1.1"
+ v8-compile-cache-lib "^3.0.0"
+ yn "3.1.1"
+
+ts-poet@^4.5.0:
+ version "4.10.0"
+ resolved "https://registry.yarnpkg.com/ts-poet/-/ts-poet-4.10.0.tgz#8732374655e87f8f833e5d110938e346713e8c66"
+ integrity sha512-V5xzt+LDMVtxWvK12WVwHhGHTA//CeoPdWOqka0mMjlRqq7RPKYSfWEnzJdMmhNbd34BwZuZpip4mm+nqEcbQA==
+ dependencies:
+ lodash "^4.17.15"
+ prettier "^2.5.1"
+
+ts-proto-descriptors@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/ts-proto-descriptors/-/ts-proto-descriptors-1.6.0.tgz#ca6eafc882495a2e920da5b981d7b181b4e49c38"
+ integrity sha512-Vrhue2Ti99us/o76mGy28nF3W/Uanl1/8detyJw2yyRwiBC5yxy+hEZqQ/ZX2PbZ1vyCpJ51A9L4PnCCnkBMTQ==
+ dependencies:
+ long "^4.0.0"
+ protobufjs "^6.8.8"
+
+ts-proto@^1.83.0:
+ version "1.106.1"
+ resolved "https://registry.yarnpkg.com/ts-proto/-/ts-proto-1.106.1.tgz#5681ce64879971e3a2ae9fa1385108b323255fb2"
+ integrity sha512-Nok5TwkqhfU4IZKtxZjvzTshKITBP6n5FMHBbgNNukplTAk+2OCBRZeA2Kh+svEmOvIHY/d4gnLHDQh8LHj/ww==
+ dependencies:
+ "@types/object-hash" "^1.3.0"
+ dataloader "^1.4.0"
+ object-hash "^1.3.1"
+ protobufjs "^6.8.8"
+ ts-poet "^4.5.0"
+ ts-proto-descriptors "1.6.0"
+
+tsconfig-paths@^3.12.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
+ integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==
+ dependencies:
+ "@types/json5" "^0.0.29"
+ json5 "^1.0.1"
+ minimist "^1.2.0"
+ strip-bom "^3.0.0"
+
+tslib@^1.8.1:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
+ integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+
+tslib@^2.0.3:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
+ integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
+
+tsutils@^3.21.0:
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
+ integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
+ dependencies:
+ tslib "^1.8.1"
+
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
+ dependencies:
+ safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+ integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
+
+type-check@^0.4.0, type-check@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
+ integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+ dependencies:
+ prelude-ls "^1.2.1"
+
+type-check@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+ integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
+ dependencies:
+ prelude-ls "~1.1.2"
+
+type-detect@^4.0.0, type-detect@^4.0.5:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
+ integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
+
+type-fest@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
+ integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
+
+type-is@~1.6.18:
+ version "1.6.18"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
+ integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
+ dependencies:
+ media-typer "0.3.0"
+ mime-types "~2.1.24"
+
+typedarray-to-buffer@^3.1.5:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
+ integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
+ dependencies:
+ is-typedarray "^1.0.0"
+
+typescript@^4.3.5, typescript@^4.4.3:
+ version "4.5.5"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
+ integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
+
+uint8arrays@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.0.0.tgz#260869efb8422418b6f04e3fac73a3908175c63b"
+ integrity sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==
+ dependencies:
+ multiformats "^9.4.2"
+
+unbox-primitive@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
+ integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==
+ dependencies:
+ function-bind "^1.1.1"
+ has-bigints "^1.0.1"
+ has-symbols "^1.0.2"
+ which-boxed-primitive "^1.0.2"
+
+undefsafe@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
+ integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
+
+union-value@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
+ integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==
+ dependencies:
+ arr-union "^3.1.0"
+ get-value "^2.0.6"
+ is-extendable "^0.1.1"
+ set-value "^2.0.1"
+
+unique-string@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
+ integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==
+ dependencies:
+ crypto-random-string "^2.0.0"
+
+universalify@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
+ integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+
+universalify@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
+ integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
+
+unordered-array-remove@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz#c546e8f88e317a0cf2644c97ecb57dba66d250ef"
+ integrity sha1-xUbo+I4xegzyZEyX7LV9umbSUO8=
+
+unpipe@1.0.0, unpipe@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
+ integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
+
+unset-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
+ integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=
+ dependencies:
+ has-value "^0.3.1"
+ isobject "^3.0.0"
+
+untildify@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
+ integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
+
+upath@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
+ integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
+
+update-notifier@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9"
+ integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==
+ dependencies:
+ boxen "^5.0.0"
+ chalk "^4.1.0"
+ configstore "^5.0.1"
+ has-yarn "^2.1.0"
+ import-lazy "^2.1.0"
+ is-ci "^2.0.0"
+ is-installed-globally "^0.4.0"
+ is-npm "^5.0.0"
+ is-yarn-global "^0.3.0"
+ latest-version "^5.1.0"
+ pupa "^2.1.1"
+ semver "^7.3.4"
+ semver-diff "^3.1.1"
+ xdg-basedir "^4.0.0"
+
+uri-js@^4.2.2:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
+ integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
+ dependencies:
+ punycode "^2.1.0"
+
+urix@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
+ integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
+
+url-parse-lax@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
+ integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
+ dependencies:
+ prepend-http "^2.0.0"
+
+url-parse@^1.4.3, url-parse@^1.5.3:
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
+ integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
+ dependencies:
+ querystringify "^2.1.1"
+ requires-port "^1.0.0"
+
+url@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
+ integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
+ dependencies:
+ punycode "1.3.2"
+ querystring "0.2.0"
+
+ursa-optional@^0.10.1:
+ version "0.10.2"
+ resolved "https://registry.yarnpkg.com/ursa-optional/-/ursa-optional-0.10.2.tgz#bd74e7d60289c22ac2a69a3c8dea5eb2817f9681"
+ integrity sha512-TKdwuLboBn7M34RcvVTuQyhvrA8gYKapuVdm0nBP0mnBc7oECOfUQZrY91cefL3/nm64ZyrejSRrhTVdX7NG/A==
+ dependencies:
+ bindings "^1.5.0"
+ nan "^2.14.2"
+
+use@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
+ integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
+
+utf8-byte-length@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
+ integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=
+
+util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+ integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+
+util@^0.12.0:
+ version "0.12.4"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
+ integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==
+ dependencies:
+ inherits "^2.0.3"
+ is-arguments "^1.0.4"
+ is-generator-function "^1.0.7"
+ is-typed-array "^1.1.3"
+ safe-buffer "^5.1.2"
+ which-typed-array "^1.1.2"
+
+utila@~0.4:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
+ integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=
+
+utils-merge@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
+ integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
+
+uuid@^3.3.2:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
+ integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
+
+uuid@^8.3.2:
+ version "8.3.2"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
+v8-compile-cache-lib@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8"
+ integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==
+
+v8-compile-cache@^2.0.3:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
+ integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
+
+validate-npm-package-license@^3.0.1:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
+ integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
+ dependencies:
+ spdx-correct "^3.0.0"
+ spdx-expression-parse "^3.0.0"
+
+value-equal@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
+ integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
+
+varint@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4"
+ integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==
+
+varint@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0"
+ integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
+
+vary@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
+ integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
+
+verror@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+ integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
+ dependencies:
+ assert-plus "^1.0.0"
+ core-util-is "1.0.2"
+ extsprintf "^1.2.0"
+
+w3c-hr-time@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
+ integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==
+ dependencies:
+ browser-process-hrtime "^1.0.0"
+
+w3c-xmlserializer@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
+ integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
+ dependencies:
+ xml-name-validator "^3.0.0"
+
+watchpack@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25"
+ integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==
+ dependencies:
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.1.2"
+
+wbuf@^1.1.0, wbuf@^1.7.3:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"
+ integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==
+ dependencies:
+ minimalistic-assert "^1.0.0"
+
+webidl-conversions@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
+ integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
+
+webidl-conversions@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
+ integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
+
+webidl-conversions@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
+ integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
+
+webpack-cli@^4.7.2:
+ version "4.9.2"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d"
+ integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==
+ dependencies:
+ "@discoveryjs/json-ext" "^0.5.0"
+ "@webpack-cli/configtest" "^1.1.1"
+ "@webpack-cli/info" "^1.4.1"
+ "@webpack-cli/serve" "^1.6.1"
+ colorette "^2.0.14"
+ commander "^7.0.0"
+ execa "^5.0.0"
+ fastest-levenshtein "^1.0.12"
+ import-local "^3.0.2"
+ interpret "^2.2.0"
+ rechoir "^0.7.0"
+ webpack-merge "^5.7.3"
+
+webpack-dev-middleware@^3.7.2:
+ version "3.7.3"
+ resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5"
+ integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==
+ dependencies:
+ memory-fs "^0.4.1"
+ mime "^2.4.4"
+ mkdirp "^0.5.1"
+ range-parser "^1.2.1"
+ webpack-log "^2.0.0"
+
+webpack-dev-server@^3.11.2:
+ version "3.11.3"
+ resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz#8c86b9d2812bf135d3c9bce6f07b718e30f7c3d3"
+ integrity sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==
+ dependencies:
+ ansi-html-community "0.0.8"
+ bonjour "^3.5.0"
+ chokidar "^2.1.8"
+ compression "^1.7.4"
+ connect-history-api-fallback "^1.6.0"
+ debug "^4.1.1"
+ del "^4.1.1"
+ express "^4.17.1"
+ html-entities "^1.3.1"
+ http-proxy-middleware "0.19.1"
+ import-local "^2.0.0"
+ internal-ip "^4.3.0"
+ ip "^1.1.5"
+ is-absolute-url "^3.0.3"
+ killable "^1.0.1"
+ loglevel "^1.6.8"
+ opn "^5.5.0"
+ p-retry "^3.0.1"
+ portfinder "^1.0.26"
+ schema-utils "^1.0.0"
+ selfsigned "^1.10.8"
+ semver "^6.3.0"
+ serve-index "^1.9.1"
+ sockjs "^0.3.21"
+ sockjs-client "^1.5.0"
+ spdy "^4.0.2"
+ strip-ansi "^3.0.1"
+ supports-color "^6.1.0"
+ url "^0.11.0"
+ webpack-dev-middleware "^3.7.2"
+ webpack-log "^2.0.0"
+ ws "^6.2.1"
+ yargs "^13.3.2"
+
+webpack-log@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f"
+ integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==
+ dependencies:
+ ansi-colors "^3.0.0"
+ uuid "^3.3.2"
+
+webpack-merge@^5.7.3:
+ version "5.8.0"
+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
+ integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
+ dependencies:
+ clone-deep "^4.0.1"
+ wildcard "^2.0.0"
+
+webpack-sources@^2.2.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd"
+ integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==
+ dependencies:
+ source-list-map "^2.0.1"
+ source-map "^0.6.1"
+
+webpack-sources@^3.2.3:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
+ integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
+
+webpack@^5.48.0:
+ version "5.69.1"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5"
+ integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A==
+ dependencies:
+ "@types/eslint-scope" "^3.7.3"
+ "@types/estree" "^0.0.51"
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/wasm-edit" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+ acorn "^8.4.1"
+ acorn-import-assertions "^1.7.6"
+ browserslist "^4.14.5"
+ chrome-trace-event "^1.0.2"
+ enhanced-resolve "^5.8.3"
+ es-module-lexer "^0.9.0"
+ eslint-scope "5.1.1"
+ events "^3.2.0"
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.2.9"
+ json-parse-better-errors "^1.0.2"
+ loader-runner "^4.2.0"
+ mime-types "^2.1.27"
+ neo-async "^2.6.2"
+ schema-utils "^3.1.0"
+ tapable "^2.1.1"
+ terser-webpack-plugin "^5.1.3"
+ watchpack "^2.3.1"
+ webpack-sources "^3.2.3"
+
+websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
+ integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
+ dependencies:
+ http-parser-js ">=0.5.1"
+ safe-buffer ">=5.1.0"
+ websocket-extensions ">=0.1.1"
+
+websocket-extensions@>=0.1.1:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
+ integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
+
+whatwg-encoding@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
+ integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
+ dependencies:
+ iconv-lite "0.4.24"
+
+whatwg-mimetype@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
+ integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
+
+whatwg-url@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
+ integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
+ dependencies:
+ tr46 "~0.0.3"
+ webidl-conversions "^3.0.0"
+
+whatwg-url@^8.0.0, whatwg-url@^8.5.0:
+ version "8.7.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
+ integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
+ dependencies:
+ lodash "^4.7.0"
+ tr46 "^2.1.0"
+ webidl-conversions "^6.1.0"
+
+wherearewe@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wherearewe/-/wherearewe-1.0.0.tgz#e6c2440bb757e57eb2ad76b4abf9961b532ee358"
+ integrity sha512-oQnRsAfMCqNAC7U4JrBdmFXAhBRLOkPGOfU5+nw9fs2D3g8O6EV7hn7BhpXtt0yno4pxFiRD55rMyt0fsLMqlw==
+ dependencies:
+ is-electron "^2.2.0"
+
+which-boxed-primitive@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
+ integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==
+ dependencies:
+ is-bigint "^1.0.1"
+ is-boolean-object "^1.1.0"
+ is-number-object "^1.0.4"
+ is-string "^1.0.5"
+ is-symbol "^1.0.3"
+
+which-module@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+ integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
+
+which-typed-array@^1.1.2:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793"
+ integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==
+ dependencies:
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ es-abstract "^1.18.5"
+ foreach "^2.0.5"
+ has-tostringtag "^1.0.0"
+ is-typed-array "^1.1.7"
+
+which@2.0.2, which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+ dependencies:
+ isexe "^2.0.0"
+
+which@^1.2.9:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
+ integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
+ dependencies:
+ isexe "^2.0.0"
+
+widest-line@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
+ integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
+ dependencies:
+ string-width "^4.0.0"
+
+wildcard@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
+ integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
+
+word-wrap@^1.2.3, word-wrap@~1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
+ integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+
+workerpool@6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b"
+ integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==
+
+wrap-ansi@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
+ integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
+ dependencies:
+ ansi-styles "^3.2.0"
+ string-width "^3.0.0"
+ strip-ansi "^5.0.0"
+
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+ integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
+
+write-file-atomic@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
+ integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
+ dependencies:
+ imurmurhash "^0.1.4"
+ is-typedarray "^1.0.0"
+ signal-exit "^3.0.2"
+ typedarray-to-buffer "^3.1.5"
+
+ws@^6.2.1:
+ version "6.2.2"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
+ integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==
+ dependencies:
+ async-limiter "~1.0.0"
+
+ws@^7.3.1, ws@^7.4.6:
+ version "7.5.7"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
+ integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
+
+wsrun@^5.2.4:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/wsrun/-/wsrun-5.2.4.tgz#6eb6c3ccd3327721a8df073a5e3578fb0dea494e"
+ integrity sha512-akv3WtKBohdHsD/5uqhYRHw6GXeCXe87FsSg28Szq+2cpoqRW2SY4yPfm1D0za1cS6MgNy5hPgzS5SqYJaGUxg==
+ dependencies:
+ bluebird "^3.5.1"
+ chalk "^2.3.0"
+ glob "^7.1.2"
+ jest-changed-files "^24.9.0"
+ lodash "^4.17.4"
+ minimatch "^3.0.4"
+ split "^1.0.1"
+ throat "^4.1.0"
+ yargs "^13.0.0"
+
+xdg-basedir@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
+ integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
+
+xml-name-validator@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
+ integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+
+xml2js@^0.4.23:
+ version "0.4.23"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
+ integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
+ dependencies:
+ sax ">=0.6.0"
+ xmlbuilder "~11.0.0"
+
+xmlbuilder@~11.0.0:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
+ integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+
+xmlchars@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
+ integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
+
+xsalsa20@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/xsalsa20/-/xsalsa20-1.2.0.tgz#e5a05cb26f8cef723f94a559102ed50c1b44c25c"
+ integrity sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==
+
+xtend@^4.0.2, xtend@~4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
+ integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
+
+y18n@^4.0.0:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
+ integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
+
+y18n@^5.0.5:
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+ integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
+yallist@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
+ integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yaml@^1.7.2:
+ version "1.10.2"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
+ integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
+
+yargs-parser@20.2.4:
+ version "20.2.4"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
+ integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
+
+yargs-parser@^13.1.2:
+ version "13.1.2"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
+ integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
+ dependencies:
+ camelcase "^5.0.0"
+ decamelize "^1.2.0"
+
+yargs-parser@^20.2.2:
+ version "20.2.9"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
+ integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
+
+yargs-unparser@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
+ integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
+ dependencies:
+ camelcase "^6.0.0"
+ decamelize "^4.0.0"
+ flat "^5.0.2"
+ is-plain-obj "^2.1.0"
+
+yargs@16.2.0, yargs@^16.1.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+ integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+ dependencies:
+ cliui "^7.0.2"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.0"
+ y18n "^5.0.5"
+ yargs-parser "^20.2.2"
+
+yargs@^13.0.0, yargs@^13.3.2:
+ version "13.3.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
+ integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==
+ dependencies:
+ cliui "^5.0.0"
+ find-up "^3.0.0"
+ get-caller-file "^2.0.1"
+ require-directory "^2.1.1"
+ require-main-filename "^2.0.0"
+ set-blocking "^2.0.0"
+ string-width "^3.0.0"
+ which-module "^2.0.0"
+ y18n "^4.0.0"
+ yargs-parser "^13.1.2"
+
+yn@3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
+ integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
+
+yocto-queue@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
+ integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==