├── .env
├── .eslintrc.cjs
├── .gitignore
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── public
└── ztm-notes.png
├── src
├── App.tsx
├── Node
│ ├── BasicNode.tsx
│ ├── CommandPanel.module.css
│ ├── CommandPanel.tsx
│ ├── ImageNode.tsx
│ ├── Node.module.css
│ ├── NodeContainer.module.css
│ ├── NodeContainer.tsx
│ ├── NodeTypeSwitcher.tsx
│ ├── PageNode.tsx
│ └── useOverflowsScreenBottom.ts
├── Page
│ ├── Cover.module.css
│ ├── Cover.tsx
│ ├── Page.module.css
│ ├── Page.tsx
│ ├── Spacer.module.css
│ ├── Spacer.tsx
│ ├── Title.module.css
│ ├── Title.tsx
│ └── useFocusedNodeIndex.ts
├── auth
│ ├── Auth.tsx
│ ├── AuthSessionContext.tsx
│ └── Private.tsx
├── components
│ ├── FileImage.tsx
│ ├── Loader.module.css
│ └── Loader.tsx
├── index.css
├── main.tsx
├── state
│ ├── AppStateContext.tsx
│ ├── startPageScaffold.json
│ ├── usePageState.ts
│ ├── useSyncedState.ts
│ └── withInitialState.tsx
├── supabaseClient.ts
├── utils.module.css
├── utils
│ ├── createPage.ts
│ ├── debounce.ts
│ ├── types.ts
│ ├── updatePage.ts
│ └── uploadImage.ts
└── vite-env.d.ts
├── supabase
├── .gitignore
├── config.toml
├── functions
│ └── .vscode
│ │ ├── extensions.json
│ │ └── settings.json
└── seed.sql
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── ztm-notion-clone.code-workspace
/.env:
--------------------------------------------------------------------------------
1 | VITE_SUPABASE_URL=https://dmthattvhhsxbigzttgv.supabase.co
2 | VITE_SUPABASE_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImRtdGhhdHR2aGhzeGJpZ3p0dGd2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTA3MTI0OTEsImV4cCI6MTk2NjI4ODQ5MX0.UtqLymPOdk2FiVJSW3OWpf03CWcs22zu3FS7hdOxfUI
3 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:@typescript-eslint/recommended',
7 | 'plugin:react-hooks/recommended',
8 | ],
9 | ignorePatterns: ['dist', '.eslintrc.cjs'],
10 | parser: '@typescript-eslint/parser',
11 | plugins: ['react-refresh'],
12 | rules: {
13 | 'react-refresh/only-export-components': [
14 | 'warn',
15 | { allowConstantExport: true },
16 | ],
17 | },
18 | }
19 |
--------------------------------------------------------------------------------
/.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 |
26 | # Local Netlify folder
27 | .netlify
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Zero To Mastery - React TypeScript Course. Notion Clone.
2 |
3 | 
4 |
5 | Notion-like app that allows users to create notes and organize them in a tree structure.
6 |
7 | ## Features
8 |
9 | - Authentication
10 | - Create, update and delete notes
11 | - Create, update and delete images
12 | - Reorder notes
13 | - Change page title
14 | - Change page cover image
15 | - Create, update and delete pages
16 |
17 | ## Tech Stack
18 |
19 | The app is generated with Vite and uses the following technologies:
20 |
21 | - React
22 | - TypeScript
23 | - DndKit (drag and drop)
24 | - CSS Modules
25 | - Supabase (database, authentication, storage)
26 | - Netlify (hosting)
27 |
28 | ## Running the app
29 |
30 | To run the app locally, you need to create a Supabase project and add the following environment variables to your `.env` file:
31 |
32 | ```
33 | VITE_SUPABASE_URL=""
34 | VITE_SUPABASE_API_KEY=""
35 | ```
36 |
37 | Then run the following commands:
38 |
39 | ```
40 | npm install
41 | npm run dev
42 | ```
43 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Notion Clone
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ztm-notion-clone",
3 | "version": "0.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "ztm-notion-clone",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "@dnd-kit/core": "^6.0.8",
12 | "@dnd-kit/sortable": "^7.0.2",
13 | "@supabase/supabase-js": "^2.31.0",
14 | "classnames": "^2.3.2",
15 | "eslint-plugin-immer": "^0.0.1",
16 | "nanoid": "^4.0.2",
17 | "react": "^18.2.0",
18 | "react-dom": "^18.2.0",
19 | "react-router-dom": "^6.14.2",
20 | "use-immer": "^0.9.0"
21 | },
22 | "devDependencies": {
23 | "@types/react": "^18.2.15",
24 | "@types/react-dom": "^18.2.7",
25 | "@typescript-eslint/eslint-plugin": "^6.0.0",
26 | "@typescript-eslint/parser": "^6.0.0",
27 | "@vitejs/plugin-react-swc": "^3.3.2",
28 | "eslint": "^8.45.0",
29 | "eslint-plugin-react-hooks": "^4.6.0",
30 | "eslint-plugin-react-refresh": "^0.4.3",
31 | "supabase": "^1.82.5",
32 | "typescript": "^5.0.2",
33 | "vite": "^4.4.5"
34 | }
35 | },
36 | "node_modules/@aashutoshrathi/word-wrap": {
37 | "version": "1.2.6",
38 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
39 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
40 | "dev": true,
41 | "engines": {
42 | "node": ">=0.10.0"
43 | }
44 | },
45 | "node_modules/@dnd-kit/accessibility": {
46 | "version": "3.0.1",
47 | "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
48 | "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
49 | "dependencies": {
50 | "tslib": "^2.0.0"
51 | },
52 | "peerDependencies": {
53 | "react": ">=16.8.0"
54 | }
55 | },
56 | "node_modules/@dnd-kit/core": {
57 | "version": "6.0.8",
58 | "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.8.tgz",
59 | "integrity": "sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==",
60 | "dependencies": {
61 | "@dnd-kit/accessibility": "^3.0.0",
62 | "@dnd-kit/utilities": "^3.2.1",
63 | "tslib": "^2.0.0"
64 | },
65 | "peerDependencies": {
66 | "react": ">=16.8.0",
67 | "react-dom": ">=16.8.0"
68 | }
69 | },
70 | "node_modules/@dnd-kit/sortable": {
71 | "version": "7.0.2",
72 | "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-7.0.2.tgz",
73 | "integrity": "sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==",
74 | "dependencies": {
75 | "@dnd-kit/utilities": "^3.2.0",
76 | "tslib": "^2.0.0"
77 | },
78 | "peerDependencies": {
79 | "@dnd-kit/core": "^6.0.7",
80 | "react": ">=16.8.0"
81 | }
82 | },
83 | "node_modules/@dnd-kit/utilities": {
84 | "version": "3.2.1",
85 | "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz",
86 | "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==",
87 | "dependencies": {
88 | "tslib": "^2.0.0"
89 | },
90 | "peerDependencies": {
91 | "react": ">=16.8.0"
92 | }
93 | },
94 | "node_modules/@esbuild/android-arm": {
95 | "version": "0.18.17",
96 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz",
97 | "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==",
98 | "cpu": [
99 | "arm"
100 | ],
101 | "dev": true,
102 | "optional": true,
103 | "os": [
104 | "android"
105 | ],
106 | "engines": {
107 | "node": ">=12"
108 | }
109 | },
110 | "node_modules/@esbuild/android-arm64": {
111 | "version": "0.18.17",
112 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz",
113 | "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==",
114 | "cpu": [
115 | "arm64"
116 | ],
117 | "dev": true,
118 | "optional": true,
119 | "os": [
120 | "android"
121 | ],
122 | "engines": {
123 | "node": ">=12"
124 | }
125 | },
126 | "node_modules/@esbuild/android-x64": {
127 | "version": "0.18.17",
128 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz",
129 | "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==",
130 | "cpu": [
131 | "x64"
132 | ],
133 | "dev": true,
134 | "optional": true,
135 | "os": [
136 | "android"
137 | ],
138 | "engines": {
139 | "node": ">=12"
140 | }
141 | },
142 | "node_modules/@esbuild/darwin-arm64": {
143 | "version": "0.18.17",
144 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz",
145 | "integrity": "sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==",
146 | "cpu": [
147 | "arm64"
148 | ],
149 | "dev": true,
150 | "optional": true,
151 | "os": [
152 | "darwin"
153 | ],
154 | "engines": {
155 | "node": ">=12"
156 | }
157 | },
158 | "node_modules/@esbuild/darwin-x64": {
159 | "version": "0.18.17",
160 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz",
161 | "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==",
162 | "cpu": [
163 | "x64"
164 | ],
165 | "dev": true,
166 | "optional": true,
167 | "os": [
168 | "darwin"
169 | ],
170 | "engines": {
171 | "node": ">=12"
172 | }
173 | },
174 | "node_modules/@esbuild/freebsd-arm64": {
175 | "version": "0.18.17",
176 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz",
177 | "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==",
178 | "cpu": [
179 | "arm64"
180 | ],
181 | "dev": true,
182 | "optional": true,
183 | "os": [
184 | "freebsd"
185 | ],
186 | "engines": {
187 | "node": ">=12"
188 | }
189 | },
190 | "node_modules/@esbuild/freebsd-x64": {
191 | "version": "0.18.17",
192 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz",
193 | "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==",
194 | "cpu": [
195 | "x64"
196 | ],
197 | "dev": true,
198 | "optional": true,
199 | "os": [
200 | "freebsd"
201 | ],
202 | "engines": {
203 | "node": ">=12"
204 | }
205 | },
206 | "node_modules/@esbuild/linux-arm": {
207 | "version": "0.18.17",
208 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz",
209 | "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==",
210 | "cpu": [
211 | "arm"
212 | ],
213 | "dev": true,
214 | "optional": true,
215 | "os": [
216 | "linux"
217 | ],
218 | "engines": {
219 | "node": ">=12"
220 | }
221 | },
222 | "node_modules/@esbuild/linux-arm64": {
223 | "version": "0.18.17",
224 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz",
225 | "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==",
226 | "cpu": [
227 | "arm64"
228 | ],
229 | "dev": true,
230 | "optional": true,
231 | "os": [
232 | "linux"
233 | ],
234 | "engines": {
235 | "node": ">=12"
236 | }
237 | },
238 | "node_modules/@esbuild/linux-ia32": {
239 | "version": "0.18.17",
240 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz",
241 | "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==",
242 | "cpu": [
243 | "ia32"
244 | ],
245 | "dev": true,
246 | "optional": true,
247 | "os": [
248 | "linux"
249 | ],
250 | "engines": {
251 | "node": ">=12"
252 | }
253 | },
254 | "node_modules/@esbuild/linux-loong64": {
255 | "version": "0.18.17",
256 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz",
257 | "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==",
258 | "cpu": [
259 | "loong64"
260 | ],
261 | "dev": true,
262 | "optional": true,
263 | "os": [
264 | "linux"
265 | ],
266 | "engines": {
267 | "node": ">=12"
268 | }
269 | },
270 | "node_modules/@esbuild/linux-mips64el": {
271 | "version": "0.18.17",
272 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz",
273 | "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==",
274 | "cpu": [
275 | "mips64el"
276 | ],
277 | "dev": true,
278 | "optional": true,
279 | "os": [
280 | "linux"
281 | ],
282 | "engines": {
283 | "node": ">=12"
284 | }
285 | },
286 | "node_modules/@esbuild/linux-ppc64": {
287 | "version": "0.18.17",
288 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz",
289 | "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==",
290 | "cpu": [
291 | "ppc64"
292 | ],
293 | "dev": true,
294 | "optional": true,
295 | "os": [
296 | "linux"
297 | ],
298 | "engines": {
299 | "node": ">=12"
300 | }
301 | },
302 | "node_modules/@esbuild/linux-riscv64": {
303 | "version": "0.18.17",
304 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz",
305 | "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==",
306 | "cpu": [
307 | "riscv64"
308 | ],
309 | "dev": true,
310 | "optional": true,
311 | "os": [
312 | "linux"
313 | ],
314 | "engines": {
315 | "node": ">=12"
316 | }
317 | },
318 | "node_modules/@esbuild/linux-s390x": {
319 | "version": "0.18.17",
320 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz",
321 | "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==",
322 | "cpu": [
323 | "s390x"
324 | ],
325 | "dev": true,
326 | "optional": true,
327 | "os": [
328 | "linux"
329 | ],
330 | "engines": {
331 | "node": ">=12"
332 | }
333 | },
334 | "node_modules/@esbuild/linux-x64": {
335 | "version": "0.18.17",
336 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz",
337 | "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==",
338 | "cpu": [
339 | "x64"
340 | ],
341 | "dev": true,
342 | "optional": true,
343 | "os": [
344 | "linux"
345 | ],
346 | "engines": {
347 | "node": ">=12"
348 | }
349 | },
350 | "node_modules/@esbuild/netbsd-x64": {
351 | "version": "0.18.17",
352 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz",
353 | "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==",
354 | "cpu": [
355 | "x64"
356 | ],
357 | "dev": true,
358 | "optional": true,
359 | "os": [
360 | "netbsd"
361 | ],
362 | "engines": {
363 | "node": ">=12"
364 | }
365 | },
366 | "node_modules/@esbuild/openbsd-x64": {
367 | "version": "0.18.17",
368 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz",
369 | "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==",
370 | "cpu": [
371 | "x64"
372 | ],
373 | "dev": true,
374 | "optional": true,
375 | "os": [
376 | "openbsd"
377 | ],
378 | "engines": {
379 | "node": ">=12"
380 | }
381 | },
382 | "node_modules/@esbuild/sunos-x64": {
383 | "version": "0.18.17",
384 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz",
385 | "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==",
386 | "cpu": [
387 | "x64"
388 | ],
389 | "dev": true,
390 | "optional": true,
391 | "os": [
392 | "sunos"
393 | ],
394 | "engines": {
395 | "node": ">=12"
396 | }
397 | },
398 | "node_modules/@esbuild/win32-arm64": {
399 | "version": "0.18.17",
400 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz",
401 | "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==",
402 | "cpu": [
403 | "arm64"
404 | ],
405 | "dev": true,
406 | "optional": true,
407 | "os": [
408 | "win32"
409 | ],
410 | "engines": {
411 | "node": ">=12"
412 | }
413 | },
414 | "node_modules/@esbuild/win32-ia32": {
415 | "version": "0.18.17",
416 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz",
417 | "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==",
418 | "cpu": [
419 | "ia32"
420 | ],
421 | "dev": true,
422 | "optional": true,
423 | "os": [
424 | "win32"
425 | ],
426 | "engines": {
427 | "node": ">=12"
428 | }
429 | },
430 | "node_modules/@esbuild/win32-x64": {
431 | "version": "0.18.17",
432 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz",
433 | "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==",
434 | "cpu": [
435 | "x64"
436 | ],
437 | "dev": true,
438 | "optional": true,
439 | "os": [
440 | "win32"
441 | ],
442 | "engines": {
443 | "node": ">=12"
444 | }
445 | },
446 | "node_modules/@eslint-community/eslint-utils": {
447 | "version": "4.4.0",
448 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
449 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
450 | "dev": true,
451 | "dependencies": {
452 | "eslint-visitor-keys": "^3.3.0"
453 | },
454 | "engines": {
455 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
456 | },
457 | "peerDependencies": {
458 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
459 | }
460 | },
461 | "node_modules/@eslint-community/regexpp": {
462 | "version": "4.6.2",
463 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz",
464 | "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==",
465 | "dev": true,
466 | "engines": {
467 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
468 | }
469 | },
470 | "node_modules/@eslint/eslintrc": {
471 | "version": "2.1.0",
472 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
473 | "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
474 | "dev": true,
475 | "dependencies": {
476 | "ajv": "^6.12.4",
477 | "debug": "^4.3.2",
478 | "espree": "^9.6.0",
479 | "globals": "^13.19.0",
480 | "ignore": "^5.2.0",
481 | "import-fresh": "^3.2.1",
482 | "js-yaml": "^4.1.0",
483 | "minimatch": "^3.1.2",
484 | "strip-json-comments": "^3.1.1"
485 | },
486 | "engines": {
487 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
488 | },
489 | "funding": {
490 | "url": "https://opencollective.com/eslint"
491 | }
492 | },
493 | "node_modules/@eslint/js": {
494 | "version": "8.44.0",
495 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
496 | "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
497 | "dev": true,
498 | "engines": {
499 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
500 | }
501 | },
502 | "node_modules/@humanwhocodes/config-array": {
503 | "version": "0.11.10",
504 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
505 | "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
506 | "dev": true,
507 | "dependencies": {
508 | "@humanwhocodes/object-schema": "^1.2.1",
509 | "debug": "^4.1.1",
510 | "minimatch": "^3.0.5"
511 | },
512 | "engines": {
513 | "node": ">=10.10.0"
514 | }
515 | },
516 | "node_modules/@humanwhocodes/module-importer": {
517 | "version": "1.0.1",
518 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
519 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
520 | "dev": true,
521 | "engines": {
522 | "node": ">=12.22"
523 | },
524 | "funding": {
525 | "type": "github",
526 | "url": "https://github.com/sponsors/nzakas"
527 | }
528 | },
529 | "node_modules/@humanwhocodes/object-schema": {
530 | "version": "1.2.1",
531 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
532 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
533 | "dev": true
534 | },
535 | "node_modules/@nodelib/fs.scandir": {
536 | "version": "2.1.5",
537 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
538 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
539 | "dev": true,
540 | "dependencies": {
541 | "@nodelib/fs.stat": "2.0.5",
542 | "run-parallel": "^1.1.9"
543 | },
544 | "engines": {
545 | "node": ">= 8"
546 | }
547 | },
548 | "node_modules/@nodelib/fs.stat": {
549 | "version": "2.0.5",
550 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
551 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
552 | "dev": true,
553 | "engines": {
554 | "node": ">= 8"
555 | }
556 | },
557 | "node_modules/@nodelib/fs.walk": {
558 | "version": "1.2.8",
559 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
560 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
561 | "dev": true,
562 | "dependencies": {
563 | "@nodelib/fs.scandir": "2.1.5",
564 | "fastq": "^1.6.0"
565 | },
566 | "engines": {
567 | "node": ">= 8"
568 | }
569 | },
570 | "node_modules/@remix-run/router": {
571 | "version": "1.7.2",
572 | "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz",
573 | "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==",
574 | "engines": {
575 | "node": ">=14"
576 | }
577 | },
578 | "node_modules/@supabase/functions-js": {
579 | "version": "2.1.2",
580 | "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.1.2.tgz",
581 | "integrity": "sha512-QCR6pwJs9exCl37bmpMisUd6mf+0SUBJ6mUpiAjEkSJ/+xW8TCuO14bvkWHADd5hElJK9MxNlMQXxSA4DRz9nQ==",
582 | "dependencies": {
583 | "cross-fetch": "^3.1.5"
584 | }
585 | },
586 | "node_modules/@supabase/gotrue-js": {
587 | "version": "2.46.1",
588 | "resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-2.46.1.tgz",
589 | "integrity": "sha512-tebFX3XvPqEJKHOVgkXTN20g9iUhLx6tebIYQvTggYTrqOT2af8oTpSBdgYzbwJ291G6P6CSpR6KY0cT9ade5A==",
590 | "dependencies": {
591 | "cross-fetch": "^3.1.5"
592 | }
593 | },
594 | "node_modules/@supabase/postgrest-js": {
595 | "version": "1.7.2",
596 | "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.7.2.tgz",
597 | "integrity": "sha512-GK80JpRq8l6Qll85erICypAfQCied8tdlXfsDN14W844HqXCSOisk8AaE01DAwGJanieaoN5fuqhzA2yKxDvEQ==",
598 | "dependencies": {
599 | "cross-fetch": "^3.1.5"
600 | }
601 | },
602 | "node_modules/@supabase/realtime-js": {
603 | "version": "2.7.3",
604 | "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.7.3.tgz",
605 | "integrity": "sha512-c7TzL81sx2kqyxsxcDduJcHL9KJdCOoKimGP6lQSqiZKX42ATlBZpWbyy9KFGFBjAP4nyopMf5JhPi2ZH9jyNw==",
606 | "dependencies": {
607 | "@types/phoenix": "^1.5.4",
608 | "@types/websocket": "^1.0.3",
609 | "websocket": "^1.0.34"
610 | }
611 | },
612 | "node_modules/@supabase/storage-js": {
613 | "version": "2.5.1",
614 | "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.1.tgz",
615 | "integrity": "sha512-nkR0fQA9ScAtIKA3vNoPEqbZv1k5B5HVRYEvRWdlP6mUpFphM9TwPL2jZ/ztNGMTG5xT6SrHr+H7Ykz8qzbhjw==",
616 | "dependencies": {
617 | "cross-fetch": "^3.1.5"
618 | }
619 | },
620 | "node_modules/@supabase/supabase-js": {
621 | "version": "2.31.0",
622 | "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.31.0.tgz",
623 | "integrity": "sha512-W9/4s+KnSUX67wJKBn/3yLq+ieycnMzVjK3nNTLX5Wko3ypNT/081l2iFYrf+nsLQ1CiT4mA92I3dxCy6CmxTg==",
624 | "dependencies": {
625 | "@supabase/functions-js": "^2.1.0",
626 | "@supabase/gotrue-js": "^2.46.1",
627 | "@supabase/postgrest-js": "^1.7.0",
628 | "@supabase/realtime-js": "^2.7.3",
629 | "@supabase/storage-js": "^2.5.1",
630 | "cross-fetch": "^3.1.5"
631 | }
632 | },
633 | "node_modules/@swc/core": {
634 | "version": "1.3.71",
635 | "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.71.tgz",
636 | "integrity": "sha512-T8dqj+SV/S8laW/FGmKHhCGw1o4GRUvJ2jHfbYgEwiJpeutT9uavHvG02t39HJvObBJ52EZs/krGtni4U5928Q==",
637 | "dev": true,
638 | "hasInstallScript": true,
639 | "engines": {
640 | "node": ">=10"
641 | },
642 | "funding": {
643 | "type": "opencollective",
644 | "url": "https://opencollective.com/swc"
645 | },
646 | "optionalDependencies": {
647 | "@swc/core-darwin-arm64": "1.3.71",
648 | "@swc/core-darwin-x64": "1.3.71",
649 | "@swc/core-linux-arm-gnueabihf": "1.3.71",
650 | "@swc/core-linux-arm64-gnu": "1.3.71",
651 | "@swc/core-linux-arm64-musl": "1.3.71",
652 | "@swc/core-linux-x64-gnu": "1.3.71",
653 | "@swc/core-linux-x64-musl": "1.3.71",
654 | "@swc/core-win32-arm64-msvc": "1.3.71",
655 | "@swc/core-win32-ia32-msvc": "1.3.71",
656 | "@swc/core-win32-x64-msvc": "1.3.71"
657 | },
658 | "peerDependencies": {
659 | "@swc/helpers": "^0.5.0"
660 | },
661 | "peerDependenciesMeta": {
662 | "@swc/helpers": {
663 | "optional": true
664 | }
665 | }
666 | },
667 | "node_modules/@swc/core-darwin-arm64": {
668 | "version": "1.3.71",
669 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.71.tgz",
670 | "integrity": "sha512-xOm0hDbcO2ShwQu1CjLtq3fwrG9AvhuE0s8vtBc8AsamYExHmR8bo6GQHJUtfPG1FVPk5a8xoQSd1fs09FQjLg==",
671 | "cpu": [
672 | "arm64"
673 | ],
674 | "dev": true,
675 | "optional": true,
676 | "os": [
677 | "darwin"
678 | ],
679 | "engines": {
680 | "node": ">=10"
681 | }
682 | },
683 | "node_modules/@swc/core-darwin-x64": {
684 | "version": "1.3.71",
685 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.71.tgz",
686 | "integrity": "sha512-9sbDXBWgM22w/3Ll5kPhXMPkOiHRoqwMOyxLJBfGtIMnFlh5O+NRN3umRerK3pe4Q6/7hj2M5V+crEHYrXmuxg==",
687 | "cpu": [
688 | "x64"
689 | ],
690 | "dev": true,
691 | "optional": true,
692 | "os": [
693 | "darwin"
694 | ],
695 | "engines": {
696 | "node": ">=10"
697 | }
698 | },
699 | "node_modules/@swc/core-linux-arm-gnueabihf": {
700 | "version": "1.3.71",
701 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.71.tgz",
702 | "integrity": "sha512-boKdMZsfKvhBs0FDeqH7KQj0lfYe0wCtrL1lv50oYMEeLajY9o4U5xSmc61Sg4HRXjlbR6dlM2cFfL84t7NpAA==",
703 | "cpu": [
704 | "arm"
705 | ],
706 | "dev": true,
707 | "optional": true,
708 | "os": [
709 | "linux"
710 | ],
711 | "engines": {
712 | "node": ">=10"
713 | }
714 | },
715 | "node_modules/@swc/core-linux-arm64-gnu": {
716 | "version": "1.3.71",
717 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.71.tgz",
718 | "integrity": "sha512-yDatyHYMiOVwhyIA/LBwknPs2CUtLYWEMzPZjgLc+56PbgPs3oiEbNWeVUND5onPrfDQgK7NK1y8JeiXZqTgGQ==",
719 | "cpu": [
720 | "arm64"
721 | ],
722 | "dev": true,
723 | "optional": true,
724 | "os": [
725 | "linux"
726 | ],
727 | "engines": {
728 | "node": ">=10"
729 | }
730 | },
731 | "node_modules/@swc/core-linux-arm64-musl": {
732 | "version": "1.3.71",
733 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.71.tgz",
734 | "integrity": "sha512-xAdCA0L/hoa0ULL5SR4sMZCxkWk7C90DOU7wJalNVG9qNWYICfq3G7AR0E9Ohphzqyahfb5QJED/nA7N0+XwbQ==",
735 | "cpu": [
736 | "arm64"
737 | ],
738 | "dev": true,
739 | "optional": true,
740 | "os": [
741 | "linux"
742 | ],
743 | "engines": {
744 | "node": ">=10"
745 | }
746 | },
747 | "node_modules/@swc/core-linux-x64-gnu": {
748 | "version": "1.3.71",
749 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.71.tgz",
750 | "integrity": "sha512-j94qLXP/yqhu2afnABAq/xrJIU8TEqcNkp1TlsAeO3R2nVLYL1w4XX8GW71SPnXmd2bwF102c3Cfv/2ilf2y2A==",
751 | "cpu": [
752 | "x64"
753 | ],
754 | "dev": true,
755 | "optional": true,
756 | "os": [
757 | "linux"
758 | ],
759 | "engines": {
760 | "node": ">=10"
761 | }
762 | },
763 | "node_modules/@swc/core-linux-x64-musl": {
764 | "version": "1.3.71",
765 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.71.tgz",
766 | "integrity": "sha512-YiyU848ql6dLlmt0BHccGAaZ36Cf61VzCAMDKID/gd72snvzWcMCHrwSRW0gEFNXHsjBJrmNl+SLYZHfqoGwUA==",
767 | "cpu": [
768 | "x64"
769 | ],
770 | "dev": true,
771 | "optional": true,
772 | "os": [
773 | "linux"
774 | ],
775 | "engines": {
776 | "node": ">=10"
777 | }
778 | },
779 | "node_modules/@swc/core-win32-arm64-msvc": {
780 | "version": "1.3.71",
781 | "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.71.tgz",
782 | "integrity": "sha512-1UsJ+6hnIRe/PVdgDPexvgGaN4KpBncT/bAOqlWc9XC7KeBXAWcGA08LrPUz2Ei00DJXzR622IGZVEYOHNkUOw==",
783 | "cpu": [
784 | "arm64"
785 | ],
786 | "dev": true,
787 | "optional": true,
788 | "os": [
789 | "win32"
790 | ],
791 | "engines": {
792 | "node": ">=10"
793 | }
794 | },
795 | "node_modules/@swc/core-win32-ia32-msvc": {
796 | "version": "1.3.71",
797 | "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.71.tgz",
798 | "integrity": "sha512-KnuI89+zojR9lDFELdQYZpxzPZ6pBfLwJfWTSGatnpL1ZHhIsV3tK1jwqIdJK1zkRxpBwc6p6FzSZdZwCSpnJw==",
799 | "cpu": [
800 | "ia32"
801 | ],
802 | "dev": true,
803 | "optional": true,
804 | "os": [
805 | "win32"
806 | ],
807 | "engines": {
808 | "node": ">=10"
809 | }
810 | },
811 | "node_modules/@swc/core-win32-x64-msvc": {
812 | "version": "1.3.71",
813 | "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.71.tgz",
814 | "integrity": "sha512-Pcw7fFirpaBOZsU8fhO48ZCb7NxIjuLnLRPrHqWQ4Mapx1+w9ZNdGya2DKP9n8EAiUrJO20WDsrBNMT2MQSWkA==",
815 | "cpu": [
816 | "x64"
817 | ],
818 | "dev": true,
819 | "optional": true,
820 | "os": [
821 | "win32"
822 | ],
823 | "engines": {
824 | "node": ">=10"
825 | }
826 | },
827 | "node_modules/@types/json-schema": {
828 | "version": "7.0.12",
829 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
830 | "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
831 | "dev": true
832 | },
833 | "node_modules/@types/node": {
834 | "version": "20.4.5",
835 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
836 | "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg=="
837 | },
838 | "node_modules/@types/phoenix": {
839 | "version": "1.6.0",
840 | "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.0.tgz",
841 | "integrity": "sha512-qwfpsHmFuhAS/dVd4uBIraMxRd56vwBUYQGZ6GpXnFuM2XMRFJbIyruFKKlW2daQliuYZwe0qfn/UjFCDKic5g=="
842 | },
843 | "node_modules/@types/prop-types": {
844 | "version": "15.7.5",
845 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
846 | "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
847 | "dev": true
848 | },
849 | "node_modules/@types/react": {
850 | "version": "18.2.16",
851 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.16.tgz",
852 | "integrity": "sha512-LLFWr12ZhBJ4YVw7neWLe6Pk7Ey5R9OCydfuMsz1L8bZxzaawJj2p06Q8/EFEHDeTBQNFLF62X+CG7B2zIyu0Q==",
853 | "dev": true,
854 | "dependencies": {
855 | "@types/prop-types": "*",
856 | "@types/scheduler": "*",
857 | "csstype": "^3.0.2"
858 | }
859 | },
860 | "node_modules/@types/react-dom": {
861 | "version": "18.2.7",
862 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz",
863 | "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==",
864 | "dev": true,
865 | "dependencies": {
866 | "@types/react": "*"
867 | }
868 | },
869 | "node_modules/@types/scheduler": {
870 | "version": "0.16.3",
871 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
872 | "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
873 | "dev": true
874 | },
875 | "node_modules/@types/semver": {
876 | "version": "7.5.0",
877 | "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
878 | "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
879 | "dev": true
880 | },
881 | "node_modules/@types/websocket": {
882 | "version": "1.0.5",
883 | "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.5.tgz",
884 | "integrity": "sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==",
885 | "dependencies": {
886 | "@types/node": "*"
887 | }
888 | },
889 | "node_modules/@typescript-eslint/eslint-plugin": {
890 | "version": "6.2.0",
891 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz",
892 | "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==",
893 | "dev": true,
894 | "dependencies": {
895 | "@eslint-community/regexpp": "^4.5.1",
896 | "@typescript-eslint/scope-manager": "6.2.0",
897 | "@typescript-eslint/type-utils": "6.2.0",
898 | "@typescript-eslint/utils": "6.2.0",
899 | "@typescript-eslint/visitor-keys": "6.2.0",
900 | "debug": "^4.3.4",
901 | "graphemer": "^1.4.0",
902 | "ignore": "^5.2.4",
903 | "natural-compare": "^1.4.0",
904 | "natural-compare-lite": "^1.4.0",
905 | "semver": "^7.5.4",
906 | "ts-api-utils": "^1.0.1"
907 | },
908 | "engines": {
909 | "node": "^16.0.0 || >=18.0.0"
910 | },
911 | "funding": {
912 | "type": "opencollective",
913 | "url": "https://opencollective.com/typescript-eslint"
914 | },
915 | "peerDependencies": {
916 | "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
917 | "eslint": "^7.0.0 || ^8.0.0"
918 | },
919 | "peerDependenciesMeta": {
920 | "typescript": {
921 | "optional": true
922 | }
923 | }
924 | },
925 | "node_modules/@typescript-eslint/parser": {
926 | "version": "6.2.0",
927 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz",
928 | "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==",
929 | "dev": true,
930 | "dependencies": {
931 | "@typescript-eslint/scope-manager": "6.2.0",
932 | "@typescript-eslint/types": "6.2.0",
933 | "@typescript-eslint/typescript-estree": "6.2.0",
934 | "@typescript-eslint/visitor-keys": "6.2.0",
935 | "debug": "^4.3.4"
936 | },
937 | "engines": {
938 | "node": "^16.0.0 || >=18.0.0"
939 | },
940 | "funding": {
941 | "type": "opencollective",
942 | "url": "https://opencollective.com/typescript-eslint"
943 | },
944 | "peerDependencies": {
945 | "eslint": "^7.0.0 || ^8.0.0"
946 | },
947 | "peerDependenciesMeta": {
948 | "typescript": {
949 | "optional": true
950 | }
951 | }
952 | },
953 | "node_modules/@typescript-eslint/scope-manager": {
954 | "version": "6.2.0",
955 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz",
956 | "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==",
957 | "dev": true,
958 | "dependencies": {
959 | "@typescript-eslint/types": "6.2.0",
960 | "@typescript-eslint/visitor-keys": "6.2.0"
961 | },
962 | "engines": {
963 | "node": "^16.0.0 || >=18.0.0"
964 | },
965 | "funding": {
966 | "type": "opencollective",
967 | "url": "https://opencollective.com/typescript-eslint"
968 | }
969 | },
970 | "node_modules/@typescript-eslint/type-utils": {
971 | "version": "6.2.0",
972 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz",
973 | "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==",
974 | "dev": true,
975 | "dependencies": {
976 | "@typescript-eslint/typescript-estree": "6.2.0",
977 | "@typescript-eslint/utils": "6.2.0",
978 | "debug": "^4.3.4",
979 | "ts-api-utils": "^1.0.1"
980 | },
981 | "engines": {
982 | "node": "^16.0.0 || >=18.0.0"
983 | },
984 | "funding": {
985 | "type": "opencollective",
986 | "url": "https://opencollective.com/typescript-eslint"
987 | },
988 | "peerDependencies": {
989 | "eslint": "^7.0.0 || ^8.0.0"
990 | },
991 | "peerDependenciesMeta": {
992 | "typescript": {
993 | "optional": true
994 | }
995 | }
996 | },
997 | "node_modules/@typescript-eslint/types": {
998 | "version": "6.2.0",
999 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz",
1000 | "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==",
1001 | "dev": true,
1002 | "engines": {
1003 | "node": "^16.0.0 || >=18.0.0"
1004 | },
1005 | "funding": {
1006 | "type": "opencollective",
1007 | "url": "https://opencollective.com/typescript-eslint"
1008 | }
1009 | },
1010 | "node_modules/@typescript-eslint/typescript-estree": {
1011 | "version": "6.2.0",
1012 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz",
1013 | "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==",
1014 | "dev": true,
1015 | "dependencies": {
1016 | "@typescript-eslint/types": "6.2.0",
1017 | "@typescript-eslint/visitor-keys": "6.2.0",
1018 | "debug": "^4.3.4",
1019 | "globby": "^11.1.0",
1020 | "is-glob": "^4.0.3",
1021 | "semver": "^7.5.4",
1022 | "ts-api-utils": "^1.0.1"
1023 | },
1024 | "engines": {
1025 | "node": "^16.0.0 || >=18.0.0"
1026 | },
1027 | "funding": {
1028 | "type": "opencollective",
1029 | "url": "https://opencollective.com/typescript-eslint"
1030 | },
1031 | "peerDependenciesMeta": {
1032 | "typescript": {
1033 | "optional": true
1034 | }
1035 | }
1036 | },
1037 | "node_modules/@typescript-eslint/utils": {
1038 | "version": "6.2.0",
1039 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz",
1040 | "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==",
1041 | "dev": true,
1042 | "dependencies": {
1043 | "@eslint-community/eslint-utils": "^4.4.0",
1044 | "@types/json-schema": "^7.0.12",
1045 | "@types/semver": "^7.5.0",
1046 | "@typescript-eslint/scope-manager": "6.2.0",
1047 | "@typescript-eslint/types": "6.2.0",
1048 | "@typescript-eslint/typescript-estree": "6.2.0",
1049 | "semver": "^7.5.4"
1050 | },
1051 | "engines": {
1052 | "node": "^16.0.0 || >=18.0.0"
1053 | },
1054 | "funding": {
1055 | "type": "opencollective",
1056 | "url": "https://opencollective.com/typescript-eslint"
1057 | },
1058 | "peerDependencies": {
1059 | "eslint": "^7.0.0 || ^8.0.0"
1060 | }
1061 | },
1062 | "node_modules/@typescript-eslint/visitor-keys": {
1063 | "version": "6.2.0",
1064 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz",
1065 | "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==",
1066 | "dev": true,
1067 | "dependencies": {
1068 | "@typescript-eslint/types": "6.2.0",
1069 | "eslint-visitor-keys": "^3.4.1"
1070 | },
1071 | "engines": {
1072 | "node": "^16.0.0 || >=18.0.0"
1073 | },
1074 | "funding": {
1075 | "type": "opencollective",
1076 | "url": "https://opencollective.com/typescript-eslint"
1077 | }
1078 | },
1079 | "node_modules/@vitejs/plugin-react-swc": {
1080 | "version": "3.3.2",
1081 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.3.2.tgz",
1082 | "integrity": "sha512-VJFWY5sfoZerQRvJrh518h3AcQt6f/yTuWn4/TRB+dqmYU0NX1qz7qM5Wfd+gOQqUzQW4gxKqKN3KpE/P3+zrA==",
1083 | "dev": true,
1084 | "dependencies": {
1085 | "@swc/core": "^1.3.61"
1086 | },
1087 | "peerDependencies": {
1088 | "vite": "^4"
1089 | }
1090 | },
1091 | "node_modules/acorn": {
1092 | "version": "8.10.0",
1093 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
1094 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
1095 | "dev": true,
1096 | "bin": {
1097 | "acorn": "bin/acorn"
1098 | },
1099 | "engines": {
1100 | "node": ">=0.4.0"
1101 | }
1102 | },
1103 | "node_modules/acorn-jsx": {
1104 | "version": "5.3.2",
1105 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
1106 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
1107 | "dev": true,
1108 | "peerDependencies": {
1109 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
1110 | }
1111 | },
1112 | "node_modules/ajv": {
1113 | "version": "6.12.6",
1114 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
1115 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
1116 | "dev": true,
1117 | "dependencies": {
1118 | "fast-deep-equal": "^3.1.1",
1119 | "fast-json-stable-stringify": "^2.0.0",
1120 | "json-schema-traverse": "^0.4.1",
1121 | "uri-js": "^4.2.2"
1122 | },
1123 | "funding": {
1124 | "type": "github",
1125 | "url": "https://github.com/sponsors/epoberezkin"
1126 | }
1127 | },
1128 | "node_modules/ansi-regex": {
1129 | "version": "5.0.1",
1130 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1131 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1132 | "dev": true,
1133 | "engines": {
1134 | "node": ">=8"
1135 | }
1136 | },
1137 | "node_modules/ansi-styles": {
1138 | "version": "4.3.0",
1139 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1140 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1141 | "dev": true,
1142 | "dependencies": {
1143 | "color-convert": "^2.0.1"
1144 | },
1145 | "engines": {
1146 | "node": ">=8"
1147 | },
1148 | "funding": {
1149 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1150 | }
1151 | },
1152 | "node_modules/argparse": {
1153 | "version": "2.0.1",
1154 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1155 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1156 | "dev": true
1157 | },
1158 | "node_modules/array-union": {
1159 | "version": "2.1.0",
1160 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
1161 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
1162 | "dev": true,
1163 | "engines": {
1164 | "node": ">=8"
1165 | }
1166 | },
1167 | "node_modules/balanced-match": {
1168 | "version": "1.0.2",
1169 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1170 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1171 | "dev": true
1172 | },
1173 | "node_modules/bin-links": {
1174 | "version": "4.0.2",
1175 | "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz",
1176 | "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==",
1177 | "dev": true,
1178 | "dependencies": {
1179 | "cmd-shim": "^6.0.0",
1180 | "npm-normalize-package-bin": "^3.0.0",
1181 | "read-cmd-shim": "^4.0.0",
1182 | "write-file-atomic": "^5.0.0"
1183 | },
1184 | "engines": {
1185 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
1186 | }
1187 | },
1188 | "node_modules/brace-expansion": {
1189 | "version": "1.1.11",
1190 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1191 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1192 | "dev": true,
1193 | "dependencies": {
1194 | "balanced-match": "^1.0.0",
1195 | "concat-map": "0.0.1"
1196 | }
1197 | },
1198 | "node_modules/braces": {
1199 | "version": "3.0.2",
1200 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
1201 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
1202 | "dev": true,
1203 | "dependencies": {
1204 | "fill-range": "^7.0.1"
1205 | },
1206 | "engines": {
1207 | "node": ">=8"
1208 | }
1209 | },
1210 | "node_modules/bufferutil": {
1211 | "version": "4.0.7",
1212 | "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz",
1213 | "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==",
1214 | "hasInstallScript": true,
1215 | "dependencies": {
1216 | "node-gyp-build": "^4.3.0"
1217 | },
1218 | "engines": {
1219 | "node": ">=6.14.2"
1220 | }
1221 | },
1222 | "node_modules/callsites": {
1223 | "version": "3.1.0",
1224 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
1225 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
1226 | "dev": true,
1227 | "engines": {
1228 | "node": ">=6"
1229 | }
1230 | },
1231 | "node_modules/chalk": {
1232 | "version": "4.1.2",
1233 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1234 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1235 | "dev": true,
1236 | "dependencies": {
1237 | "ansi-styles": "^4.1.0",
1238 | "supports-color": "^7.1.0"
1239 | },
1240 | "engines": {
1241 | "node": ">=10"
1242 | },
1243 | "funding": {
1244 | "url": "https://github.com/chalk/chalk?sponsor=1"
1245 | }
1246 | },
1247 | "node_modules/chownr": {
1248 | "version": "2.0.0",
1249 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
1250 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
1251 | "dev": true,
1252 | "engines": {
1253 | "node": ">=10"
1254 | }
1255 | },
1256 | "node_modules/classnames": {
1257 | "version": "2.3.2",
1258 | "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
1259 | "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
1260 | },
1261 | "node_modules/cmd-shim": {
1262 | "version": "6.0.1",
1263 | "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz",
1264 | "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==",
1265 | "dev": true,
1266 | "engines": {
1267 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
1268 | }
1269 | },
1270 | "node_modules/color-convert": {
1271 | "version": "2.0.1",
1272 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1273 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1274 | "dev": true,
1275 | "dependencies": {
1276 | "color-name": "~1.1.4"
1277 | },
1278 | "engines": {
1279 | "node": ">=7.0.0"
1280 | }
1281 | },
1282 | "node_modules/color-name": {
1283 | "version": "1.1.4",
1284 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1285 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1286 | "dev": true
1287 | },
1288 | "node_modules/concat-map": {
1289 | "version": "0.0.1",
1290 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1291 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
1292 | "dev": true
1293 | },
1294 | "node_modules/cross-fetch": {
1295 | "version": "3.1.8",
1296 | "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
1297 | "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
1298 | "dependencies": {
1299 | "node-fetch": "^2.6.12"
1300 | }
1301 | },
1302 | "node_modules/cross-spawn": {
1303 | "version": "7.0.3",
1304 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
1305 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
1306 | "dev": true,
1307 | "dependencies": {
1308 | "path-key": "^3.1.0",
1309 | "shebang-command": "^2.0.0",
1310 | "which": "^2.0.1"
1311 | },
1312 | "engines": {
1313 | "node": ">= 8"
1314 | }
1315 | },
1316 | "node_modules/csstype": {
1317 | "version": "3.1.2",
1318 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
1319 | "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
1320 | "dev": true
1321 | },
1322 | "node_modules/d": {
1323 | "version": "1.0.1",
1324 | "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
1325 | "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
1326 | "dependencies": {
1327 | "es5-ext": "^0.10.50",
1328 | "type": "^1.0.1"
1329 | }
1330 | },
1331 | "node_modules/data-uri-to-buffer": {
1332 | "version": "4.0.1",
1333 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
1334 | "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
1335 | "dev": true,
1336 | "engines": {
1337 | "node": ">= 12"
1338 | }
1339 | },
1340 | "node_modules/debug": {
1341 | "version": "4.3.4",
1342 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1343 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1344 | "dev": true,
1345 | "dependencies": {
1346 | "ms": "2.1.2"
1347 | },
1348 | "engines": {
1349 | "node": ">=6.0"
1350 | },
1351 | "peerDependenciesMeta": {
1352 | "supports-color": {
1353 | "optional": true
1354 | }
1355 | }
1356 | },
1357 | "node_modules/deep-is": {
1358 | "version": "0.1.4",
1359 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
1360 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
1361 | "dev": true
1362 | },
1363 | "node_modules/dir-glob": {
1364 | "version": "3.0.1",
1365 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
1366 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
1367 | "dev": true,
1368 | "dependencies": {
1369 | "path-type": "^4.0.0"
1370 | },
1371 | "engines": {
1372 | "node": ">=8"
1373 | }
1374 | },
1375 | "node_modules/doctrine": {
1376 | "version": "3.0.0",
1377 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
1378 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
1379 | "dev": true,
1380 | "dependencies": {
1381 | "esutils": "^2.0.2"
1382 | },
1383 | "engines": {
1384 | "node": ">=6.0.0"
1385 | }
1386 | },
1387 | "node_modules/es5-ext": {
1388 | "version": "0.10.62",
1389 | "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
1390 | "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
1391 | "hasInstallScript": true,
1392 | "dependencies": {
1393 | "es6-iterator": "^2.0.3",
1394 | "es6-symbol": "^3.1.3",
1395 | "next-tick": "^1.1.0"
1396 | },
1397 | "engines": {
1398 | "node": ">=0.10"
1399 | }
1400 | },
1401 | "node_modules/es6-iterator": {
1402 | "version": "2.0.3",
1403 | "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
1404 | "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
1405 | "dependencies": {
1406 | "d": "1",
1407 | "es5-ext": "^0.10.35",
1408 | "es6-symbol": "^3.1.1"
1409 | }
1410 | },
1411 | "node_modules/es6-symbol": {
1412 | "version": "3.1.3",
1413 | "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
1414 | "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
1415 | "dependencies": {
1416 | "d": "^1.0.1",
1417 | "ext": "^1.1.2"
1418 | }
1419 | },
1420 | "node_modules/esbuild": {
1421 | "version": "0.18.17",
1422 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz",
1423 | "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==",
1424 | "dev": true,
1425 | "hasInstallScript": true,
1426 | "bin": {
1427 | "esbuild": "bin/esbuild"
1428 | },
1429 | "engines": {
1430 | "node": ">=12"
1431 | },
1432 | "optionalDependencies": {
1433 | "@esbuild/android-arm": "0.18.17",
1434 | "@esbuild/android-arm64": "0.18.17",
1435 | "@esbuild/android-x64": "0.18.17",
1436 | "@esbuild/darwin-arm64": "0.18.17",
1437 | "@esbuild/darwin-x64": "0.18.17",
1438 | "@esbuild/freebsd-arm64": "0.18.17",
1439 | "@esbuild/freebsd-x64": "0.18.17",
1440 | "@esbuild/linux-arm": "0.18.17",
1441 | "@esbuild/linux-arm64": "0.18.17",
1442 | "@esbuild/linux-ia32": "0.18.17",
1443 | "@esbuild/linux-loong64": "0.18.17",
1444 | "@esbuild/linux-mips64el": "0.18.17",
1445 | "@esbuild/linux-ppc64": "0.18.17",
1446 | "@esbuild/linux-riscv64": "0.18.17",
1447 | "@esbuild/linux-s390x": "0.18.17",
1448 | "@esbuild/linux-x64": "0.18.17",
1449 | "@esbuild/netbsd-x64": "0.18.17",
1450 | "@esbuild/openbsd-x64": "0.18.17",
1451 | "@esbuild/sunos-x64": "0.18.17",
1452 | "@esbuild/win32-arm64": "0.18.17",
1453 | "@esbuild/win32-ia32": "0.18.17",
1454 | "@esbuild/win32-x64": "0.18.17"
1455 | }
1456 | },
1457 | "node_modules/escape-string-regexp": {
1458 | "version": "4.0.0",
1459 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
1460 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
1461 | "dev": true,
1462 | "engines": {
1463 | "node": ">=10"
1464 | },
1465 | "funding": {
1466 | "url": "https://github.com/sponsors/sindresorhus"
1467 | }
1468 | },
1469 | "node_modules/eslint": {
1470 | "version": "8.45.0",
1471 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz",
1472 | "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==",
1473 | "dev": true,
1474 | "dependencies": {
1475 | "@eslint-community/eslint-utils": "^4.2.0",
1476 | "@eslint-community/regexpp": "^4.4.0",
1477 | "@eslint/eslintrc": "^2.1.0",
1478 | "@eslint/js": "8.44.0",
1479 | "@humanwhocodes/config-array": "^0.11.10",
1480 | "@humanwhocodes/module-importer": "^1.0.1",
1481 | "@nodelib/fs.walk": "^1.2.8",
1482 | "ajv": "^6.10.0",
1483 | "chalk": "^4.0.0",
1484 | "cross-spawn": "^7.0.2",
1485 | "debug": "^4.3.2",
1486 | "doctrine": "^3.0.0",
1487 | "escape-string-regexp": "^4.0.0",
1488 | "eslint-scope": "^7.2.0",
1489 | "eslint-visitor-keys": "^3.4.1",
1490 | "espree": "^9.6.0",
1491 | "esquery": "^1.4.2",
1492 | "esutils": "^2.0.2",
1493 | "fast-deep-equal": "^3.1.3",
1494 | "file-entry-cache": "^6.0.1",
1495 | "find-up": "^5.0.0",
1496 | "glob-parent": "^6.0.2",
1497 | "globals": "^13.19.0",
1498 | "graphemer": "^1.4.0",
1499 | "ignore": "^5.2.0",
1500 | "imurmurhash": "^0.1.4",
1501 | "is-glob": "^4.0.0",
1502 | "is-path-inside": "^3.0.3",
1503 | "js-yaml": "^4.1.0",
1504 | "json-stable-stringify-without-jsonify": "^1.0.1",
1505 | "levn": "^0.4.1",
1506 | "lodash.merge": "^4.6.2",
1507 | "minimatch": "^3.1.2",
1508 | "natural-compare": "^1.4.0",
1509 | "optionator": "^0.9.3",
1510 | "strip-ansi": "^6.0.1",
1511 | "text-table": "^0.2.0"
1512 | },
1513 | "bin": {
1514 | "eslint": "bin/eslint.js"
1515 | },
1516 | "engines": {
1517 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1518 | },
1519 | "funding": {
1520 | "url": "https://opencollective.com/eslint"
1521 | }
1522 | },
1523 | "node_modules/eslint-plugin-immer": {
1524 | "version": "0.0.1",
1525 | "resolved": "https://registry.npmjs.org/eslint-plugin-immer/-/eslint-plugin-immer-0.0.1.tgz",
1526 | "integrity": "sha512-Pb8D9lP4q1fhwefUSElwC1YHvJUWjcz+7saj7n/QPtpPOCwtsEyMK+ypFrLkq99BGGkjAWVJ4xOWEu82JSwKPA==",
1527 | "dependencies": {
1528 | "requireindex": "~1.1.0"
1529 | },
1530 | "engines": {
1531 | "node": ">=0.10.0"
1532 | }
1533 | },
1534 | "node_modules/eslint-plugin-react-hooks": {
1535 | "version": "4.6.0",
1536 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
1537 | "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
1538 | "dev": true,
1539 | "engines": {
1540 | "node": ">=10"
1541 | },
1542 | "peerDependencies": {
1543 | "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
1544 | }
1545 | },
1546 | "node_modules/eslint-plugin-react-refresh": {
1547 | "version": "0.4.3",
1548 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz",
1549 | "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==",
1550 | "dev": true,
1551 | "peerDependencies": {
1552 | "eslint": ">=7"
1553 | }
1554 | },
1555 | "node_modules/eslint-scope": {
1556 | "version": "7.2.1",
1557 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz",
1558 | "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==",
1559 | "dev": true,
1560 | "dependencies": {
1561 | "esrecurse": "^4.3.0",
1562 | "estraverse": "^5.2.0"
1563 | },
1564 | "engines": {
1565 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1566 | },
1567 | "funding": {
1568 | "url": "https://opencollective.com/eslint"
1569 | }
1570 | },
1571 | "node_modules/eslint-visitor-keys": {
1572 | "version": "3.4.1",
1573 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
1574 | "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
1575 | "dev": true,
1576 | "engines": {
1577 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1578 | },
1579 | "funding": {
1580 | "url": "https://opencollective.com/eslint"
1581 | }
1582 | },
1583 | "node_modules/espree": {
1584 | "version": "9.6.1",
1585 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
1586 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
1587 | "dev": true,
1588 | "dependencies": {
1589 | "acorn": "^8.9.0",
1590 | "acorn-jsx": "^5.3.2",
1591 | "eslint-visitor-keys": "^3.4.1"
1592 | },
1593 | "engines": {
1594 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1595 | },
1596 | "funding": {
1597 | "url": "https://opencollective.com/eslint"
1598 | }
1599 | },
1600 | "node_modules/esquery": {
1601 | "version": "1.5.0",
1602 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
1603 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
1604 | "dev": true,
1605 | "dependencies": {
1606 | "estraverse": "^5.1.0"
1607 | },
1608 | "engines": {
1609 | "node": ">=0.10"
1610 | }
1611 | },
1612 | "node_modules/esrecurse": {
1613 | "version": "4.3.0",
1614 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
1615 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
1616 | "dev": true,
1617 | "dependencies": {
1618 | "estraverse": "^5.2.0"
1619 | },
1620 | "engines": {
1621 | "node": ">=4.0"
1622 | }
1623 | },
1624 | "node_modules/estraverse": {
1625 | "version": "5.3.0",
1626 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
1627 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
1628 | "dev": true,
1629 | "engines": {
1630 | "node": ">=4.0"
1631 | }
1632 | },
1633 | "node_modules/esutils": {
1634 | "version": "2.0.3",
1635 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
1636 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
1637 | "dev": true,
1638 | "engines": {
1639 | "node": ">=0.10.0"
1640 | }
1641 | },
1642 | "node_modules/ext": {
1643 | "version": "1.7.0",
1644 | "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
1645 | "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
1646 | "dependencies": {
1647 | "type": "^2.7.2"
1648 | }
1649 | },
1650 | "node_modules/ext/node_modules/type": {
1651 | "version": "2.7.2",
1652 | "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
1653 | "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
1654 | },
1655 | "node_modules/fast-deep-equal": {
1656 | "version": "3.1.3",
1657 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
1658 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
1659 | "dev": true
1660 | },
1661 | "node_modules/fast-glob": {
1662 | "version": "3.3.1",
1663 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
1664 | "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
1665 | "dev": true,
1666 | "dependencies": {
1667 | "@nodelib/fs.stat": "^2.0.2",
1668 | "@nodelib/fs.walk": "^1.2.3",
1669 | "glob-parent": "^5.1.2",
1670 | "merge2": "^1.3.0",
1671 | "micromatch": "^4.0.4"
1672 | },
1673 | "engines": {
1674 | "node": ">=8.6.0"
1675 | }
1676 | },
1677 | "node_modules/fast-glob/node_modules/glob-parent": {
1678 | "version": "5.1.2",
1679 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1680 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1681 | "dev": true,
1682 | "dependencies": {
1683 | "is-glob": "^4.0.1"
1684 | },
1685 | "engines": {
1686 | "node": ">= 6"
1687 | }
1688 | },
1689 | "node_modules/fast-json-stable-stringify": {
1690 | "version": "2.1.0",
1691 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
1692 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
1693 | "dev": true
1694 | },
1695 | "node_modules/fast-levenshtein": {
1696 | "version": "2.0.6",
1697 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
1698 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
1699 | "dev": true
1700 | },
1701 | "node_modules/fastq": {
1702 | "version": "1.15.0",
1703 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
1704 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
1705 | "dev": true,
1706 | "dependencies": {
1707 | "reusify": "^1.0.4"
1708 | }
1709 | },
1710 | "node_modules/fetch-blob": {
1711 | "version": "3.2.0",
1712 | "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
1713 | "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
1714 | "dev": true,
1715 | "funding": [
1716 | {
1717 | "type": "github",
1718 | "url": "https://github.com/sponsors/jimmywarting"
1719 | },
1720 | {
1721 | "type": "paypal",
1722 | "url": "https://paypal.me/jimmywarting"
1723 | }
1724 | ],
1725 | "dependencies": {
1726 | "node-domexception": "^1.0.0",
1727 | "web-streams-polyfill": "^3.0.3"
1728 | },
1729 | "engines": {
1730 | "node": "^12.20 || >= 14.13"
1731 | }
1732 | },
1733 | "node_modules/file-entry-cache": {
1734 | "version": "6.0.1",
1735 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
1736 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
1737 | "dev": true,
1738 | "dependencies": {
1739 | "flat-cache": "^3.0.4"
1740 | },
1741 | "engines": {
1742 | "node": "^10.12.0 || >=12.0.0"
1743 | }
1744 | },
1745 | "node_modules/fill-range": {
1746 | "version": "7.0.1",
1747 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1748 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1749 | "dev": true,
1750 | "dependencies": {
1751 | "to-regex-range": "^5.0.1"
1752 | },
1753 | "engines": {
1754 | "node": ">=8"
1755 | }
1756 | },
1757 | "node_modules/find-up": {
1758 | "version": "5.0.0",
1759 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
1760 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
1761 | "dev": true,
1762 | "dependencies": {
1763 | "locate-path": "^6.0.0",
1764 | "path-exists": "^4.0.0"
1765 | },
1766 | "engines": {
1767 | "node": ">=10"
1768 | },
1769 | "funding": {
1770 | "url": "https://github.com/sponsors/sindresorhus"
1771 | }
1772 | },
1773 | "node_modules/flat-cache": {
1774 | "version": "3.0.4",
1775 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
1776 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
1777 | "dev": true,
1778 | "dependencies": {
1779 | "flatted": "^3.1.0",
1780 | "rimraf": "^3.0.2"
1781 | },
1782 | "engines": {
1783 | "node": "^10.12.0 || >=12.0.0"
1784 | }
1785 | },
1786 | "node_modules/flatted": {
1787 | "version": "3.2.7",
1788 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
1789 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
1790 | "dev": true
1791 | },
1792 | "node_modules/formdata-polyfill": {
1793 | "version": "4.0.10",
1794 | "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
1795 | "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
1796 | "dev": true,
1797 | "dependencies": {
1798 | "fetch-blob": "^3.1.2"
1799 | },
1800 | "engines": {
1801 | "node": ">=12.20.0"
1802 | }
1803 | },
1804 | "node_modules/fs-minipass": {
1805 | "version": "2.1.0",
1806 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
1807 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
1808 | "dev": true,
1809 | "dependencies": {
1810 | "minipass": "^3.0.0"
1811 | },
1812 | "engines": {
1813 | "node": ">= 8"
1814 | }
1815 | },
1816 | "node_modules/fs-minipass/node_modules/minipass": {
1817 | "version": "3.3.6",
1818 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
1819 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
1820 | "dev": true,
1821 | "dependencies": {
1822 | "yallist": "^4.0.0"
1823 | },
1824 | "engines": {
1825 | "node": ">=8"
1826 | }
1827 | },
1828 | "node_modules/fs.realpath": {
1829 | "version": "1.0.0",
1830 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1831 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
1832 | "dev": true
1833 | },
1834 | "node_modules/fsevents": {
1835 | "version": "2.3.2",
1836 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
1837 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1838 | "dev": true,
1839 | "hasInstallScript": true,
1840 | "optional": true,
1841 | "os": [
1842 | "darwin"
1843 | ],
1844 | "engines": {
1845 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1846 | }
1847 | },
1848 | "node_modules/glob": {
1849 | "version": "7.2.3",
1850 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
1851 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
1852 | "dev": true,
1853 | "dependencies": {
1854 | "fs.realpath": "^1.0.0",
1855 | "inflight": "^1.0.4",
1856 | "inherits": "2",
1857 | "minimatch": "^3.1.1",
1858 | "once": "^1.3.0",
1859 | "path-is-absolute": "^1.0.0"
1860 | },
1861 | "engines": {
1862 | "node": "*"
1863 | },
1864 | "funding": {
1865 | "url": "https://github.com/sponsors/isaacs"
1866 | }
1867 | },
1868 | "node_modules/glob-parent": {
1869 | "version": "6.0.2",
1870 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
1871 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
1872 | "dev": true,
1873 | "dependencies": {
1874 | "is-glob": "^4.0.3"
1875 | },
1876 | "engines": {
1877 | "node": ">=10.13.0"
1878 | }
1879 | },
1880 | "node_modules/globals": {
1881 | "version": "13.20.0",
1882 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
1883 | "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
1884 | "dev": true,
1885 | "dependencies": {
1886 | "type-fest": "^0.20.2"
1887 | },
1888 | "engines": {
1889 | "node": ">=8"
1890 | },
1891 | "funding": {
1892 | "url": "https://github.com/sponsors/sindresorhus"
1893 | }
1894 | },
1895 | "node_modules/globby": {
1896 | "version": "11.1.0",
1897 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
1898 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
1899 | "dev": true,
1900 | "dependencies": {
1901 | "array-union": "^2.1.0",
1902 | "dir-glob": "^3.0.1",
1903 | "fast-glob": "^3.2.9",
1904 | "ignore": "^5.2.0",
1905 | "merge2": "^1.4.1",
1906 | "slash": "^3.0.0"
1907 | },
1908 | "engines": {
1909 | "node": ">=10"
1910 | },
1911 | "funding": {
1912 | "url": "https://github.com/sponsors/sindresorhus"
1913 | }
1914 | },
1915 | "node_modules/graphemer": {
1916 | "version": "1.4.0",
1917 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
1918 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
1919 | "dev": true
1920 | },
1921 | "node_modules/has-flag": {
1922 | "version": "4.0.0",
1923 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1924 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1925 | "dev": true,
1926 | "engines": {
1927 | "node": ">=8"
1928 | }
1929 | },
1930 | "node_modules/ignore": {
1931 | "version": "5.2.4",
1932 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
1933 | "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
1934 | "dev": true,
1935 | "engines": {
1936 | "node": ">= 4"
1937 | }
1938 | },
1939 | "node_modules/immer": {
1940 | "version": "10.0.2",
1941 | "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz",
1942 | "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==",
1943 | "peer": true,
1944 | "funding": {
1945 | "type": "opencollective",
1946 | "url": "https://opencollective.com/immer"
1947 | }
1948 | },
1949 | "node_modules/import-fresh": {
1950 | "version": "3.3.0",
1951 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
1952 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
1953 | "dev": true,
1954 | "dependencies": {
1955 | "parent-module": "^1.0.0",
1956 | "resolve-from": "^4.0.0"
1957 | },
1958 | "engines": {
1959 | "node": ">=6"
1960 | },
1961 | "funding": {
1962 | "url": "https://github.com/sponsors/sindresorhus"
1963 | }
1964 | },
1965 | "node_modules/imurmurhash": {
1966 | "version": "0.1.4",
1967 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
1968 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
1969 | "dev": true,
1970 | "engines": {
1971 | "node": ">=0.8.19"
1972 | }
1973 | },
1974 | "node_modules/inflight": {
1975 | "version": "1.0.6",
1976 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1977 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
1978 | "dev": true,
1979 | "dependencies": {
1980 | "once": "^1.3.0",
1981 | "wrappy": "1"
1982 | }
1983 | },
1984 | "node_modules/inherits": {
1985 | "version": "2.0.4",
1986 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1987 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1988 | "dev": true
1989 | },
1990 | "node_modules/is-extglob": {
1991 | "version": "2.1.1",
1992 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1993 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1994 | "dev": true,
1995 | "engines": {
1996 | "node": ">=0.10.0"
1997 | }
1998 | },
1999 | "node_modules/is-glob": {
2000 | "version": "4.0.3",
2001 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
2002 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
2003 | "dev": true,
2004 | "dependencies": {
2005 | "is-extglob": "^2.1.1"
2006 | },
2007 | "engines": {
2008 | "node": ">=0.10.0"
2009 | }
2010 | },
2011 | "node_modules/is-number": {
2012 | "version": "7.0.0",
2013 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
2014 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
2015 | "dev": true,
2016 | "engines": {
2017 | "node": ">=0.12.0"
2018 | }
2019 | },
2020 | "node_modules/is-path-inside": {
2021 | "version": "3.0.3",
2022 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
2023 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
2024 | "dev": true,
2025 | "engines": {
2026 | "node": ">=8"
2027 | }
2028 | },
2029 | "node_modules/is-typedarray": {
2030 | "version": "1.0.0",
2031 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
2032 | "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
2033 | },
2034 | "node_modules/isexe": {
2035 | "version": "2.0.0",
2036 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2037 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
2038 | "dev": true
2039 | },
2040 | "node_modules/js-tokens": {
2041 | "version": "4.0.0",
2042 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
2043 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
2044 | },
2045 | "node_modules/js-yaml": {
2046 | "version": "4.1.0",
2047 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
2048 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
2049 | "dev": true,
2050 | "dependencies": {
2051 | "argparse": "^2.0.1"
2052 | },
2053 | "bin": {
2054 | "js-yaml": "bin/js-yaml.js"
2055 | }
2056 | },
2057 | "node_modules/json-schema-traverse": {
2058 | "version": "0.4.1",
2059 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
2060 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
2061 | "dev": true
2062 | },
2063 | "node_modules/json-stable-stringify-without-jsonify": {
2064 | "version": "1.0.1",
2065 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
2066 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
2067 | "dev": true
2068 | },
2069 | "node_modules/levn": {
2070 | "version": "0.4.1",
2071 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
2072 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
2073 | "dev": true,
2074 | "dependencies": {
2075 | "prelude-ls": "^1.2.1",
2076 | "type-check": "~0.4.0"
2077 | },
2078 | "engines": {
2079 | "node": ">= 0.8.0"
2080 | }
2081 | },
2082 | "node_modules/locate-path": {
2083 | "version": "6.0.0",
2084 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
2085 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
2086 | "dev": true,
2087 | "dependencies": {
2088 | "p-locate": "^5.0.0"
2089 | },
2090 | "engines": {
2091 | "node": ">=10"
2092 | },
2093 | "funding": {
2094 | "url": "https://github.com/sponsors/sindresorhus"
2095 | }
2096 | },
2097 | "node_modules/lodash.merge": {
2098 | "version": "4.6.2",
2099 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
2100 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
2101 | "dev": true
2102 | },
2103 | "node_modules/loose-envify": {
2104 | "version": "1.4.0",
2105 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
2106 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
2107 | "dependencies": {
2108 | "js-tokens": "^3.0.0 || ^4.0.0"
2109 | },
2110 | "bin": {
2111 | "loose-envify": "cli.js"
2112 | }
2113 | },
2114 | "node_modules/lru-cache": {
2115 | "version": "6.0.0",
2116 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
2117 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
2118 | "dev": true,
2119 | "dependencies": {
2120 | "yallist": "^4.0.0"
2121 | },
2122 | "engines": {
2123 | "node": ">=10"
2124 | }
2125 | },
2126 | "node_modules/merge2": {
2127 | "version": "1.4.1",
2128 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
2129 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
2130 | "dev": true,
2131 | "engines": {
2132 | "node": ">= 8"
2133 | }
2134 | },
2135 | "node_modules/micromatch": {
2136 | "version": "4.0.5",
2137 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
2138 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
2139 | "dev": true,
2140 | "dependencies": {
2141 | "braces": "^3.0.2",
2142 | "picomatch": "^2.3.1"
2143 | },
2144 | "engines": {
2145 | "node": ">=8.6"
2146 | }
2147 | },
2148 | "node_modules/minimatch": {
2149 | "version": "3.1.2",
2150 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
2151 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
2152 | "dev": true,
2153 | "dependencies": {
2154 | "brace-expansion": "^1.1.7"
2155 | },
2156 | "engines": {
2157 | "node": "*"
2158 | }
2159 | },
2160 | "node_modules/minipass": {
2161 | "version": "5.0.0",
2162 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
2163 | "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
2164 | "dev": true,
2165 | "engines": {
2166 | "node": ">=8"
2167 | }
2168 | },
2169 | "node_modules/minizlib": {
2170 | "version": "2.1.2",
2171 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
2172 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
2173 | "dev": true,
2174 | "dependencies": {
2175 | "minipass": "^3.0.0",
2176 | "yallist": "^4.0.0"
2177 | },
2178 | "engines": {
2179 | "node": ">= 8"
2180 | }
2181 | },
2182 | "node_modules/minizlib/node_modules/minipass": {
2183 | "version": "3.3.6",
2184 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
2185 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
2186 | "dev": true,
2187 | "dependencies": {
2188 | "yallist": "^4.0.0"
2189 | },
2190 | "engines": {
2191 | "node": ">=8"
2192 | }
2193 | },
2194 | "node_modules/mkdirp": {
2195 | "version": "1.0.4",
2196 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
2197 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
2198 | "dev": true,
2199 | "bin": {
2200 | "mkdirp": "bin/cmd.js"
2201 | },
2202 | "engines": {
2203 | "node": ">=10"
2204 | }
2205 | },
2206 | "node_modules/ms": {
2207 | "version": "2.1.2",
2208 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2209 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
2210 | "dev": true
2211 | },
2212 | "node_modules/nanoid": {
2213 | "version": "4.0.2",
2214 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz",
2215 | "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==",
2216 | "funding": [
2217 | {
2218 | "type": "github",
2219 | "url": "https://github.com/sponsors/ai"
2220 | }
2221 | ],
2222 | "bin": {
2223 | "nanoid": "bin/nanoid.js"
2224 | },
2225 | "engines": {
2226 | "node": "^14 || ^16 || >=18"
2227 | }
2228 | },
2229 | "node_modules/natural-compare": {
2230 | "version": "1.4.0",
2231 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
2232 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
2233 | "dev": true
2234 | },
2235 | "node_modules/natural-compare-lite": {
2236 | "version": "1.4.0",
2237 | "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
2238 | "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
2239 | "dev": true
2240 | },
2241 | "node_modules/next-tick": {
2242 | "version": "1.1.0",
2243 | "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
2244 | "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
2245 | },
2246 | "node_modules/node-domexception": {
2247 | "version": "1.0.0",
2248 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
2249 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
2250 | "dev": true,
2251 | "funding": [
2252 | {
2253 | "type": "github",
2254 | "url": "https://github.com/sponsors/jimmywarting"
2255 | },
2256 | {
2257 | "type": "github",
2258 | "url": "https://paypal.me/jimmywarting"
2259 | }
2260 | ],
2261 | "engines": {
2262 | "node": ">=10.5.0"
2263 | }
2264 | },
2265 | "node_modules/node-fetch": {
2266 | "version": "2.6.12",
2267 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
2268 | "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
2269 | "dependencies": {
2270 | "whatwg-url": "^5.0.0"
2271 | },
2272 | "engines": {
2273 | "node": "4.x || >=6.0.0"
2274 | },
2275 | "peerDependencies": {
2276 | "encoding": "^0.1.0"
2277 | },
2278 | "peerDependenciesMeta": {
2279 | "encoding": {
2280 | "optional": true
2281 | }
2282 | }
2283 | },
2284 | "node_modules/node-gyp-build": {
2285 | "version": "4.6.0",
2286 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",
2287 | "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==",
2288 | "bin": {
2289 | "node-gyp-build": "bin.js",
2290 | "node-gyp-build-optional": "optional.js",
2291 | "node-gyp-build-test": "build-test.js"
2292 | }
2293 | },
2294 | "node_modules/npm-normalize-package-bin": {
2295 | "version": "3.0.1",
2296 | "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
2297 | "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
2298 | "dev": true,
2299 | "engines": {
2300 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
2301 | }
2302 | },
2303 | "node_modules/once": {
2304 | "version": "1.4.0",
2305 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
2306 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
2307 | "dev": true,
2308 | "dependencies": {
2309 | "wrappy": "1"
2310 | }
2311 | },
2312 | "node_modules/optionator": {
2313 | "version": "0.9.3",
2314 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
2315 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
2316 | "dev": true,
2317 | "dependencies": {
2318 | "@aashutoshrathi/word-wrap": "^1.2.3",
2319 | "deep-is": "^0.1.3",
2320 | "fast-levenshtein": "^2.0.6",
2321 | "levn": "^0.4.1",
2322 | "prelude-ls": "^1.2.1",
2323 | "type-check": "^0.4.0"
2324 | },
2325 | "engines": {
2326 | "node": ">= 0.8.0"
2327 | }
2328 | },
2329 | "node_modules/p-limit": {
2330 | "version": "3.1.0",
2331 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
2332 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
2333 | "dev": true,
2334 | "dependencies": {
2335 | "yocto-queue": "^0.1.0"
2336 | },
2337 | "engines": {
2338 | "node": ">=10"
2339 | },
2340 | "funding": {
2341 | "url": "https://github.com/sponsors/sindresorhus"
2342 | }
2343 | },
2344 | "node_modules/p-locate": {
2345 | "version": "5.0.0",
2346 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
2347 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
2348 | "dev": true,
2349 | "dependencies": {
2350 | "p-limit": "^3.0.2"
2351 | },
2352 | "engines": {
2353 | "node": ">=10"
2354 | },
2355 | "funding": {
2356 | "url": "https://github.com/sponsors/sindresorhus"
2357 | }
2358 | },
2359 | "node_modules/parent-module": {
2360 | "version": "1.0.1",
2361 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
2362 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
2363 | "dev": true,
2364 | "dependencies": {
2365 | "callsites": "^3.0.0"
2366 | },
2367 | "engines": {
2368 | "node": ">=6"
2369 | }
2370 | },
2371 | "node_modules/path-exists": {
2372 | "version": "4.0.0",
2373 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
2374 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
2375 | "dev": true,
2376 | "engines": {
2377 | "node": ">=8"
2378 | }
2379 | },
2380 | "node_modules/path-is-absolute": {
2381 | "version": "1.0.1",
2382 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
2383 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
2384 | "dev": true,
2385 | "engines": {
2386 | "node": ">=0.10.0"
2387 | }
2388 | },
2389 | "node_modules/path-key": {
2390 | "version": "3.1.1",
2391 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
2392 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
2393 | "dev": true,
2394 | "engines": {
2395 | "node": ">=8"
2396 | }
2397 | },
2398 | "node_modules/path-type": {
2399 | "version": "4.0.0",
2400 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
2401 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
2402 | "dev": true,
2403 | "engines": {
2404 | "node": ">=8"
2405 | }
2406 | },
2407 | "node_modules/picocolors": {
2408 | "version": "1.0.0",
2409 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
2410 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
2411 | "dev": true
2412 | },
2413 | "node_modules/picomatch": {
2414 | "version": "2.3.1",
2415 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
2416 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
2417 | "dev": true,
2418 | "engines": {
2419 | "node": ">=8.6"
2420 | },
2421 | "funding": {
2422 | "url": "https://github.com/sponsors/jonschlinkert"
2423 | }
2424 | },
2425 | "node_modules/postcss": {
2426 | "version": "8.4.27",
2427 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz",
2428 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==",
2429 | "dev": true,
2430 | "funding": [
2431 | {
2432 | "type": "opencollective",
2433 | "url": "https://opencollective.com/postcss/"
2434 | },
2435 | {
2436 | "type": "tidelift",
2437 | "url": "https://tidelift.com/funding/github/npm/postcss"
2438 | },
2439 | {
2440 | "type": "github",
2441 | "url": "https://github.com/sponsors/ai"
2442 | }
2443 | ],
2444 | "dependencies": {
2445 | "nanoid": "^3.3.6",
2446 | "picocolors": "^1.0.0",
2447 | "source-map-js": "^1.0.2"
2448 | },
2449 | "engines": {
2450 | "node": "^10 || ^12 || >=14"
2451 | }
2452 | },
2453 | "node_modules/postcss/node_modules/nanoid": {
2454 | "version": "3.3.6",
2455 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
2456 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
2457 | "dev": true,
2458 | "funding": [
2459 | {
2460 | "type": "github",
2461 | "url": "https://github.com/sponsors/ai"
2462 | }
2463 | ],
2464 | "bin": {
2465 | "nanoid": "bin/nanoid.cjs"
2466 | },
2467 | "engines": {
2468 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
2469 | }
2470 | },
2471 | "node_modules/prelude-ls": {
2472 | "version": "1.2.1",
2473 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
2474 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
2475 | "dev": true,
2476 | "engines": {
2477 | "node": ">= 0.8.0"
2478 | }
2479 | },
2480 | "node_modules/punycode": {
2481 | "version": "2.3.0",
2482 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
2483 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
2484 | "dev": true,
2485 | "engines": {
2486 | "node": ">=6"
2487 | }
2488 | },
2489 | "node_modules/queue-microtask": {
2490 | "version": "1.2.3",
2491 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
2492 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
2493 | "dev": true,
2494 | "funding": [
2495 | {
2496 | "type": "github",
2497 | "url": "https://github.com/sponsors/feross"
2498 | },
2499 | {
2500 | "type": "patreon",
2501 | "url": "https://www.patreon.com/feross"
2502 | },
2503 | {
2504 | "type": "consulting",
2505 | "url": "https://feross.org/support"
2506 | }
2507 | ]
2508 | },
2509 | "node_modules/react": {
2510 | "version": "18.2.0",
2511 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
2512 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
2513 | "dependencies": {
2514 | "loose-envify": "^1.1.0"
2515 | },
2516 | "engines": {
2517 | "node": ">=0.10.0"
2518 | }
2519 | },
2520 | "node_modules/react-dom": {
2521 | "version": "18.2.0",
2522 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
2523 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
2524 | "dependencies": {
2525 | "loose-envify": "^1.1.0",
2526 | "scheduler": "^0.23.0"
2527 | },
2528 | "peerDependencies": {
2529 | "react": "^18.2.0"
2530 | }
2531 | },
2532 | "node_modules/react-router": {
2533 | "version": "6.14.2",
2534 | "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz",
2535 | "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==",
2536 | "dependencies": {
2537 | "@remix-run/router": "1.7.2"
2538 | },
2539 | "engines": {
2540 | "node": ">=14"
2541 | },
2542 | "peerDependencies": {
2543 | "react": ">=16.8"
2544 | }
2545 | },
2546 | "node_modules/react-router-dom": {
2547 | "version": "6.14.2",
2548 | "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz",
2549 | "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==",
2550 | "dependencies": {
2551 | "@remix-run/router": "1.7.2",
2552 | "react-router": "6.14.2"
2553 | },
2554 | "engines": {
2555 | "node": ">=14"
2556 | },
2557 | "peerDependencies": {
2558 | "react": ">=16.8",
2559 | "react-dom": ">=16.8"
2560 | }
2561 | },
2562 | "node_modules/read-cmd-shim": {
2563 | "version": "4.0.0",
2564 | "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz",
2565 | "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==",
2566 | "dev": true,
2567 | "engines": {
2568 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
2569 | }
2570 | },
2571 | "node_modules/requireindex": {
2572 | "version": "1.1.0",
2573 | "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz",
2574 | "integrity": "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==",
2575 | "engines": {
2576 | "node": ">=0.10.5"
2577 | }
2578 | },
2579 | "node_modules/resolve-from": {
2580 | "version": "4.0.0",
2581 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2582 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2583 | "dev": true,
2584 | "engines": {
2585 | "node": ">=4"
2586 | }
2587 | },
2588 | "node_modules/reusify": {
2589 | "version": "1.0.4",
2590 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
2591 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
2592 | "dev": true,
2593 | "engines": {
2594 | "iojs": ">=1.0.0",
2595 | "node": ">=0.10.0"
2596 | }
2597 | },
2598 | "node_modules/rimraf": {
2599 | "version": "3.0.2",
2600 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
2601 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
2602 | "dev": true,
2603 | "dependencies": {
2604 | "glob": "^7.1.3"
2605 | },
2606 | "bin": {
2607 | "rimraf": "bin.js"
2608 | },
2609 | "funding": {
2610 | "url": "https://github.com/sponsors/isaacs"
2611 | }
2612 | },
2613 | "node_modules/rollup": {
2614 | "version": "3.26.3",
2615 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz",
2616 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==",
2617 | "dev": true,
2618 | "bin": {
2619 | "rollup": "dist/bin/rollup"
2620 | },
2621 | "engines": {
2622 | "node": ">=14.18.0",
2623 | "npm": ">=8.0.0"
2624 | },
2625 | "optionalDependencies": {
2626 | "fsevents": "~2.3.2"
2627 | }
2628 | },
2629 | "node_modules/run-parallel": {
2630 | "version": "1.2.0",
2631 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
2632 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
2633 | "dev": true,
2634 | "funding": [
2635 | {
2636 | "type": "github",
2637 | "url": "https://github.com/sponsors/feross"
2638 | },
2639 | {
2640 | "type": "patreon",
2641 | "url": "https://www.patreon.com/feross"
2642 | },
2643 | {
2644 | "type": "consulting",
2645 | "url": "https://feross.org/support"
2646 | }
2647 | ],
2648 | "dependencies": {
2649 | "queue-microtask": "^1.2.2"
2650 | }
2651 | },
2652 | "node_modules/scheduler": {
2653 | "version": "0.23.0",
2654 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
2655 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
2656 | "dependencies": {
2657 | "loose-envify": "^1.1.0"
2658 | }
2659 | },
2660 | "node_modules/semver": {
2661 | "version": "7.5.4",
2662 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
2663 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
2664 | "dev": true,
2665 | "dependencies": {
2666 | "lru-cache": "^6.0.0"
2667 | },
2668 | "bin": {
2669 | "semver": "bin/semver.js"
2670 | },
2671 | "engines": {
2672 | "node": ">=10"
2673 | }
2674 | },
2675 | "node_modules/shebang-command": {
2676 | "version": "2.0.0",
2677 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2678 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2679 | "dev": true,
2680 | "dependencies": {
2681 | "shebang-regex": "^3.0.0"
2682 | },
2683 | "engines": {
2684 | "node": ">=8"
2685 | }
2686 | },
2687 | "node_modules/shebang-regex": {
2688 | "version": "3.0.0",
2689 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2690 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2691 | "dev": true,
2692 | "engines": {
2693 | "node": ">=8"
2694 | }
2695 | },
2696 | "node_modules/signal-exit": {
2697 | "version": "4.1.0",
2698 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
2699 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
2700 | "dev": true,
2701 | "engines": {
2702 | "node": ">=14"
2703 | },
2704 | "funding": {
2705 | "url": "https://github.com/sponsors/isaacs"
2706 | }
2707 | },
2708 | "node_modules/slash": {
2709 | "version": "3.0.0",
2710 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
2711 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
2712 | "dev": true,
2713 | "engines": {
2714 | "node": ">=8"
2715 | }
2716 | },
2717 | "node_modules/source-map-js": {
2718 | "version": "1.0.2",
2719 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
2720 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
2721 | "dev": true,
2722 | "engines": {
2723 | "node": ">=0.10.0"
2724 | }
2725 | },
2726 | "node_modules/strip-ansi": {
2727 | "version": "6.0.1",
2728 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2729 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2730 | "dev": true,
2731 | "dependencies": {
2732 | "ansi-regex": "^5.0.1"
2733 | },
2734 | "engines": {
2735 | "node": ">=8"
2736 | }
2737 | },
2738 | "node_modules/strip-json-comments": {
2739 | "version": "3.1.1",
2740 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
2741 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
2742 | "dev": true,
2743 | "engines": {
2744 | "node": ">=8"
2745 | },
2746 | "funding": {
2747 | "url": "https://github.com/sponsors/sindresorhus"
2748 | }
2749 | },
2750 | "node_modules/supabase": {
2751 | "version": "1.82.5",
2752 | "resolved": "https://registry.npmjs.org/supabase/-/supabase-1.82.5.tgz",
2753 | "integrity": "sha512-mqLAFNB450NDQC2mG/DKRS09zsRflO8YtUuY+O2NhuUYCuZTMbqRU0XdQmh3ImvKcXWtnZTJtORZ2clAx8NlLA==",
2754 | "dev": true,
2755 | "hasInstallScript": true,
2756 | "dependencies": {
2757 | "bin-links": "^4.0.1",
2758 | "node-fetch": "^3.2.10",
2759 | "tar": "6.1.15"
2760 | },
2761 | "bin": {
2762 | "supabase": "bin/supabase"
2763 | },
2764 | "engines": {
2765 | "npm": ">=8"
2766 | }
2767 | },
2768 | "node_modules/supabase/node_modules/node-fetch": {
2769 | "version": "3.3.2",
2770 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
2771 | "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
2772 | "dev": true,
2773 | "dependencies": {
2774 | "data-uri-to-buffer": "^4.0.0",
2775 | "fetch-blob": "^3.1.4",
2776 | "formdata-polyfill": "^4.0.10"
2777 | },
2778 | "engines": {
2779 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
2780 | },
2781 | "funding": {
2782 | "type": "opencollective",
2783 | "url": "https://opencollective.com/node-fetch"
2784 | }
2785 | },
2786 | "node_modules/supports-color": {
2787 | "version": "7.2.0",
2788 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2789 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2790 | "dev": true,
2791 | "dependencies": {
2792 | "has-flag": "^4.0.0"
2793 | },
2794 | "engines": {
2795 | "node": ">=8"
2796 | }
2797 | },
2798 | "node_modules/tar": {
2799 | "version": "6.1.15",
2800 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
2801 | "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
2802 | "dev": true,
2803 | "dependencies": {
2804 | "chownr": "^2.0.0",
2805 | "fs-minipass": "^2.0.0",
2806 | "minipass": "^5.0.0",
2807 | "minizlib": "^2.1.1",
2808 | "mkdirp": "^1.0.3",
2809 | "yallist": "^4.0.0"
2810 | },
2811 | "engines": {
2812 | "node": ">=10"
2813 | }
2814 | },
2815 | "node_modules/text-table": {
2816 | "version": "0.2.0",
2817 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
2818 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
2819 | "dev": true
2820 | },
2821 | "node_modules/to-regex-range": {
2822 | "version": "5.0.1",
2823 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2824 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2825 | "dev": true,
2826 | "dependencies": {
2827 | "is-number": "^7.0.0"
2828 | },
2829 | "engines": {
2830 | "node": ">=8.0"
2831 | }
2832 | },
2833 | "node_modules/tr46": {
2834 | "version": "0.0.3",
2835 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
2836 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
2837 | },
2838 | "node_modules/ts-api-utils": {
2839 | "version": "1.0.1",
2840 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz",
2841 | "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==",
2842 | "dev": true,
2843 | "engines": {
2844 | "node": ">=16.13.0"
2845 | },
2846 | "peerDependencies": {
2847 | "typescript": ">=4.2.0"
2848 | }
2849 | },
2850 | "node_modules/tslib": {
2851 | "version": "2.6.1",
2852 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
2853 | "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
2854 | },
2855 | "node_modules/type": {
2856 | "version": "1.2.0",
2857 | "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
2858 | "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
2859 | },
2860 | "node_modules/type-check": {
2861 | "version": "0.4.0",
2862 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
2863 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
2864 | "dev": true,
2865 | "dependencies": {
2866 | "prelude-ls": "^1.2.1"
2867 | },
2868 | "engines": {
2869 | "node": ">= 0.8.0"
2870 | }
2871 | },
2872 | "node_modules/type-fest": {
2873 | "version": "0.20.2",
2874 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
2875 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
2876 | "dev": true,
2877 | "engines": {
2878 | "node": ">=10"
2879 | },
2880 | "funding": {
2881 | "url": "https://github.com/sponsors/sindresorhus"
2882 | }
2883 | },
2884 | "node_modules/typedarray-to-buffer": {
2885 | "version": "3.1.5",
2886 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
2887 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
2888 | "dependencies": {
2889 | "is-typedarray": "^1.0.0"
2890 | }
2891 | },
2892 | "node_modules/typescript": {
2893 | "version": "5.1.6",
2894 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
2895 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
2896 | "dev": true,
2897 | "bin": {
2898 | "tsc": "bin/tsc",
2899 | "tsserver": "bin/tsserver"
2900 | },
2901 | "engines": {
2902 | "node": ">=14.17"
2903 | }
2904 | },
2905 | "node_modules/uri-js": {
2906 | "version": "4.4.1",
2907 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
2908 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
2909 | "dev": true,
2910 | "dependencies": {
2911 | "punycode": "^2.1.0"
2912 | }
2913 | },
2914 | "node_modules/use-immer": {
2915 | "version": "0.9.0",
2916 | "resolved": "https://registry.npmjs.org/use-immer/-/use-immer-0.9.0.tgz",
2917 | "integrity": "sha512-/L+enLi0nvuZ6j4WlyK0US9/ECUtV5v9RUbtxnn5+WbtaXYUaOBoKHDNL9I5AETdurQ4rIFIj/s+Z5X80ATyKw==",
2918 | "peerDependencies": {
2919 | "immer": ">=2.0.0",
2920 | "react": "^16.8.0 || ^17.0.1 || ^18.0.0"
2921 | }
2922 | },
2923 | "node_modules/utf-8-validate": {
2924 | "version": "5.0.10",
2925 | "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
2926 | "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
2927 | "hasInstallScript": true,
2928 | "dependencies": {
2929 | "node-gyp-build": "^4.3.0"
2930 | },
2931 | "engines": {
2932 | "node": ">=6.14.2"
2933 | }
2934 | },
2935 | "node_modules/vite": {
2936 | "version": "4.4.7",
2937 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz",
2938 | "integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==",
2939 | "dev": true,
2940 | "dependencies": {
2941 | "esbuild": "^0.18.10",
2942 | "postcss": "^8.4.26",
2943 | "rollup": "^3.25.2"
2944 | },
2945 | "bin": {
2946 | "vite": "bin/vite.js"
2947 | },
2948 | "engines": {
2949 | "node": "^14.18.0 || >=16.0.0"
2950 | },
2951 | "funding": {
2952 | "url": "https://github.com/vitejs/vite?sponsor=1"
2953 | },
2954 | "optionalDependencies": {
2955 | "fsevents": "~2.3.2"
2956 | },
2957 | "peerDependencies": {
2958 | "@types/node": ">= 14",
2959 | "less": "*",
2960 | "lightningcss": "^1.21.0",
2961 | "sass": "*",
2962 | "stylus": "*",
2963 | "sugarss": "*",
2964 | "terser": "^5.4.0"
2965 | },
2966 | "peerDependenciesMeta": {
2967 | "@types/node": {
2968 | "optional": true
2969 | },
2970 | "less": {
2971 | "optional": true
2972 | },
2973 | "lightningcss": {
2974 | "optional": true
2975 | },
2976 | "sass": {
2977 | "optional": true
2978 | },
2979 | "stylus": {
2980 | "optional": true
2981 | },
2982 | "sugarss": {
2983 | "optional": true
2984 | },
2985 | "terser": {
2986 | "optional": true
2987 | }
2988 | }
2989 | },
2990 | "node_modules/web-streams-polyfill": {
2991 | "version": "3.2.1",
2992 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
2993 | "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
2994 | "dev": true,
2995 | "engines": {
2996 | "node": ">= 8"
2997 | }
2998 | },
2999 | "node_modules/webidl-conversions": {
3000 | "version": "3.0.1",
3001 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
3002 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
3003 | },
3004 | "node_modules/websocket": {
3005 | "version": "1.0.34",
3006 | "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz",
3007 | "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==",
3008 | "dependencies": {
3009 | "bufferutil": "^4.0.1",
3010 | "debug": "^2.2.0",
3011 | "es5-ext": "^0.10.50",
3012 | "typedarray-to-buffer": "^3.1.5",
3013 | "utf-8-validate": "^5.0.2",
3014 | "yaeti": "^0.0.6"
3015 | },
3016 | "engines": {
3017 | "node": ">=4.0.0"
3018 | }
3019 | },
3020 | "node_modules/websocket/node_modules/debug": {
3021 | "version": "2.6.9",
3022 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
3023 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
3024 | "dependencies": {
3025 | "ms": "2.0.0"
3026 | }
3027 | },
3028 | "node_modules/websocket/node_modules/ms": {
3029 | "version": "2.0.0",
3030 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
3031 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
3032 | },
3033 | "node_modules/whatwg-url": {
3034 | "version": "5.0.0",
3035 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
3036 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
3037 | "dependencies": {
3038 | "tr46": "~0.0.3",
3039 | "webidl-conversions": "^3.0.0"
3040 | }
3041 | },
3042 | "node_modules/which": {
3043 | "version": "2.0.2",
3044 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
3045 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
3046 | "dev": true,
3047 | "dependencies": {
3048 | "isexe": "^2.0.0"
3049 | },
3050 | "bin": {
3051 | "node-which": "bin/node-which"
3052 | },
3053 | "engines": {
3054 | "node": ">= 8"
3055 | }
3056 | },
3057 | "node_modules/wrappy": {
3058 | "version": "1.0.2",
3059 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
3060 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
3061 | "dev": true
3062 | },
3063 | "node_modules/write-file-atomic": {
3064 | "version": "5.0.1",
3065 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
3066 | "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
3067 | "dev": true,
3068 | "dependencies": {
3069 | "imurmurhash": "^0.1.4",
3070 | "signal-exit": "^4.0.1"
3071 | },
3072 | "engines": {
3073 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
3074 | }
3075 | },
3076 | "node_modules/yaeti": {
3077 | "version": "0.0.6",
3078 | "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
3079 | "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==",
3080 | "engines": {
3081 | "node": ">=0.10.32"
3082 | }
3083 | },
3084 | "node_modules/yallist": {
3085 | "version": "4.0.0",
3086 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
3087 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
3088 | "dev": true
3089 | },
3090 | "node_modules/yocto-queue": {
3091 | "version": "0.1.0",
3092 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
3093 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
3094 | "dev": true,
3095 | "engines": {
3096 | "node": ">=10"
3097 | },
3098 | "funding": {
3099 | "url": "https://github.com/sponsors/sindresorhus"
3100 | }
3101 | }
3102 | }
3103 | }
3104 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ztm-notion-clone",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview",
11 | "supabase:start": "supabase start",
12 | "supabase:init": "supabase init"
13 | },
14 | "dependencies": {
15 | "@dnd-kit/core": "^6.0.8",
16 | "@dnd-kit/sortable": "^7.0.2",
17 | "@supabase/supabase-js": "^2.31.0",
18 | "classnames": "^2.3.2",
19 | "eslint-plugin-immer": "^0.0.1",
20 | "nanoid": "^4.0.2",
21 | "react": "^18.2.0",
22 | "react-dom": "^18.2.0",
23 | "react-router-dom": "^6.14.2",
24 | "use-immer": "^0.9.0"
25 | },
26 | "devDependencies": {
27 | "@types/react": "^18.2.15",
28 | "@types/react-dom": "^18.2.7",
29 | "@typescript-eslint/eslint-plugin": "^6.0.0",
30 | "@typescript-eslint/parser": "^6.0.0",
31 | "@vitejs/plugin-react-swc": "^3.3.2",
32 | "eslint": "^8.45.0",
33 | "eslint-plugin-react-hooks": "^4.6.0",
34 | "eslint-plugin-react-refresh": "^0.4.3",
35 | "supabase": "^1.82.5",
36 | "typescript": "^5.0.2",
37 | "vite": "^4.4.5"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/public/ztm-notes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satansdeer/ztm-notion-clone/83f407169bf413804cd2f0af07278d500e85120f/public/ztm-notes.png
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { Page } from "./Page/Page";
2 | import { AppStateProvider } from "./state/AppStateContext";
3 | import { Route, Routes } from "react-router-dom";
4 | import { Auth } from "./auth/Auth";
5 | import { Private } from "./auth/Private";
6 |
7 | function App() {
8 | return (
9 |
10 | } />
11 |
17 |
18 |
19 | }
20 | />
21 | }
22 | />
23 |
29 |
30 |
31 | }
32 | />
33 | }
34 | />
35 |
36 | );
37 | }
38 |
39 | export default App;
40 |
--------------------------------------------------------------------------------
/src/Node/BasicNode.tsx:
--------------------------------------------------------------------------------
1 | import { NodeData, NodeType } from "../utils/types";
2 | import styles from "./Node.module.css";
3 | import {
4 | useRef,
5 | useEffect,
6 | FormEventHandler,
7 | KeyboardEventHandler,
8 | } from "react";
9 | import { nanoid } from "nanoid";
10 | import { useAppState } from "../state/AppStateContext";
11 | import { CommandPanel } from "./CommandPanel";
12 | import cx from "classnames"
13 |
14 | type BasicNodeProps = {
15 | node: NodeData;
16 | updateFocusedIndex(index: number): void;
17 | isFocused: boolean;
18 | index: number;
19 | };
20 |
21 | export const BasicNode = ({
22 | node,
23 | updateFocusedIndex,
24 | isFocused,
25 | index,
26 | }: BasicNodeProps) => {
27 | const nodeRef = useRef(null);
28 | const showCommandPanel = isFocused && node?.value?.match(/^\//);
29 |
30 | const { changeNodeValue, changeNodeType, removeNodeByIndex, addNode } =
31 | useAppState();
32 |
33 | useEffect(() => {
34 | if (nodeRef.current && document.activeElement !== nodeRef.current) {
35 | nodeRef.current.textContent = node.value;
36 | }
37 | if (isFocused) {
38 | nodeRef.current?.focus();
39 | } else {
40 | nodeRef.current?.blur();
41 | }
42 | }, [node, isFocused]);
43 |
44 | const parseCommand = (nodeType: NodeType) => {
45 | if (nodeRef.current) {
46 | changeNodeType(index, nodeType);
47 | nodeRef.current.textContent = "";
48 | }
49 | };
50 |
51 | const handleInput: FormEventHandler = ({ currentTarget }) => {
52 | const { textContent } = currentTarget;
53 | changeNodeValue(index, textContent || "");
54 | };
55 |
56 | const handleClick = () => {
57 | updateFocusedIndex(index);
58 | };
59 |
60 | const onKeyDown: KeyboardEventHandler = (event) => {
61 | const target = event.target as HTMLDivElement;
62 | if (event.key === "Enter") {
63 | event.preventDefault();
64 | if (target.textContent?.[0] === "/") {
65 | return;
66 | }
67 | addNode({ type: node.type, value: "", id: nanoid() }, index + 1);
68 | updateFocusedIndex(index + 1);
69 | }
70 | if (event.key === "Backspace") {
71 | if (target.textContent?.length === 0) {
72 | event.preventDefault();
73 | removeNodeByIndex(index);
74 | updateFocusedIndex(index - 1);
75 | } else if (window?.getSelection()?.anchorOffset === 0) {
76 | event.preventDefault();
77 | removeNodeByIndex(index - 1);
78 | updateFocusedIndex(index - 1);
79 | }
80 | }
81 | };
82 |
83 | return (
84 | <>
85 | {showCommandPanel && (
86 |
87 | )}
88 |
97 | >
98 | );
99 | };
100 |
--------------------------------------------------------------------------------
/src/Node/CommandPanel.module.css:
--------------------------------------------------------------------------------
1 | .panel {
2 | z-index: 10;
3 | position: absolute;
4 | bottom: -10px;
5 | left: 60px;
6 | background: white;
7 | width: 200px;
8 | padding: 6px;
9 | transform: translateY(100%);
10 | border-radius: 4px;
11 | box-shadow: rgb(15 15 15 / 10%) 0px 0px 0px 1px,
12 | rgb(15 15 15 / 20%) 0px 3px 6px, rgb(15 15 15 / 40%) 0px 9px 24px;
13 | }
14 |
15 | .panel.reverse {
16 | transform: translateY(-50px);
17 | }
18 |
19 | .panel ul {
20 | list-style: none;
21 | padding: 0;
22 | margin: 0;
23 | width: 100%;
24 | }
25 |
26 | .panel ul li {
27 | padding: 12px;
28 | cursor: pointer;
29 | border-radius: 4px;
30 | }
31 |
32 | .panel ul li:hover {
33 | background-color: #d0d0d0;
34 | }
35 |
36 | .panel ul li.selected {
37 | background-color: #d0d0d0;
38 | }
39 |
40 | .title {
41 | font-weight: bold;
42 | padding: 12px;
43 | }
44 |
--------------------------------------------------------------------------------
/src/Node/CommandPanel.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { NodeType } from "../utils/types";
3 | import { useOverflowsScreenBottom } from "./useOverflowsScreenBottom";
4 | import styles from "./CommandPanel.module.css";
5 | import cx from "classnames";
6 |
7 | type CommandPanelProps = {
8 | nodeText: string;
9 | selectItem: (nodeType: NodeType) => void;
10 | };
11 |
12 | type SupportedNodeType = {
13 | value: NodeType;
14 | name: string;
15 | };
16 |
17 | const supportedNodeTypes: SupportedNodeType[] = [
18 | { value: "text", name: "Text" },
19 | { value: "list", name: "List" },
20 | { value: "page", name: "Page" },
21 | { value: "image", name: "Image" },
22 | { value: "heading1", name: "Heading 1" },
23 | { value: "heading2", name: "Heading 2" },
24 | { value: "heading3", name: "Heading 3" },
25 | ];
26 |
27 | export const CommandPanel = ({ selectItem, nodeText }: CommandPanelProps) => {
28 | const [selectedItemIndex, setSelectedItemIndex] = useState(0);
29 | const { overflows, ref } = useOverflowsScreenBottom();
30 |
31 | useEffect(() => {
32 | const handleKeyDown = (event: KeyboardEvent) => {
33 | if (event.key === "Enter") {
34 | selectItem(supportedNodeTypes[selectedItemIndex].value);
35 | }
36 | };
37 |
38 | window.addEventListener("keydown", handleKeyDown);
39 |
40 | return () => {
41 | window.removeEventListener("keydown", handleKeyDown);
42 | };
43 | }, [selectedItemIndex, selectItem]);
44 |
45 | useEffect(() => {
46 | const normalizedValue = nodeText.toLowerCase().replace(/\//, "");
47 | setSelectedItemIndex(
48 | supportedNodeTypes.findIndex((item) => item.value.match(normalizedValue))
49 | );
50 | }, [nodeText]);
51 |
52 | return (
53 |
59 |
Blocks
60 |
61 | {supportedNodeTypes.map((type, index) => {
62 | const selected = selectedItemIndex === index;
63 |
64 | return (
65 | - selectItem(type.value)}
71 | >
72 | {type.name}
73 |
74 | );
75 | })}
76 |
77 |
78 | );
79 | };
80 |
--------------------------------------------------------------------------------
/src/Node/ImageNode.tsx:
--------------------------------------------------------------------------------
1 | import { NodeData } from "../utils/types";
2 | import { ChangeEvent, useEffect, useRef } from "react";
3 | import { useAppState } from "../state/AppStateContext";
4 | import cx from "classnames";
5 | import styles from "./Node.module.css";
6 | import { FileImage } from "../components/FileImage";
7 | import { uploadImage } from "../utils/uploadImage";
8 |
9 | type ImageNodeProps = {
10 | node: NodeData;
11 | isFocused: boolean;
12 | index: number;
13 | };
14 |
15 | export const ImageNode = ({ node, isFocused, index }: ImageNodeProps) => {
16 | const { removeNodeByIndex, changeNodeValue, changeNodeType } = useAppState();
17 | const fileInputRef = useRef(null);
18 |
19 | useEffect(() => {
20 | if (!node.value || node.value.length === 0) {
21 | fileInputRef.current?.click();
22 | }
23 | }, [node.value]);
24 |
25 | useEffect(() => {
26 | const handleKeyDown = (event: KeyboardEvent) => {
27 | event.preventDefault();
28 | if (event.key === "Backspace") {
29 | removeNodeByIndex(index);
30 | }
31 | if (event.key === "Enter") {
32 | fileInputRef.current?.click();
33 | }
34 | };
35 | if (isFocused) {
36 | window.addEventListener("keydown", handleKeyDown);
37 | } else {
38 | window.removeEventListener("keydown", handleKeyDown);
39 | }
40 |
41 | return () => {
42 | window.removeEventListener("keydown", handleKeyDown);
43 | };
44 | }, [isFocused, removeNodeByIndex, index, node]);
45 |
46 | const onImageUpload = async (event: ChangeEvent) => {
47 | const target = event.target;
48 | if (!target.files) {
49 | changeNodeType(index, "text");
50 | }
51 | try {
52 | const result = await uploadImage(target.files?.[0]);
53 | if (result?.filePath) {
54 | changeNodeValue(index, result?.filePath);
55 | }
56 | } catch (error) {
57 | changeNodeType(index, "text");
58 | }
59 | };
60 |
61 | return (
62 |
67 |
68 |
74 |
75 | );
76 | };
77 |
--------------------------------------------------------------------------------
/src/Node/Node.module.css:
--------------------------------------------------------------------------------
1 | .node {
2 | border-radius: 4px;
3 | padding: 6px 6px 6px 46px;
4 | cursor: text;
5 | width: 100%;
6 | }
7 |
8 | .page {
9 | cursor: pointer;
10 | font-weight: bold;
11 | }
12 |
13 | .page:hover {
14 | background-color: #f0f0f0;
15 | }
16 |
17 | .list {
18 | position: relative;
19 | padding-left: 20px;
20 | }
21 |
22 | .list::after {
23 | content: "";
24 | position: absolute;
25 | bottom: 50%;
26 | left: 6px;
27 | width: 6px;
28 | height: 6px;
29 | background-color: #222;
30 | border-radius: 50%;
31 | transform: translateY(50%);
32 | }
33 |
34 | .heading1 {
35 | font-size: 40px;
36 | font-weight: bold;
37 | }
38 |
39 | .heading2 {
40 | font-size: 30px;
41 | font-weight: bold;
42 | }
43 |
44 | .heading3 {
45 | font-size: 20px;
46 | font-weight: bold;
47 | }
48 |
49 | .focused {
50 | background-color: #00bcd4;
51 | }
52 |
--------------------------------------------------------------------------------
/src/Node/NodeContainer.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: row;
4 | position: relative;
5 | padding-left: 18px;
6 | }
7 |
8 | .container img {
9 | width: 100%;
10 | }
11 |
12 | .dragHandle {
13 | padding: 6px;
14 | cursor: grab;
15 | font-weight: bold;
16 | opacity: 0;
17 | transition: opacity 0.2s ease-in-out;
18 | }
19 |
20 | .dragHandle:hover {
21 | opacity: 1;
22 | }
23 |
--------------------------------------------------------------------------------
/src/Node/NodeContainer.tsx:
--------------------------------------------------------------------------------
1 | import { NodeData } from "../utils/types";
2 | import { CSS } from "@dnd-kit/utilities";
3 | import { useSortable } from "@dnd-kit/sortable";
4 | import { NodeTypeSwitcher } from "./NodeTypeSwitcher";
5 | import styles from "./NodeContainer.module.css";
6 |
7 | type NodeContainerProps = {
8 | node: NodeData;
9 | updateFocusedIndex(index: number): void;
10 | isFocused: boolean;
11 | index: number;
12 | };
13 |
14 | export const NodeContainer = ({
15 | node,
16 | index,
17 | isFocused,
18 | updateFocusedIndex,
19 | }: NodeContainerProps) => {
20 | const { attributes, listeners, setNodeRef, transform, transition } =
21 | useSortable({
22 | id: node.id,
23 | });
24 |
25 | const style = {
26 | transform: CSS.Transform.toString(transform),
27 | transition,
28 | };
29 |
30 | return (
31 |
37 |
38 | ⠿
39 |
40 |
46 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/src/Node/NodeTypeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | import { NodeType, NodeData } from "../utils/types"
2 | import { BasicNode } from "./BasicNode"
3 | import { ImageNode } from "./ImageNode";
4 | import { PageNode } from "./PageNode"
5 |
6 | type NodeTypeSwitcherProps = {
7 | node: NodeData;
8 | updateFocusedIndex(index: number): void;
9 | isFocused: boolean;
10 | index: number;
11 | };
12 |
13 | const TEXT_NODE_TYPES: NodeType[] = [
14 | "text", "list", "heading1", "heading2", "heading3"
15 | ]
16 |
17 | export const NodeTypeSwitcher = ({
18 | node,
19 | isFocused,
20 | index,
21 | updateFocusedIndex
22 | }: NodeTypeSwitcherProps) => {
23 | if(TEXT_NODE_TYPES.includes(node.type)) {
24 | return
30 | }
31 |
32 | if(node.type == "page"){
33 | return
34 | }
35 |
36 | if(node.type === "image") {
37 | return
38 | }
39 |
40 | return null
41 | }
42 |
--------------------------------------------------------------------------------
/src/Node/PageNode.tsx:
--------------------------------------------------------------------------------
1 | import { NodeData } from "../utils/types";
2 | import { useEffect, useState } from "react";
3 | import { useNavigate } from "react-router-dom";
4 | import { useAppState } from "../state/AppStateContext";
5 | import { supabase } from "../supabaseClient";
6 | import cx from "classnames";
7 | import styles from "./Node.module.css"
8 |
9 | type PageNodeProps = {
10 | node: NodeData;
11 | isFocused: boolean;
12 | index: number;
13 | };
14 |
15 | export const PageNode = ({ node, isFocused, index }: PageNodeProps) => {
16 | const navigate = useNavigate();
17 | const [pageTitle, setPageTitle] = useState("");
18 | const { removeNodeByIndex } = useAppState();
19 |
20 | useEffect(() => {
21 | const handleKeyDown = (event: KeyboardEvent) => {
22 | event.preventDefault();
23 | if (event.key === "Backspace") {
24 | removeNodeByIndex(index);
25 | }
26 | if (event.key === "Enter") {
27 | navigate(`/${node.value}`);
28 | }
29 | };
30 | if (isFocused) {
31 | window.addEventListener("keydown", handleKeyDown);
32 | } else {
33 | window.removeEventListener("keydown", handleKeyDown);
34 | }
35 |
36 | return () => {
37 | window.removeEventListener("keydown", handleKeyDown);
38 | };
39 | }, [isFocused, removeNodeByIndex, index, navigate, node]);
40 |
41 | useEffect(() => {
42 | const fetchPageTitle = async () => {
43 | const { data } = await supabase
44 | .from("pages")
45 | .select("title")
46 | .eq("slug", node.value)
47 | .single();
48 | setPageTitle(data?.title);
49 | };
50 | if (node.type === "page" && node.value) {
51 | fetchPageTitle();
52 | }
53 | }, [node.type, node.value]);
54 |
55 | const navigateToPage = () => {
56 | navigate(`/${node.value}`);
57 | };
58 |
59 | return (
60 |
66 | 📄 {pageTitle}
67 |
68 | );
69 | };
70 |
--------------------------------------------------------------------------------
/src/Node/useOverflowsScreenBottom.ts:
--------------------------------------------------------------------------------
1 | import { useRef, useState, useEffect } from "react";
2 |
3 | export const useOverflowsScreenBottom = () => {
4 | const ref = useRef(null);
5 | const [overflows, setOverflows] = useState(false);
6 |
7 | useEffect(() => {
8 | if (ref.current) {
9 | const { bottom } = ref.current.getBoundingClientRect();
10 | const { innerHeight } = window;
11 | setOverflows(bottom > innerHeight);
12 | }
13 | }, []);
14 |
15 | return { overflows, ref };
16 | };
17 |
--------------------------------------------------------------------------------
/src/Page/Cover.module.css:
--------------------------------------------------------------------------------
1 | .cover {
2 | position: relative;
3 | height: 295px;
4 | border-bottom: 2px solid #eaeaea;
5 | display: flex;
6 | justify-content: center;
7 | align-items: center;
8 | }
9 |
10 | .button {
11 | position: absolute;
12 | bottom: 20px;
13 | right: 90px;
14 | padding: 6px;
15 | opacity: 0;
16 | transition: opacity 0.2s ease-in-out;
17 | background: white;
18 | border: 2px solid #888;
19 | border-radius: 4px;
20 | color: #6f6f6f;
21 | font-weight: bold;
22 | cursor: pointer;
23 | }
24 |
25 | .cover:hover .button {
26 | opacity: 1;
27 | }
28 |
29 | .image {
30 | width: 100%;
31 | max-height: 295px;
32 | object-fit: cover;
33 | }
34 |
--------------------------------------------------------------------------------
/src/Page/Cover.tsx:
--------------------------------------------------------------------------------
1 | import { useRef, ChangeEventHandler } from "react";
2 | import styles from "./Cover.module.css";
3 | import { FileImage } from "../components/FileImage";
4 | import { uploadImage } from "../utils/uploadImage"
5 |
6 | type CoverProps = {
7 | filePath?: string;
8 | changePageCover: (filePath: string) => void;
9 | };
10 |
11 | export const Cover = ({ filePath, changePageCover }: CoverProps) => {
12 | const fileInputRef = useRef(null);
13 |
14 | const onChangeCoverImage = () => {
15 | fileInputRef.current?.click();
16 | };
17 |
18 | const onCoverImageUpload: ChangeEventHandler = async (event) => {
19 | const target = event.target;
20 | const result = await uploadImage(target?.files?.[0])
21 |
22 | if(result?.filePath){
23 | changePageCover(result.filePath)
24 | }
25 | };
26 |
27 | return (
28 |
29 | {filePath ? (
30 |
31 | ) : (
32 |

33 | )}
34 |
37 |
43 |
44 | );
45 | };
46 |
--------------------------------------------------------------------------------
/src/Page/Page.module.css:
--------------------------------------------------------------------------------
1 | .body {
2 | padding-left: 50px;
3 | padding-right: 90px;
4 | max-width: 900px;
5 | }
6 |
7 | .backLink {
8 | padding-left: 46px;
9 | padding-top: 10px;
10 | }
11 |
--------------------------------------------------------------------------------
/src/Page/Page.tsx:
--------------------------------------------------------------------------------
1 | import { useFocusedNodeIndex } from "./useFocusedNodeIndex";
2 | import { Cover } from "./Cover";
3 | import { Spacer } from "./Spacer";
4 | import { NodeContainer } from "../Node/NodeContainer";
5 | import { Title } from "./Title";
6 | import { nanoid } from "nanoid";
7 | import { useAppState } from "../state/AppStateContext";
8 | import { DndContext, DragOverlay, DragEndEvent } from "@dnd-kit/core";
9 | import {
10 | SortableContext,
11 | verticalListSortingStrategy,
12 | } from "@dnd-kit/sortable";
13 |
14 | export const Page = () => {
15 | const { title, nodes, addNode, cover, setCoverImage, reorderNodes, setTitle } = useAppState();
16 |
17 | const [focusedNodeIndex, setFocusedNodeIndex] = useFocusedNodeIndex({
18 | nodes,
19 | });
20 |
21 | const handleDragEvent = (event: DragEndEvent) => {
22 | const { active, over } = event;
23 | if (over?.id && active.id !== over?.id) {
24 | reorderNodes(active.id as string, over.id as string);
25 | }
26 | };
27 |
28 | return (
29 | <>
30 |
31 |
32 |
33 |
34 |
35 | {nodes.map((node, index) => (
36 |
43 | ))}
44 |
45 |
46 |
47 | {
49 | addNode({ type: "text", value: "", id: nanoid() }, nodes.length);
50 | }}
51 | showHint={!nodes.length}
52 | />
53 |
54 | >
55 | );
56 | };
57 |
--------------------------------------------------------------------------------
/src/Page/Spacer.module.css:
--------------------------------------------------------------------------------
1 | .spacer {
2 | height: 200px;
3 | width: 100%;
4 | padding: 0 46px;
5 | color: grey;
6 | }
7 |
--------------------------------------------------------------------------------
/src/Page/Spacer.tsx:
--------------------------------------------------------------------------------
1 | import styles from "./Spacer.module.css";
2 |
3 | type SpacerProps = {
4 | handleClick(): void;
5 | showHint: boolean;
6 | };
7 |
8 | export const Spacer = ({ handleClick, showHint }: SpacerProps) => {
9 | return (
10 |
11 | {showHint && "Click to create the first paragraph."}
12 |
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/src/Page/Title.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding-left: 40px;
3 | padding-right: 40px;
4 | max-width: 900px;
5 | }
6 |
7 | .title {
8 | padding: 6px;
9 | }
10 |
--------------------------------------------------------------------------------
/src/Page/Title.tsx:
--------------------------------------------------------------------------------
1 | import { NodeData } from "../utils/types";
2 | import { useRef, useEffect } from "react";
3 | import styles from "./Title.module.css";
4 | import { nanoid } from "nanoid";
5 |
6 | type TitleProps = {
7 | title: string;
8 | changePageTitle(title: string): void;
9 | addNode(node: NodeData, index: number): void;
10 | };
11 |
12 | export const Title = ({ title, changePageTitle, addNode }: TitleProps) => {
13 | const headerRef = useRef(null);
14 |
15 | useEffect(() => {
16 | const isFocused = document.activeElement == headerRef.current;
17 | if (!isFocused && headerRef.current) {
18 | headerRef.current.textContent = title;
19 | }
20 | }, [title]);
21 |
22 | return (
23 |
24 |
changePageTitle(e.currentTarget.textContent || "")}
30 | onKeyDown={(event) => {
31 | if (event.key === "Enter") {
32 | event.preventDefault();
33 | addNode({ type: "text", id: nanoid(), value: "" }, 0);
34 | }
35 | }}
36 | />
37 |
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/src/Page/useFocusedNodeIndex.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, Dispatch, SetStateAction } from "react";
2 | import { NodeData } from "../utils/types";
3 |
4 | type UseFocusedNodeIndexProps = {
5 | nodes: NodeData[];
6 | };
7 |
8 | export const useFocusedNodeIndex = ({
9 | nodes,
10 | }: UseFocusedNodeIndexProps): [number, Dispatch>] => {
11 | const [focusedNodeIndex, setFocusedNodeIndex] = useState(0);
12 |
13 | useEffect(() => {
14 | const onKeyDown = (event: KeyboardEvent) => {
15 | if (event.key === "ArrowUp") {
16 | setFocusedNodeIndex((index) => Math.max(index - 1, 0));
17 | }
18 | if (event.key === "ArrowDown") {
19 | setFocusedNodeIndex((index) => Math.min(index + 1, nodes.length - 1));
20 | }
21 | };
22 | document.addEventListener("keydown", onKeyDown);
23 |
24 | return () => document.removeEventListener("keydown", onKeyDown);
25 | }, [nodes]);
26 |
27 | return [focusedNodeIndex, setFocusedNodeIndex];
28 | };
29 |
--------------------------------------------------------------------------------
/src/auth/Auth.tsx:
--------------------------------------------------------------------------------
1 | import { useState, FormEvent} from "react"
2 | import { useAuthSession } from "./AuthSessionContext"
3 | import { Navigate } from "react-router-dom"
4 | import styles from "../utils.module.css"
5 | import { supabase } from "../supabaseClient"
6 |
7 | export const Auth = () => {
8 | const [loading, setLoading] = useState(false)
9 | const [email, setEmail] = useState("")
10 | const { session } = useAuthSession()
11 |
12 | const handleLogin = async (e: FormEvent) => {
13 | e.preventDefault()
14 |
15 | try {
16 | setLoading(true)
17 | const { error } = await supabase.auth.signInWithOtp({ email })
18 | if(error) throw error
19 | alert("CHeck your email for the login link!")
20 | } catch (error){
21 | alert(error)
22 | } finally {
23 | setLoading(false)
24 | }
25 | }
26 |
27 | if(session){
28 | return
29 | }
30 |
31 | return (
32 |
33 |
34 |
ZTM Notes App
35 |
Sign in via magic link with your email below
36 | {loading ? ("Sending magic link...") : (
37 |
50 | )}
51 |
52 |
53 | )
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/auth/AuthSessionContext.tsx:
--------------------------------------------------------------------------------
1 | import { supabase } from "../supabaseClient"
2 | import { Session } from "@supabase/supabase-js"
3 | import { createContext, ReactNode, useState, useEffect, useContext } from "react"
4 |
5 | type AuthSessionContextValue = {
6 | session: Session | null;
7 | loading: boolean;
8 | }
9 |
10 | const AuthSessionContext = createContext({} as AuthSessionContextValue)
11 |
12 |
13 | type AuthSessionProviderProps = {
14 | children: ReactNode
15 | }
16 |
17 | export const AuthSessionProvider = ({children}: AuthSessionProviderProps) => {
18 | const [ session, setSession ] = useState(null)
19 | const [ loading, setLoading ] = useState(true);
20 |
21 | useEffect(() => {
22 | const auth = async () => {
23 | const {data, error } = await supabase.auth.getSession()
24 | if(data.session){
25 | setSession(data.session)
26 | setLoading(false)
27 | } else {
28 | console.log(error)
29 | }
30 | }
31 | auth()
32 | supabase.auth.onAuthStateChange((_event, session) => {
33 | setSession(session)
34 | setLoading(false)
35 | })
36 | }, [])
37 |
38 | return (
39 |
40 | {children}
41 |
42 | )
43 | }
44 |
45 | export const useAuthSession = () => useContext(AuthSessionContext)
46 |
--------------------------------------------------------------------------------
/src/auth/Private.tsx:
--------------------------------------------------------------------------------
1 | import { ReactElement } from "react"
2 | import { useAuthSession } from "./AuthSessionContext"
3 | import { Navigate } from "react-router-dom"
4 |
5 | type PrivateProps = {
6 | component: ReactElement;
7 | }
8 |
9 | export const Private = ({ component }: PrivateProps) => {
10 | const { session, loading } = useAuthSession()
11 |
12 | if (loading) {
13 | return <> Authenticating...>
14 | }
15 |
16 | return session ? component :
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/FileImage.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react"
2 | import { supabase } from "../supabaseClient"
3 | import { Loader } from "./Loader"
4 | import styles from "../utils.module.css"
5 |
6 | type FileImageProps = {
7 | filePath: string
8 | } & React.ImgHTMLAttributes
9 |
10 | export const FileImage = ({filePath, ...props}: FileImageProps) => {
11 | const [image, setImage] = useState("")
12 | const [ loading, setLoading ] = useState(true)
13 |
14 | useEffect(() => {
15 | const downloadImage = async (filePath: string) => {
16 | setLoading(true);
17 | const {data} = await supabase.storage.from("images").download(filePath)
18 | if(data){
19 | const url = URL.createObjectURL(data)
20 | setImage(url)
21 | setLoading(false)
22 | }
23 | }
24 | if(filePath && filePath.length > 0){
25 | downloadImage(filePath)
26 | }
27 | }, [filePath])
28 |
29 | if(loading){
30 | return
31 |
32 |
33 | }
34 |
35 | return
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/src/components/Loader.module.css:
--------------------------------------------------------------------------------
1 | .loader {
2 | display: inline-block;
3 | position: relative;
4 | width: 80px;
5 | height: 80px;
6 | }
7 | .loader div {
8 | position: absolute;
9 | top: 33px;
10 | width: 13px;
11 | height: 13px;
12 | border-radius: 50%;
13 | background: #ccc;
14 | animation-timing-function: cubic-bezier(0, 1, 1, 0);
15 | }
16 | .loader div:nth-child(1) {
17 | left: 8px;
18 | animation: loader1 0.6s infinite;
19 | }
20 | .loader div:nth-child(2) {
21 | left: 8px;
22 | animation: loader2 0.6s infinite;
23 | }
24 | .loader div:nth-child(3) {
25 | left: 32px;
26 | animation: loader2 0.6s infinite;
27 | }
28 | .loader div:nth-child(4) {
29 | left: 56px;
30 | animation: loader3 0.6s infinite;
31 | }
32 | @keyframes loader1 {
33 | 0% {
34 | transform: scale(0);
35 | }
36 | 100% {
37 | transform: scale(1);
38 | }
39 | }
40 | @keyframes loader3 {
41 | 0% {
42 | transform: scale(1);
43 | }
44 | 100% {
45 | transform: scale(0);
46 | }
47 | }
48 | @keyframes loader2 {
49 | 0% {
50 | transform: translate(0, 0);
51 | }
52 | 100% {
53 | transform: translate(24px, 0);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/Loader.tsx:
--------------------------------------------------------------------------------
1 | import styles from "./Loader.module.css";
2 |
3 | // https://loading.io/css/
4 |
5 | export const Loader = () => {
6 | return (
7 |
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
15 | html,
16 | body,
17 | #root {
18 | height: 100%;
19 | position: relative;
20 | }
21 |
22 | [contenteditable="true"]:focus {
23 | outline: none;
24 | }
25 |
26 | [contenteditable="true"]:empty:focus:before {
27 | content: attr(data-placeholder);
28 | color: grey;
29 | }
30 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import App from "./App.tsx";
4 | import "./index.css";
5 | import { BrowserRouter } from "react-router-dom";
6 | import { AuthSessionProvider } from "./auth/AuthSessionContext"
7 |
8 | ReactDOM.createRoot(document.getElementById("root")!).render(
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/src/state/AppStateContext.tsx:
--------------------------------------------------------------------------------
1 | import { createContext, useContext } from "react";
2 | import { usePageState } from "./usePageState";
3 | import { Page } from "../utils/types";
4 | import { withInitialState } from "./withInitialState"
5 |
6 | type AppStateContextType = ReturnType;
7 |
8 | const AppStateContext = createContext(
9 | {} as AppStateContextType
10 | );
11 |
12 | type AppStateProviderProps = {
13 | children: React.ReactNode;
14 | initialState: Page;
15 | };
16 |
17 | export const AppStateProvider = withInitialState(({
18 | children,
19 | initialState,
20 | }: AppStateProviderProps) => {
21 | const pageStateHandlers = usePageState(initialState);
22 |
23 | return (
24 |
25 | {children}
26 |
27 | );
28 | });
29 |
30 | export const useAppState = () => useContext(AppStateContext);
31 |
--------------------------------------------------------------------------------
/src/state/startPageScaffold.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to ZTM Notes",
3 | "nodes": [
4 | {
5 | "type": "text",
6 | "value": "This app is written in React + TypeScript and works similarly to Notion. For example, try entering the text below this paragraph 👇",
7 | "id": "dgkm6uWT58KKIvBuo4KCE"
8 | },
9 | { "type": "text", "value": "", "id": "cZjPbQHUQmv5h-v1rpDoD" },
10 | {
11 | "type": "text",
12 | "value": "You can also add lists, to do this bring up the command palette by starting a new line with `/`",
13 | "id": "eK__MFBh2DieZzKQDf5rl"
14 | },
15 | { "type": "text", "value": "", "id": "IYd7XsCkoiqysGrOLvM0B" },
16 | {
17 | "type": "text",
18 | "value": "Here are a few list items just to show how it looks like:",
19 | "id": "tGEVZQlUB_zGi66GU2TIz"
20 | },
21 | { "type": "list", "value": "First item", "id": "zJ42BYE7QCx_1XSsZETuc" },
22 | { "type": "list", "value": "Second item", "id": "ia_pE2qrqR8un_BYqqM9_" },
23 | { "type": "list", "value": "Third item", "id": "gD6IRCl09HQGpaDorOiF6" },
24 | { "type": "text", "value": "", "id": "pH0TGrzTJ09_8w8XXfKO8" },
25 | {
26 | "type": "heading2",
27 | "value": "You can add headings as well",
28 | "id": "qbsmQ_NkTC7jRO4csWL8h"
29 | },
30 | {
31 | "type": "text",
32 | "value": "If you tried adding list items, you've noticed that there are also other types of blocks.",
33 | "id": "e1pnucOk3k_G3_Gjw7SrB"
34 | },
35 | { "type": "text", "value": "", "id": "Zctuc8G9XyWEPhUGIYBVW" },
36 | {
37 | "type": "text",
38 | "value": "Currently the app supports:",
39 | "id": "v3s7NU1a-X_uWSAELT2nK"
40 | },
41 | { "type": "list", "value": "regular text", "id": "ADtjGSZ4p53f9VpQK72f1" },
42 | {
43 | "type": "list",
44 | "value": "unordered lists",
45 | "id": "Zrwh60KFLzqeBmmhAAKDN"
46 | },
47 | {
48 | "type": "list",
49 | "value": "heading levels 1-3",
50 | "id": "SLNB1qZ3TuGiNerxfAL7N"
51 | },
52 | { "type": "list", "value": "images", "id": "rT-xkKSS3l23Olui4XUF8" },
53 | {
54 | "type": "list",
55 | "value": "links to other pages",
56 | "id": "oHdB3ghNMer9DTlCp0dhA"
57 | },
58 | { "type": "text", "value": "", "id": "qD6vnHeExO5gTg5ZmPUt3" },
59 | {
60 | "type": "text",
61 | "value": "Try adding a new page.",
62 | "id": "765A3xPw56d8j7NcYpi3D"
63 | }
64 | ]
65 | }
66 |
--------------------------------------------------------------------------------
/src/state/usePageState.ts:
--------------------------------------------------------------------------------
1 | import { Page, NodeData, NodeType } from "../utils/types";
2 | import { arrayMove } from "@dnd-kit/sortable"
3 | import { useSyncedState } from "./useSyncedState"
4 | import { updatePage } from "../utils/updatePage"
5 | import { createPage } from "../utils/createPage"
6 |
7 | export const usePageState = (initialState: Page) => {
8 | const [page, setPage] = useSyncedState(initialState, updatePage);
9 |
10 | const addNode = (node: NodeData, index: number) => {
11 | setPage((draft) => {
12 | draft.nodes.splice(index, 0, node);
13 | });
14 | };
15 |
16 | const removeNodeByIndex = (nodeIndex: number) => {
17 | setPage((draft) => {
18 | draft.nodes.splice(nodeIndex, 1);
19 | });
20 | };
21 |
22 | const changeNodeValue = (nodeIndex: number, value: string) => {
23 | setPage((draft) => {
24 | draft.nodes[nodeIndex].value = value;
25 | });
26 | };
27 |
28 | const changeNodeType = async (nodeIndex: number, type: NodeType) => {
29 | if (type === "page") {
30 | const newPage = await createPage();
31 | if (newPage) {
32 | setPage((draft) => {
33 | draft.nodes[nodeIndex].type = type;
34 | draft.nodes[nodeIndex].value = newPage.slug;
35 | });
36 | }
37 | } else {
38 | setPage((draft) => {
39 | draft.nodes[nodeIndex].type = type;
40 | draft.nodes[nodeIndex].value = "";
41 | });
42 | }
43 | };
44 |
45 | const setNodes = (nodes: NodeData[]) => {
46 | setPage((draft) => {
47 | draft.nodes = nodes;
48 | });
49 | };
50 |
51 | const setTitle = (title: string) => {
52 | setPage((draft) => {
53 | draft.title = title;
54 | });
55 | };
56 |
57 | const setCoverImage = (coverImage: string) => {
58 | setPage((draft) => {
59 | draft.cover = coverImage;
60 | });
61 | };
62 |
63 | const reorderNodes = (id1: string, id2: string) => {
64 | setPage((draft) => {
65 | const index1 = draft.nodes.findIndex(node => node.id === id1)
66 | const index2 = draft.nodes.findIndex(node => node.id === id2)
67 | draft.nodes = arrayMove(draft.nodes, index1, index2)
68 | })
69 | }
70 |
71 | return {
72 | nodes: page.nodes,
73 | title: page.title,
74 | cover: page.cover,
75 | changeNodeType,
76 | changeNodeValue,
77 | addNode,
78 | removeNodeByIndex,
79 | setTitle,
80 | setCoverImage,
81 | setNodes,
82 | reorderNodes
83 | };
84 | };
85 |
--------------------------------------------------------------------------------
/src/state/useSyncedState.ts:
--------------------------------------------------------------------------------
1 | import { ImmerHook, useImmer } from "use-immer"
2 | import { useRef, useEffect } from "react"
3 |
4 | export const useSyncedState = (
5 | initialState: TState,
6 | syncCallback: (state: TState) => void
7 | ): ImmerHook => {
8 | const [state, setState] = useImmer(initialState)
9 | const didMountRef = useRef(false)
10 |
11 | useEffect(() => {
12 | if(didMountRef.current){
13 | syncCallback(state)
14 | }
15 | didMountRef.current = true;
16 | }, [state, setState])
17 |
18 | return [state, setState]
19 | }
20 |
--------------------------------------------------------------------------------
/src/state/withInitialState.tsx:
--------------------------------------------------------------------------------
1 | import { Page } from "../utils/types";
2 | import { useMatch } from "react-router-dom";
3 | import { useState, useEffect, useRef } from "react";
4 | import { supabase } from "../supabaseClient";
5 | import startPageScaffold from "./startPageScaffold.json";
6 | import styles from "../utils.module.css";
7 | import { Loader } from "../components/Loader";
8 |
9 | type InjectedProps = {
10 | initialState: Page;
11 | };
12 |
13 | type PropsWithoutInjected = Omit;
14 |
15 | export function withInitialState(
16 | WrappedComponent: React.ComponentType<
17 | PropsWithoutInjected & InjectedProps
18 | >
19 | ) {
20 | return (props: PropsWithoutInjected) => {
21 | const match = useMatch("/:slug");
22 | const pageSlug = match ? match.params.slug : "start";
23 |
24 | const [initialState, setInitialState] = useState();
25 | const [isLoading, setIsLoading] = useState(true);
26 | const [error, setError] = useState();
27 | const inProgress = useRef(false)
28 |
29 | useEffect(() => {
30 | if (inProgress.current) {
31 | return
32 | }
33 | setIsLoading(true);
34 | inProgress.current = true
35 | const fetchInitialState = async () => {
36 | try {
37 | const { data: userData } = await supabase.auth.getUser();
38 | const user = userData.user;
39 | if (!user) {
40 | throw new Error("User is not logged in");
41 | }
42 | const { data } = await supabase
43 | .from("pages")
44 | .select("title, id, cover, nodes, slug")
45 | .match({ slug: pageSlug, created_by: user.id })
46 |
47 | if (data?.[0]) {
48 | setInitialState(data?.[0]);
49 | inProgress.current = false;
50 | setIsLoading(false);
51 | return
52 | }
53 |
54 | if (pageSlug === "start") {
55 | await supabase
56 | .from("pages")
57 | .insert({
58 | ...startPageScaffold,
59 | slug: "start",
60 | created_by: user.id,
61 | })
62 |
63 | const { data } = await supabase
64 | .from("pages")
65 | .select("title, id, cover, nodes, slug")
66 | .match({ slug: "start", created_by: user.id })
67 |
68 | setInitialState(data?.[0]);
69 | } else {
70 | setInitialState(data?.[0]);
71 | }
72 | } catch (e) {
73 | if (e instanceof Error) {
74 | setError(e);
75 | }
76 | }
77 | inProgress.current = false;
78 | setIsLoading(false);
79 | };
80 | fetchInitialState();
81 | }, [pageSlug]);
82 |
83 | if (isLoading) {
84 | return (
85 |
86 |
87 |
88 | );
89 | }
90 |
91 | if (error) {
92 | return {error.message}
;
93 | }
94 |
95 | if (!initialState) {
96 | return Page not found
;
97 | }
98 |
99 | return ;
100 | };
101 | }
102 |
--------------------------------------------------------------------------------
/src/supabaseClient.ts:
--------------------------------------------------------------------------------
1 | import { createClient } from "@supabase/supabase-js"
2 |
3 | const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
4 | const supabaseKey = import.meta.env.VITE_SUPABASE_API_KEY;
5 |
6 | if(!supabaseUrl || !supabaseKey){
7 | throw new Error("Missing supabase url or key")
8 | }
9 |
10 | export const supabase = createClient(supabaseUrl, supabaseKey)
11 |
--------------------------------------------------------------------------------
/src/utils.module.css:
--------------------------------------------------------------------------------
1 | .centeredFlex {
2 | width: 100%;
3 | height: 100%;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | }
8 |
--------------------------------------------------------------------------------
/src/utils/createPage.ts:
--------------------------------------------------------------------------------
1 | import { nanoid } from "nanoid";
2 | import { supabase } from "../supabaseClient";
3 |
4 | export const createPage = async () => {
5 | const { data: userData } = await supabase.auth.getUser();
6 | const user = userData.user;
7 | if (!user) {
8 | throw new Error("You must be logged in to create a page.");
9 | }
10 | const slug = nanoid();
11 |
12 | const page = {
13 | id: undefined,
14 | title: "Untitled",
15 | slug,
16 | nodes: [],
17 | created_by: user.id,
18 | };
19 |
20 | await supabase.from("pages").insert(page);
21 | const { data: pageData } = await supabase
22 | .from("pages")
23 | .select("id")
24 | .match({ slug, created_by: user.id })
25 | .single();
26 |
27 | page.id = pageData?.id;
28 |
29 | return page;
30 | };
31 |
32 |
--------------------------------------------------------------------------------
/src/utils/debounce.ts:
--------------------------------------------------------------------------------
1 | type ArgumentTypes = F extends (...args: infer A) => any
2 | ? A
3 | : never;
4 |
5 | export function debounce(
6 | callback: TCallback,
7 | delay = 300
8 | ) {
9 | let timeoutId: ReturnType;
10 | return function (...args: ArgumentTypes) {
11 | clearTimeout(timeoutId);
12 | timeoutId = setTimeout(() => callback(...args), delay);
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/src/utils/types.ts:
--------------------------------------------------------------------------------
1 | export type NodeType = "text" | "image" | "list" | "page" | "heading1" | "heading2" | "heading3"
2 |
3 | export type NodeData = {
4 | id: string;
5 | type: NodeType;
6 | value: string;
7 | }
8 |
9 | export type Page = {
10 | id: string;
11 | slug: string;
12 | title: string;
13 | nodes: NodeData[];
14 | cover: string;
15 | }
16 |
--------------------------------------------------------------------------------
/src/utils/updatePage.ts:
--------------------------------------------------------------------------------
1 | import { Page } from "../utils/types";
2 | import { supabase } from "../supabaseClient";
3 | import { debounce } from "./debounce";
4 |
5 | export const updatePage = debounce(
6 | async (page: Partial & Pick) => {
7 | await supabase.from("pages").update(page).eq("id", page.id);
8 | },
9 | 500
10 | );
11 |
--------------------------------------------------------------------------------
/src/utils/uploadImage.ts:
--------------------------------------------------------------------------------
1 | import { supabase } from "../supabaseClient"
2 |
3 | export const uploadImage = async (file?: File) => {
4 | try {
5 | if(!file){
6 | throw new Error("You must select an image to upload");
7 | }
8 |
9 | const fileExt = file.name.split(".").pop()
10 | const fileName = `${Math.random()}.${fileExt}`
11 | const filePath = fileName;
12 |
13 | await supabase.storage.from("images").upload(filePath, file);
14 |
15 | return {filePath, fileName}
16 | } catch (e) {
17 | alert(e)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/supabase/.gitignore:
--------------------------------------------------------------------------------
1 | # Supabase
2 | .branches
3 | .temp
4 |
--------------------------------------------------------------------------------
/supabase/config.toml:
--------------------------------------------------------------------------------
1 | # A string used to distinguish different Supabase projects on the same host. Defaults to the
2 | # working directory name when running `supabase init`.
3 | project_id = "ztm-notion-clone"
4 |
5 | [api]
6 | # Port to use for the API URL.
7 | port = 54321
8 | # Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
9 | # endpoints. public and storage are always included.
10 | schemas = ["public", "storage", "graphql_public"]
11 | # Extra schemas to add to the search_path of every request. public is always included.
12 | extra_search_path = ["public", "extensions"]
13 | # The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
14 | # for accidental or malicious requests.
15 | max_rows = 1000
16 |
17 | [db]
18 | # Port to use for the local database URL.
19 | port = 54322
20 | # Port used by db diff command to initialise the shadow database.
21 | shadow_port = 54320
22 | # The database major version to use. This has to be the same as your remote database's. Run `SHOW
23 | # server_version;` on the remote database to check.
24 | major_version = 15
25 |
26 | [studio]
27 | enabled = true
28 | # Port to use for Supabase Studio.
29 | port = 54323
30 | # External URL of the API server that frontend connects to.
31 | api_url = "http://localhost"
32 |
33 | # Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
34 | # are monitored, and you can view the emails that would have been sent from the web interface.
35 | [inbucket]
36 | enabled = true
37 | # Port to use for the email testing server web interface.
38 | port = 54324
39 | # Uncomment to expose additional ports for testing user applications that send emails.
40 | # smtp_port = 54325
41 | # pop3_port = 54326
42 |
43 | [storage]
44 | # The maximum file size allowed (e.g. "5MB", "500KB").
45 | file_size_limit = "50MiB"
46 |
47 | [auth]
48 | # The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
49 | # in emails.
50 | site_url = "http://localhost:3000"
51 | # A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
52 | additional_redirect_urls = ["https://localhost:3000"]
53 | # How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
54 | jwt_expiry = 3600
55 | # If disabled, the refresh token will never expire.
56 | enable_refresh_token_rotation = true
57 | # Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
58 | # Requires enable_refresh_token_rotation = true.
59 | refresh_token_reuse_interval = 10
60 | # Allow/disallow new user signups to your project.
61 | enable_signup = true
62 |
63 | [auth.email]
64 | # Allow/disallow new user signups via email to your project.
65 | enable_signup = true
66 | # If enabled, a user will be required to confirm any email change on both the old, and new email
67 | # addresses. If disabled, only the new email is required to confirm.
68 | double_confirm_changes = true
69 | # If enabled, users need to confirm their email address before signing in.
70 | enable_confirmations = false
71 |
72 | [auth.sms]
73 | # Allow/disallow new user signups via SMS to your project.
74 | enable_signup = true
75 | # If enabled, users need to confirm their phone number before signing in.
76 | enable_confirmations = false
77 |
78 | # Configure one of the supported SMS providers: `twilio`, `messagebird`, `textlocal`, `vonage`.
79 | [auth.sms.twilio]
80 | enabled = false
81 | account_sid = ""
82 | message_service_sid = ""
83 | # DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
84 | auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
85 |
86 | # Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
87 | # `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin`, `notion`, `twitch`,
88 | # `twitter`, `slack`, `spotify`, `workos`, `zoom`.
89 | [auth.external.apple]
90 | enabled = false
91 | client_id = ""
92 | # DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
93 | secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
94 | # Overrides the default auth redirectUrl.
95 | redirect_uri = ""
96 | # Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
97 | # or any other third-party OIDC providers.
98 | url = ""
99 |
100 | [analytics]
101 | enabled = false
102 | port = 54327
103 | vector_port = 54328
104 | # Setup BigQuery project to enable log viewer on local development stack.
105 | # See: https://supabase.com/docs/guides/getting-started/local-development#enabling-local-logging
106 | gcp_project_id = ""
107 | gcp_project_number = ""
108 | gcp_jwt_path = "supabase/gcloud.json"
109 |
--------------------------------------------------------------------------------
/supabase/functions/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["denoland.vscode-deno"]
3 | }
4 |
--------------------------------------------------------------------------------
/supabase/functions/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "deno.enable": true,
3 | "deno.lint": true,
4 | "editor.defaultFormatter": "denoland.vscode-deno"
5 | }
6 |
--------------------------------------------------------------------------------
/supabase/seed.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satansdeer/ztm-notion-clone/83f407169bf413804cd2f0af07278d500e85120f/supabase/seed.sql
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src"],
24 | "references": [{ "path": "./tsconfig.node.json" }]
25 | }
26 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react-swc'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/ztm-notion-clone.code-workspace:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "name": "project-root",
5 | "path": "./"
6 | },
7 | {
8 | "name": "supabase-functions",
9 | "path": "supabase/functions"
10 | }
11 | ],
12 | "settings": {
13 | "files.exclude": {
14 | "supabase/functions/": true
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------