Vitalik AMA Standby Site (#323)

* add tevan's info

* fix conflict

* Add Vitalik AMA Standby Page :)

* small changes ( AMA )

* responsive changes + fix counter

* add buttons for livestream

* Rename vitalik-ama.js to vitalik.js

Co-authored-by: Sam Poder <39828164+sampoder@users.noreply.github.com>
This commit is contained in:
Belle 2022-02-02 00:11:12 +08:00 committed by GitHub
parent 991a7b24ba
commit 0bc0274b2c
10 changed files with 735 additions and 0 deletions

94
components/particles.js Normal file
View file

@ -0,0 +1,94 @@
import Particles from 'react-tsparticles'
import React from 'react'
const Particle = React.memo(function Particle() {
const particlesInit = main => {
console.log(main)
}
const particlesLoaded = container => {
console.log(container)
}
return (
<Particles
id="tsparticles"
init={particlesInit}
loaded={particlesLoaded}
options={{
fpsLimit: 60,
interactivity: {
events: {
onClick: {
enable: true,
mode: 'push'
},
onHover: {
enable: true,
mode: 'repulse'
},
resize: true
},
modes: {
bubble: {
distance: 200,
duration: 2,
opacity: 0.5,
size: 40
},
push: {
quantity: 2
},
repulse: {
distance: 100,
duration: 0.5
}
}
},
particles: {
color: {
value: '#CDAEFB',
opacity: 0.2
},
links: {
color: '#82A9F9',
distance: 200,
enable: true,
opacity: 0.2,
width: 1
},
collisions: {
enable: false
},
move: {
direction: 'none',
enable: true,
outMode: 'bounce',
random: false,
speed: 1,
straight: false
},
number: {
density: {
enable: true,
area: 500
},
value: 50
},
opacity: {
value: 0.25
},
shape: {
type: 'circle'
},
size: {
random: true,
value: 1.5
}
},
detectRetina: true
}}
/>
)
})
export default Particle

View file

