├── vite.config.js ├── src ├── main.jsx ├── connecters │ ├── connectToUser.js │ └── connectToEducational.js ├── index.css ├── redux.jsx └── App.jsx ├── .gitignore ├── index.html ├── package.json ├── README.md ├── public └── redux.svg └── pnpm-lock.yaml /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import { App } from './App' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render() 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/connecters/connectToUser.js: -------------------------------------------------------------------------------- 1 | import { connect } from '../redux' 2 | 3 | const userSelector = state => { 4 | return { user: state.user } 5 | } 6 | 7 | const userDispatches = dispatch => { 8 | return { 9 | updateUser: attrs => dispatch({ type: 'updateUser', payload: attrs }) 10 | } 11 | } 12 | 13 | export const connectToUser = connect(userSelector, userDispatches) 14 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Mini Redux 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/connecters/connectToEducational.js: -------------------------------------------------------------------------------- 1 | import { connect } from '../redux' 2 | 3 | const educationalSelector = state => { 4 | return { educational: state.educational } 5 | } 6 | 7 | const educationalDispatches = dispatch => { 8 | return { 9 | updateEducational: attrs => dispatch({ type: 'updateEducational', payload: attrs }) 10 | } 11 | } 12 | 13 | export const connectToEducational = connect(educationalSelector, educationalDispatches) 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mini-redux", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "react": "18.2.0", 13 | "react-dom": "18.2.0" 14 | }, 15 | "devDependencies": { 16 | "@types/react": "18.0.26", 17 | "@types/react-dom": "18.0.9", 18 | "@vitejs/plugin-react": "3.0.0", 19 | "vite": "4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## mini-redux 2 | 3 | 从零到实现 redux 的过程,更好的学习 redux,更轻松的理解 redux 原理。 4 | 5 | 我把实现过程中结成了一篇博客 —— [手写 Redux,核心原理逐层击破!](https://juejin.cn/post/7177213738028630073) 6 | 7 | ## 为什么要实现 mini-redux 8 | 9 | 个人愚见:Redux 的源码特别难看懂,也可能是 Redux 的源码是以实用为目的,看起来没什么头绪; 10 | 11 | 所以我一步一步实现一个 Redux,其中也有一些坑,通过手写 redux,我们基本可以理解 redux 的实现 12 | 13 | ## 亮点 14 | 15 | - commit 信息详细,每个 commit 都是一个小的功能点,可以很方便的查看每个 commit 的变化 16 | - 接口和官方几乎一致 17 | - 实现过程清晰详细,概览 redux 核心概念 18 | - 使用 `context` 来读写数据 19 | - 数据从哪里来 20 | - 如何获取数据 21 | - 如何修改数据 22 | - 理解 `reducer` 的由来 23 | - `reducer` 雏形 —— `createNewState` 24 | - `reducer` 的两个参数 25 | - `dispatch` 规范 `setState` 的流程 26 | - 高阶组件 `connect` 的实现 27 | - 避免多余的 `render` 28 | - `redux` 雏形 29 | - 让 `connect` 支持 `selector` 30 | - 使用 `selector` 来实现精准渲染 31 | - `connect` 的第二个参数:`mapDispatchToProps` 32 | - api 的完善 33 | - `connect` 的意义 34 | - 封装 `Provider` 和 `createStore` 35 | 36 | ## 如何预览 37 | 38 | ```bash 39 | pnpm i 40 | pnpm dev 41 | ``` 42 | -------------------------------------------------------------------------------- /public/redux.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | min-height: 100vh; 12 | background-color: #f4f4f4; 13 | color: #666; 14 | } 15 | 16 | #root { 17 | display: flex; 18 | flex-direction: column; 19 | justify-content: center; 20 | align-items: center; 21 | } 22 | 23 | section { 24 | border: 1px solid #e1e4e8; 25 | background-color: #f6f8fa; 26 | border-radius: 6px; 27 | padding: 16px; 28 | margin: 16px 0; 29 | display: flex; 30 | flex-direction: column; 31 | align-items: center; 32 | } 33 | 34 | h2 { 35 | color: #000; 36 | } 37 | 38 | h3 { 39 | color: #333; 40 | } 41 | 42 | button { 43 | background-color: #94a5be; 44 | color: #fff; 45 | border: none; 46 | border-radius: 6px; 47 | padding: 8px 16px; 48 | cursor: pointer; 49 | font-size: 14px; 50 | } 51 | 52 | input { 53 | border: 1px solid #e1e4e8; 54 | border-radius: 6px; 55 | padding: 8px 16px; 56 | font-size: 14px; 57 | margin-left: 8px; 58 | font-size: 16px; 59 | } 60 | 61 | .flex { 62 | display: flex; 63 | width: 700px; 64 | align-items: center; 65 | justify-content: space-around; 66 | } 67 | -------------------------------------------------------------------------------- /src/redux.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useContext } from 'react' 2 | 3 | let state = void 0 4 | let reducer = void 0 5 | let listeners = [] 6 | const setState = newState => { 7 | state = newState 8 | listeners.map(fn => fn(state)) 9 | } 10 | 11 | const store = { 12 | getState() { 13 | return 14 | }, 15 | dispatch: action => { 16 | setState(reducer(state, action)) 17 | }, 18 | subscribe(fn) { 19 | listeners.push(fn) 20 | return () => { 21 | const index = listeners.indexOf(fn) 22 | listeners.splice(index, 1) 23 | } 24 | } 25 | } 26 | 27 | let { dispatch } = store 28 | 29 | const prevDispatch = dispatch 30 | 31 | dispatch = action => { 32 | action instanceof Function 33 | ? action(dispatch) 34 | : prevDispatch(action) 35 | } 36 | 37 | const asyncDispatch = dispatch 38 | 39 | dispatch = action => { 40 | action.payload instanceof Promise 41 | ? action.payload.then(data => { 42 | dispatch({ ...action, payload: data }) 43 | }) 44 | : asyncDispatch(action) 45 | } 46 | 47 | export const createStore = (_reducer, initState) => { 48 | state = initState 49 | reducer = _reducer 50 | return store 51 | } 52 | 53 | const changed = (oldState, newState) => { 54 | let changed = false 55 | for (let key in oldState) { 56 | if (oldState[key] !== newState[key]) { 57 | changed = true 58 | break 59 | } 60 | } 61 | return changed 62 | } 63 | 64 | export const connect = (mapStateToProps, mapDispatchToProps) => Component => { 65 | return props => { 66 | const [_, forceUpdate] = useState({}) 67 | const selectedState = mapStateToProps ? mapStateToProps(state) : { state } 68 | const selectedDispatches = mapDispatchToProps ? mapDispatchToProps(dispatch) : { dispatch } 69 | useEffect(() => ( 70 | store.subscribe(() => { 71 | const newSelectedState = mapStateToProps ? mapStateToProps(state) : { state } 72 | if (changed(selectedState, newSelectedState)) { 73 | forceUpdate({}) 74 | } 75 | }) 76 | ), [mapStateToProps]) 77 | return 78 | } 79 | } 80 | 81 | const appContext = React.createContext(null) 82 | 83 | export const Provider = ({ store, children }) => { 84 | return ( 85 | 86 | {children} 87 | 88 | ) 89 | } 90 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { connect, createStore, Provider } from './redux' 3 | import { connectToUser } from './connecters/connectToUser' 4 | import {connectToEducational} from './connecters/connectToEducational' 5 | 6 | const reducer = (state, { type, payload }) => { 7 | const updateMap = { 8 | updateUser: { 9 | ...state, 10 | user: { 11 | ...state.user, 12 | ...payload 13 | } 14 | }, 15 | updateEducational: { 16 | ...state, 17 | educational: { 18 | ...state.educational, 19 | ...payload 20 | } 21 | } 22 | } 23 | 24 | return updateMap[type] || state 25 | } 26 | 27 | const initState = { 28 | user: { name: '', age: '' }, 29 | educational: { school: '', major: '' } 30 | } 31 | const store = createStore(reducer, initState) 32 | 33 | const empty = string => (string ? string : '--') 34 | 35 | export const App = () => { 36 | return ( 37 | 38 | 39 |
40 | 41 | 42 |
43 |
44 | 45 | 46 |
47 |
48 | ) 49 | } 50 | 51 | const ReadData = () => { 52 | return ( 53 |
54 |

读取数据

55 |
56 | 57 |
58 |

用户信息

59 | 60 |
61 |

教育信息

62 | 63 |
64 | ) 65 | } 66 | 67 | const AllData = connect()(({state}) => { 68 | return ( 69 | <> 70 |

Store

71 |
{JSON.stringify(state)}
72 | 73 | ) 74 | }) 75 | 76 | const WriteUser = () => { 77 | return ( 78 |
79 |

修改用户信息

80 |
81 | 82 |
83 | ) 84 | } 85 | 86 | const WriteEducational = () => { 87 | return ( 88 |
89 |

修改教育信息

90 |
91 | 92 |
93 | ) 94 | } 95 | 96 | const User = connectToUser(({ user }) => { 97 | return ( 98 | <> 99 |
姓名: {empty(user.name)}
100 |
年龄: {empty(user.age)}
101 | 102 | ) 103 | }) 104 | 105 | const Educational = connectToEducational(({ educational }) => { 106 | return ( 107 | <> 108 |
学校: {empty(educational.school)}
109 |
专业: {empty(educational.major)}
110 | 111 | ) 112 | }) 113 | 114 | const AsyncAction = () => { 115 | return ( 116 |
117 |

支持异步的 Action

118 |
119 | 120 |
121 | ) 122 | } 123 | 124 | const PromiseAction = () => { 125 | return ( 126 |
127 |

支持 Promise 的 Action

128 |
129 | 130 |
131 | ) 132 | } 133 | 134 | const UserModifier = connectToUser(({ updateUser, user }) => { 135 | const changName = e => { 136 | updateUser({ name: e.target.value }) 137 | } 138 | const changAge = e => { 139 | updateUser({ age: e.target.value }) 140 | } 141 | return ( 142 | <> 143 |
144 | 修改姓名 145 | 146 |
147 |
148 |
149 | 修改年龄 150 | 151 |
152 | 153 | ) 154 | }) 155 | 156 | const EducationalModifier = connectToEducational(({ updateEducational, educational }) => { 157 | const changSchool = e => { 158 | updateEducational({ school: e.target.value }) 159 | } 160 | const changMajor = e => { 161 | updateEducational({ major: e.target.value }) 162 | } 163 | return ( 164 | <> 165 |
166 | 修改学校 167 | 168 |
169 |
170 |
171 | 修改专业 172 | 173 |
174 | 175 | ) 176 | }) 177 | 178 | const ajax = url => { 179 | const urlMap = { 180 | '/user': { name: '异步的小王', age: '异步的18岁' }, 181 | '/promiseEducational': { school: 'Promise的学校', major: 'Promise的专业' }, 182 | } 183 | return new Promise(resolve => { 184 | setTimeout(() => { 185 | resolve({ data: urlMap[url] }) 186 | }, 500) 187 | }) 188 | } 189 | 190 | const FetchUser = connect()(({state, dispatch}) => { 191 | console.log(state) 192 | const fetchUser = dispatch => { 193 | ajax('/user').then(response => { 194 | dispatch({ type: 'updateUser', payload: response.data }) 195 | }) 196 | } 197 | const onClick = () => { 198 | dispatch(fetchUser) 199 | } 200 | return 201 | }) 202 | 203 | const FetchPromiseUser = connect(null, null)(({state, dispatch}) => { 204 | const fetchUserPromise = async () => { 205 | const response = await ajax('/promiseEducational') 206 | return response.data 207 | } 208 | const fetchUserPromiseFunc = async dispatch => { 209 | const response = await ajax('/promiseEducational') 210 | return dispatch({ type: 'updateEducational', payload: response.data }) 211 | } 212 | const onClick = () => { 213 | dispatch({ type: 'updateEducational', payload: fetchUserPromise() }) 214 | // dispatch(fetchUserPromiseFunc) 215 | } 216 | return 217 | }) 218 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@types/react': ^18.0.26 5 | '@types/react-dom': ^18.0.9 6 | '@vitejs/plugin-react': ^3.0.0 7 | react: ^18.2.0 8 | react-dom: ^18.2.0 9 | vite: ^4.0.0 10 | 11 | dependencies: 12 | react: 18.2.0 13 | react-dom: 18.2.0_react@18.2.0 14 | 15 | devDependencies: 16 | '@types/react': 18.0.26 17 | '@types/react-dom': 18.0.9 18 | '@vitejs/plugin-react': 3.0.0_vite@4.0.1 19 | vite: 4.0.1 20 | 21 | packages: 22 | 23 | /@ampproject/remapping/2.2.0: 24 | resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} 25 | engines: {node: '>=6.0.0'} 26 | dependencies: 27 | '@jridgewell/gen-mapping': 0.1.1 28 | '@jridgewell/trace-mapping': 0.3.17 29 | dev: true 30 | 31 | /@babel/code-frame/7.18.6: 32 | resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} 33 | engines: {node: '>=6.9.0'} 34 | dependencies: 35 | '@babel/highlight': 7.18.6 36 | dev: true 37 | 38 | /@babel/compat-data/7.20.5: 39 | resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} 40 | engines: {node: '>=6.9.0'} 41 | dev: true 42 | 43 | /@babel/core/7.20.5: 44 | resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} 45 | engines: {node: '>=6.9.0'} 46 | dependencies: 47 | '@ampproject/remapping': 2.2.0 48 | '@babel/code-frame': 7.18.6 49 | '@babel/generator': 7.20.5 50 | '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 51 | '@babel/helper-module-transforms': 7.20.2 52 | '@babel/helpers': 7.20.6 53 | '@babel/parser': 7.20.5 54 | '@babel/template': 7.18.10 55 | '@babel/traverse': 7.20.5 56 | '@babel/types': 7.20.5 57 | convert-source-map: 1.9.0 58 | debug: 4.3.4 59 | gensync: 1.0.0-beta.2 60 | json5: 2.2.1 61 | semver: 6.3.0 62 | transitivePeerDependencies: 63 | - supports-color 64 | dev: true 65 | 66 | /@babel/generator/7.20.5: 67 | resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} 68 | engines: {node: '>=6.9.0'} 69 | dependencies: 70 | '@babel/types': 7.20.5 71 | '@jridgewell/gen-mapping': 0.3.2 72 | jsesc: 2.5.2 73 | dev: true 74 | 75 | /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: 76 | resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} 77 | engines: {node: '>=6.9.0'} 78 | peerDependencies: 79 | '@babel/core': ^7.0.0 80 | dependencies: 81 | '@babel/compat-data': 7.20.5 82 | '@babel/core': 7.20.5 83 | '@babel/helper-validator-option': 7.18.6 84 | browserslist: 4.21.4 85 | semver: 6.3.0 86 | dev: true 87 | 88 | /@babel/helper-environment-visitor/7.18.9: 89 | resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} 90 | engines: {node: '>=6.9.0'} 91 | dev: true 92 | 93 | /@babel/helper-function-name/7.19.0: 94 | resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} 95 | engines: {node: '>=6.9.0'} 96 | dependencies: 97 | '@babel/template': 7.18.10 98 | '@babel/types': 7.20.5 99 | dev: true 100 | 101 | /@babel/helper-hoist-variables/7.18.6: 102 | resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} 103 | engines: {node: '>=6.9.0'} 104 | dependencies: 105 | '@babel/types': 7.20.5 106 | dev: true 107 | 108 | /@babel/helper-module-imports/7.18.6: 109 | resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} 110 | engines: {node: '>=6.9.0'} 111 | dependencies: 112 | '@babel/types': 7.20.5 113 | dev: true 114 | 115 | /@babel/helper-module-transforms/7.20.2: 116 | resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} 117 | engines: {node: '>=6.9.0'} 118 | dependencies: 119 | '@babel/helper-environment-visitor': 7.18.9 120 | '@babel/helper-module-imports': 7.18.6 121 | '@babel/helper-simple-access': 7.20.2 122 | '@babel/helper-split-export-declaration': 7.18.6 123 | '@babel/helper-validator-identifier': 7.19.1 124 | '@babel/template': 7.18.10 125 | '@babel/traverse': 7.20.5 126 | '@babel/types': 7.20.5 127 | transitivePeerDependencies: 128 | - supports-color 129 | dev: true 130 | 131 | /@babel/helper-plugin-utils/7.20.2: 132 | resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} 133 | engines: {node: '>=6.9.0'} 134 | dev: true 135 | 136 | /@babel/helper-simple-access/7.20.2: 137 | resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} 138 | engines: {node: '>=6.9.0'} 139 | dependencies: 140 | '@babel/types': 7.20.5 141 | dev: true 142 | 143 | /@babel/helper-split-export-declaration/7.18.6: 144 | resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} 145 | engines: {node: '>=6.9.0'} 146 | dependencies: 147 | '@babel/types': 7.20.5 148 | dev: true 149 | 150 | /@babel/helper-string-parser/7.19.4: 151 | resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} 152 | engines: {node: '>=6.9.0'} 153 | dev: true 154 | 155 | /@babel/helper-validator-identifier/7.19.1: 156 | resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} 157 | engines: {node: '>=6.9.0'} 158 | dev: true 159 | 160 | /@babel/helper-validator-option/7.18.6: 161 | resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} 162 | engines: {node: '>=6.9.0'} 163 | dev: true 164 | 165 | /@babel/helpers/7.20.6: 166 | resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} 167 | engines: {node: '>=6.9.0'} 168 | dependencies: 169 | '@babel/template': 7.18.10 170 | '@babel/traverse': 7.20.5 171 | '@babel/types': 7.20.5 172 | transitivePeerDependencies: 173 | - supports-color 174 | dev: true 175 | 176 | /@babel/highlight/7.18.6: 177 | resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} 178 | engines: {node: '>=6.9.0'} 179 | dependencies: 180 | '@babel/helper-validator-identifier': 7.19.1 181 | chalk: 2.4.2 182 | js-tokens: 4.0.0 183 | dev: true 184 | 185 | /@babel/parser/7.20.5: 186 | resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} 187 | engines: {node: '>=6.0.0'} 188 | hasBin: true 189 | dependencies: 190 | '@babel/types': 7.20.5 191 | dev: true 192 | 193 | /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.5: 194 | resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} 195 | engines: {node: '>=6.9.0'} 196 | peerDependencies: 197 | '@babel/core': ^7.0.0-0 198 | dependencies: 199 | '@babel/core': 7.20.5 200 | '@babel/helper-plugin-utils': 7.20.2 201 | dev: true 202 | 203 | /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.5: 204 | resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} 205 | engines: {node: '>=6.9.0'} 206 | peerDependencies: 207 | '@babel/core': ^7.0.0-0 208 | dependencies: 209 | '@babel/core': 7.20.5 210 | '@babel/helper-plugin-utils': 7.20.2 211 | dev: true 212 | 213 | /@babel/template/7.18.10: 214 | resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} 215 | engines: {node: '>=6.9.0'} 216 | dependencies: 217 | '@babel/code-frame': 7.18.6 218 | '@babel/parser': 7.20.5 219 | '@babel/types': 7.20.5 220 | dev: true 221 | 222 | /@babel/traverse/7.20.5: 223 | resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} 224 | engines: {node: '>=6.9.0'} 225 | dependencies: 226 | '@babel/code-frame': 7.18.6 227 | '@babel/generator': 7.20.5 228 | '@babel/helper-environment-visitor': 7.18.9 229 | '@babel/helper-function-name': 7.19.0 230 | '@babel/helper-hoist-variables': 7.18.6 231 | '@babel/helper-split-export-declaration': 7.18.6 232 | '@babel/parser': 7.20.5 233 | '@babel/types': 7.20.5 234 | debug: 4.3.4 235 | globals: 11.12.0 236 | transitivePeerDependencies: 237 | - supports-color 238 | dev: true 239 | 240 | /@babel/types/7.20.5: 241 | resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} 242 | engines: {node: '>=6.9.0'} 243 | dependencies: 244 | '@babel/helper-string-parser': 7.19.4 245 | '@babel/helper-validator-identifier': 7.19.1 246 | to-fast-properties: 2.0.0 247 | dev: true 248 | 249 | /@esbuild/android-arm/0.16.4: 250 | resolution: {integrity: sha512-rZzb7r22m20S1S7ufIc6DC6W659yxoOrl7sKP1nCYhuvUlnCFHVSbATG4keGUtV8rDz11sRRDbWkvQZpzPaHiw==} 251 | engines: {node: '>=12'} 252 | cpu: [arm] 253 | os: [android] 254 | requiresBuild: true 255 | dev: true 256 | optional: true 257 | 258 | /@esbuild/android-arm64/0.16.4: 259 | resolution: {integrity: sha512-VPuTzXFm/m2fcGfN6CiwZTlLzxrKsWbPkG7ArRFpuxyaHUm/XFHQPD4xNwZT6uUmpIHhnSjcaCmcla8COzmZ5Q==} 260 | engines: {node: '>=12'} 261 | cpu: [arm64] 262 | os: [android] 263 | requiresBuild: true 264 | dev: true 265 | optional: true 266 | 267 | /@esbuild/android-x64/0.16.4: 268 | resolution: {integrity: sha512-MW+B2O++BkcOfMWmuHXB15/l1i7wXhJFqbJhp82IBOais8RBEQv2vQz/jHrDEHaY2X0QY7Wfw86SBL2PbVOr0g==} 269 | engines: {node: '>=12'} 270 | cpu: [x64] 271 | os: [android] 272 | requiresBuild: true 273 | dev: true 274 | optional: true 275 | 276 | /@esbuild/darwin-arm64/0.16.4: 277 | resolution: {integrity: sha512-a28X1O//aOfxwJVZVs7ZfM8Tyih2Za4nKJrBwW5Wm4yKsnwBy9aiS/xwpxiiTRttw3EaTg4Srerhcm6z0bu9Wg==} 278 | engines: {node: '>=12'} 279 | cpu: [arm64] 280 | os: [darwin] 281 | requiresBuild: true 282 | dev: true 283 | optional: true 284 | 285 | /@esbuild/darwin-x64/0.16.4: 286 | resolution: {integrity: sha512-e3doCr6Ecfwd7VzlaQqEPrnbvvPjE9uoTpxG5pyLzr2rI2NMjDHmvY1E5EO81O/e9TUOLLkXA5m6T8lfjK9yAA==} 287 | engines: {node: '>=12'} 288 | cpu: [x64] 289 | os: [darwin] 290 | requiresBuild: true 291 | dev: true 292 | optional: true 293 | 294 | /@esbuild/freebsd-arm64/0.16.4: 295 | resolution: {integrity: sha512-Oup3G/QxBgvvqnXWrBed7xxkFNwAwJVHZcklWyQt7YCAL5bfUkaa6FVWnR78rNQiM8MqqLiT6ZTZSdUFuVIg1w==} 296 | engines: {node: '>=12'} 297 | cpu: [arm64] 298 | os: [freebsd] 299 | requiresBuild: true 300 | dev: true 301 | optional: true 302 | 303 | /@esbuild/freebsd-x64/0.16.4: 304 | resolution: {integrity: sha512-vAP+eYOxlN/Bpo/TZmzEQapNS8W1njECrqkTpNgvXskkkJC2AwOXwZWai/Kc2vEFZUXQttx6UJbj9grqjD/+9Q==} 305 | engines: {node: '>=12'} 306 | cpu: [x64] 307 | os: [freebsd] 308 | requiresBuild: true 309 | dev: true 310 | optional: true 311 | 312 | /@esbuild/linux-arm/0.16.4: 313 | resolution: {integrity: sha512-A47ZmtpIPyERxkSvIv+zLd6kNIOtJH03XA0Hy7jaceRDdQaQVGSDt4mZqpWqJYgDk9rg96aglbF6kCRvPGDSUA==} 314 | engines: {node: '>=12'} 315 | cpu: [arm] 316 | os: [linux] 317 | requiresBuild: true 318 | dev: true 319 | optional: true 320 | 321 | /@esbuild/linux-arm64/0.16.4: 322 | resolution: {integrity: sha512-2zXoBhv4r5pZiyjBKrOdFP4CXOChxXiYD50LRUU+65DkdS5niPFHbboKZd/c81l0ezpw7AQnHeoCy5hFrzzs4g==} 323 | engines: {node: '>=12'} 324 | cpu: [arm64] 325 | os: [linux] 326 | requiresBuild: true 327 | dev: true 328 | optional: true 329 | 330 | /@esbuild/linux-ia32/0.16.4: 331 | resolution: {integrity: sha512-uxdSrpe9wFhz4yBwt2kl2TxS/NWEINYBUFIxQtaEVtglm1eECvsj1vEKI0KX2k2wCe17zDdQ3v+jVxfwVfvvjw==} 332 | engines: {node: '>=12'} 333 | cpu: [ia32] 334 | os: [linux] 335 | requiresBuild: true 336 | dev: true 337 | optional: true 338 | 339 | /@esbuild/linux-loong64/0.16.4: 340 | resolution: {integrity: sha512-peDrrUuxbZ9Jw+DwLCh/9xmZAk0p0K1iY5d2IcwmnN+B87xw7kujOkig6ZRcZqgrXgeRGurRHn0ENMAjjD5DEg==} 341 | engines: {node: '>=12'} 342 | cpu: [loong64] 343 | os: [linux] 344 | requiresBuild: true 345 | dev: true 346 | optional: true 347 | 348 | /@esbuild/linux-mips64el/0.16.4: 349 | resolution: {integrity: sha512-sD9EEUoGtVhFjjsauWjflZklTNr57KdQ6xfloO4yH1u7vNQlOfAlhEzbyBKfgbJlW7rwXYBdl5/NcZ+Mg2XhQA==} 350 | engines: {node: '>=12'} 351 | cpu: [mips64el] 352 | os: [linux] 353 | requiresBuild: true 354 | dev: true 355 | optional: true 356 | 357 | /@esbuild/linux-ppc64/0.16.4: 358 | resolution: {integrity: sha512-X1HSqHUX9D+d0l6/nIh4ZZJ94eQky8d8z6yxAptpZE3FxCWYWvTDd9X9ST84MGZEJx04VYUD/AGgciddwO0b8g==} 359 | engines: {node: '>=12'} 360 | cpu: [ppc64] 361 | os: [linux] 362 | requiresBuild: true 363 | dev: true 364 | optional: true 365 | 366 | /@esbuild/linux-riscv64/0.16.4: 367 | resolution: {integrity: sha512-97ANpzyNp0GTXCt6SRdIx1ngwncpkV/z453ZuxbnBROCJ5p/55UjhbaG23UdHj88fGWLKPFtMoU4CBacz4j9FA==} 368 | engines: {node: '>=12'} 369 | cpu: [riscv64] 370 | os: [linux] 371 | requiresBuild: true 372 | dev: true 373 | optional: true 374 | 375 | /@esbuild/linux-s390x/0.16.4: 376 | resolution: {integrity: sha512-pUvPQLPmbEeJRPjP0DYTC1vjHyhrnCklQmCGYbipkep+oyfTn7GTBJXoPodR7ZS5upmEyc8lzAkn2o29wD786A==} 377 | engines: {node: '>=12'} 378 | cpu: [s390x] 379 | os: [linux] 380 | requiresBuild: true 381 | dev: true 382 | optional: true 383 | 384 | /@esbuild/linux-x64/0.16.4: 385 | resolution: {integrity: sha512-N55Q0mJs3Sl8+utPRPBrL6NLYZKBCLLx0bme/+RbjvMforTGGzFvsRl4xLTZMUBFC1poDzBEPTEu5nxizQ9Nlw==} 386 | engines: {node: '>=12'} 387 | cpu: [x64] 388 | os: [linux] 389 | requiresBuild: true 390 | dev: true 391 | optional: true 392 | 393 | /@esbuild/netbsd-x64/0.16.4: 394 | resolution: {integrity: sha512-LHSJLit8jCObEQNYkgsDYBh2JrJT53oJO2HVdkSYLa6+zuLJh0lAr06brXIkljrlI+N7NNW1IAXGn/6IZPi3YQ==} 395 | engines: {node: '>=12'} 396 | cpu: [x64] 397 | os: [netbsd] 398 | requiresBuild: true 399 | dev: true 400 | optional: true 401 | 402 | /@esbuild/openbsd-x64/0.16.4: 403 | resolution: {integrity: sha512-nLgdc6tWEhcCFg/WVFaUxHcPK3AP/bh+KEwKtl69Ay5IBqUwKDaq/6Xk0E+fh/FGjnLwqFSsarsbPHeKM8t8Sw==} 404 | engines: {node: '>=12'} 405 | cpu: [x64] 406 | os: [openbsd] 407 | requiresBuild: true 408 | dev: true 409 | optional: true 410 | 411 | /@esbuild/sunos-x64/0.16.4: 412 | resolution: {integrity: sha512-08SluG24GjPO3tXKk95/85n9kpyZtXCVwURR2i4myhrOfi3jspClV0xQQ0W0PYWHioJj+LejFMt41q+PG3mlAQ==} 413 | engines: {node: '>=12'} 414 | cpu: [x64] 415 | os: [sunos] 416 | requiresBuild: true 417 | dev: true 418 | optional: true 419 | 420 | /@esbuild/win32-arm64/0.16.4: 421 | resolution: {integrity: sha512-yYiRDQcqLYQSvNQcBKN7XogbrSvBE45FEQdH8fuXPl7cngzkCvpsG2H9Uey39IjQ6gqqc+Q4VXYHsQcKW0OMjQ==} 422 | engines: {node: '>=12'} 423 | cpu: [arm64] 424 | os: [win32] 425 | requiresBuild: true 426 | dev: true 427 | optional: true 428 | 429 | /@esbuild/win32-ia32/0.16.4: 430 | resolution: {integrity: sha512-5rabnGIqexekYkh9zXG5waotq8mrdlRoBqAktjx2W3kb0zsI83mdCwrcAeKYirnUaTGztR5TxXcXmQrEzny83w==} 431 | engines: {node: '>=12'} 432 | cpu: [ia32] 433 | os: [win32] 434 | requiresBuild: true 435 | dev: true 436 | optional: true 437 | 438 | /@esbuild/win32-x64/0.16.4: 439 | resolution: {integrity: sha512-sN/I8FMPtmtT2Yw+Dly8Ur5vQ5a/RmC8hW7jO9PtPSQUPkowxWpcUZnqOggU7VwyT3Xkj6vcXWd3V/qTXwultQ==} 440 | engines: {node: '>=12'} 441 | cpu: [x64] 442 | os: [win32] 443 | requiresBuild: true 444 | dev: true 445 | optional: true 446 | 447 | /@jridgewell/gen-mapping/0.1.1: 448 | resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} 449 | engines: {node: '>=6.0.0'} 450 | dependencies: 451 | '@jridgewell/set-array': 1.1.2 452 | '@jridgewell/sourcemap-codec': 1.4.14 453 | dev: true 454 | 455 | /@jridgewell/gen-mapping/0.3.2: 456 | resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} 457 | engines: {node: '>=6.0.0'} 458 | dependencies: 459 | '@jridgewell/set-array': 1.1.2 460 | '@jridgewell/sourcemap-codec': 1.4.14 461 | '@jridgewell/trace-mapping': 0.3.17 462 | dev: true 463 | 464 | /@jridgewell/resolve-uri/3.1.0: 465 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 466 | engines: {node: '>=6.0.0'} 467 | dev: true 468 | 469 | /@jridgewell/set-array/1.1.2: 470 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 471 | engines: {node: '>=6.0.0'} 472 | dev: true 473 | 474 | /@jridgewell/sourcemap-codec/1.4.14: 475 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 476 | dev: true 477 | 478 | /@jridgewell/trace-mapping/0.3.17: 479 | resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} 480 | dependencies: 481 | '@jridgewell/resolve-uri': 3.1.0 482 | '@jridgewell/sourcemap-codec': 1.4.14 483 | dev: true 484 | 485 | /@types/prop-types/15.7.5: 486 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 487 | dev: true 488 | 489 | /@types/react-dom/18.0.9: 490 | resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} 491 | dependencies: 492 | '@types/react': 18.0.26 493 | dev: true 494 | 495 | /@types/react/18.0.26: 496 | resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} 497 | dependencies: 498 | '@types/prop-types': 15.7.5 499 | '@types/scheduler': 0.16.2 500 | csstype: 3.1.1 501 | dev: true 502 | 503 | /@types/scheduler/0.16.2: 504 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 505 | dev: true 506 | 507 | /@vitejs/plugin-react/3.0.0_vite@4.0.1: 508 | resolution: {integrity: sha512-1mvyPc0xYW5G8CHQvJIJXLoMjl5Ct3q2g5Y2s6Ccfgwm45y48LBvsla7az+GkkAtYikWQ4Lxqcsq5RHLcZgtNQ==} 509 | engines: {node: ^14.18.0 || >=16.0.0} 510 | peerDependencies: 511 | vite: ^4.0.0 512 | dependencies: 513 | '@babel/core': 7.20.5 514 | '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.5 515 | '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.5 516 | magic-string: 0.27.0 517 | react-refresh: 0.14.0 518 | vite: 4.0.1 519 | transitivePeerDependencies: 520 | - supports-color 521 | dev: true 522 | 523 | /ansi-styles/3.2.1: 524 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 525 | engines: {node: '>=4'} 526 | dependencies: 527 | color-convert: 1.9.3 528 | dev: true 529 | 530 | /browserslist/4.21.4: 531 | resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} 532 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 533 | hasBin: true 534 | dependencies: 535 | caniuse-lite: 1.0.30001439 536 | electron-to-chromium: 1.4.284 537 | node-releases: 2.0.6 538 | update-browserslist-db: 1.0.10_browserslist@4.21.4 539 | dev: true 540 | 541 | /caniuse-lite/1.0.30001439: 542 | resolution: {integrity: sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==} 543 | dev: true 544 | 545 | /chalk/2.4.2: 546 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 547 | engines: {node: '>=4'} 548 | dependencies: 549 | ansi-styles: 3.2.1 550 | escape-string-regexp: 1.0.5 551 | supports-color: 5.5.0 552 | dev: true 553 | 554 | /color-convert/1.9.3: 555 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 556 | dependencies: 557 | color-name: 1.1.3 558 | dev: true 559 | 560 | /color-name/1.1.3: 561 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 562 | dev: true 563 | 564 | /convert-source-map/1.9.0: 565 | resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} 566 | dev: true 567 | 568 | /csstype/3.1.1: 569 | resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} 570 | dev: true 571 | 572 | /debug/4.3.4: 573 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 574 | engines: {node: '>=6.0'} 575 | peerDependencies: 576 | supports-color: '*' 577 | peerDependenciesMeta: 578 | supports-color: 579 | optional: true 580 | dependencies: 581 | ms: 2.1.2 582 | dev: true 583 | 584 | /electron-to-chromium/1.4.284: 585 | resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} 586 | dev: true 587 | 588 | /esbuild/0.16.4: 589 | resolution: {integrity: sha512-qQrPMQpPTWf8jHugLWHoGqZjApyx3OEm76dlTXobHwh/EBbavbRdjXdYi/GWr43GyN0sfpap14GPkb05NH3ROA==} 590 | engines: {node: '>=12'} 591 | hasBin: true 592 | requiresBuild: true 593 | optionalDependencies: 594 | '@esbuild/android-arm': 0.16.4 595 | '@esbuild/android-arm64': 0.16.4 596 | '@esbuild/android-x64': 0.16.4 597 | '@esbuild/darwin-arm64': 0.16.4 598 | '@esbuild/darwin-x64': 0.16.4 599 | '@esbuild/freebsd-arm64': 0.16.4 600 | '@esbuild/freebsd-x64': 0.16.4 601 | '@esbuild/linux-arm': 0.16.4 602 | '@esbuild/linux-arm64': 0.16.4 603 | '@esbuild/linux-ia32': 0.16.4 604 | '@esbuild/linux-loong64': 0.16.4 605 | '@esbuild/linux-mips64el': 0.16.4 606 | '@esbuild/linux-ppc64': 0.16.4 607 | '@esbuild/linux-riscv64': 0.16.4 608 | '@esbuild/linux-s390x': 0.16.4 609 | '@esbuild/linux-x64': 0.16.4 610 | '@esbuild/netbsd-x64': 0.16.4 611 | '@esbuild/openbsd-x64': 0.16.4 612 | '@esbuild/sunos-x64': 0.16.4 613 | '@esbuild/win32-arm64': 0.16.4 614 | '@esbuild/win32-ia32': 0.16.4 615 | '@esbuild/win32-x64': 0.16.4 616 | dev: true 617 | 618 | /escalade/3.1.1: 619 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 620 | engines: {node: '>=6'} 621 | dev: true 622 | 623 | /escape-string-regexp/1.0.5: 624 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 625 | engines: {node: '>=0.8.0'} 626 | dev: true 627 | 628 | /fsevents/2.3.2: 629 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 630 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 631 | os: [darwin] 632 | requiresBuild: true 633 | dev: true 634 | optional: true 635 | 636 | /function-bind/1.1.1: 637 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 638 | dev: true 639 | 640 | /gensync/1.0.0-beta.2: 641 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 642 | engines: {node: '>=6.9.0'} 643 | dev: true 644 | 645 | /globals/11.12.0: 646 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 647 | engines: {node: '>=4'} 648 | dev: true 649 | 650 | /has-flag/3.0.0: 651 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 652 | engines: {node: '>=4'} 653 | dev: true 654 | 655 | /has/1.0.3: 656 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 657 | engines: {node: '>= 0.4.0'} 658 | dependencies: 659 | function-bind: 1.1.1 660 | dev: true 661 | 662 | /is-core-module/2.11.0: 663 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 664 | dependencies: 665 | has: 1.0.3 666 | dev: true 667 | 668 | /js-tokens/4.0.0: 669 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 670 | 671 | /jsesc/2.5.2: 672 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 673 | engines: {node: '>=4'} 674 | hasBin: true 675 | dev: true 676 | 677 | /json5/2.2.1: 678 | resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} 679 | engines: {node: '>=6'} 680 | hasBin: true 681 | dev: true 682 | 683 | /loose-envify/1.4.0: 684 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 685 | hasBin: true 686 | dependencies: 687 | js-tokens: 4.0.0 688 | dev: false 689 | 690 | /magic-string/0.27.0: 691 | resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} 692 | engines: {node: '>=12'} 693 | dependencies: 694 | '@jridgewell/sourcemap-codec': 1.4.14 695 | dev: true 696 | 697 | /ms/2.1.2: 698 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 699 | dev: true 700 | 701 | /nanoid/3.3.4: 702 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 703 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 704 | hasBin: true 705 | dev: true 706 | 707 | /node-releases/2.0.6: 708 | resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} 709 | dev: true 710 | 711 | /path-parse/1.0.7: 712 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 713 | dev: true 714 | 715 | /picocolors/1.0.0: 716 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 717 | dev: true 718 | 719 | /postcss/8.4.20: 720 | resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==} 721 | engines: {node: ^10 || ^12 || >=14} 722 | dependencies: 723 | nanoid: 3.3.4 724 | picocolors: 1.0.0 725 | source-map-js: 1.0.2 726 | dev: true 727 | 728 | /react-dom/18.2.0_react@18.2.0: 729 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 730 | peerDependencies: 731 | react: ^18.2.0 732 | dependencies: 733 | loose-envify: 1.4.0 734 | react: 18.2.0 735 | scheduler: 0.23.0 736 | dev: false 737 | 738 | /react-refresh/0.14.0: 739 | resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} 740 | engines: {node: '>=0.10.0'} 741 | dev: true 742 | 743 | /react/18.2.0: 744 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 745 | engines: {node: '>=0.10.0'} 746 | dependencies: 747 | loose-envify: 1.4.0 748 | dev: false 749 | 750 | /resolve/1.22.1: 751 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 752 | hasBin: true 753 | dependencies: 754 | is-core-module: 2.11.0 755 | path-parse: 1.0.7 756 | supports-preserve-symlinks-flag: 1.0.0 757 | dev: true 758 | 759 | /rollup/3.7.3: 760 | resolution: {integrity: sha512-7e68MQbAWCX6mI4/0lG1WHd+NdNAlVamg0Zkd+8LZ/oXojligdGnCNyHlzXqXCZObyjs5FRc3AH0b17iJESGIQ==} 761 | engines: {node: '>=14.18.0', npm: '>=8.0.0'} 762 | hasBin: true 763 | optionalDependencies: 764 | fsevents: 2.3.2 765 | dev: true 766 | 767 | /scheduler/0.23.0: 768 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 769 | dependencies: 770 | loose-envify: 1.4.0 771 | dev: false 772 | 773 | /semver/6.3.0: 774 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 775 | hasBin: true 776 | dev: true 777 | 778 | /source-map-js/1.0.2: 779 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 780 | engines: {node: '>=0.10.0'} 781 | dev: true 782 | 783 | /supports-color/5.5.0: 784 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 785 | engines: {node: '>=4'} 786 | dependencies: 787 | has-flag: 3.0.0 788 | dev: true 789 | 790 | /supports-preserve-symlinks-flag/1.0.0: 791 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 792 | engines: {node: '>= 0.4'} 793 | dev: true 794 | 795 | /to-fast-properties/2.0.0: 796 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 797 | engines: {node: '>=4'} 798 | dev: true 799 | 800 | /update-browserslist-db/1.0.10_browserslist@4.21.4: 801 | resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} 802 | hasBin: true 803 | peerDependencies: 804 | browserslist: '>= 4.21.0' 805 | dependencies: 806 | browserslist: 4.21.4 807 | escalade: 3.1.1 808 | picocolors: 1.0.0 809 | dev: true 810 | 811 | /vite/4.0.1: 812 | resolution: {integrity: sha512-kZQPzbDau35iWOhy3CpkrRC7It+HIHtulAzBhMqzGHKRf/4+vmh8rPDDdv98SWQrFWo6//3ozwsRmwQIPZsK9g==} 813 | engines: {node: ^14.18.0 || >=16.0.0} 814 | hasBin: true 815 | peerDependencies: 816 | '@types/node': '>= 14' 817 | less: '*' 818 | sass: '*' 819 | stylus: '*' 820 | sugarss: '*' 821 | terser: ^5.4.0 822 | peerDependenciesMeta: 823 | '@types/node': 824 | optional: true 825 | less: 826 | optional: true 827 | sass: 828 | optional: true 829 | stylus: 830 | optional: true 831 | sugarss: 832 | optional: true 833 | terser: 834 | optional: true 835 | dependencies: 836 | esbuild: 0.16.4 837 | postcss: 8.4.20 838 | resolve: 1.22.1 839 | rollup: 3.7.3 840 | optionalDependencies: 841 | fsevents: 2.3.2 842 | dev: true 843 | --------------------------------------------------------------------------------