├── leccion10 ├── .gitignore ├── vite.config.js ├── package.json ├── index.html ├── Readme.md └── package-lock.json ├── leccion11 ├── .gitignore ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion12 ├── .gitignore ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion13 ├── .gitignore ├── src │ ├── index.jsx │ ├── App.jsx │ ├── components │ │ ├── TweetList.jsx │ │ ├── Main.jsx │ │ └── Sidebar.jsx │ ├── index.css │ ├── tweet.json │ └── assets │ │ └── ToolbarImages.jsx ├── postcss.config.js ├── vite.config.js ├── index.html ├── package.json ├── tailwind.config.js └── Readme.md ├── leccion02 ├── vite.config.js ├── package.json └── Readme.md ├── leccion03 ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion04 ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion05 ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion06 ├── vite.config.js ├── package.json ├── Readme.md └── index.html ├── leccion07 ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion08 ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── leccion09 ├── vite.config.js ├── package.json ├── index.html └── Readme.md ├── package.json ├── runner.js ├── .all-contributorsrc ├── leccion01 └── Readme.md ├── leccion00 └── Readme.md └── Readme.md /leccion10/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /leccion11/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /leccion12/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /leccion13/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /leccion13/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | 6 | 7 | ReactDOM.render(, document.getElementById("root")); -------------------------------------------------------------------------------- /leccion13/postcss.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | plugins: [ 4 | require("tailwindcss"), 5 | require("postcss-nested"), // or require('postcss-nesting') 6 | require("autoprefixer"), 7 | ], 8 | }; -------------------------------------------------------------------------------- /leccion02/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion03/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion04/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion05/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion06/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion07/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion08/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion09/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion10/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion11/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion12/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion13/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [reactRefresh()] 7 | }) 8 | -------------------------------------------------------------------------------- /leccion02/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson22", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } -------------------------------------------------------------------------------- /leccion03/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson03", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion04/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson04", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion05/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson05", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion06/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson05", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion07/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson06", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion08/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson07", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion09/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson08", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion10/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson09", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion11/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson10", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion12/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson10", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "vite": "^2.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /leccion13/src/App.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | /* 💡 Importa los siguientes componentes para configurar el layout base */ 3 | // import Sidebar from "./components/Sidebar.jsx"; 4 | // import Main from './components/Main'; 5 | 6 | /* 🏋️‍♂️ 1. Renderiza el layout base 7 | Puedes utilizar la class "app" para definir el estilo global de la aplicación 8 | */ 9 | function App() { 10 | return null 11 | } 12 | export default App -------------------------------------------------------------------------------- /leccion13/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Leccion 13 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson10", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "node runner.js" 6 | }, 7 | "dependencies": { 8 | "cross-spawn": "7.0.3", 9 | "npm": "7.14.0", 10 | "prompts": "2.4.1", 11 | "react": "^17.0.0", 12 | "react-dom": "^17.0.0" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-react-refresh": "^1.3.1", 16 | "all-contributors-cli": "6.20.0", 17 | "vite": "^2.1.5" 18 | }, 19 | "workspaces": [ 20 | "lesson*/*" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /leccion13/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson11", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "react": "^17.0.0", 11 | "react-dom": "^17.0.0" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-react-refresh": "^1.3.1", 15 | "autoprefixer": "10.2.4", 16 | "postcss": "8.2.10", 17 | "postcss-nesting": "7.0.1", 18 | "tailwindcss": "2.0.3", 19 | "vite": "^2.1.5" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /runner.js: -------------------------------------------------------------------------------- 1 | const spawn = require('cross-spawn'); 2 | const { readdirSync, fstat, statSync } = require('fs') 3 | const path = require('path') 4 | const prompts = require('prompts') 5 | const getLessons = () => { 6 | return readdirSync(path.resolve(__dirname)).filter(path => statSync(path).isDirectory()).filter(d => d.includes('leccion')) 7 | } 8 | 9 | const main = async () => { 10 | const lessons = getLessons() 11 | const response = await prompts({ 12 | type: 'select', 13 | choices: lessons.map(item => ({ title: item, value: item })), 14 | name: 'lesson', 15 | message: 'What lesson you want to run?', 16 | }) 17 | const { lesson } = response 18 | 19 | spawn.sync('npm', ['run', '--prefix', lesson, 'dev'], { stdio: 'inherit' }) 20 | } 21 | 22 | main() 23 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "react-fundamentals", 3 | "projectOwner": "matiasfha", 4 | "repoType": "github", 5 | "repoHost": "https://github.com", 6 | "files": [ 7 | "README.md" 8 | ], 9 | "imageSize": 100, 10 | "commit": true, 11 | "commitConvention": "eslint", 12 | "contributors": [ 13 | { 14 | "login": "horacioh", 15 | "name": "Horacio Herrera", 16 | "avatar_url": "https://avatars.githubusercontent.com/u/725120?v=4", 17 | "profile": "http://horacioh.com/", 18 | "contributions": [ 19 | "code", 20 | "infra" 21 | ] 22 | }, 23 | { 24 | "login": "matiasfha", 25 | "name": "Matías Hernández Arellano", 26 | "avatar_url": "https://avatars.githubusercontent.com/u/282006?v=4", 27 | "profile": "http://matiashernandez.dev/", 28 | "contributions": [ 29 | "doc", 30 | "content", 31 | "code", 32 | "infra", 33 | "example", 34 | "content" 35 | ] 36 | } 37 | ], 38 | "contributorsPerLine": 7 39 | } 40 | -------------------------------------------------------------------------------- /leccion13/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: [], 3 | darkMode: false, // or 'media' or 'class' 4 | theme: { 5 | fontFamily: { 6 | roboto: [ 7 | "-apple-system", 8 | "BlinkMacSystemFont", 9 | "Roboto", 10 | "Helvetica", 11 | "Arial", 12 | "sans-serif", 13 | ], 14 | }, 15 | extend: { 16 | colors: { 17 | black: "rgb(10,10,10)", 18 | "dodger-blue": { 19 | DEFAULT: "#1DA1F2", 20 | 50: "#F6FBFE", 21 | 100: "#DEF1FD", 22 | 200: "#AEDDFA", 23 | 300: "#7DC9F8", 24 | 400: "#4DB5F5", 25 | 500: "#1DA1F2", 26 | 600: "#0C85D0", 27 | 700: "#0967A0", 28 | 800: "#064870", 29 | 900: "#04293F", 30 | }, 31 | }, 32 | }, 33 | }, 34 | variants: { 35 | extend: { 36 | opacity: ["disabled"], 37 | }, 38 | }, 39 | plugins: [], 40 | }; -------------------------------------------------------------------------------- /leccion05/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Lección 05 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /leccion08/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Leccion 08 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /leccion04/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Lección 04 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 20 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /leccion13/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 13 - Construyamos una interfaz 2 | 3 | En esta lección podrás a prueba lo que has aprendido hasta ahora implementando una interfáz estática utilizando componentes React. 4 | 5 | Esta será una aplicación completamente escrita en React a modo SPA (Single Page Application) pero te enfocarás solo en la creación de componentes y su composición. 6 | 7 | Para lograr esto tendrás acceso a algunos componentes pre-determinados y otros recursos como estilos para utilizar. 8 | 9 | 10 | ## 🐾 Primeros Pasos 11 | 12 | - Ejecuta el código de esta lección utilizando `npm run dev` y seleccionado lección 13 13 | - Abre el código de la lección en tu editor de código favorito. 14 | - Revisa la estructura de archivos 15 | - Realiza tu trabajo en lls archivos 16 | 17 | 18 | ## 🎯 Objetivos 19 | 20 | - Crear una aplicación estática utilizando componentes React. 21 | - Esta aplicación tiene que contar con: 22 | - Una layout pre-definido 23 | - Un formulario ( con al menos un campo de texto) para capturar texto del usuario 24 | - Un botón para iniciar la captura de datos 25 | - Una lista de elementos renderizada desde una arreglo de datos. 26 | 27 | ## 🏋️‍♂️ Ejercicios 28 | 29 | 1. Implementar el layout base utilizando los componentes propuestos. 30 | 2. Impementar un formulario para capturar información de usuario (con componentes controlados o no-controlados) 31 | 3. Implementar una lista de "items" (utilizando el componente correspodiente) 32 | 33 | 34 | ## 🍬 Crédito Extra 35 | 36 | - Desplegar en la lista de items el texto capturado en el componente formularuio. 37 | 38 | 39 | ## 📣 Feedback 40 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2013) -------------------------------------------------------------------------------- /leccion13/src/components/TweetList.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Reply, Retweet, Like, Share } from '../assets/ToolbarImages'; 3 | 4 | /* 💡 Componente de Layout que renderiza una lista de componentes React que renderizan imagenes. */ 5 | const images = [Reply, Retweet, Like, Share] 6 | const Toolbar = () => { 7 | return ( 8 |
9 | {images.map((Item, index) => { 10 | return 11 | })} 12 |
13 | ) 14 | } 15 | 16 | 17 | /* 💡 Este componente renderiza 1 Tweet basado en los datos recibidos en la prop `tweet` 18 | La prop `tweet` es un objecto que contiene { avatar, author, tag, date, content }. 19 | Tienes que acceder a los datos de la prop tweet para poder renderizarlos. 20 | Puedes usar destructuring o acceder directamente sus propiedades 21 | */ 22 | 23 | const Tweet = ({ tweet }) => { 24 | 25 | return ( 26 |
27 | 28 |
29 |
30 | {/* author */} 31 | @{/* tag */} {/* date */} 32 |
33 |

{/* content*/ }

34 | 35 |
36 |
37 | ) 38 | } 39 | 40 | /* 🏋️‍♂️ 3. Implementa la lista de Tweets basado en el arreglo de tweets recibido mediante props. 41 | Esta lista renderiza componentes Tweet. 42 | No olivdes la prop key. */ 43 | const TweetList = ({ tweets = [] }) => { 44 | return ( 45 |
46 | {/* 💡 Aquí debes iterar sobre la prop tweets para renderizar */} 47 |
48 | ) 49 | } 50 | 51 | export default TweetList -------------------------------------------------------------------------------- /leccion03/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Lección 03 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |
19 | 20 | 21 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /leccion07/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Lección 07 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /leccion06/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 06 - Renderizado condicional 2 | 3 | Una interfaz es la forma de representar datos en la pantalla para facilitar la interpretación de parte del usuario y también para permitir interactuar con esos datos. Es común que en dependiendo de alguna acción del usuario o de alguna particularidad de los datos quieras no mostrar ciertos componentes, es decir, querrás renderizar tus componentes de forma condicional. 4 | 5 | Lograr esto es relativamente sencillo, sólo es necesario recordar que JSX no es un lenguaje de templates, si no, una forma más expresiva de realizar llamadas a la función `React.createElement`. También es adecuado que recuerdes que cada vez que quieras evaluar una expresión debes utilizar interpolación. 6 | 7 | Existen dos formas de lograr un rederizado condicional: 8 | 9 | - operador ternario 10 | - operadores lógicos 11 | 12 | > Es recomendable utilizar bloques condicionales u el operador ternario ya que el uso de simples operadores lógicos puede traer resultados inesperados 13 | 14 | > ¿Qué ocurre si evalúas la siguiente operación? `0 && algunaFuncionQueRetornaUnNumero()` 15 | 16 | ## 🐾 Primeros Pasos 17 | 18 | En esta lección revisaremos como renderizar componentes de forma condicional, es decir, definir cuando ser renderiza o no cierto componente. 19 | 20 | Para esto definiremos el siguiente ejemplo. 21 | 22 | > Una página de perfil de usuario que muestra sus contactos 23 | 24 | ## 🎯 Objetivos 25 | 26 | - Conocer los 2 métodos para renderizar componentes de forma condicional. 27 | - Conocer las limitaciones y resultados de cada método. 28 | - Reconocer por que no se puede utilizar un bloque condicional `if` 29 | - Ejercitar interpolación 30 | 31 | ## 🏋️‍♂️ Ejercicios 32 | 33 | 1. Renderiza el componente `` sólo cuando el atributo `contacts` está vacío utilizando un operador lógico 34 | 2. Lo mismo pero utizando el operador lógico `&&` 35 | 36 | ## 🍬 Crédito Extra 37 | 38 | - Intenta utilizar un bloque condicional `if-else`. ¿Cuál es el resultado? ¿Por qué? 39 | 40 | 41 | ## 📣 Feedback 42 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2006) -------------------------------------------------------------------------------- /leccion04/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 04 - Conociendo JSX 2 | 3 | JSX es una abstracción sobre la API `Reac.createElement` que permite expresar de forma aún más declarativa la definición de la UI que quieres renderizar. 4 | 5 | JSX es una forma más intuitiva de crear componentes, al menos más intuitiva o declarativa que la API `React.createElement`. Es muy similar a HTML. 6 | 7 | Pero JSX no es javascript por lo que necesitamos algunas herramientas extra, en particular [Babel](https://babeljs.io). 8 | 9 | Babel se encarga de transpilar o transformar el código JSX en javascript puro, es decir en llamadas a `React.createElement`. 10 | 11 | Es una buena idea recordar que tras el uso de JSX hay un grupo de llamadas a `React.createElement` a modo de “compilador humano". Esto te ayudará cuando necesites realizar operaciones complejas sobre JSX. 12 | 13 | ## 🐾 Primeros Pasos 14 | 15 | Iniciaremos los primeros pasos utilizando JSX para crear elementos y componentes React incluyendo anidación, comprendiendo así la ventajas que ofrece el uso de JSX. 16 | 17 | Para eso primero agregaremos babel a nuestra app, inicialmente usaremos una versión “standalone” que permite ejecutar el proceso de transpilación directamente en el browser. Es importante mencionar que esta forma estática de uso de Babel no es la adecuada para producción, para esos casos estarás ejecutando el proceso de compilación en tiempo de compilación, antes de hacer tu deploy. 18 | 19 | ## 🎯 Objetivos 20 | 21 | - Crear componentes y elementos JSX. 22 | 23 | Para lograr esto primero debemos agregar Babel a nuestro proyecto, lo haremos directamente con un snippet en nuestro HTML 24 | 25 | ```other 26 | 27 | ``` 28 | 29 | Además tenemos que realizar una pequeña modificación extra, en el tag ` 39 | 40 | ``` 41 | 42 | 3. Explorar nuestros archivos y verificar que React está disponible 43 | 44 | > La aplicación es servida por [Vite](https://vitejs.dev/), para ejecutar y ver el resultado de tu trabajo puedes ejecutar en la terminal y seleccionar la lección corresondiente 45 | 46 | > `$ npm run dev` 47 | 48 | Debes revisar que al cargar el archivo html React esté disponible en el scope global. Tip: utiliza las DevTools 49 | 50 | ## 🍬 Crédito Extra 51 | 52 | - Escribe en tu archivo un simple console.log para identificar que `React` está disponible. 53 | 54 | ## 📣 Feedback 55 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2002) -------------------------------------------------------------------------------- /leccion12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Leccion 12s 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /leccion12/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 12 - Formularios - Componentes no controlados 2 | 3 | ## Componentes no-Controlados 4 | 5 | La gran diferencia con los componentes controlados, es que en este caso el elemento no es manejado por el estado de su componente Padre, si no, se utiliza directamente el DOM. 6 | 7 | Para escribir un componente no controlado conoceremos brevemente otro **hook**. 8 | 9 | En estos componentes, en vez de escribir un manejador de eventos para cada actualización de estado podemos usar un **ref** para obtener los valores directamente desde el DOM. 10 | 11 | Un **ref** es una "válvula de escape" del flujo de datos de un componente React. El flujo normal es que las `props` sean la única forma en que un componente padre interactúe con los componente que renderiza. Si necesitas modificar un componente hijo, simplemente actualizas las `props` y este se re-renderizará. 12 | 13 | **ref** te provee una forma de acceder a los nodos del DOM o elementos que son creados "on-the-fly" en el renderizado, ejemplos de uso de esto es: 14 | 15 | - Manejar el foco o selección de texto de un elemento 16 | - Inicializar animaciones de forma imperativa. 17 | - Integración de librerías externas no directamente compatibles con React. 18 | 19 | Para crear un **ref** utilizamos el hook `useRef` que crea un objeto que se mantiene consistente entre diferentes renderizados del componente, es decir, cuando el ref cambia no se lanza un nuevo render. El objeto tiene un atributo llamado `current` que se mantiene actualizado. Para interactuar con el DOM, puedes pasar el `ref` a cualquier elemento y React se enlazar el valor de `current` con el elemento en el DOM. 20 | 21 | ```javascript 22 | const Component = () => { 23 | const inputRef = React.useRef() 24 | 25 | const onClickButton = () > { 26 | console.log(inputRef.current.value) 27 | } 28 | 29 | return ( 30 |
31 | Click 33 |
34 | ) 35 | } 36 | ``` 37 | 38 | ## Form 39 | 40 | Como ya sabemos el evento `onSubmit` del formulario recibe una función que permite capturar o reunir la información del formularia para después ser procesada. 41 | 42 | Si estás utilizando componentes no-controlados, tendrás que acceder a los `ref` de cada elemento para obtener su valor 43 | 44 | ## 🐾 Primeros Pasos 45 | 46 | En esta lección trabajaremos con elementos de un formulario para capturar información del usuario. 47 | 48 | Para esto usaremos **componentes no-controlados** y definiremos una función para manejar el envío del formulario. 49 | 50 | ## 🎯 Objetivos 51 | 52 | - Conocer el uso básico de un `ref`. 53 | - Capturar los datos de un form. 54 | - Conocer componentes no-controlados. 55 | 56 | ## 🏋️‍♂️ Ejercicios 57 | 58 | 1. Define el evento `onSubmit` para el form. 59 | 2. Captura los datos desde los ref utilizados. 60 | 61 | 62 | ## 📣 Feedback 63 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2012s) -------------------------------------------------------------------------------- /leccion10/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Leccion 10 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /leccion03/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 03 - El mundo sin JSX 2 | 3 | React ofrece una API “cruda” que te permite crear componentes y en realidad realizar todo lo que pienses sin necesidad de utilizar JSX. 4 | 5 | Esta API es la que se encarga de la creación de los componentes y elementos sin que tengas que tocar directamente la API imperativa del DOM, aún así la API de React mantiene cierta semejanza con el DOM. 6 | 7 | DOM API: 8 | 9 | `document.createElement(‘h1’)` 10 | 11 | React API. 12 | 13 | `React.createElement(‘h1’, props)` 14 | 15 | La gran (e importante) diferencia es que la API de React acepta props. Un objeto que describe los atributos que este componente u elemento tendrá. En el caso de la API del DOM, si quieres modificar, por ejemplo, el contenido de texto de un elemento harías: 16 | 17 | ```javascript 18 | const h1 = document.createElement('h1') 19 | h1.textNode = "Este es el título" 20 | ``` 21 | 22 | Con la API de React tienes una forma más declarativa: 23 | 24 | ```javascript 25 | const h1 = React.createElement('h1', { children: 'Este es el titulo' }) 26 | ``` 27 | 28 | Es también importante notar que para poder ejecutar React en el browser debes agregar dos script base `react` y `react-dom`. 29 | 30 | `react` es la librería que implementa las API necesarias para crear y manejar tus componentes. `react-dom` es quien "traduce" el árbol de componentes de React a algo que el DOM pueda entender. 31 | 32 | Para renderizar tus componentes en pantalla usamos 33 | 34 | ```javascript 35 | ReactDOM.render(rootElement, tuApp) 36 | ``` 37 | 38 | ## 🐾 Primeros Pasos 39 | 40 | En esta lección revisaremos como utilizar la API “cruda” para crear elementos y componentes React. 41 | 42 | ## 🎯 Objetivos 43 | 44 | - Conocer la API base de React para crear elementos y componentes. 45 | - Notar la diferencia entre elemento y componente. 46 | 47 | ## 🏋️‍♂️ Ejercicios 48 | 49 | 1. Crea una interfaz utilizando las API de Javascript. 50 | Para este ejercicio crearás elementos utilizando `document.createElement` y `document.appendChild`. 51 | 52 | - [ ] Crea un elemento H1. 53 | - [ ] Crea una lista de al menos dos items. 54 | 55 | 2. Crear un elemento h1 utilizando las API de React. 56 | 57 | Para este ejercicio crearás un elemento `h1` utilizando `React.createElement` y lo desplegarás en la página principal. 58 | 59 | 3. Crear elementos anidados. 60 | 61 | En este caso tendrás que utilizar la api `React.createElement` para crear un grupo de componentes anidados. 62 | La estructura a crear es: 63 | ```html 64 |