@ -33,9 +33,11 @@
"react-masonry-css": "^1.0.16",
"react-reveal": "^1.2.2",
"react-scrolllock": "^5.0.1",
"react-tsparticles": "^1.39.2",
"react-use-websocket": "2.9.1",
"resnow": "^1.0.0",
"theme-ui": "^0.13",
"tinytime": "^0.2.6",
"turndown": "^7.1.1"
},
"devDependencies": {

393
pages/vitalik.js Normal file
View file

@ -0,0 +1,393 @@
import { Box, Button, Image, Grid, Text, Link } from 'theme-ui'
import Head from 'next/head'
import Meta from '@hackclub/meta'
import React, { useEffect, useState } from 'react'
import tt from 'tinytime'
import Particle from '../components/particles'
export default function Vitalik() {
const calculateTimeLeft = () => {
const difference = +new Date(`2022-02-04T01:00:00.000Z`) - +new Date()
let timeLeft = {}
if (difference > 0) {
timeLeft = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
min: Math.floor((difference / 1000 / 60) % 60),
sec: Math.floor((difference / 1000) % 60)
}
}
return timeLeft
}
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft())
useEffect(() => {
const timer = setTimeout(() => {
setTimeLeft(calculateTimeLeft())
}, 1000)
return () => clearTimeout(timer)
})
const timer = []
Object.keys(timeLeft).forEach(e => {
if (!timeLeft[e]) {
if (e == 'days') {
return
} else if (e == 'hours') {
if (!timeLeft['days']) {
return
}
} else if (e == 'min') {
if (!timeLeft['days'] && !timeLeft['hours']) {
return
}
} else {
if (!timeLeft['days'] && !timeLeft['hours'] && !timeLeft['min']) {
return
}
}
}
var name = ''
if (e == 'days') {
if (timeLeft[e] == 1 || timeLeft[e] == 0) {
name = 'day'
} else {
name = 'days'
}
} else if (e == 'hours') {
if (timeLeft[e] == 1 || timeLeft[e] == 0) {
name = 'hour'
} else {
name = 'hours'
}
} else if (e == 'min') {
name = 'min'
} else {
name = 'sec'
}
timer.push(
<Box
sx={theme => ({
color: 'primary',
...theme.util.gxText('#CDAEFB', '#82A9F9'),
position: 'relative',
width: ['16vw', '15vw', '15vw'],
height: ['15vh', '20vh', '35vh'],
borderRadius: '5px',
border: ['none', '1.5px solid'],
borderColor: theme.util.gxText('#CDAEFB', '#82A9F9'),
fontSize: [4, 5, 7],
fontWeight: 'bold',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center'
})}
>
<Box>
<Text
sx={theme => ({
color: 'primary',
...theme.util.gxText('#CDAEFB', '#82A9F9')
})}
>
{timeLeft[e]}{' '}
</Text>
<Text
sx={theme => ({
color: 'primary',
...theme.util.gxText('#CDAEFB', '#82A9F9'),
position: 'relative',
fontSize: [1, 3, 4],
fontWeight: 'bold',
display: 'block',
pb: '15px'
})}
>
{name}
</Text>
</Box>
</Box>
)
})
return (
<>
<Meta
as={Head}
title="Vitalik Buterin | AMA"
description="Were excited to welcome Vitalik Buterin ( Co-creator of Ethereum ) to speak to teenagers at Hack Club!"
image="https://cloud-je16il79h-hack-club-bot.vercel.app/0slack.png"
/>
<Head>
<meta name="theme-color" content="#CDAEFB" />
</Head>
<Box
sx={{
minHeight: '100vh',
width: '100vw',
bg: '#222222',
position: 'relative',
zIndex: '0',
overflow: 'hidden'
}}
>
<Link href="https://hackclub.com" target="_blank" color="inherit">
<Image
src={`/ama/logo-purple.svg`}
width={150}
height={75}
sx={{
position: 'absolute',
top: '0',
left: ['10vw', '5vw']
}}
/>
</Link>
<Particle />
<Box>
<Box sx={{ position: 'absolute', top: '10px', right: '5%' }}>
<Text
sx={theme => ({
color: 'primary',
...theme.util.gxText('#CDAEFB', '#82A9F9'),
mt: [3, 4],
px: '10px',
py: '5px',
borderRadius: '5px',
border: '1px solid',
fontSize: [1, 2],
display: 'block',
fontWeight: 'bold'
})}
>
{tt('{MM} {Do} {h}:{mm} {a}').render(
new Date(`2022-02-04T01:00:00.000Z`)
)}
</Text>
<Text
sx={theme => ({
color: 'primary',
...theme.util.gxText('#CDAEFB', '#82A9F9'),
display: 'block'
})}
>
in your local date/time
</Text>
</Box>
</Box>
<Box
sx={{
p: ['15vh 20px 0 20px', '100px 50px 0 50px'],
height: '80%',
width: '90%',
bg: 'transparent',
position: 'relative',
left: '5%',
top: '10%'
}}
>
<Image
src={`/ama/vitalikName2.svg`}
width={700}
height={500}
sx={{ display: ['none', 'block'], pb: '50px' }}
/>
<Image
src={`/ama/vitalikNameMobile.svg`}
width={250}
height={200}
sx={{ display: ['block', 'none'], pt: '20px', pb: '10px' }}
/>
{timer.length ? (
<Grid
key="{e}"
gap={[1, 2, 4]}
columns={[
'1fr 1fr 1fr 1fr',
'1fr 1fr 1fr 1fr',
'1fr 1fr 1fr 1fr 1fr'
]}
sx={{
width: ['100%', '100%']
}}
>
{timer}
</Grid>
) : (
<Box
sx={{
border: ['none', '#CDAEFB 1.6px solid'],
my: ['30px', 0],
px: ['0px', '40px', '40px'],
py: ['0px', '40px', '40px'],
width: ['100%', '70%'],
borderRadius: '10px'
}}
>
<Text
sx={theme => ({
color: 'primary',
...theme.util.gxText('#CDAEFB', '#82A9F9'),
fontSize: [3, 4, 5],
fontWeight: 'bold'
})}
>
The AMA is happening right now...
</Text>
<Box>
<Button
as="a"
href="https://hack.af/vitalik-live"
sx={{
background: '#CDAEFB',
margin: ['10px', '15px'],
marginLeft: '0',
color: '#222222',
display: 'inline-block'
}}
>
Watch Livestream
</Button>
<Box
sx={{
display: 'inline-block',
margin: ['10px', '15px']
}}
>
<Text
sx={{
color: '#82A9F9',
display: 'block',
marginLeft: '5px'
}}
>
{' '}
( for Hack Clubbers )
</Text>
<Button
as="a"
href="https://hackclub.slack.com/archives/C0266FRGT/p1643334109368379"
sx={{
background: '#82A9F9',
marginLeft: '0',
color: '#222222',
display: 'block'
}}
>
Join The Call
</Button>
</Box>
</Box>
</Box>
)}
{timer.length ? (
<Box
sx={{
color: '#82A9F9',
width: ['25vw', '50vw', '50vw'],
pt: ['10px', '50px'],
zIndex: '2',
fontSize: ['12px', 1, 2],
'@media screen and (min-width: 768px) and (max-width: 1200px)':
{
fontSize: '15px'
}
}}
>
<Text>
<strong>Teenager? New here? Welcome!</strong>{' '}
<Link
href="https://hackclub.com"
target="_blank"
color="inherit"
>
Hack Club
</Link>{' '}
is a global community of high school makers & student-led coding
clubs. Weve got a 24/7 Slack chatroom of 10k+ teenagers
learning to code & building amazing projects, & youll fit right
in.
</Text>
</Box>
) : (
<Box
sx={{
color: '#82A9F9',
width: ['80vw', '50vw'],
pt: ['10px', '50px'],
zIndex: '2',
fontSize: ['15px', 1, 2],
'@media screen and (min-width: 768px) and (max-width: 1200px)':
{
fontSize: '15px'
}
}}
>
<Text>
<strong>Teenager? New here? Welcome!</strong>{' '}
<Link
href="https://hackclub.com"
target="_blank"
color="inherit"
>
Hack Club
</Link>{' '}
is a global community of high school makers & student-led coding
clubs. Weve got a 24/7 Slack chatroom of 10k+ teenagers
learning to code & building amazing projects, & youll fit right
in.
</Text>
</Box>
)}
</Box>
<Box
sx={{
position: 'absolute',
bottom: '0',
right: '0',
marginRight: ['-100px', '-50px', '-50px'],
width: ['100vw', '70vw', '40vw']
}}
>
{timer.length ? (
<>
<Image
src={`/ama/vitalikImage.svg`}
layout="responsive"
sx={{ display: ['none', 'block'] }}
/>
<Image
src={`/ama/vitalikImageMobile.svg`}
// layout="fill"
width={400}
height={400}
sx={{ display: ['block', 'none'] }}
/>
</>
) : (
<>
<Image
src={`/ama/vitalikImage.svg`}
layout="responsive"
sx={{ display: ['none', 'block'] }}
/>
</>
)}
</Box>
</Box>
</>
)
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.4 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 3.4 MiB

View file

@ -0,0 +1,86 @@
<svg width="904" height="109" viewBox="0 0 904 109" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.8896 13.6779H0L30.4531 106.783H59.1493L89.4561 13.6779H65.4449L45.2405 83.5809L24.8896 13.6779Z" fill="url(#paint0_linear_32_32)"/>
<path d="M96.7902 106.783H119.337V41.7573H96.7902V106.783Z" fill="url(#paint1_linear_32_32)"/>
<path d="M125.946 59.4917H139.562V82.6941C139.562 101.759 148.64 109 166.209 109C170.894 109 176.311 108.557 180.703 107.522V87.8667C177.775 88.31 174.115 89.049 170.747 89.049C165.038 89.049 162.109 87.4233 162.109 81.0685V59.4917H180.703V41.7573H162.109V16.6336H139.562V41.7573H125.946V59.4917Z" fill="url(#paint2_linear_32_32)"/>
<path d="M188.653 74.2703C188.653 96.5861 201.39 109 216.471 109C225.109 109 232.868 105.453 237.554 98.2117V106.783H260.101V41.7573H237.554V50.3289C232.868 43.0874 225.109 39.5405 216.471 39.5405C201.39 39.5405 188.653 51.9546 188.653 74.2703ZM224.523 58.0138C232.576 58.0138 237.846 63.9253 237.846 74.2703C237.846 84.6154 232.429 90.5268 224.523 90.5268C216.031 90.5268 211.2 83.5809 211.2 74.2703C211.2 64.9598 216.031 58.0138 224.523 58.0138Z" fill="url(#paint3_linear_32_32)"/>
<path d="M273.225 106.783H295.772V6.28857H273.225V106.783Z" fill="url(#paint4_linear_32_32)"/>
<path d="M308.969 106.783H331.516V41.7573H308.969V106.783Z" fill="url(#paint5_linear_32_32)"/>
<path d="M344.714 106.783H367.261V78.7039L388.197 106.783H415.722L388.49 72.4969L413.672 41.7573H389.076L367.261 67.3244V6.28857H344.714V106.783Z" fill="url(#paint6_linear_32_32)"/>
<path d="M449.373 106.783H489.05C511.305 106.783 521.992 95.1082 521.992 78.8517C521.992 71.4624 518.918 62.4474 504.277 58.0138C514.672 53.728 518.332 45.8953 518.332 38.3582C518.332 24.9097 509.548 13.6779 486.269 13.6779H449.373V106.783ZM483.926 30.6733C491.246 30.6733 495.492 33.6291 495.492 40.575C495.492 48.2599 491.832 51.3634 483.048 51.3634H472.067V30.6733H483.926ZM486.415 67.6199C494.467 67.6199 499.153 71.3146 499.153 78.8517C499.153 86.0932 494.321 89.7879 486.122 89.7879H472.067V67.6199H486.415Z" fill="url(#paint7_linear_32_32)"/>
<path d="M553.823 41.7573H531.276V83.1375C531.276 99.6896 540.499 109 554.262 109C561.29 109 568.171 105.453 572.417 98.3595V106.783H594.964V41.7573H572.417V74.7137C572.417 85.2065 568.317 89.7879 563.046 89.7879C557.483 89.7879 553.823 85.5021 553.823 76.6349V41.7573Z" fill="url(#paint8_linear_32_32)"/>
<path d="M601.49 59.4917H615.106V82.6941C615.106 101.759 624.184 109 641.753 109C646.438 109 651.855 108.557 656.247 107.522V87.8667C653.319 88.31 649.659 89.049 646.292 89.049C640.582 89.049 637.653 87.4233 637.653 81.0685V59.4917H656.247V41.7573H637.653V16.6336H615.106V41.7573H601.49V59.4917Z" fill="url(#paint9_linear_32_32)"/>
<path d="M698.75 109C714.708 109 728.617 100.872 731.692 85.0587H709.437C708.413 89.1967 705.192 92.0047 698.75 92.0047C692.161 92.0047 687.476 89.049 686.158 79.5906H732.131C732.424 77.0783 732.57 74.8615 732.57 72.3491C732.57 53.2846 719.979 39.5405 698.603 39.5405C678.252 39.5405 663.904 53.8758 663.904 74.2703C663.904 94.6648 678.399 109 698.75 109ZM698.31 56.5359C705.192 56.5359 709.877 59.935 710.609 66.881H685.865C687.037 59.4917 691.575 56.5359 698.31 56.5359Z" fill="url(#paint10_linear_32_32)"/>
<path d="M742.049 106.783H764.596V76.4871C764.596 66.7332 768.549 61.4129 782.165 61.4129C786.118 61.4129 789.193 61.8563 792.707 62.4474V40.1317C791.242 39.8361 789.046 39.5405 786.704 39.5405C776.894 39.5405 768.988 44.5652 764.596 54.7625V41.7573H742.049V106.783Z" fill="url(#paint11_linear_32_32)"/>
<path d="M801.814 106.783H824.361V41.7573H801.814V106.783Z" fill="url(#paint12_linear_32_32)"/>
<path d="M837.558 106.783H860.105V71.1668C860.105 62.004 864.351 58.0138 871.232 58.0138C877.528 58.0138 880.895 62.2996 880.895 71.1668V106.783H903.442V68.95C903.442 50.4767 894.072 39.5405 878.992 39.5405C870.793 39.5405 864.205 43.383 860.105 50.3289V41.7573H837.558V106.783Z" fill="url(#paint13_linear_32_32)"/>
<path d="M98.5195 18.1114L108.172 23.814V2.09619L98.5195 18.1114Z" fill="#CDAEFB"/>
<path d="M310.23 18.1114L319.883 23.814V2.09619L310.23 18.1114Z" fill="#CDAEFB"/>
<path d="M802.827 16.0152L812.479 21.7178V0L802.827 16.0152Z" fill="#90AAF9"/>
<path d="M108.171 2.09619V23.814L117.819 18.1114L108.171 2.09619Z" fill="#CDAEFB"/>
<path d="M319.883 2.09619V23.814L329.531 18.1114L319.883 2.09619Z" fill="#CDAEFB"/>
<path d="M812.479 0V21.7178L822.127 16.0152L812.479 0Z" fill="#90AAF9"/>
<path d="M98.5195 19.9404L108.172 33.5387V25.6431L98.5195 19.9404Z" fill="#CDAEFB"/>
<path d="M310.23 19.9404L319.883 33.5387V25.6431L310.23 19.9404Z" fill="#CDAEFB"/>
<path d="M802.827 17.8442L812.479 31.4426V23.5469L802.827 17.8442Z" fill="#90AAF9"/>
<path d="M108.171 25.6431V33.5387L117.827 19.9404L108.171 25.6431Z" fill="#CDAEFB"/>
<path d="M319.883 25.6431V33.5387L329.539 19.9404L319.883 25.6431Z" fill="#CDAEFB"/>
<path d="M812.479 23.5469V31.4426L822.135 17.8442L812.479 23.5469Z" fill="#90AAF9"/>
<defs>
<linearGradient id="paint0_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint1_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint2_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint3_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint4_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint5_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint6_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint7_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint8_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint9_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint10_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint11_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint12_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
<linearGradient id="paint13_linear_32_32" x1="47.3086" y1="5.18024" x2="990.072" y2="118.527" gradientUnits="userSpaceOnUse">
<stop stop-color="#CDAEFB"/>
<stop offset="1" stop-color="#82A9F9"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -2910,6 +2910,14 @@ react-scrolllock@^5.0.1:
dependencies:
exenv "^1.2.2"
react-tsparticles@^1.39.2:
version "1.39.2"
resolved "https://registry.yarnpkg.com/react-tsparticles/-/react-tsparticles-1.39.2.tgz#8706f264b9775a321f0b0e1d3c436e174319a6ec"
integrity sha512-KDMLhKHuLQS3M6tKiS9fAt9dWWEuckv/Bhh3kqGAXwS9JnA7UGklav4WrtKlZE8fKTQ+c1yIRPfX2GD+AaNZ3g==
dependencies:
fast-deep-equal "^3.1.3"
tsparticles "^1.39.2"
react-use-websocket@2.9.1:
version "2.9.1"
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-2.9.1.tgz#ef4a73a618b24f2a5875829ac0a0a0573c524710"
@ -3299,6 +3307,11 @@ theme-ui@^0.13:
"@theme-ui/mdx" "0.13.1"
"@theme-ui/theme-provider" "0.13.1"
tinytime@^0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/tinytime/-/tinytime-0.2.6.tgz#3d68b8eda06fd2a0d650f9206c57e4e44280bfa7"
integrity sha512-FdiVbzssIGxpi9tuDWcMnDb4dUeoYIA4rpsdx1wVzvCaGMk5pt4WyFg2G+MFZ08HGyWB/CM/ajQfLKp6CYiD3w==
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
@ -3354,6 +3367,11 @@ tslib@^1.8.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tsparticles@^1.39.2:
version "1.39.2"
resolved "https://registry.yarnpkg.com/tsparticles/-/tsparticles-1.39.2.tgz#5529b52967ba67f4cc48d66fabaf1001de29fffd"
integrity sha512-ClhuRuruVoR0ijj4fA8tmV+dRgGymMNqcBlvYu2gKUUIXRAkQRJrRfzqHqHY9eHqC/7gXEr6yUTNHs2vvvvUqw==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"