Hola Mundo!

65 | ``` 66 | 67 | Tip: Recuerda que `React.createElement` acepta como segundo parámetros un arreglos de `props` donde una de ellas puede ser `children` 68 | 69 | ## 🍬 Crédito Extra 70 | 71 | 1. Utilizando `React.createElement` crea una lista de 3 elementos utilizando `ul` y `li`. 72 | 2. ¿Como definirías esta API. Imperativa o Declarativa? ¿Cómo se relaciona con la API nativa del DOM? 73 | 74 | 75 | ## 📣 Feedback 76 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2003) -------------------------------------------------------------------------------- /leccion13/src/components/Main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Image, Gif, Poll, Emoticon, Schedule } from '../assets/ToolbarImages'; 3 | /* 💡 Este componente es el que se encarga de renderizar la lista de Tweets */ 4 | import TweetList from './TweetList' 5 | /* 💡 Este es un arreglo de tweets que se renderizarán. */ 6 | import data from '../tweet.json' 7 | /* 💡 Este es el contenido de un tweet, contiene los datos del usuario que crea un tweet 8 | será de utilidad para la funcionalidad de efectivamente twittear y mostrar el 9 | contenido en la lista de tweets */ 10 | const fakeTweet = { 11 | avatar: "https://robohash.org/tweeter.png", 12 | author: "Bax Jowitt", 13 | tag: "bjowitt0", 14 | date: "10/6/2020", 15 | id: new Date().getTime() 16 | } 17 | 18 | // 💡 Esta es una lista de imagenes (Estas imagenes son componentes React). El componente Toolbar debe renderizarlas. 19 | // no olvides utilizar la prop `key`. 20 | // Este componente Toolbar define 21 | const images = [Image, Gif, Poll, Emoticon, Schedule] 22 | const Toolbar = () => { 23 | return ( 24 |
25 | {/* 💡 Aqui debes renderizar las imagenes */} 26 |
27 | ) 28 | } 29 | 30 | const Header = () => { 31 | return ( 32 |
33 |

Inicio

34 |
35 | ) 36 | } 37 | 38 | 39 | // 🏋️‍♂️ 2. Crea el componente formulario para capturar información del usuario 40 | // Puedes utilizar componentes controlados o no controlados 41 | // 💡 Si usas componentes controlados recuerda usarás el hook React.useState('') 42 | // 💡 Si usas componentes NO-controlados recuerda usarás el hook React.useRef() 43 | // Encuentra más información [en este post](https://escuelafrontend.com/articulos/las-diferencias-entre-componentes-controlados-y-no-controlados-en-react) 44 | 45 | const TweetForm = () => { 46 | // Define aquí el hook que usarás 47 | 48 | // 💡 Esta es la función que se ejecutará al presionar el boton "Twittear" 49 | // Esta función debe ejecutar la prop `onSubmit` que el formulario recibe 50 | const submit = (event) => { 51 | 52 | } 53 | 54 | // 💡 Si estás utilizando componentes controlados no olvides que 55 | // necesitas una función que te permita actualizar el estado del input/textarea 56 | /*const updateValue = (event) => { 57 | 58 | }*/ 59 | return ( 60 |
61 | 62 |
63 | {/* 💡 Aqui debes agregar el elemento textarea para capturar el texto del usuario */} 64 |
65 | 66 | {/* 💡 Aqui debes renderizar el botón para "Twittear" */} 67 |
68 |
69 |
70 | ) 71 | } 72 | 73 | 74 | /* 💡 Este es el componente principal que renderizará los componentes previamente definidos 75 | Este componente es quien recibirá la lista de datos */ 76 | const Main = () => { 77 | /* 🍬 Necesitas capturar los datos en un estado para poder actualizar su contenido 78 | y debes compartir este estado con el componente "TweetList" */ 79 | 80 | return ( 81 |
82 |
83 | {/* 💡 Aqui debes renderizar el componente TweetForm y TweetList. */} 84 |
85 | ) 86 | } 87 | 88 | 89 | 90 | export default Main -------------------------------------------------------------------------------- /leccion11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Leccion 11 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /leccion09/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Leccion 09 8 | 9 | 10 | 11 | 12 | 37 | 38 | 39 |
40 | 41 | 42 | 43 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /leccion10/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 10 - Eventos 2 | 3 | Una aplicación web tiene dos tareas esenciales: presentar información al usuario y “reaccionar” a acciones que el usuario realiza. Hasta ahora hemos visto como presentar información - creando componentes para renderizar cierto contenido - pero, ¿cómo reaccionar a una acción del usuario?. 4 | 5 | Reaccionar al usuario es conocido como manejar eventos y esto es algo que javascript ya implementa por medio de los eventos del DOM. 6 | 7 | Los eventos en React son similares a los eventos del DOM, con pequeñas diferencias. 8 | 9 | - Los eventos en React son nombrados en `camelCase` por ejemplo . `onClick`. 10 | - El evento que pasas como argumento es una función y no un string como en el DOM. 11 | 12 | ```javascript 13 | 14 | ``` 15 | 16 | Otra diferencia se encuentra en una práctica común al escribir HTML y vanilla JS: utilizar `return false;` para evitar el comportamiento por defecto del evento en cuestión. En React debes utilizar explicitamente `preventDefault`. ¿por qué? React no expone los eventos del DOM directamente, al contrario, expone una API llamadas `SyntheticEvent`. 17 | 18 | Estos eventos son implementados de forma compatible con todos los navegadores (basados en el [spec W3C](https://www.w3.org/TR/DOM-Level-3-Events/)). Cuando defines un manejador de eventos como `onClick` la función que defines como argumento recibe un evento sintético. Este evento tiene la misma interfaz que los eventos nativos del navegador, por lo que su uso se hace "conocido”. 19 | 20 | La idea de usar esta API es que React normaliza los eventos para hacer que funcionen de la misma manera en todos los navegadores. 21 | 22 | Ahora, volviendo al uso de `preventDefault`. ¿Cómo evitas el comportamiento por defecto de un evento?. Simplemente accediendo al argumento evento y llamando `preventDefault` 23 | 24 | ```javascript 25 | function onClickEvent(event) { 26 | event.preventDefault() 27 | } 28 | ``` 29 | 30 | Una práctica común, es utilizar los eventos para pasar ciertos datos de un lado a otro, por ejemplo para pasar el `id` de algún elemento para crear una llamada al servidor, para lograr esto debes pasar argumentos extra a la función que usas como manejador de eventos, para hacer esto simplem`nte rodeas tu función con otra función. 31 | 32 | ```javascript 33 | items.map(item => { 34 | 35 | }) 36 | ``` 37 | 38 | ## 🐾 Primeros Pasos 39 | 40 | En esta lección trabajaremos agregando estilos utilizando los dos métodos base para definir el css de tus componentes. 41 | 42 | Para esta lección usaremos algunos elementos que solicitan acciones de usuario para así capturar sus eventos, también crearemos un componente con el mismo objetivo 43 | 44 | - Boton 45 | - Selectbox 46 | - Input 47 | - div: Si!. En React es posible agregar un manejador de eventos a cualquier componente. Los eventos de React son “sintéticos” y puede ser utilizados en cualquier elemento. 48 | 49 | ## 🎯 Objetivos 50 | 51 | - Aprender como agregar eventos a un elemento. 52 | - Conocer como manejar los eventos definidos. 53 | - Conocer como definir componentes que acepten eventos. 54 | 55 | ## 🏋️‍♂️ Ejercicios 56 | 57 | 1. Crea un elemento botón que al ser clickeado muestra un alerta. 58 | 2. Crea un elemento `select` que al cambiar el valor seleccionado muestra una alerta con el valor. 59 | 3. Crea un elemento input que muestra en consola lo que se escribe. 60 | 61 | ## 🍬 Crédito Extra 62 | 63 | 1. Crea un **componente** `Button` que acepta una prop `onClick`. Esta función estará definida en el componente padre. 64 | 65 | ## 📣 Feedback 66 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2010) -------------------------------------------------------------------------------- /leccion06/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Curso: React desde cero - Lección 06 8 | 9 | 10 | 11 | 12 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /leccion00/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 00: Introducción 2 | 3 | React es una poderosa librería para crear interfaces de usuario para tus aplicaciones web. Propone un modelo de componentes que al interactuar entre si proveen grandes experiencias de usuario. 4 | 5 | Al trabajar con React tendremos que tomar varias decisiones ya que la librería no proporciona opiniones sobre como manejar ciertos aspectos de tu aplicación, si no, sólo se enfoca - y de muy buena manera - en ofrecer una forma de crear y manejar una interfaz. 6 | 7 | **¿Qué necesitas para comenzar?** 8 | 9 | ## Primeros Pasos 10 | 11 | Antes de iniciar la primera lección en profundidad, revisemos los contenidos básicos y cuál es el proceso y resultado esperado de este workshop. 12 | 13 | ### 🎯Objetivos 14 | 15 | - Bienvenid@ al workshop 16 | - Revisar que aprenderás. 17 | 18 | ## Bienvenid@ 19 | 👋 Mi nombre es Matías Hernández, padre, desarrollador, podcaster, escritor e instructor. 20 | 21 | Trabajo formalmente desde hace ya 11 años donde al menos 6 de ellos han sido principalmente dedicados a desarrollar con React. 22 | 23 | 🐦 Encuentrame en twitter como [@matiasfha](https://twitter.com/matiasfha) 24 | 25 | ## ¿Qué esperar de este workshop? 26 | Este workshop está orientado a quienes quieren comenzar a trabajar con React o incluso para quienes llevan un tiempo trabajando ya que profundizaremos en algunos de los conceptos y modelos mentales base para entendeer cómo y por qué de algunas técnicas o métodos de uso de React. 27 | 28 | Comenzaremos desde los fundamentos revisando que es un componente y como **Pensar en React** para finalizar implementando una interfáz estática. 29 | 30 | 31 | ## 🍬 Créditos Extra 32 | 33 | Revisemos algunos artículos que nos ayudaran a preparar los conceptos base que usaremos en el curso 34 | - [ ] [¿Qué es Babel?](https://www.freecodecamp.org/espanol/news/que-es-babel/) - [Matías Hernánedez](https://twitter.com/matiasfha) 35 | - [ ] [¿Qué es Inmutabilidad en Javascript](https://www.freecodecamp.org/espanol/news/que-es-inmutabilidad-en-javascript/) - [Matías Hernánedez](https://twitter.com/matiasfha) 36 | - [ ] [¿Qué es un closure en Javascript](https://www.freecodecamp.org/espanol/news/que-es-un-closure-en-javascript/) - [Matías Hernánedez](https://twitter.com/matiasfha) 37 | - [ ] [Diferences Entre Valor y Referencia en Javascript](https://www.escuelafrontend.com/articulos/diferencias-valor-y-referencia-en-js) - [Claudia Valdivieso](https://twitter.com/lavaldi_) 38 | - [ ] [Lo que Nadie te Enseña Sobre la Igualdad en Javascript](https://www.escuelafrontend.com/articulos/nadie-te-ensena-sobre-la-igualdad-en-js) - [Horacio Herrera](https://twitter.com/hhg2288) 39 | - [ ] [Aprendamos Sobre los Tipos de Datos Primitivos en Javascript](https://www.escuelafrontend.com/articulos/los-tipos-primitivos-en-javascript) - [Horacio Herrera](https://twitter.com/ 40 | - [ ] [Entiende Hoisting en Javascript con Ejemplos Prácticos](https://escuelafrontend.com/articulos/hoisting-ejemplos-practicos) - [Claudia Valdivieso](https://twitter.com/lavaldi_) 41 | - [ ] [Entiende el Concepto de Elevación (Hoisting) en JavaScript](https://escuelafrontend.com/articulos/hoisting-javascript) - [Horacio Herrera](https://twitter.com/hhg2288) 42 | - [ ] [Diferencias Entre Declaraciones de Funciones y Expresiones de Funciones](https://escuelafrontend.com/articulos/declaraciones-de-funciones-y-expresiones-de-funciones) - [Horacio Herrera](https://twitter.com/hhg2288) 43 | - [ ] [La guía definitiva de Métodos de Arreglos](https://escuelafrontend.com/articulos/metodos-de-arreglos) - [Matías Hernánedez](https://twitter.com/matiasfha) 44 | - [ ] [4 formas de eliminar elementos duplicados en un arreglo con Javascript](https://matiashernandez.dev/4-formas-de-eliminar-elementos-duplicados-en-un-arreglo-con-javascript) 45 | - [ ] [Arreglos de objetos en Javascript: Cómo crear y actualizar su contenido](https://matiashernandez.dev/arreglos-de-objetos-en-javascript-como-crear-y-actualizar-su-contenido) 46 | - [ ] [Repositorio: Javascript Moderno](https://github.com/matiasfha/modern-javascript) 47 | - [ ] [¿Cómo crear una aplicación en React?](https://escuelafrontend.com/articulos/como-crear-una-aplicacion-en-react) -------------------------------------------------------------------------------- /leccion08/Readme.md: -------------------------------------------------------------------------------- 1 | # Lesson 08 - Arrays 2 | 3 | Una de las estructuras de datos más utilizada en cualquier aplicación web es el Array. Esta simple estructura es la forma más sencilla de contener y manipular colecciones de datos. Por esto, es importante conocer como trabajar con ella al momento de utilizar componentes React. 4 | 5 | Una de las tareas más comunes relacionadas con arrays es la idea de renderizar una lista de elementos en la interfaz, esta lista de elementos está representada por un array. 6 | 7 | Para poder renderizar una lista debemos iterar sobre ella y como ya revisamos en la lección sobre JSX, podemos utilizar interpolación para escribir código javascript válido en forma de una expresión que nos permita iterar sobre los elementos, en este caso usaremos `Array.map` . 8 | 9 | > Una expresión produce un valor y puede ser escrita en cualquier parte donde un valor sea esperado, por ejemplo como un argumento de una función. 10 | 11 | `Array.map` permite iterar sobre un arreglo y retorna un nuevo arreglo, es decir retorna un valor. Este nuevo arreglo es el que será renderizado por React. 12 | 13 | Un componente React acepta arreglos de valores o componentes en su prop `children` por lo que podemos transformar los elementos de arreglo en un nuevo componente o simplemente renderizar el arreglo directamente. 14 | 15 | ```jsx 16 | const ui = ( 17 | arreglo.map(item => item) 18 | ) 19 | ``` 20 | 21 | Una vez que tenemos el arreglo renderizado podemos ver que React nos avisa de un problema: Nos falta definir una prop llamad a `key` en nuestros compoenntes. 22 | 23 | Esta prop debe recibir un valor único e invariable. Esto es simple de resolver en un caso donde el arreglo de datos utilizado es fijo y no cambia en el tiempo, podemos resolver este problema simplemente utilizando un valor como el indice del elemento en el arreglo. ¿Pero que ocurre si el arreglo de datos cambia en el tiempo? 24 | 25 | La prop `key` le ayuda a React a mantener una forma de "rastrear" los elementos renderizados en cada proceso de actualización, si la prop no está presente React no podrá saber que elemento cambió y donde estaba y puede mezclar algunas cosas. 26 | 27 | Un caso es que renderizas la lista y despues agregas un nuevo elemento. React no podrá identificar si el elemento que agregaste se debe ubicar al principio, final o en medio, esto es por que React no puede entender nuestras intenciones y solo ve que en un momento se le entrego una lista a renderizar, y luego se le pide renderizar una lista diferente. React intenta comparar el antes y después por lo que hará su mejor suposición y muchas veces esto funciona. 28 | 29 | Pero las cosas se complican cuando alguno de los elementos del arreglo es un componente que contiene cierto estado React puede errar y complicar el resultado de tu UI. 30 | 31 | > Aquí estado puede ser tanto estado interno de un componente personalizado o incluso estado de un elemento HTML como un input. 32 | 33 | Puedes profundizar más sobre como funciona la prop `key` revisando el siguiente artículo en Escuela Frontend: [¿Cómo funciona la prop key en React?](https://escuelafrontend.com/articulos/como-funciona-la-prop-key-en-react) 34 | 35 | 36 | 37 | ## 🐾 Primeros Pasos 38 | 39 | En esta lección trabajaremos renderizando múltples elementos de forma “automática”. Para ello construiremos una lista de elementos basados en un arreglo de strings. 40 | 41 | ## 🎯 Objetivos 42 | 43 | - Conocer como renderizar múltiples elementos utilizando interpolación y `Array.map` 44 | - Comprender que hace la prop `key` y por que es necesaria. 45 | 46 | ## 🏋️‍♂️ Ejercicios 47 | 48 | 1. Renderiza manualmente una lista de elementos. 49 | 2. Utiliza `Array.map` para crear una lista de elementos basado en un arreglo de strings. 50 | 3. Agrega la prop `key` faltante utilizando un valor único. 51 | 52 | ## 🍬 Crédito Extra 53 | 54 | - Revisa el siguiente demo sobre como funciona la prop `key`. ¿Cuál es el problema al eliminar elementos?. ¿Cómo el uso de la prop `key`afecta el funcionamiento del demo? 55 | [https://codesandbox.io/s/react-array-keys-qmwwk?from-embed=&file=/src/App.js](https://codesandbox.io/s/react-array-keys-qmwwk?from-embed=&file=/src/App.js) 56 | 57 | ## 📣 Feedback 58 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2008) -------------------------------------------------------------------------------- /leccion11/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 11 - Formularios - Componentes Controlados 2 | 3 | La forma primaria de obtener datos de un usuario en un sitio web es por medio del formularios. 4 | 5 | Un formulario permite manejar un conjunto de elementos que capturan información del usuario. A su vez, permiten comunicarse con el servidor o una api externa al ser enviados. 6 | 7 | Los elementos de un formulario funcionan ligeramente diferente a otros elementos HTML base ya que estos, de forma nativa, manejan un estado interno que les permite almacenar los datos capturados. 8 | 9 | En React existen dos formas de manejar los formularios: 10 | 11 | - **Componentes Controlados** 12 | - **Componentes no-Controlados** 13 | 14 | ## Componentes Controlados 15 | 16 | Como mencione antes, los elementos de un formulario HTML mantienen su propio estado interno y lo actualizan en base a las acciones del usuario. React también maneja su prop estado y si hablamos de estado mutable React ofrece su propia API para manejarlo. Esta es nuestra primera aproximación al manejo de estado. 17 | 18 | La forma en que utilizas el estado en React es por medio de la función llamada `useState` esta función es parte de la api de **hooks**. Esta función es sencilla de utilizar, su intención almacenar en un solo lugar el estado que el componente renderizará. Esto permite que tus componentes reaccionen al cambio de estado y se vuelvan a renderizar para reflejar dicho cambio. 19 | 20 | Su forma de uso es sencilla 21 | 22 | ```javascript 23 | const [ count, setCount ] = React.useState(0) 24 | ``` 25 | 26 | La función recibe un argumento que representa el estado inicial, en este caso el valor `0` y retorna un arreglo o "tupla” cuyo primera valor representa el estado actual y el segundo valor siempre será una función (que puedes llamar como quieras) que te permite actualizar dicho estado. 27 | 28 | Utilizaremos esta funcionalidad de React para mantener una “sola fuente de la verdad” al utilizar elementos de formulario, es decir, el componente que renderiza los elementos de formulario es también quien controlará el estado de los elementos en base a las acciones del usuario. Estos elementos que son manejados por el estado del componente padre son llamados **componentes controlados**. 29 | 30 | En este tipo de componentes, el valor del input (o de cualquier otro elemento del formulario) es manejado por el estado de React. Ciertamente esto implica escribir un poco más de código, pero también te da gran poder y flexibilidad permitiéndote por ejemplo pasar este valor como prop a toras partes de la interfaz. 31 | 32 | ## Form 33 | 34 | El element `
` te permite reunir elementos de captura de datos, es un contenedor que por lo general permite enviar los datos reunidos al servidor un "manejador del formulario" que se define en el atributo `action`, esto además de enviar los datos también refresca la página, un comportamiento que actualmente no se utiliza mucho. Con React tienes una forma de controlar que hacer con los datos recolectados por medio del evento `onSubmit`. 35 | 36 | El evento `onSubmit` recibe una función que a su vez recibe un evento. Esta función es ejecutada cuando el formulario es "enviado", por ejemplo al presionar el botón `submit` . 37 | 38 | SI estas usando componentes controlados, es decir, estado interno en tu componente entonces en el manejador de `onSubmit` simplemente debes leer el estado. 39 | 40 | ## 🐾 Primeros Pasos 41 | 42 | En esta lección trabajaremos con elementos de un formulario para capturar información del usuario. 43 | 44 | Para esto usaremos **componentes controlados** y definiremos una función para manejar el envío del formulario. 45 | 46 | ## 🎯 Objetivos 47 | 48 | - Manejar estados de un form. 49 | - Capturar los datos de un form. 50 | - Conocer componentes controlados. 51 | 52 | ## 🏋️‍♂️ Ejercicios 53 | 54 | 1. Define el evento `onSubmit` para el form. 55 | 2. Define los manejadores de eventos para el input y para el select. 56 | 3. Actualiza el método `onSubmit` para que no refresque la página. 57 | 58 | ## 🍬 Crédito Extra 59 | 60 | 1. Agrega un nuevo input al formulario y maneja un solo estado para todos los elementos. (Tip: puede usar la prop `name` para obtener los datos). 61 | 62 | ## 📣 Feedback 63 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2011) -------------------------------------------------------------------------------- /leccion05/Readme.md: -------------------------------------------------------------------------------- 1 | # Leccion 05 - Props 2 | 3 | En React los componentes son representados por funciones encapsulan lógica y descripción de la UI usando JSX. También sabemos que un componente React es en cierta forma una unidad aislada del mundo, pero al mismo tiempo sabemos que debe existir una forma de que el componente se comunique con el mundo exterior. Para esto se usa el concepto de **props**. 4 | 5 | Al igual que las funciones aceptan argumentos, un componente React acepta “valores” que son pasados por medio de un objeto llamado **props**. 6 | 7 | Recordemos la API cruda de `React.createElement` 8 | 9 | ```javascript 10 | React.createElement(type, [props],[...children]) 11 | ``` 12 | 13 | Lo que esta definición indica es que un componente creado con `React.createElement` acepta un objeto opcional llamado **props** y un número indefinido de hijos. 14 | 15 | Para escribir lo mismo en JSX y pasar estos valores llamados props, simplemente agregamos “atributos” a la declaración 16 | 17 | ```javascript 18 | Este es el Titulo 19 | ``` 20 | 21 | En este ejemplo `color=“red”` define una **prop** llamada `color` con el valor string `red` 22 | ¿Cómo se reciben las props en un componente? 23 | 24 | Cuando definimos un componente, en realidad estamos creando una función que retorna JSX, para que esta función sea considerada un componente React valido debe aceptar solo un argumento, este único argumento es el que llamamos **props**. 25 | 26 | ```javascript 27 | const Title = (props) => { 28 | const { color, children } = props 29 | return

{children} - {color}

30 | } 31 | ``` 32 | 33 | El componente título es una función que acepta un argumento, este argumento llamado **props** es un objeto cuyos atributos son los nombres que has dado a las props, por lo que puedes usar destructuring para acceder a ellos (puedes hacerlo también directamente en los argumentos). 34 | 35 | Existe una prop por defecto que no fue definida por ti. **children**. Esta prop (opcional) hace referencia a el tercer argumento de `React.createElement.` **children** es una estructura de datos opaca, es decir, no hay que lidiar con ella directamente, si no, utilizando las utilidades que la propia API ofrece. 36 | 37 | **children** puede ser: Un string, boolean, número, null, un elemento, un componente, o un array de los anteriores. 38 | 39 | Además en este ejemplo pudiste ver otra característica de JSX. Interpolación. Esta es la forma en que puedes definir declaraciones javascript dentro de tu JSX, es muy similar a usar template literals, es una forma de “poner valores” desde un mundo en otro. 40 | 41 | En el ejemplo, abrimos el uso de JSX y usamos las llaves `{}`para determinar que estaremos interpolando javascript dentro de JSX. 42 | 43 | Puedes interpolar lo que sea dentro de las llaves `{}` mientras sea javascript válido, solo recuerda que lo que estás haciendo al interpolar dentro de JSX es en realidad creando un nuevo **children** que es el tercer arugmento de `React.createElement` 44 | 45 | ```javascript 46 | const Title = (props) => { 47 | const { color, children } = props 48 | return

{children} - {color}

49 | } 50 | ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 51 | 52 | const Title = (props) => { 53 | const { color, childrn } = props 54 | return React.createElement('h1',null, children, " _ ", color) 55 | } 56 | ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 57 | const Title = ({ color, children })=> { 58 | return React.createElement('h1',null, children, " _ ", color) 59 | } 60 | ``` 61 | 62 | ## 🐾 Primeros Pasos 63 | 64 | En esta lección trabajaremos pasando props a nuestros componentes y renderizando interpolaciones de esos valores. 65 | 66 | Para esto crearemos componentes que se comunicaran entre ellos mediante el uso de **props**. 67 | 68 | ## 🎯 Objetivos 69 | 70 | - Conocer como comunicar componentes mediante el uso de props. 71 | - Utilizar interpolación y conocer que es y no posible de interpolar en React. 72 | 73 | ## 🏋️‍♂️ Ejercicios 74 | 75 | 1 Crea un componente que mostrará la información de un usuario. El componente debe recibir como props los datos del usuario (nombre, email y telefono). 76 | 2. Crea un componente padre que pase los datos del usuario como props al componente anterior. 77 | 78 | ## 🍬 Crédito Extra 79 | 80 | 1. Considera que tienes un objeto con varios atributos, ¿cómo puedes pasar ese objeto directamente como props a tu componente? 81 | 82 | 83 | ## 📣 Feedback 84 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2005) -------------------------------------------------------------------------------- /leccion09/Readme.md: -------------------------------------------------------------------------------- 1 | # Lección 09 - Estilos 2 | 3 | React ofrece dos formas básicas o por defecto para manejar los estilos de tus componentes. 4 | 5 | Los elementos que usas para crear tus componente React aceptan dos props para estos fines `style` y `className`. 6 | 7 | ```javascript 8 | const Container = () => { 9 | return
Hola Mundo!
10 | } 11 | 12 | const Title = () => { 13 | return

Hola Mundo!

14 | } 15 | 16 | ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 17 | 18 | HTML 19 |
Hola Mundo!
20 | 21 |

Hola Mundo!

22 | ``` 23 | 24 | En el primer ejemplo puedes notar que el uso de la prop `style` es muy similar a como utilizas estilos `in-line` en HTML, la gran diferencia aquí es que en React la prop `style` recibe un objeto (por eso se usan dobles llaves `{{` una para iniciar la interpolación y otra para definir el objeto). La otra diferencia es que las propiedades CSS son escritas en formato `camelCase` ¿por qué? Recuerda que JSX es básicamente javascript, babel se encarga de transformarlo a simples llamadas a `React.createElement`. Esta llamada hace uso de la propiedad `style` del DOM que utiliza el formato `camelCase` (la propiedad `style` del DOM utiliza un objeto tipo [CSSStyleDeclaration](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration) ) 25 | 26 | La siguiente prop que podemos usar es `className` , esta es una de las pocas diferencias con HTML, `className` es lo mismo que usar `class`, es decir, acepta un string con los nombres de las clases CSS que serán aplicadas. 27 | 28 | Estas son las formas básicas en que puedes aplicar estilos a tus componentes utilizando CSS tal como lo has hecho hasta ahora. 29 | 30 | Pero recuerda que la idea de los componentes es que estos encapsulen tanto lógica como representación, por lo que los estilos también deberían estar encapsulados. Para lograr esto existen varias técnicas entre ellas. 31 | 32 | - **inline styles:** Esta es la forma base de la modularización de los estilos. Simplemente usando la prop `style` puedes pasar estilos que afectan solo al componente en juego. 33 | - **CSS Modules**: Esta técnica te permite importar archivos css directamente en tu archivo javascript de un componente en particular, el css generado aquí afecta exclusivamente a tu componente. 34 | - **CSS-in-JS**: La idea de esta técnica es escribir el código css directamente usando el poder de javascript, dentro de esta area se encuentra styled-componentes 35 | 36 | Revisaremos estas técnicas más avanzadas en una siguiente lección, por ahora usaremos la forma básica de agregar estilos a nuestra aplicación estática. 37 | 38 | ## 🐾 Primeros Pasos 39 | 40 | En esta lección trabajaremos agregando estilos utilizando los dos métodos base para definir el css de tus componentes. 41 | 42 | Tendremos el siguiente css disponible en nuestra página 43 | 44 | ```css 45 | .list { 46 | list-style: none 47 | } 48 | .item { 49 | background-color: lightblue; 50 | padding: 10px; 51 | border: 1px blue solid; 52 | border-radius: 5px; 53 | margin: 5px; 54 | } 55 | .item--red { 56 | background-color: red; 57 | } 58 | .item--blue { 59 | background-color: lightblue; 60 | } 61 | .item--purple { 62 | background-color:purple ; 63 | } 64 | .item--underline { 65 | text-decoration: underline; 66 | } 67 | ``` 68 | 69 | Tu trabajo será utilizar estos estilos en tus componentes aplicando lo que hemos aprendido hasta ahora. 70 | 71 | - Renderizado de arreglos 72 | - interpolación 73 | 74 | ## 🎯 Objetivos 75 | 76 | - Conocer como funciona las prop `style` y `className`. 77 | - Utilizar conocimientos adquiridos en conjunto para dar estilos a los componentes. 78 | 79 | ## 🏋️‍♂️ Ejercicios 80 | 81 | 1. Renderiza una lista de elementos. El contenedor de la lista debe utiliza la clase `list` y los elementos de la lista deben usar estilo en linea por ejemplo para definir el tamaño de la fuente. 82 | 2. Define el uso de una prop para recibir el estilo en linea de cada Item. la definición del estilo en linea deberá hacerse fuera del componente Item. 83 | 3. Define el uso de diferentes tamaños de fuente para cada item renderizado. Para esto tendrás que crear un arreglo con los valores que quieres usar y luego utilizar `Array.map` para acceder a cada tamaño en el momento de renderizar cada elemento. 84 | 85 | ## 🍬 Crédito Extra 86 | 87 | 1. Además de usar estilos en linea, utiliza la clase `item` en cada item. 88 | 2. Permite que el componente `Item` reciba una prop para modificar la clase css base. 89 | 90 | ## 📣 Feedback 91 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2009) -------------------------------------------------------------------------------- /leccion07/Readme.md: -------------------------------------------------------------------------------- 1 | # Lesson 7 - Composicion 2 | 3 | Uno de los conceptos que cambió radicalmente la forma en que desarrollamos aplicaciones en la web es la idea de utilizar componentes. 4 | 5 | Los componentes son las bases de construcción, los bloques lego, que nos permiten crear estructuras más complejas que nos permitirán desarrollar una solución. 6 | 7 | Una característica de este modelo de componentes es su capacidad de unirse o 8 | 9 | La forma en que React facilita la composición de componentes es usando las props. 10 | 11 | Las props son la forma en que los componentes se comunican entre si, es su API, una los componentes en React tienen una prop particular: `children`. Esta prop permite pasar diferentes valores: componentes, elementos, strings, números o incluso `null` 12 | 13 | Los valores pasados por medio de la prop `children` son después renderizados por el componente que las acepta. 14 | 15 | ```javascript 16 | function BoxContainer({ children}) { 17 | return ( 18 |
19 | {children} 20 |
21 | ) 22 | } 23 | ``` 24 | 25 | Esto permite que otros componentes puedan utilizar `BoxContainer` como padre. 26 | 27 | ```javascript 28 | function App() { 29 | return ( 30 | 31 |

Welcome

32 | 33 | 34 | 35 | 36 |
37 | ) 38 | } 39 | ``` 40 | 41 | Todo lo que este dentro del tag `` es considerado `children` y es pasado al componente `BoxContainer`. 42 | 43 | Por lo general, estos componentes (como `BoxContainer`) que actúan como padres contenedores son componentes que definen la interfaz y estilo pero con poca o nada de lógica en si, es decir son componentes de Layout. 44 | 45 | `children` es la prop por defecto para definir estos componentes de `Layout` y pasar componentes para que sean renderizados, pero ¿Qué ocurre si necesitas mas "espacios" dentro de tu interfaz? 46 | 47 | Las prop pueden recibir cualquier tipo de dato, primitiva o función y un componente React es en esencia una función, entonces puedes crear una prop que reciba un componente. 48 | 49 | ```javascript 50 | function App() { 51 | return ( 52 | 53 |

Welcome

54 | } footer={} 56 | > 57 | 58 | 59 |
60 | ) 61 | } 62 | ``` 63 | 64 | En este ejemplo el componente `Dashboard` recibe dos nuevas props `navbar` y `footer` que aceptan un componente cada una. Si miramos dentro del componente podremos tener algo así. 65 | 66 | ```javascript 67 | function Dashboard({ navbar, footer, children }) { 68 | return ( 69 |
70 | 73 |

This is the Dashboard

74 |
75 | {children} 76 |
77 | {footer} 78 |
79 | ) 80 | } 81 | ``` 82 | 83 | Como resultado tenemos un componente que se encarga de renderizar las “piezas” de tu interfaz permitiéndote cambiar esas piezas como más adecuado sea. 84 | 85 | Este proceso de composición es nativo a React y puede ser realmente poderoso permitiendo por ejemplo: 86 | 87 | - Especialización: A veces tienes componentes genéricos y un componente casí idéntico pero que aplica a un caso de uso particular o especial. En este caso simplemente aceptas diferentes props en el componente genérico y creas un componente especial que define esas props. 88 | - Manejo de estado: Si bien aún no hemos hablado de que es el estado dentro de tu aplicación, es bueno saber que este patrón de utilizar las props para pasar datos y componer componentes complejos es la forma “natural” de React de manejar y manipular el estado. 89 | 90 | ## 🐾 Primeros Pasos 91 | 92 | En esta lección trabajarás en conocer un concepto base de React y el modelo de componentes: Composición. 93 | 94 | Para eso crearás algunos componentes base con los que “compondrás” una interfaz más compleja. 95 | 96 | ## 🎯 Objetivos 97 | 98 | - Conocer como pasar datos y componentes utilizando props y la prop `children`. 99 | - Conocer y utilizar las props para pasar componentes. 100 | - Utilizar composición como el patrón base para manipular datos y la interfaz. 101 | 102 | ## 🏋️‍♂️ Ejercicios 103 | 104 | - 1. Define que props debe utilizar el componente `Page` para poder renderizar las distintas partes de la página 105 | - 2. Utiliza interpolación para renderizar los diferentes componentes hijos 106 | 107 | ## 🍬 Crédito Extra 108 | 109 | - Declara props en los componentes hijos: `PageBody` y `Footer`. Define estas props en el componente `App`. ¿Cómo puedes pasar estas props para ser renderizadas? 110 | 111 | ## 📣 Feedback 112 | Por favor completa [este formulario](https://docs.google.com/forms/d/e/1FAIpQLSfVXaAKvJ7aj_de08YTet3g4Go5FV7QrI9TJWkYI1UDg1KW6A/viewform?usp=pp_url&entry.1045988887=Lección%2007) -------------------------------------------------------------------------------- /leccion13/src/tweet.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avatar": "https://robohash.org/tweeter.png", 4 | "author": "Bax Jowitt", 5 | "tag": "bjowitt0", 6 | "date": "10/6/2020", 7 | "content": "nulla elit ac nulla sed vel enim sit amet nunc viverra dapibus nulla suscipit ligula in lacus curabitur at ipsum ac tellus semper interdum", 8 | "id": "18d75543-a3f8-4873-940f-a9912e0e2e4e" 9 | }, 10 | { 11 | "avatar": "https://robohash.org/react.png", 12 | "author": "Elizabet Giacoboni", 13 | "tag": "egiacoboni1", 14 | "date": "10/23/2020", 15 | "content": "est congue elementum in hac habitasse platea dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum justo nec condimentum neque sapien placerat ante nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis sed ante vivamus tortor duis mattis egestas metus aenean fermentum donec ut mauris eget massa tempor convallis nulla neque libero convallis eget eleifend luctus ultricies", 16 | "id": "582aee8a-e206-4d7e-8aa7-1d66d1e1fa11" 17 | }, 18 | { 19 | "avatar": "https://robohash.org/sedlaboriosamsaepe.png", 20 | "author": "Hilliary Strutley", 21 | "tag": "hstrutley2", 22 | "date": "4/11/2020", 23 | "content": "hac habitasse platea dictumst etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam varius nulla facilisi cras non velit nec nisi vulputate nonummy maecenas tincidunt lacus at velit vivamus vel nulla eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis donec semper sapien a libero nam dui proin leo odio porttitor id consequat in consequat ut nulla sed accumsan felis ut at dolor quis odio consequat varius integer ac leo pellentesque ultrices mattis odio donec vitae nisi nam", 24 | "id": "7c305a95-172f-4bbb-bfd2-161fbbd10164" 25 | }, 26 | { 27 | "avatar": "https://robohash.org/eggheadio", 28 | "author": "Pebrook Rodder", 29 | "tag": "prodder3", 30 | "date": "6/7/2020", 31 | "content": "in ante vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae duis faucibus accumsan odio curabitur convallis duis", 32 | "id": "6f5cffbd-24bf-42bb-ab02-14ffb941802a" 33 | }, 34 | { 35 | "avatar": "https://robohash.org/quasirepellendusnon.png", 36 | "author": "Sigfrid Scholes", 37 | "tag": "sscholes4", 38 | "date": "3/18/2020", 39 | "content": "bibendum felis sed interdum venenatis turpis enim blandit mi in porttitor pede justo eu massa donec dapibus duis at velit eu est congue elementum in hac habitasse platea dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum justo nec condimentum neque sapien placerat ante nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis sed ante vivamus tortor duis mattis egestas metus aenean fermentum donec ut mauris", 40 | "id": "5292a18b-3535-4656-b6b5-9800c7c8bf5c" 41 | }, 42 | { 43 | "avatar": "https://robohash.org/quianimiaut.png", 44 | "author": "Frank Oley", 45 | "tag": "foley5", 46 | "date": "3/14/2020", 47 | "content": "feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium iaculis justo in", 48 | "id": "eb82dbb4-035e-4c11-9b79-2bf09756f483" 49 | }, 50 | { 51 | "avatar": "https://robohash.org/corporisdolorealias.png", 52 | "author": "Ashly Dodds", 53 | "tag": "adodds6", 54 | "date": "12/2/2020", 55 | "content": "sit amet nunc viverra dapibus nulla suscipit ligula in lacus curabitur at ipsum ac tellus semper interdum mauris ullamcorper purus sit amet nulla", 56 | "id": "12aabcdb-09e2-487f-99e5-d86d2f9691c4" 57 | }, 58 | { 59 | "avatar": "https://robohash.org/eestautem", 60 | "author": "Pebrook Bellefonte", 61 | "tag": "pbellefonte7", 62 | "date": "3/18/2020", 63 | "content": "odio elementum eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus", 64 | "id": "9783e2d5-ef18-49df-bed5-36630e38a69b" 65 | }, 66 | { 67 | "avatar": "https://robohash.org/dictaenim", 68 | "author": "Boot Joll", 69 | "tag": "bjoll8", 70 | "date": "10/21/2020", 71 | "content": "et magnis dis parturient montes nascetur ridiculus mus etiam vel augue vestibulum rutrum rutrum neque aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices enim", 72 | "id": "a5cddd87-6496-4a33-9ebb-1f7190cea263" 73 | }, 74 | { 75 | "avatar": "https://robohash.org/ducimusminus", 76 | "author": "Ewart Christofides", 77 | "tag": "echristofides9", 78 | "date": "8/2/2020", 79 | "content": "in faucibus orci luctus et ultrices posuere cubilia curae nulla dapibus dolor vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam varius nulla facilisi cras non velit nec nisi vulputate nonummy", 80 | "id": "b15ab5d8-b93f-4e2b-b997-505dafc28786" 81 | } 82 | ] -------------------------------------------------------------------------------- /leccion13/src/components/Sidebar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | /* 💡 Este es un arreglo de items para renderizar los elementos del menu */ 4 | const items = [ 5 | { 6 | icon: ( 7 | 8 | 9 | 10 | 11 | 12 | ), 13 | text: "Inicio", 14 | }, 15 | { 16 | icon: ( 17 | 18 | 19 | 20 | 21 | 22 | ), 23 | text: "Explorar", 24 | }, 25 | { 26 | icon: ( 27 | 28 | 29 | 30 | 31 | 32 | ), 33 | text: "Notificationes", 34 | }, 35 | { 36 | icon: ( 37 | 38 | 39 | 40 | 41 | 42 | ), 43 | text: "Mensajes", 44 | }, 45 | { 46 | icon: ( 47 | 48 | 49 | 50 | 51 | 52 | ), 53 | text: "Perfil", 54 | }, 55 | { 56 | icon: ( 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ), 66 | text: "Más opciones", 67 | }, 68 | ]; 69 | 70 | /* 💡 Componente principal para renderizar la barra lateral del menu */ 71 | const Sidebar = () => { 72 | return ( 73 |
74 |
    75 |
  • 76 | 77 | 78 | 79 | 80 | 81 |
  • 82 | {/* 🏋️‍♂️ 1. Esto es parte del layout. Debes renderizar la lista de menu. Esta lista proviene del arreglo `items` */} 83 | {/* El componente a renderizar es un li. No olivdes utilizar la prop `key` 84 |
  • 87 |
    {item.icon}
    88 | {item.text} 89 |
  • 90 | 91 | */} 92 | 93 |
  • 94 | 97 |
  • 98 |
99 |
100 | ); 101 | }; 102 | 103 | export default Sidebar; -------------------------------------------------------------------------------- /leccion13/src/assets/ToolbarImages.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export const Image = () => { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | ); 12 | }; 13 | 14 | export const Gif = () => { 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | }; 24 | export const Poll = () => { 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | }; 33 | export const Emoticon = () => { 34 | return ( 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | }; 45 | export const Schedule = () => { 46 | return ( 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ); 56 | }; 57 | 58 | export const Reply = () => { 59 | return ( 60 | 61 | 62 | 63 | 64 | 65 | ); 66 | }; 67 | 68 | export const Retweet = () => { 69 | return ( 70 | 71 | 72 | 73 | 74 | 75 | ); 76 | }; 77 | 78 | export const Like = () => { 79 | return ( 80 | 81 | 82 | 83 | 84 | 85 | ); 86 | }; 87 | 88 | export const Share = () => { 89 | return ( 90 | 91 | 92 | 93 | 94 | 95 | 96 | ); 97 | }; -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # 🎉 Bienvenido 2 | 3 | 4 | [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) 5 | 6 | 7 | ## 🚌 Fundamentos de React 8 | 9 | - Demo app: 10 | 11 | En este workshop aprenderás los diferentes conceptos base que fundamentan el cómo y por qué de ciertas prácticas en React. Revisaremos que necesidad viene a cubrir, desde donde nace su API, el uso de JSX, como manejar estilos, eventos y estado de un componente 12 | 13 | ## 👨🏻‍💻 Resumen del Workshop 14 | 15 | Ok. ¿listo y ansioso de aprender?, genial, este será un viaje divertido y lleno de desafíos. Algunas de las cosas que podrás aprender serán: 16 | 17 | - Pensando en React 18 | - Como configurar una app React desde cero y de forma estática. 19 | - ¿Por que usamos JSX? 20 | - ¿Qué es un componente? y como pensar en términos de componentes. 21 | - Como crear componentes utilizando React y JSX. 22 | - Cómo manejar estilos en tu aplicación. 23 | - Cómo renderizar listas de datos y que es la prop key. 24 | - Cómo manejar formularios y eventos mendiante manipulación del estado. 25 | 26 | 27 | ## 👨🏻‍💻¿Quién soy? 28 | 29 | 👋 Soy [Matías Hernández](https://matiashernandez.dev), padre, desarrollador, podcaster, escritor e instructor. 30 | 31 | Desde hace mucho tiempo (antes de que jQuery existiese) que escribo software y durante todos esos años el desarrollo web ha sido mi pasión. En los últimos 10 años he trabajado oficial y profesionalmente como Ingeniero de Software para diferentes proyectos. Durante esos años he recolectado muchas ideas, conceptos y conocimientos que intento destilar en diferentes formatos para ayudar a otros desarrolladores a mejorar su carrera. 32 | 33 | Me encanta lo que hago y trato de traer la misma pasión a la creación de contenido por medio de cursos en [egghead.io](https://matiasfha.dev/egghead), artículos en [FreeCodeCamp](https://matiasfha.dev/fcces), [mi blog](https://matiashernandez.dev), [Cloudinary](https://mediajams.dev/author/matias-hernandez) y otras publicaciones, en mis podcasts [Café con Tech](https://www.cafecon.tech/) y [Control Remoto](https://www.controlremoto.io/) y en mis [cursos via email](https://microbytes.dev). 34 | 35 | Puedes encontrarme en twitter como [@matiasfha](https://twitter.com/matiasfha) 36 | 37 | ## ⏰ Antes del workshop 38 | 39 | ¿Que necesitas saber para iniciar tu camino con React? 40 | 41 | Primero, y por sobre todo, necesitas conocer conceptos fundamentales sobre desarrollo web y sobre todo tener conocimientos sobre Javascript moderno o avanzado. Durante tu trabajo con React verás mucho ideas y conceptos como: 42 | 43 | - Destructuring. 44 | - Spread. 45 | - Ternaries. 46 | - [Closures.](https://www.freecodecamp.org/espanol/news/que-es-un-closure-en-javascript/) 47 | - Parámetros por defecto. 48 | - [Arrow functions.](https://escuelafrontend.com/articulos/arrow-functions) 49 | - [Métodos de arreglos.](https://escuelafrontend.com/articulos/metodos-de-arreglos) 50 | - Promesas, async/await. 51 | 52 | Te invito a revisar tus conocimientos en esas áreas para que puedas sacar el máximo provecho a este workshop. 53 | 54 | Puedes revisar mi newsletter [Microbytes](https://microbytes.dev) y unirte al curso Javascript para React donde encontrarás más material al respecto. 55 | 56 | ### 🛠 Requerimientos 57 | 58 | Para aprovechar al máximo nuestro tiempo durante el workshop, por favor realiza los siguientes pasos antes de iniciar: 59 | 60 | #### Requerimientos del sistema 61 | - [git](https://git-scm.com/) v2.13 o superior 62 | - [NodeJS](https://nodejs.org/) `12 || 14 || 15 || 16` 63 | - [npm](https://www.npmjs.com/) v6 o superio 64 | 65 | Estas herramientas deben ser parte de tu sistema, para verificar puedes ejecutar en la terminal 66 | 67 | ```shell 68 | git --version 69 | node --version 70 | npm --version 71 | ``` 72 | 73 | #### Configuración 74 | 75 | > Si gustas, puedes hacer un fork de este repositorio para poder ir "guardando" tu progreso. 76 | 77 | - [ ] Clona este repositorio, en la terminal ejecuta: 78 | 79 | ```shell 80 | git clone https://github.com/matiasfha/workshop-react-desde-cero.git 81 | ``` 82 | 83 | - [ ] Instala las dependencias 84 | 85 | ```shell 86 | cd workshop-react-desde-cero 87 | npm install 88 | ``` 89 | > Esto puede tardar unos minutos dependeniendo de tu conexión. 90 | 91 | Si tienes algún error durante este proceso por favor [completa un issue](https://github.com/matiasfha/workshop-react-desde-cero/issues/new) en el reposotiorio. Escribe en el toda la información de los pasos realizados y el resultado del script que ejecutaste 92 | 93 | #### Ejecutando los ejercicios 94 | 95 | Para ejecutar los ejercicios, una vez que tienes los pasos anteriores listos, solo debes abrir la terminal y ejecutar 96 | 97 | ```shell 98 | npm run dev 99 | ``` 100 | 101 | Esto te mostrará una lista de opciones con el nombre de la lección. Selecciona la que corresponda y luego visita `http://localhost:3000` en tu navegador. 102 | 103 | > Para terminar el proceso y cambiar de lección solo presiona CTRL-C, esto detendrá el script y podras ejecutarlo nuevamente 104 | 105 | - [ ] Ten listo tu editor de código favorito para resolver los ejercicios 106 | 107 | 108 | 109 | ### ❓ ¿Cómo ejecutar las lecciones? 110 | 111 | Cada lección "vive" dentro de su propio directorio dentro de este monorepo, para ejecutar el ejercicio de una lección en particular sólo debes, desde la terminal, ejecutar `npm run dev`. Esto te mostrará una lista de las lecciones donde podrás seleccionar utilizando el teclado. 112 | 113 | 114 | 115 | 116 | ## 📝 Sobre el workshop 117 | 118 | ### Estructura de las lecciones 119 | 120 | Cada concepto o contenido esta encapsulado en su propia lección y cada lección tiene su propio directorio con recursos, ejemplos de código y desafíos. 121 | 122 | En cada directorio encontrarás un nuevo archivo Readme.md, en el encontrarás una descripción de lo que encontrarás en la lección e instrucciones para llevar a cabo los ejercicios, desafíos o cuestionarios. 123 | 124 | Además encontrarás la configuración necesaria para ejecutar el proyecto que te permitirá resolver los ejercicios. 125 | 126 | ### Ejemplos de Ejercicios 127 | 128 | Los ejercicios consisten en el desarrollo y solución de una problemática asociada al concepto que estás aprendiendo en la lección. Esto implica, que el código tendrá pistas y guías para que te mantengas enfocado en el tema correspondiente. 129 | 130 | Para esto encontrás comentarios y emojis que te ayudarán en el camino. 131 | 132 | - 💡: Indica el contenido del ejercicio. 133 | - 🏋️‍♂️: Indica el ejercicio en particular. 134 | - 🍬: Desafío o crédito extra. 135 | 136 | ### Listado de lecciones 137 | 138 | - [00 - Introducción](./leccion00/Readme.md) 139 | - [01 - Componentes](./leccion01/Readme.md) 140 | - [02 - Creando una app estática base ](./leccion02/Readme.md) 141 | - [03 - El mundo sin JSX](./leccion03/Readme.md) 142 | - [04 - Conociendo JSX](./leccion04/Readme.md) 143 | - [05 - Props](./leccion05/Readme.md) 144 | - [06 - Renderizado Condicional](./leccion06/Readme.md) 145 | - [07 - Composición](./leccion07/Readme.md) 146 | - [08 - Arrays](./leccion08/Readme.md) 147 | - [09 - Estilos](./leccion09/Readme.md) 148 | - [10 - Eventos](./leccion10/Readme.md) 149 | - [11 - Formularios: Componentes Controlados](./leccion11/Readme.md) 150 | - [12 - Formularios: Componentes No-Controlados](./leccion11/Readme.md) 151 | - [13 - Construyendo una interfaz](./leccion11/Readme.md) 152 | 153 | ## Contributors ✨ 154 | 155 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 |

Horacio Herrera

💻 🚇

Matías Hernández Arellano

📖 🖋 💻 🚇 💡 🖋
166 | 167 | 168 | 169 | 170 | 171 | 172 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 173 | -------------------------------------------------------------------------------- /leccion10/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lesson10", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "lesson10", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "react": "^17.0.0", 12 | "react-dom": "^17.0.0" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-react-refresh": "^1.3.1", 16 | "vite": "^2.1.5" 17 | } 18 | }, 19 | "node_modules/@babel/code-frame": { 20 | "version": "7.12.13", 21 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", 22 | "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", 23 | "dev": true, 24 | "dependencies": { 25 | "@babel/highlight": "^7.12.13" 26 | } 27 | }, 28 | "node_modules/@babel/compat-data": { 29 | "version": "7.14.0", 30 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", 31 | "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", 32 | "dev": true 33 | }, 34 | "node_modules/@babel/core": { 35 | "version": "7.14.3", 36 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz", 37 | "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==", 38 | "dev": true, 39 | "dependencies": { 40 | "@babel/code-frame": "^7.12.13", 41 | "@babel/generator": "^7.14.3", 42 | "@babel/helper-compilation-targets": "^7.13.16", 43 | "@babel/helper-module-transforms": "^7.14.2", 44 | "@babel/helpers": "^7.14.0", 45 | "@babel/parser": "^7.14.3", 46 | "@babel/template": "^7.12.13", 47 | "@babel/traverse": "^7.14.2", 48 | "@babel/types": "^7.14.2", 49 | "convert-source-map": "^1.7.0", 50 | "debug": "^4.1.0", 51 | "gensync": "^1.0.0-beta.2", 52 | "json5": "^2.1.2", 53 | "semver": "^6.3.0", 54 | "source-map": "^0.5.0" 55 | }, 56 | "engines": { 57 | "node": ">=6.9.0" 58 | }, 59 | "funding": { 60 | "type": "opencollective", 61 | "url": "https://opencollective.com/babel" 62 | } 63 | }, 64 | "node_modules/@babel/generator": { 65 | "version": "7.14.3", 66 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", 67 | "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", 68 | "dev": true, 69 | "dependencies": { 70 | "@babel/types": "^7.14.2", 71 | "jsesc": "^2.5.1", 72 | "source-map": "^0.5.0" 73 | } 74 | }, 75 | "node_modules/@babel/helper-compilation-targets": { 76 | "version": "7.13.16", 77 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", 78 | "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", 79 | "dev": true, 80 | "dependencies": { 81 | "@babel/compat-data": "^7.13.15", 82 | "@babel/helper-validator-option": "^7.12.17", 83 | "browserslist": "^4.14.5", 84 | "semver": "^6.3.0" 85 | }, 86 | "peerDependencies": { 87 | "@babel/core": "^7.0.0" 88 | } 89 | }, 90 | "node_modules/@babel/helper-function-name": { 91 | "version": "7.14.2", 92 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", 93 | "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", 94 | "dev": true, 95 | "dependencies": { 96 | "@babel/helper-get-function-arity": "^7.12.13", 97 | "@babel/template": "^7.12.13", 98 | "@babel/types": "^7.14.2" 99 | } 100 | }, 101 | "node_modules/@babel/helper-get-function-arity": { 102 | "version": "7.12.13", 103 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", 104 | "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", 105 | "dev": true, 106 | "dependencies": { 107 | "@babel/types": "^7.12.13" 108 | } 109 | }, 110 | "node_modules/@babel/helper-member-expression-to-functions": { 111 | "version": "7.13.12", 112 | "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", 113 | "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", 114 | "dev": true, 115 | "dependencies": { 116 | "@babel/types": "^7.13.12" 117 | } 118 | }, 119 | "node_modules/@babel/helper-module-imports": { 120 | "version": "7.13.12", 121 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", 122 | "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", 123 | "dev": true, 124 | "dependencies": { 125 | "@babel/types": "^7.13.12" 126 | } 127 | }, 128 | "node_modules/@babel/helper-module-transforms": { 129 | "version": "7.14.2", 130 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz", 131 | "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==", 132 | "dev": true, 133 | "dependencies": { 134 | "@babel/helper-module-imports": "^7.13.12", 135 | "@babel/helper-replace-supers": "^7.13.12", 136 | "@babel/helper-simple-access": "^7.13.12", 137 | "@babel/helper-split-export-declaration": "^7.12.13", 138 | "@babel/helper-validator-identifier": "^7.14.0", 139 | "@babel/template": "^7.12.13", 140 | "@babel/traverse": "^7.14.2", 141 | "@babel/types": "^7.14.2" 142 | } 143 | }, 144 | "node_modules/@babel/helper-optimise-call-expression": { 145 | "version": "7.12.13", 146 | "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", 147 | "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", 148 | "dev": true, 149 | "dependencies": { 150 | "@babel/types": "^7.12.13" 151 | } 152 | }, 153 | "node_modules/@babel/helper-plugin-utils": { 154 | "version": "7.13.0", 155 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", 156 | "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", 157 | "dev": true 158 | }, 159 | "node_modules/@babel/helper-replace-supers": { 160 | "version": "7.14.3", 161 | "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz", 162 | "integrity": "sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==", 163 | "dev": true, 164 | "dependencies": { 165 | "@babel/helper-member-expression-to-functions": "^7.13.12", 166 | "@babel/helper-optimise-call-expression": "^7.12.13", 167 | "@babel/traverse": "^7.14.2", 168 | "@babel/types": "^7.14.2" 169 | } 170 | }, 171 | "node_modules/@babel/helper-simple-access": { 172 | "version": "7.13.12", 173 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", 174 | "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", 175 | "dev": true, 176 | "dependencies": { 177 | "@babel/types": "^7.13.12" 178 | } 179 | }, 180 | "node_modules/@babel/helper-split-export-declaration": { 181 | "version": "7.12.13", 182 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", 183 | "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", 184 | "dev": true, 185 | "dependencies": { 186 | "@babel/types": "^7.12.13" 187 | } 188 | }, 189 | "node_modules/@babel/helper-validator-identifier": { 190 | "version": "7.14.0", 191 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", 192 | "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", 193 | "dev": true 194 | }, 195 | "node_modules/@babel/helper-validator-option": { 196 | "version": "7.12.17", 197 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", 198 | "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", 199 | "dev": true 200 | }, 201 | "node_modules/@babel/helpers": { 202 | "version": "7.14.0", 203 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", 204 | "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", 205 | "dev": true, 206 | "dependencies": { 207 | "@babel/template": "^7.12.13", 208 | "@babel/traverse": "^7.14.0", 209 | "@babel/types": "^7.14.0" 210 | } 211 | }, 212 | "node_modules/@babel/highlight": { 213 | "version": "7.14.0", 214 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", 215 | "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", 216 | "dev": true, 217 | "dependencies": { 218 | "@babel/helper-validator-identifier": "^7.14.0", 219 | "chalk": "^2.0.0", 220 | "js-tokens": "^4.0.0" 221 | } 222 | }, 223 | "node_modules/@babel/parser": { 224 | "version": "7.14.3", 225 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", 226 | "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", 227 | "dev": true, 228 | "bin": { 229 | "parser": "bin/babel-parser.js" 230 | }, 231 | "engines": { 232 | "node": ">=6.0.0" 233 | } 234 | }, 235 | "node_modules/@babel/plugin-transform-react-jsx-self": { 236 | "version": "7.12.13", 237 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz", 238 | "integrity": "sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ==", 239 | "dev": true, 240 | "dependencies": { 241 | "@babel/helper-plugin-utils": "^7.12.13" 242 | }, 243 | "peerDependencies": { 244 | "@babel/core": "^7.0.0-0" 245 | } 246 | }, 247 | "node_modules/@babel/plugin-transform-react-jsx-source": { 248 | "version": "7.14.2", 249 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.2.tgz", 250 | "integrity": "sha512-OMorspVyjxghAjzgeAWc6O7W7vHbJhV69NeTGdl9Mxgz6PaweAuo7ffB9T5A1OQ9dGcw0As4SYMUhyNC4u7mVg==", 251 | "dev": true, 252 | "dependencies": { 253 | "@babel/helper-plugin-utils": "^7.13.0" 254 | }, 255 | "peerDependencies": { 256 | "@babel/core": "^7.0.0-0" 257 | } 258 | }, 259 | "node_modules/@babel/template": { 260 | "version": "7.12.13", 261 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", 262 | "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", 263 | "dev": true, 264 | "dependencies": { 265 | "@babel/code-frame": "^7.12.13", 266 | "@babel/parser": "^7.12.13", 267 | "@babel/types": "^7.12.13" 268 | } 269 | }, 270 | "node_modules/@babel/traverse": { 271 | "version": "7.14.2", 272 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", 273 | "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", 274 | "dev": true, 275 | "dependencies": { 276 | "@babel/code-frame": "^7.12.13", 277 | "@babel/generator": "^7.14.2", 278 | "@babel/helper-function-name": "^7.14.2", 279 | "@babel/helper-split-export-declaration": "^7.12.13", 280 | "@babel/parser": "^7.14.2", 281 | "@babel/types": "^7.14.2", 282 | "debug": "^4.1.0", 283 | "globals": "^11.1.0" 284 | } 285 | }, 286 | "node_modules/@babel/types": { 287 | "version": "7.14.2", 288 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", 289 | "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", 290 | "dev": true, 291 | "dependencies": { 292 | "@babel/helper-validator-identifier": "^7.14.0", 293 | "to-fast-properties": "^2.0.0" 294 | } 295 | }, 296 | "node_modules/@vitejs/plugin-react-refresh": { 297 | "version": "1.3.3", 298 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-refresh/-/plugin-react-refresh-1.3.3.tgz", 299 | "integrity": "sha512-J3KFwSQKrEK7fgOwTx0PMTlsolZORUch6BswjsM50q+Y7zSvX1ROIRn+tK2VE8SCvbYRHtzEKFlYW3vsWyTosQ==", 300 | "dev": true, 301 | "dependencies": { 302 | "@babel/core": "^7.12.13", 303 | "@babel/plugin-transform-react-jsx-self": "^7.12.13", 304 | "@babel/plugin-transform-react-jsx-source": "^7.12.13", 305 | "react-refresh": "^0.9.0" 306 | }, 307 | "engines": { 308 | "node": ">=12.0.0" 309 | } 310 | }, 311 | "node_modules/ansi-styles": { 312 | "version": "3.2.1", 313 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 314 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 315 | "dev": true, 316 | "dependencies": { 317 | "color-convert": "^1.9.0" 318 | }, 319 | "engines": { 320 | "node": ">=4" 321 | } 322 | }, 323 | "node_modules/browserslist": { 324 | "version": "4.16.6", 325 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", 326 | "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", 327 | "dev": true, 328 | "dependencies": { 329 | "caniuse-lite": "^1.0.30001219", 330 | "colorette": "^1.2.2", 331 | "electron-to-chromium": "^1.3.723", 332 | "escalade": "^3.1.1", 333 | "node-releases": "^1.1.71" 334 | }, 335 | "bin": { 336 | "browserslist": "cli.js" 337 | }, 338 | "engines": { 339 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 340 | }, 341 | "funding": { 342 | "type": "opencollective", 343 | "url": "https://opencollective.com/browserslist" 344 | } 345 | }, 346 | "node_modules/caniuse-lite": { 347 | "version": "1.0.30001228", 348 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", 349 | "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", 350 | "dev": true, 351 | "funding": { 352 | "type": "opencollective", 353 | "url": "https://opencollective.com/browserslist" 354 | } 355 | }, 356 | "node_modules/chalk": { 357 | "version": "2.4.2", 358 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 359 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 360 | "dev": true, 361 | "dependencies": { 362 | "ansi-styles": "^3.2.1", 363 | "escape-string-regexp": "^1.0.5", 364 | "supports-color": "^5.3.0" 365 | }, 366 | "engines": { 367 | "node": ">=4" 368 | } 369 | }, 370 | "node_modules/color-convert": { 371 | "version": "1.9.3", 372 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 373 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 374 | "dev": true, 375 | "dependencies": { 376 | "color-name": "1.1.3" 377 | } 378 | }, 379 | "node_modules/color-name": { 380 | "version": "1.1.3", 381 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 382 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 383 | "dev": true 384 | }, 385 | "node_modules/colorette": { 386 | "version": "1.2.2", 387 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", 388 | "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", 389 | "dev": true 390 | }, 391 | "node_modules/convert-source-map": { 392 | "version": "1.7.0", 393 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", 394 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", 395 | "dev": true, 396 | "dependencies": { 397 | "safe-buffer": "~5.1.1" 398 | } 399 | }, 400 | "node_modules/debug": { 401 | "version": "4.3.1", 402 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 403 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 404 | "dev": true, 405 | "dependencies": { 406 | "ms": "2.1.2" 407 | }, 408 | "engines": { 409 | "node": ">=6.0" 410 | }, 411 | "peerDependenciesMeta": { 412 | "supports-color": { 413 | "optional": true 414 | } 415 | } 416 | }, 417 | "node_modules/electron-to-chromium": { 418 | "version": "1.3.735", 419 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.735.tgz", 420 | "integrity": "sha512-cp7MWzC3NseUJV2FJFgaiesdrS+A8ZUjX5fLAxdRlcaPDkaPGFplX930S5vf84yqDp4LjuLdKouWuVOTwUfqHQ==", 421 | "dev": true 422 | }, 423 | "node_modules/esbuild": { 424 | "version": "0.11.23", 425 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz", 426 | "integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==", 427 | "dev": true, 428 | "hasInstallScript": true, 429 | "bin": { 430 | "esbuild": "bin/esbuild" 431 | } 432 | }, 433 | "node_modules/escalade": { 434 | "version": "3.1.1", 435 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 436 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 437 | "dev": true, 438 | "engines": { 439 | "node": ">=6" 440 | } 441 | }, 442 | "node_modules/escape-string-regexp": { 443 | "version": "1.0.5", 444 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 445 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 446 | "dev": true, 447 | "engines": { 448 | "node": ">=0.8.0" 449 | } 450 | }, 451 | "node_modules/fsevents": { 452 | "version": "2.3.2", 453 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 454 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 455 | "dev": true, 456 | "hasInstallScript": true, 457 | "optional": true, 458 | "os": [ 459 | "darwin" 460 | ], 461 | "engines": { 462 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 463 | } 464 | }, 465 | "node_modules/function-bind": { 466 | "version": "1.1.1", 467 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 468 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 469 | "dev": true 470 | }, 471 | "node_modules/gensync": { 472 | "version": "1.0.0-beta.2", 473 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 474 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 475 | "dev": true, 476 | "engines": { 477 | "node": ">=6.9.0" 478 | } 479 | }, 480 | "node_modules/globals": { 481 | "version": "11.12.0", 482 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 483 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 484 | "dev": true, 485 | "engines": { 486 | "node": ">=4" 487 | } 488 | }, 489 | "node_modules/has": { 490 | "version": "1.0.3", 491 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 492 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 493 | "dev": true, 494 | "dependencies": { 495 | "function-bind": "^1.1.1" 496 | }, 497 | "engines": { 498 | "node": ">= 0.4.0" 499 | } 500 | }, 501 | "node_modules/has-flag": { 502 | "version": "3.0.0", 503 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 504 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 505 | "dev": true, 506 | "engines": { 507 | "node": ">=4" 508 | } 509 | }, 510 | "node_modules/is-core-module": { 511 | "version": "2.4.0", 512 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", 513 | "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", 514 | "dev": true, 515 | "dependencies": { 516 | "has": "^1.0.3" 517 | }, 518 | "funding": { 519 | "url": "https://github.com/sponsors/ljharb" 520 | } 521 | }, 522 | "node_modules/js-tokens": { 523 | "version": "4.0.0", 524 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 525 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 526 | }, 527 | "node_modules/jsesc": { 528 | "version": "2.5.2", 529 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 530 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 531 | "dev": true, 532 | "bin": { 533 | "jsesc": "bin/jsesc" 534 | }, 535 | "engines": { 536 | "node": ">=4" 537 | } 538 | }, 539 | "node_modules/json5": { 540 | "version": "2.2.0", 541 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 542 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 543 | "dev": true, 544 | "dependencies": { 545 | "minimist": "^1.2.5" 546 | }, 547 | "bin": { 548 | "json5": "lib/cli.js" 549 | }, 550 | "engines": { 551 | "node": ">=6" 552 | } 553 | }, 554 | "node_modules/loose-envify": { 555 | "version": "1.4.0", 556 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 557 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 558 | "dependencies": { 559 | "js-tokens": "^3.0.0 || ^4.0.0" 560 | }, 561 | "bin": { 562 | "loose-envify": "cli.js" 563 | } 564 | }, 565 | "node_modules/minimist": { 566 | "version": "1.2.5", 567 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 568 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 569 | "dev": true 570 | }, 571 | "node_modules/ms": { 572 | "version": "2.1.2", 573 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 574 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 575 | "dev": true 576 | }, 577 | "node_modules/nanoid": { 578 | "version": "3.1.23", 579 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", 580 | "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", 581 | "dev": true, 582 | "bin": { 583 | "nanoid": "bin/nanoid.cjs" 584 | }, 585 | "engines": { 586 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 587 | } 588 | }, 589 | "node_modules/node-releases": { 590 | "version": "1.1.72", 591 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", 592 | "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", 593 | "dev": true 594 | }, 595 | "node_modules/object-assign": { 596 | "version": "4.1.1", 597 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 598 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 599 | "engines": { 600 | "node": ">=0.10.0" 601 | } 602 | }, 603 | "node_modules/path-parse": { 604 | "version": "1.0.6", 605 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 606 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 607 | "dev": true 608 | }, 609 | "node_modules/postcss": { 610 | "version": "8.3.0", 611 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", 612 | "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", 613 | "dev": true, 614 | "dependencies": { 615 | "colorette": "^1.2.2", 616 | "nanoid": "^3.1.23", 617 | "source-map-js": "^0.6.2" 618 | }, 619 | "engines": { 620 | "node": "^10 || ^12 || >=14" 621 | }, 622 | "funding": { 623 | "type": "opencollective", 624 | "url": "https://opencollective.com/postcss/" 625 | } 626 | }, 627 | "node_modules/react": { 628 | "version": "17.0.2", 629 | "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", 630 | "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", 631 | "dependencies": { 632 | "loose-envify": "^1.1.0", 633 | "object-assign": "^4.1.1" 634 | }, 635 | "engines": { 636 | "node": ">=0.10.0" 637 | } 638 | }, 639 | "node_modules/react-dom": { 640 | "version": "17.0.2", 641 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", 642 | "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", 643 | "dependencies": { 644 | "loose-envify": "^1.1.0", 645 | "object-assign": "^4.1.1", 646 | "scheduler": "^0.20.2" 647 | }, 648 | "peerDependencies": { 649 | "react": "17.0.2" 650 | } 651 | }, 652 | "node_modules/react-refresh": { 653 | "version": "0.9.0", 654 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz", 655 | "integrity": "sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==", 656 | "dev": true, 657 | "engines": { 658 | "node": ">=0.10.0" 659 | } 660 | }, 661 | "node_modules/resolve": { 662 | "version": "1.20.0", 663 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", 664 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", 665 | "dev": true, 666 | "dependencies": { 667 | "is-core-module": "^2.2.0", 668 | "path-parse": "^1.0.6" 669 | }, 670 | "funding": { 671 | "url": "https://github.com/sponsors/ljharb" 672 | } 673 | }, 674 | "node_modules/rollup": { 675 | "version": "2.48.0", 676 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.48.0.tgz", 677 | "integrity": "sha512-wl9ZSSSsi5579oscSDYSzGn092tCS076YB+TQrzsGuSfYyJeep8eEWj0eaRjuC5McuMNmcnR8icBqiE/FWNB1A==", 678 | "dev": true, 679 | "bin": { 680 | "rollup": "dist/bin/rollup" 681 | }, 682 | "engines": { 683 | "node": ">=10.0.0" 684 | }, 685 | "optionalDependencies": { 686 | "fsevents": "~2.3.1" 687 | } 688 | }, 689 | "node_modules/safe-buffer": { 690 | "version": "5.1.2", 691 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 692 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 693 | "dev": true 694 | }, 695 | "node_modules/scheduler": { 696 | "version": "0.20.2", 697 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", 698 | "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", 699 | "dependencies": { 700 | "loose-envify": "^1.1.0", 701 | "object-assign": "^4.1.1" 702 | } 703 | }, 704 | "node_modules/semver": { 705 | "version": "6.3.0", 706 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 707 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 708 | "dev": true, 709 | "bin": { 710 | "semver": "bin/semver.js" 711 | } 712 | }, 713 | "node_modules/source-map": { 714 | "version": "0.5.7", 715 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 716 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 717 | "dev": true, 718 | "engines": { 719 | "node": ">=0.10.0" 720 | } 721 | }, 722 | "node_modules/source-map-js": { 723 | "version": "0.6.2", 724 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", 725 | "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", 726 | "dev": true, 727 | "engines": { 728 | "node": ">=0.10.0" 729 | } 730 | }, 731 | "node_modules/supports-color": { 732 | "version": "5.5.0", 733 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 734 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 735 | "dev": true, 736 | "dependencies": { 737 | "has-flag": "^3.0.0" 738 | }, 739 | "engines": { 740 | "node": ">=4" 741 | } 742 | }, 743 | "node_modules/to-fast-properties": { 744 | "version": "2.0.0", 745 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 746 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 747 | "dev": true, 748 | "engines": { 749 | "node": ">=4" 750 | } 751 | }, 752 | "node_modules/vite": { 753 | "version": "2.3.3", 754 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.3.3.tgz", 755 | "integrity": "sha512-eO1iwRbn3/BfkNVMNJDeANAFCZ5NobYOFPu7IqfY7DcI7I9nFGjJIZid0EViTmLDGwwSUPmRAq3cRBbO3+DsMA==", 756 | "dev": true, 757 | "dependencies": { 758 | "esbuild": "^0.11.23", 759 | "postcss": "^8.2.10", 760 | "resolve": "^1.19.0", 761 | "rollup": "^2.38.5" 762 | }, 763 | "bin": { 764 | "vite": "bin/vite.js" 765 | }, 766 | "engines": { 767 | "node": ">=12.0.0" 768 | }, 769 | "optionalDependencies": { 770 | "fsevents": "~2.3.1" 771 | } 772 | } 773 | }, 774 | "dependencies": { 775 | "@babel/code-frame": { 776 | "version": "7.12.13", 777 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", 778 | "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", 779 | "dev": true, 780 | "requires": { 781 | "@babel/highlight": "^7.12.13" 782 | } 783 | }, 784 | "@babel/compat-data": { 785 | "version": "7.14.0", 786 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", 787 | "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", 788 | "dev": true 789 | }, 790 | "@babel/core": { 791 | "version": "7.14.3", 792 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz", 793 | "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==", 794 | "dev": true, 795 | "requires": { 796 | "@babel/code-frame": "^7.12.13", 797 | "@babel/generator": "^7.14.3", 798 | "@babel/helper-compilation-targets": "^7.13.16", 799 | "@babel/helper-module-transforms": "^7.14.2", 800 | "@babel/helpers": "^7.14.0", 801 | "@babel/parser": "^7.14.3", 802 | "@babel/template": "^7.12.13", 803 | "@babel/traverse": "^7.14.2", 804 | "@babel/types": "^7.14.2", 805 | "convert-source-map": "^1.7.0", 806 | "debug": "^4.1.0", 807 | "gensync": "^1.0.0-beta.2", 808 | "json5": "^2.1.2", 809 | "semver": "^6.3.0", 810 | "source-map": "^0.5.0" 811 | } 812 | }, 813 | "@babel/generator": { 814 | "version": "7.14.3", 815 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", 816 | "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", 817 | "dev": true, 818 | "requires": { 819 | "@babel/types": "^7.14.2", 820 | "jsesc": "^2.5.1", 821 | "source-map": "^0.5.0" 822 | } 823 | }, 824 | "@babel/helper-compilation-targets": { 825 | "version": "7.13.16", 826 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", 827 | "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", 828 | "dev": true, 829 | "requires": { 830 | "@babel/compat-data": "^7.13.15", 831 | "@babel/helper-validator-option": "^7.12.17", 832 | "browserslist": "^4.14.5", 833 | "semver": "^6.3.0" 834 | } 835 | }, 836 | "@babel/helper-function-name": { 837 | "version": "7.14.2", 838 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", 839 | "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", 840 | "dev": true, 841 | "requires": { 842 | "@babel/helper-get-function-arity": "^7.12.13", 843 | "@babel/template": "^7.12.13", 844 | "@babel/types": "^7.14.2" 845 | } 846 | }, 847 | "@babel/helper-get-function-arity": { 848 | "version": "7.12.13", 849 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", 850 | "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", 851 | "dev": true, 852 | "requires": { 853 | "@babel/types": "^7.12.13" 854 | } 855 | }, 856 | "@babel/helper-member-expression-to-functions": { 857 | "version": "7.13.12", 858 | "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", 859 | "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", 860 | "dev": true, 861 | "requires": { 862 | "@babel/types": "^7.13.12" 863 | } 864 | }, 865 | "@babel/helper-module-imports": { 866 | "version": "7.13.12", 867 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", 868 | "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", 869 | "dev": true, 870 | "requires": { 871 | "@babel/types": "^7.13.12" 872 | } 873 | }, 874 | "@babel/helper-module-transforms": { 875 | "version": "7.14.2", 876 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz", 877 | "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==", 878 | "dev": true, 879 | "requires": { 880 | "@babel/helper-module-imports": "^7.13.12", 881 | "@babel/helper-replace-supers": "^7.13.12", 882 | "@babel/helper-simple-access": "^7.13.12", 883 | "@babel/helper-split-export-declaration": "^7.12.13", 884 | "@babel/helper-validator-identifier": "^7.14.0", 885 | "@babel/template": "^7.12.13", 886 | "@babel/traverse": "^7.14.2", 887 | "@babel/types": "^7.14.2" 888 | } 889 | }, 890 | "@babel/helper-optimise-call-expression": { 891 | "version": "7.12.13", 892 | "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", 893 | "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", 894 | "dev": true, 895 | "requires": { 896 | "@babel/types": "^7.12.13" 897 | } 898 | }, 899 | "@babel/helper-plugin-utils": { 900 | "version": "7.13.0", 901 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", 902 | "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", 903 | "dev": true 904 | }, 905 | "@babel/helper-replace-supers": { 906 | "version": "7.14.3", 907 | "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz", 908 | "integrity": "sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==", 909 | "dev": true, 910 | "requires": { 911 | "@babel/helper-member-expression-to-functions": "^7.13.12", 912 | "@babel/helper-optimise-call-expression": "^7.12.13", 913 | "@babel/traverse": "^7.14.2", 914 | "@babel/types": "^7.14.2" 915 | } 916 | }, 917 | "@babel/helper-simple-access": { 918 | "version": "7.13.12", 919 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", 920 | "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", 921 | "dev": true, 922 | "requires": { 923 | "@babel/types": "^7.13.12" 924 | } 925 | }, 926 | "@babel/helper-split-export-declaration": { 927 | "version": "7.12.13", 928 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", 929 | "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", 930 | "dev": true, 931 | "requires": { 932 | "@babel/types": "^7.12.13" 933 | } 934 | }, 935 | "@babel/helper-validator-identifier": { 936 | "version": "7.14.0", 937 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", 938 | "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", 939 | "dev": true 940 | }, 941 | "@babel/helper-validator-option": { 942 | "version": "7.12.17", 943 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", 944 | "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", 945 | "dev": true 946 | }, 947 | "@babel/helpers": { 948 | "version": "7.14.0", 949 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", 950 | "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", 951 | "dev": true, 952 | "requires": { 953 | "@babel/template": "^7.12.13", 954 | "@babel/traverse": "^7.14.0", 955 | "@babel/types": "^7.14.0" 956 | } 957 | }, 958 | "@babel/highlight": { 959 | "version": "7.14.0", 960 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", 961 | "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", 962 | "dev": true, 963 | "requires": { 964 | "@babel/helper-validator-identifier": "^7.14.0", 965 | "chalk": "^2.0.0", 966 | "js-tokens": "^4.0.0" 967 | } 968 | }, 969 | "@babel/parser": { 970 | "version": "7.14.3", 971 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", 972 | "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", 973 | "dev": true 974 | }, 975 | "@babel/plugin-transform-react-jsx-self": { 976 | "version": "7.12.13", 977 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz", 978 | "integrity": "sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ==", 979 | "dev": true, 980 | "requires": { 981 | "@babel/helper-plugin-utils": "^7.12.13" 982 | } 983 | }, 984 | "@babel/plugin-transform-react-jsx-source": { 985 | "version": "7.14.2", 986 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.2.tgz", 987 | "integrity": "sha512-OMorspVyjxghAjzgeAWc6O7W7vHbJhV69NeTGdl9Mxgz6PaweAuo7ffB9T5A1OQ9dGcw0As4SYMUhyNC4u7mVg==", 988 | "dev": true, 989 | "requires": { 990 | "@babel/helper-plugin-utils": "^7.13.0" 991 | } 992 | }, 993 | "@babel/template": { 994 | "version": "7.12.13", 995 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", 996 | "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", 997 | "dev": true, 998 | "requires": { 999 | "@babel/code-frame": "^7.12.13", 1000 | "@babel/parser": "^7.12.13", 1001 | "@babel/types": "^7.12.13" 1002 | } 1003 | }, 1004 | "@babel/traverse": { 1005 | "version": "7.14.2", 1006 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", 1007 | "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", 1008 | "dev": true, 1009 | "requires": { 1010 | "@babel/code-frame": "^7.12.13", 1011 | "@babel/generator": "^7.14.2", 1012 | "@babel/helper-function-name": "^7.14.2", 1013 | "@babel/helper-split-export-declaration": "^7.12.13", 1014 | "@babel/parser": "^7.14.2", 1015 | "@babel/types": "^7.14.2", 1016 | "debug": "^4.1.0", 1017 | "globals": "^11.1.0" 1018 | } 1019 | }, 1020 | "@babel/types": { 1021 | "version": "7.14.2", 1022 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", 1023 | "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", 1024 | "dev": true, 1025 | "requires": { 1026 | "@babel/helper-validator-identifier": "^7.14.0", 1027 | "to-fast-properties": "^2.0.0" 1028 | } 1029 | }, 1030 | "@vitejs/plugin-react-refresh": { 1031 | "version": "1.3.3", 1032 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-refresh/-/plugin-react-refresh-1.3.3.tgz", 1033 | "integrity": "sha512-J3KFwSQKrEK7fgOwTx0PMTlsolZORUch6BswjsM50q+Y7zSvX1ROIRn+tK2VE8SCvbYRHtzEKFlYW3vsWyTosQ==", 1034 | "dev": true, 1035 | "requires": { 1036 | "@babel/core": "^7.12.13", 1037 | "@babel/plugin-transform-react-jsx-self": "^7.12.13", 1038 | "@babel/plugin-transform-react-jsx-source": "^7.12.13", 1039 | "react-refresh": "^0.9.0" 1040 | } 1041 | }, 1042 | "ansi-styles": { 1043 | "version": "3.2.1", 1044 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1045 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1046 | "dev": true, 1047 | "requires": { 1048 | "color-convert": "^1.9.0" 1049 | } 1050 | }, 1051 | "browserslist": { 1052 | "version": "4.16.6", 1053 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", 1054 | "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", 1055 | "dev": true, 1056 | "requires": { 1057 | "caniuse-lite": "^1.0.30001219", 1058 | "colorette": "^1.2.2", 1059 | "electron-to-chromium": "^1.3.723", 1060 | "escalade": "^3.1.1", 1061 | "node-releases": "^1.1.71" 1062 | } 1063 | }, 1064 | "caniuse-lite": { 1065 | "version": "1.0.30001228", 1066 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", 1067 | "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", 1068 | "dev": true 1069 | }, 1070 | "chalk": { 1071 | "version": "2.4.2", 1072 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1073 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1074 | "dev": true, 1075 | "requires": { 1076 | "ansi-styles": "^3.2.1", 1077 | "escape-string-regexp": "^1.0.5", 1078 | "supports-color": "^5.3.0" 1079 | } 1080 | }, 1081 | "color-convert": { 1082 | "version": "1.9.3", 1083 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 1084 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 1085 | "dev": true, 1086 | "requires": { 1087 | "color-name": "1.1.3" 1088 | } 1089 | }, 1090 | "color-name": { 1091 | "version": "1.1.3", 1092 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 1093 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 1094 | "dev": true 1095 | }, 1096 | "colorette": { 1097 | "version": "1.2.2", 1098 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", 1099 | "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", 1100 | "dev": true 1101 | }, 1102 | "convert-source-map": { 1103 | "version": "1.7.0", 1104 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", 1105 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", 1106 | "dev": true, 1107 | "requires": { 1108 | "safe-buffer": "~5.1.1" 1109 | } 1110 | }, 1111 | "debug": { 1112 | "version": "4.3.1", 1113 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 1114 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 1115 | "dev": true, 1116 | "requires": { 1117 | "ms": "2.1.2" 1118 | } 1119 | }, 1120 | "electron-to-chromium": { 1121 | "version": "1.3.735", 1122 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.735.tgz", 1123 | "integrity": "sha512-cp7MWzC3NseUJV2FJFgaiesdrS+A8ZUjX5fLAxdRlcaPDkaPGFplX930S5vf84yqDp4LjuLdKouWuVOTwUfqHQ==", 1124 | "dev": true 1125 | }, 1126 | "esbuild": { 1127 | "version": "0.11.23", 1128 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz", 1129 | "integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==", 1130 | "dev": true 1131 | }, 1132 | "escalade": { 1133 | "version": "3.1.1", 1134 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1135 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1136 | "dev": true 1137 | }, 1138 | "escape-string-regexp": { 1139 | "version": "1.0.5", 1140 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1141 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 1142 | "dev": true 1143 | }, 1144 | "fsevents": { 1145 | "version": "2.3.2", 1146 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1147 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1148 | "dev": true, 1149 | "optional": true 1150 | }, 1151 | "function-bind": { 1152 | "version": "1.1.1", 1153 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1154 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1155 | "dev": true 1156 | }, 1157 | "gensync": { 1158 | "version": "1.0.0-beta.2", 1159 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 1160 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 1161 | "dev": true 1162 | }, 1163 | "globals": { 1164 | "version": "11.12.0", 1165 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1166 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1167 | "dev": true 1168 | }, 1169 | "has": { 1170 | "version": "1.0.3", 1171 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1172 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1173 | "dev": true, 1174 | "requires": { 1175 | "function-bind": "^1.1.1" 1176 | } 1177 | }, 1178 | "has-flag": { 1179 | "version": "3.0.0", 1180 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1181 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1182 | "dev": true 1183 | }, 1184 | "is-core-module": { 1185 | "version": "2.4.0", 1186 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", 1187 | "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", 1188 | "dev": true, 1189 | "requires": { 1190 | "has": "^1.0.3" 1191 | } 1192 | }, 1193 | "js-tokens": { 1194 | "version": "4.0.0", 1195 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1196 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 1197 | }, 1198 | "jsesc": { 1199 | "version": "2.5.2", 1200 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1201 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1202 | "dev": true 1203 | }, 1204 | "json5": { 1205 | "version": "2.2.0", 1206 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 1207 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 1208 | "dev": true, 1209 | "requires": { 1210 | "minimist": "^1.2.5" 1211 | } 1212 | }, 1213 | "loose-envify": { 1214 | "version": "1.4.0", 1215 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 1216 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 1217 | "requires": { 1218 | "js-tokens": "^3.0.0 || ^4.0.0" 1219 | } 1220 | }, 1221 | "minimist": { 1222 | "version": "1.2.5", 1223 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 1224 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 1225 | "dev": true 1226 | }, 1227 | "ms": { 1228 | "version": "2.1.2", 1229 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1230 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1231 | "dev": true 1232 | }, 1233 | "nanoid": { 1234 | "version": "3.1.23", 1235 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", 1236 | "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", 1237 | "dev": true 1238 | }, 1239 | "node-releases": { 1240 | "version": "1.1.72", 1241 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", 1242 | "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", 1243 | "dev": true 1244 | }, 1245 | "object-assign": { 1246 | "version": "4.1.1", 1247 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1248 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1249 | }, 1250 | "path-parse": { 1251 | "version": "1.0.6", 1252 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1253 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1254 | "dev": true 1255 | }, 1256 | "postcss": { 1257 | "version": "8.3.0", 1258 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", 1259 | "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", 1260 | "dev": true, 1261 | "requires": { 1262 | "colorette": "^1.2.2", 1263 | "nanoid": "^3.1.23", 1264 | "source-map-js": "^0.6.2" 1265 | } 1266 | }, 1267 | "react": { 1268 | "version": "17.0.2", 1269 | "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", 1270 | "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", 1271 | "requires": { 1272 | "loose-envify": "^1.1.0", 1273 | "object-assign": "^4.1.1" 1274 | } 1275 | }, 1276 | "react-dom": { 1277 | "version": "17.0.2", 1278 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", 1279 | "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", 1280 | "requires": { 1281 | "loose-envify": "^1.1.0", 1282 | "object-assign": "^4.1.1", 1283 | "scheduler": "^0.20.2" 1284 | } 1285 | }, 1286 | "react-refresh": { 1287 | "version": "0.9.0", 1288 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz", 1289 | "integrity": "sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==", 1290 | "dev": true 1291 | }, 1292 | "resolve": { 1293 | "version": "1.20.0", 1294 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", 1295 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", 1296 | "dev": true, 1297 | "requires": { 1298 | "is-core-module": "^2.2.0", 1299 | "path-parse": "^1.0.6" 1300 | } 1301 | }, 1302 | "rollup": { 1303 | "version": "2.48.0", 1304 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.48.0.tgz", 1305 | "integrity": "sha512-wl9ZSSSsi5579oscSDYSzGn092tCS076YB+TQrzsGuSfYyJeep8eEWj0eaRjuC5McuMNmcnR8icBqiE/FWNB1A==", 1306 | "dev": true, 1307 | "requires": { 1308 | "fsevents": "~2.3.1" 1309 | } 1310 | }, 1311 | "safe-buffer": { 1312 | "version": "5.1.2", 1313 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1314 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1315 | "dev": true 1316 | }, 1317 | "scheduler": { 1318 | "version": "0.20.2", 1319 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", 1320 | "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", 1321 | "requires": { 1322 | "loose-envify": "^1.1.0", 1323 | "object-assign": "^4.1.1" 1324 | } 1325 | }, 1326 | "semver": { 1327 | "version": "6.3.0", 1328 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1329 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1330 | "dev": true 1331 | }, 1332 | "source-map": { 1333 | "version": "0.5.7", 1334 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1335 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 1336 | "dev": true 1337 | }, 1338 | "source-map-js": { 1339 | "version": "0.6.2", 1340 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", 1341 | "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", 1342 | "dev": true 1343 | }, 1344 | "supports-color": { 1345 | "version": "5.5.0", 1346 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1347 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1348 | "dev": true, 1349 | "requires": { 1350 | "has-flag": "^3.0.0" 1351 | } 1352 | }, 1353 | "to-fast-properties": { 1354 | "version": "2.0.0", 1355 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1356 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 1357 | "dev": true 1358 | }, 1359 | "vite": { 1360 | "version": "2.3.3", 1361 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.3.3.tgz", 1362 | "integrity": "sha512-eO1iwRbn3/BfkNVMNJDeANAFCZ5NobYOFPu7IqfY7DcI7I9nFGjJIZid0EViTmLDGwwSUPmRAq3cRBbO3+DsMA==", 1363 | "dev": true, 1364 | "requires": { 1365 | "esbuild": "^0.11.23", 1366 | "fsevents": "~2.3.1", 1367 | "postcss": "^8.2.10", 1368 | "resolve": "^1.19.0", 1369 | "rollup": "^2.38.5" 1370 | } 1371 | } 1372 | } 1373 | } 1374 | --------------------------------------------------------------------------------