diff --git a/.gitignore b/.gitignore index a0f0e53..82da4af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,39 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# Dependencies +node_modules +.pnp +.pnp.js + +# Local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Testing +coverage + +# Turbo +.turbo + +# Vercel +.vercel + +# Build Outputs +.next/ +out/ +build +dist + + +# Debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Misc .vscode .DS_Store +*.pem diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..d4b4a3b --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +pnpm nano-staged \ No newline at end of file diff --git a/.nanostagedrc b/.nanostagedrc new file mode 100644 index 0000000..af87dd4 --- /dev/null +++ b/.nanostagedrc @@ -0,0 +1,6 @@ +{ + "*.{ts,tsx,json,jsonc}": [ + "biome format --write", + "biome lint" + ] +} diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..d79a9a2 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.13.0 \ No newline at end of file diff --git a/README.md b/README.md index b994bf7..7ac0fd6 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,28 @@ # functional-javascript-programming + 함수형 자바스크립트 프로그래밍 ![image](https://github.com/user-attachments/assets/d31776df-7a65-4064-8a08-3d256aa3aab7) # 시간 및 장소 + - 시간: 매주 일요일 16시 - 장소: 디스코드 # 방식 + - 주 1회 온라인 환경인 디스코드에서 진행합니다. - 최대한 해당 책을 기반으로 코드를 많이 짜보는 것을 목표로 합니다. - 스터디 진행 전에 주 차별 챕터를 읽고 정리합니다. 마크 다운 기반으로 정리를 하고 형식은 자유입니다. 논의하고 싶은 사항이 있다면 포함합니다. - 정리가 완료되면 스터디 전까지 Github 레포의 해당되는 주차의 폴더에 업로드를 합니다. ([참고](https://github.com/FEBookStudy/Grokking-Simplicity)) - - 파일 이름 형식: 이름.md - - 커밋 형식: `docs: 업데이트 내용` + - 파일 이름 형식: 이름.md + - 커밋 형식: `docs: 업데이트 내용` - 온라인으로 스터디 진행 전에 발표자 1명을 무작위로 선정해 발표를 진행합니다. - 발표 후에 궁금한 점, 논의가 필요한 점을 이야기합니다. - - 해당 내용은 질문, 논의별 [Issue](https://github.com/FEBookStudy/Grokking-Simplicity/issues)를 생성해 기록합니다. + - 해당 내용은 질문, 논의별 [Issue](https://github.com/FEBookStudy/Grokking-Simplicity/issues)를 생성해 기록합니다. # 발표 방식 + - 주차 별 브랜치에 정리한 내용을 commit합니다. (`week-1` 브랜치에 `/docs/1주차/이름.md`) - 발표 당일에 `main` 브랜치로 PR을 합니다. - CODEOWNERS와 팀 설정으로 reviewer가 1명 자동 선정됩니다. (Load balance) @@ -27,17 +31,17 @@ # 스터디 상세 일정표 -| **주차** | **날짜** | **학습 내용** | -|---------|-------------|--------------------------------------------| -| **0주차** | 11/25 (20시) | OT 및 스터디 방식 상세 논의 | -| **1주차** | 12/8 | 1장 함수형 자바스크립트 소개 | -| **2주차** | 12/15 | 2장 함수형 자바스크립트를 위한 문법 다시 보기 | -| **3주차** | 12/22 | 3장 Underscore.js를 직접 만들며 함수형 자바스크립트의 뼈대 익히기 | -| **4주차** | 12/29 | 4장 함수 조립하기 | -| **5주차** | 1/5 | 5장 Partial.js와 함수 조립 | -| **6주차** | 1/12 | 6장 값에 대해 & 7장 실전에서 함수형 자바스크립트 더 많이 사용하기 | -| **7주차** | 1/19 | 8장 함수형으로 만드는 할 일 앱 & 9장 메모이제이션 & 회고 | - +| **주차** | **날짜** | **학습 내용** | +| --------- | ------------ | ----------------------------------------------------------------- | +| **0주차** | 11/25 (20시) | OT 및 스터디 방식 상세 논의 | +| **1주차** | 12/8 | 1장 함수형 자바스크립트 소개 | +| **2주차** | 12/15 | 2장 함수형 자바스크립트를 위한 문법 다시 보기 | +| **3주차** | 12/22 | 3장 Underscore.js를 직접 만들며 함수형 자바스크립트의 뼈대 익히기 | +| **4주차** | 12/29 | 4장 함수 조립하기 | +| **5주차** | 1/5 | 5장 Partial.js와 함수 조립 | +| **6주차** | 1/12 | 6장 값에 대해 & 7장 실전에서 함수형 자바스크립트 더 많이 사용하기 | +| **7주차** | 1/19 | 8장 함수형으로 만드는 할 일 앱 & 9장 메모이제이션 & 회고 | # 함수형 자바스크립트 서적 깃허브 참고 + https://github.com/indongyoo/functional-javascript diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..448be1d --- /dev/null +++ b/biome.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.7.0/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "ignore": ["node_modules", "dist", ".next"], + "rules": { + "recommended": true, + "style": { + "useBlockStatements": "error" + } + } + }, + "formatter": { + "enabled": true, + "indentWidth": 2, + "indentStyle": "space", + "lineWidth": 100, + "ignore": ["node_modules", "dist", ".next"] + }, + "json": { + "parser": { + "allowTrailingCommas": true + }, + "formatter": { + "enabled": true + } + }, + "javascript": { + "formatter": { + "enabled": true, + "quoteStyle": "single", + "jsxQuoteStyle": "double", + "trailingComma": "all", + "semicolons": "asNeeded", + "arrowParentheses": "always", + "quoteProperties": "asNeeded" + } + } +} diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..40b1379 --- /dev/null +++ b/cspell.json @@ -0,0 +1,3 @@ +{ + "words": ["functional-javascript-programming", "hyobum"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6563744 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "functional-javascript-programming", + "private": true, + "scripts": { + "clean:branch": "git fetch --prune && git branch | grep -v '^*' | xargs git branch -D", + "clean:cache": "turbo clean", + "build:all": "turbo build", + "start": "turbo start", + "lint": "turbo lint", + "format": "turbo format", + "prepare": "husky", + "preinstall": "corepack enable" + }, + "devDependencies": { + "@biomejs/biome": "1.7.3", + "husky": "^9.0.11", + "nano-staged": "^0.8.0", + "turbo": "^2.0.7", + "typescript": "^5.4.5", + "@types/node": "20.13.0" + }, + "packageManager": "pnpm@9.1.0", + "engines": { + "node": "20.13.0" + } +} diff --git a/playground/README.md b/playground/README.md index 74872fd..7c8d451 100644 --- a/playground/README.md +++ b/playground/README.md @@ -1,50 +1 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js -export default tseslint.config({ - languageOptions: { - // other options... - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - }, -}) -``` - -- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` -- Optionally add `...tseslint.configs.stylisticTypeChecked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: - -```js -// eslint.config.js -import react from 'eslint-plugin-react' - -export default tseslint.config({ - // Set the react version - settings: { react: { version: '18.3' } }, - plugins: { - // Add the react plugin - react, - }, - rules: { - // other rules... - // Enable its recommended rules - ...react.configs.recommended.rules, - ...react.configs['jsx-runtime'].rules, - }, -}) -``` +# functional-javascript-programming playground diff --git a/playground/.gitignore b/playground/apps/home/.gitignore similarity index 100% rename from playground/.gitignore rename to playground/apps/home/.gitignore diff --git a/playground/apps/home/README.md b/playground/apps/home/README.md new file mode 100644 index 0000000..780c92d --- /dev/null +++ b/playground/apps/home/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ["./tsconfig.node.json", "./tsconfig.app.json"], + tsconfigRootDir: import.meta.dirname, + }, + }, +}); +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from "eslint-plugin-react"; + +export default tseslint.config({ + // Set the react version + settings: { react: { version: "18.3" } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs["jsx-runtime"].rules, + }, +}); +``` diff --git a/playground/apps/home/eslint.config.js b/playground/apps/home/eslint.config.js new file mode 100644 index 0000000..0bbf074 --- /dev/null +++ b/playground/apps/home/eslint.config.js @@ -0,0 +1,28 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, + } +); diff --git a/playground/index.html b/playground/apps/home/index.html similarity index 95% rename from playground/index.html rename to playground/apps/home/index.html index e4b78ea..e0d1c84 100644 --- a/playground/index.html +++ b/playground/apps/home/index.html @@ -1,4 +1,4 @@ - + diff --git a/playground/apps/home/package.json b/playground/apps/home/package.json new file mode 100644 index 0000000..0d26381 --- /dev/null +++ b/playground/apps/home/package.json @@ -0,0 +1,36 @@ +{ + "name": "home", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "lint": "biome lint ./src", + "format": "biome format ./src --write", + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@functional-javascript-programming/utils": "workspace:*", + "axios": "^1.7.9", + "js-cookie": "^3.0.5", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^7.0.2" + }, + "devDependencies": { + "@eslint/js": "^9.15.0", + "@originjs/vite-plugin-federation": "^1.3.6", + "@types/js-cookie": "^3.0.6", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^9.15.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.12.0", + "typescript": "~5.6.2", + "typescript-eslint": "^8.15.0", + "vite": "^6.0.1" + } +} diff --git a/playground/public/vite.svg b/playground/apps/home/public/vite.svg similarity index 100% rename from playground/public/vite.svg rename to playground/apps/home/public/vite.svg diff --git a/playground/src/App.css b/playground/apps/home/src/App.css similarity index 80% rename from playground/src/App.css rename to playground/apps/home/src/App.css index b9d355d..172761c 100644 --- a/playground/src/App.css +++ b/playground/apps/home/src/App.css @@ -1,10 +1,3 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - .logo { height: 6em; padding: 1.5em; @@ -34,9 +27,14 @@ } .card { - padding: 2em; + width: 400px; + display: flex; + align-items: center; + justify-content: flex-end; + margin: 0 auto; + padding: 0; } .read-the-docs { - color: #888; + color: var(--blue-300); } diff --git a/playground/apps/home/src/App.tsx b/playground/apps/home/src/App.tsx new file mode 100644 index 0000000..7156f85 --- /dev/null +++ b/playground/apps/home/src/App.tsx @@ -0,0 +1,20 @@ +import { BrowserRouter } from 'react-router-dom' + +import './App.css' +import Router from './router' + +interface Props { + hello?: string +} + +function App({ hello }: Props) { + console.log('hello:', hello) + + return ( + + + + ) +} + +export default App diff --git a/playground/apps/home/src/apis/index.ts b/playground/apps/home/src/apis/index.ts new file mode 100644 index 0000000..6e7898a --- /dev/null +++ b/playground/apps/home/src/apis/index.ts @@ -0,0 +1,10 @@ +import axios, { type AxiosInstance } from 'axios' + +export const axiosInstance: AxiosInstance = axios.create({ + withCredentials: true, + baseURL: '/common', + headers: { + dataType: 'json', + contentType: 'application/x-www-form-urlencoded', + }, +}) diff --git a/playground/src/assets/react.svg b/playground/apps/home/src/assets/react.svg similarity index 100% rename from playground/src/assets/react.svg rename to playground/apps/home/src/assets/react.svg diff --git a/playground/src/main.tsx b/playground/apps/home/src/main.tsx similarity index 77% rename from playground/src/main.tsx rename to playground/apps/home/src/main.tsx index bef5202..79f5105 100644 --- a/playground/src/main.tsx +++ b/playground/apps/home/src/main.tsx @@ -1,8 +1,8 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' -import './index.css' import App from './App.tsx' +// biome-ignore lint/style/noNonNullAssertion: createRoot(document.getElementById('root')!).render( diff --git a/playground/apps/home/src/pages/dashboard/index.tsx b/playground/apps/home/src/pages/dashboard/index.tsx new file mode 100644 index 0000000..62f4cfa --- /dev/null +++ b/playground/apps/home/src/pages/dashboard/index.tsx @@ -0,0 +1,5 @@ +const DashboardPage = () => { + return
함수형 프로그래밍 소개팅에 오신걸 환영합니다.
+} + +export default DashboardPage diff --git a/playground/apps/home/src/pages/entrance/index.tsx b/playground/apps/home/src/pages/entrance/index.tsx new file mode 100644 index 0000000..0aeee18 --- /dev/null +++ b/playground/apps/home/src/pages/entrance/index.tsx @@ -0,0 +1,26 @@ +import viteLogo from '/vite.svg' +import { useNavigate } from 'react-router-dom' + +const EntrancePage = () => { + const navigate = useNavigate() + const goDashboardPage = () => navigate('/home/dashboard') + + return ( + <> +
+ + Vite logo + +
+

+ +

함수형 자바스크립트 프로그래밍 스터디의 멤버들을 소개해드릴까요?

+
+ + + ) +} + +export default EntrancePage diff --git a/playground/apps/home/src/pages/index.ts b/playground/apps/home/src/pages/index.ts new file mode 100644 index 0000000..d604612 --- /dev/null +++ b/playground/apps/home/src/pages/index.ts @@ -0,0 +1,2 @@ +export { default as EntrancePage } from './entrance' +export { default as DashboardPage } from './dashboard' diff --git a/playground/apps/home/src/router/index.tsx b/playground/apps/home/src/router/index.tsx new file mode 100644 index 0000000..32e2e4d --- /dev/null +++ b/playground/apps/home/src/router/index.tsx @@ -0,0 +1,14 @@ +import { Routes, Route } from 'react-router-dom' +import { EntrancePage, DashboardPage } from '@/pages' + +function Router() { + return ( + + } /> + } /> + Other...} /> + + ) +} + +export default Router diff --git a/playground/src/vite-env.d.ts b/playground/apps/home/src/vite-env.d.ts similarity index 100% rename from playground/src/vite-env.d.ts rename to playground/apps/home/src/vite-env.d.ts diff --git a/playground/tsconfig.app.json b/playground/apps/home/tsconfig.app.json similarity index 79% rename from playground/tsconfig.app.json rename to playground/apps/home/tsconfig.app.json index f867de0..b416f44 100644 --- a/playground/tsconfig.app.json +++ b/playground/apps/home/tsconfig.app.json @@ -7,20 +7,23 @@ "module": "ESNext", "skipLibCheck": true, - /* Bundler mode */ - "moduleResolution": "Bundler", + "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", - /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noUncheckedSideEffectImports": true, + + "baseUrl": "./", + "paths": { + "@/*": ["./src/*"] + } }, "include": ["src"] } diff --git a/playground/apps/home/tsconfig.json b/playground/apps/home/tsconfig.json new file mode 100644 index 0000000..d32ff68 --- /dev/null +++ b/playground/apps/home/tsconfig.json @@ -0,0 +1,4 @@ +{ + "files": [], + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }] +} diff --git a/playground/tsconfig.node.json b/playground/apps/home/tsconfig.node.json similarity index 87% rename from playground/tsconfig.node.json rename to playground/apps/home/tsconfig.node.json index abcd7f0..c921d97 100644 --- a/playground/tsconfig.node.json +++ b/playground/apps/home/tsconfig.node.json @@ -6,14 +6,12 @@ "module": "ESNext", "skipLibCheck": true, - /* Bundler mode */ - "moduleResolution": "Bundler", + "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, - /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, diff --git a/playground/apps/home/vite.config.ts b/playground/apps/home/vite.config.ts new file mode 100644 index 0000000..15a122d --- /dev/null +++ b/playground/apps/home/vite.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' +import federation from '@originjs/vite-plugin-federation' +import * as path from 'node:path' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + react(), + federation({ + name: 'remote-app', + filename: 'home.js', + // Modules to expose + exposes: { + './HomeRoutes': './src/router/index.tsx', + }, + shared: ['react', 'react-dom', 'react-router-dom'], + }), + ], + server: { + port: 3001, + }, + preview: { + port: 3001, + }, + resolve: { + alias: [ + { + find: '@', + replacement: path.resolve(__dirname, 'src'), + }, + ], + }, + build: { + modulePreload: false, + target: 'esnext', + minify: false, + cssCodeSplit: false, + }, +}) diff --git a/playground/apps/members/.gitignore b/playground/apps/members/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/playground/apps/members/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/playground/apps/members/README.md b/playground/apps/members/README.md new file mode 100644 index 0000000..780c92d --- /dev/null +++ b/playground/apps/members/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ["./tsconfig.node.json", "./tsconfig.app.json"], + tsconfigRootDir: import.meta.dirname, + }, + }, +}); +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from "eslint-plugin-react"; + +export default tseslint.config({ + // Set the react version + settings: { react: { version: "18.3" } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs["jsx-runtime"].rules, + }, +}); +``` diff --git a/playground/apps/members/eslint.config.js b/playground/apps/members/eslint.config.js new file mode 100644 index 0000000..0bbf074 --- /dev/null +++ b/playground/apps/members/eslint.config.js @@ -0,0 +1,28 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, + } +); diff --git a/playground/apps/members/index.html b/playground/apps/members/index.html new file mode 100644 index 0000000..e0d1c84 --- /dev/null +++ b/playground/apps/members/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/playground/apps/members/package.json b/playground/apps/members/package.json new file mode 100644 index 0000000..77c9f94 --- /dev/null +++ b/playground/apps/members/package.json @@ -0,0 +1,36 @@ +{ + "name": "members", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "lint": "biome lint ./src", + "format": "biome format ./src --write", + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@functional-javascript-programming/utils": "workspace:*", + "axios": "^1.7.9", + "js-cookie": "^3.0.5", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^7.0.2" + }, + "devDependencies": { + "@eslint/js": "^9.15.0", + "@originjs/vite-plugin-federation": "^1.3.6", + "@types/js-cookie": "^3.0.6", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^9.15.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.12.0", + "typescript": "~5.6.2", + "typescript-eslint": "^8.15.0", + "vite": "^6.0.1" + } +} diff --git a/playground/apps/members/public/vite.svg b/playground/apps/members/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/playground/apps/members/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/apps/members/src/App.css b/playground/apps/members/src/App.css new file mode 100644 index 0000000..172761c --- /dev/null +++ b/playground/apps/members/src/App.css @@ -0,0 +1,40 @@ +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + width: 400px; + display: flex; + align-items: center; + justify-content: flex-end; + margin: 0 auto; + padding: 0; +} + +.read-the-docs { + color: var(--blue-300); +} diff --git a/playground/apps/members/src/App.tsx b/playground/apps/members/src/App.tsx new file mode 100644 index 0000000..7156f85 --- /dev/null +++ b/playground/apps/members/src/App.tsx @@ -0,0 +1,20 @@ +import { BrowserRouter } from 'react-router-dom' + +import './App.css' +import Router from './router' + +interface Props { + hello?: string +} + +function App({ hello }: Props) { + console.log('hello:', hello) + + return ( + + + + ) +} + +export default App diff --git a/playground/apps/members/src/apis/index.ts b/playground/apps/members/src/apis/index.ts new file mode 100644 index 0000000..6e7898a --- /dev/null +++ b/playground/apps/members/src/apis/index.ts @@ -0,0 +1,10 @@ +import axios, { type AxiosInstance } from 'axios' + +export const axiosInstance: AxiosInstance = axios.create({ + withCredentials: true, + baseURL: '/common', + headers: { + dataType: 'json', + contentType: 'application/x-www-form-urlencoded', + }, +}) diff --git a/playground/apps/members/src/assets/react.svg b/playground/apps/members/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/playground/apps/members/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/apps/members/src/main.tsx b/playground/apps/members/src/main.tsx new file mode 100644 index 0000000..79f5105 --- /dev/null +++ b/playground/apps/members/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App.tsx' + +// biome-ignore lint/style/noNonNullAssertion: +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/playground/apps/members/src/pages/dashboard/index.tsx b/playground/apps/members/src/pages/dashboard/index.tsx new file mode 100644 index 0000000..1bda9a4 --- /dev/null +++ b/playground/apps/members/src/pages/dashboard/index.tsx @@ -0,0 +1,15 @@ +const DashboardPage = () => { + return ( +
+
    +
  • 안녕하세요 저는 holim0!
  • +
  • 안녕하세요 저는 wo-o29!
  • +
  • 안녕하세요 저는 wontory!
  • +
  • 안녕하세요 저는 onlyoon!
  • +
  • 안녕하세요 저는 createhb21!
  • +
+
+ ) +} + +export default DashboardPage diff --git a/playground/apps/members/src/pages/entrance/index.tsx b/playground/apps/members/src/pages/entrance/index.tsx new file mode 100644 index 0000000..144a0be --- /dev/null +++ b/playground/apps/members/src/pages/entrance/index.tsx @@ -0,0 +1,23 @@ +import viteLogo from '/vite.svg' +import { useNavigate } from 'react-router-dom' + +const EntrancePage = () => { + const navigate = useNavigate() + const goDashboardPage = () => navigate('/members/dashboard') + + return ( + <> +
+ + Vite logo + +
+

함수형 자바스크립트 프로그래밍 스터디의 멤버들을 소개할게요!

+ + + ) +} + +export default EntrancePage diff --git a/playground/apps/members/src/pages/index.ts b/playground/apps/members/src/pages/index.ts new file mode 100644 index 0000000..d604612 --- /dev/null +++ b/playground/apps/members/src/pages/index.ts @@ -0,0 +1,2 @@ +export { default as EntrancePage } from './entrance' +export { default as DashboardPage } from './dashboard' diff --git a/playground/apps/members/src/router/index.tsx b/playground/apps/members/src/router/index.tsx new file mode 100644 index 0000000..32e2e4d --- /dev/null +++ b/playground/apps/members/src/router/index.tsx @@ -0,0 +1,14 @@ +import { Routes, Route } from 'react-router-dom' +import { EntrancePage, DashboardPage } from '@/pages' + +function Router() { + return ( + + } /> + } /> + Other...} /> + + ) +} + +export default Router diff --git a/playground/apps/members/src/vite-env.d.ts b/playground/apps/members/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/playground/apps/members/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/playground/apps/members/tsconfig.app.json b/playground/apps/members/tsconfig.app.json new file mode 100644 index 0000000..b416f44 --- /dev/null +++ b/playground/apps/members/tsconfig.app.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + + "baseUrl": "./", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/playground/apps/members/tsconfig.json b/playground/apps/members/tsconfig.json new file mode 100644 index 0000000..d32ff68 --- /dev/null +++ b/playground/apps/members/tsconfig.json @@ -0,0 +1,4 @@ +{ + "files": [], + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }] +} diff --git a/playground/apps/members/tsconfig.node.json b/playground/apps/members/tsconfig.node.json new file mode 100644 index 0000000..c921d97 --- /dev/null +++ b/playground/apps/members/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/playground/apps/members/vite.config.ts b/playground/apps/members/vite.config.ts new file mode 100644 index 0000000..eb32d26 --- /dev/null +++ b/playground/apps/members/vite.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' +import federation from '@originjs/vite-plugin-federation' +import * as path from 'node:path' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + react(), + federation({ + name: 'remote-app', + filename: 'members.js', + // Modules to expose + exposes: { + './MembersRoutes': './src/router/index.tsx', + }, + shared: ['react', 'react-dom', 'react-router-dom'], + }), + ], + server: { + port: 3003, + }, + preview: { + port: 3003, + }, + resolve: { + alias: [ + { + find: '@', + replacement: path.resolve(__dirname, 'src'), + }, + ], + }, + build: { + modulePreload: false, + target: 'esnext', + minify: false, + cssCodeSplit: false, + }, +}) diff --git a/playground/apps/projects/.gitignore b/playground/apps/projects/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/playground/apps/projects/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/playground/apps/projects/README.md b/playground/apps/projects/README.md new file mode 100644 index 0000000..780c92d --- /dev/null +++ b/playground/apps/projects/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ["./tsconfig.node.json", "./tsconfig.app.json"], + tsconfigRootDir: import.meta.dirname, + }, + }, +}); +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from "eslint-plugin-react"; + +export default tseslint.config({ + // Set the react version + settings: { react: { version: "18.3" } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs["jsx-runtime"].rules, + }, +}); +``` diff --git a/playground/apps/projects/eslint.config.js b/playground/apps/projects/eslint.config.js new file mode 100644 index 0000000..0bbf074 --- /dev/null +++ b/playground/apps/projects/eslint.config.js @@ -0,0 +1,28 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, + } +); diff --git a/playground/apps/projects/index.html b/playground/apps/projects/index.html new file mode 100644 index 0000000..e0d1c84 --- /dev/null +++ b/playground/apps/projects/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/playground/apps/projects/package.json b/playground/apps/projects/package.json new file mode 100644 index 0000000..f00ea1d --- /dev/null +++ b/playground/apps/projects/package.json @@ -0,0 +1,36 @@ +{ + "name": "projects", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "lint": "biome lint ./src", + "format": "biome format ./src --write", + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@functional-javascript-programming/utils": "workspace:*", + "axios": "^1.7.9", + "js-cookie": "^3.0.5", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^7.0.2" + }, + "devDependencies": { + "@eslint/js": "^9.15.0", + "@originjs/vite-plugin-federation": "^1.3.6", + "@types/js-cookie": "^3.0.6", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^9.15.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.12.0", + "typescript": "~5.6.2", + "typescript-eslint": "^8.15.0", + "vite": "^6.0.1" + } +} diff --git a/playground/apps/projects/public/vite.svg b/playground/apps/projects/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/playground/apps/projects/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/apps/projects/src/App.css b/playground/apps/projects/src/App.css new file mode 100644 index 0000000..172761c --- /dev/null +++ b/playground/apps/projects/src/App.css @@ -0,0 +1,40 @@ +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + width: 400px; + display: flex; + align-items: center; + justify-content: flex-end; + margin: 0 auto; + padding: 0; +} + +.read-the-docs { + color: var(--blue-300); +} diff --git a/playground/apps/projects/src/App.tsx b/playground/apps/projects/src/App.tsx new file mode 100644 index 0000000..7156f85 --- /dev/null +++ b/playground/apps/projects/src/App.tsx @@ -0,0 +1,20 @@ +import { BrowserRouter } from 'react-router-dom' + +import './App.css' +import Router from './router' + +interface Props { + hello?: string +} + +function App({ hello }: Props) { + console.log('hello:', hello) + + return ( + + + + ) +} + +export default App diff --git a/playground/apps/projects/src/apis/index.ts b/playground/apps/projects/src/apis/index.ts new file mode 100644 index 0000000..6e7898a --- /dev/null +++ b/playground/apps/projects/src/apis/index.ts @@ -0,0 +1,10 @@ +import axios, { type AxiosInstance } from 'axios' + +export const axiosInstance: AxiosInstance = axios.create({ + withCredentials: true, + baseURL: '/common', + headers: { + dataType: 'json', + contentType: 'application/x-www-form-urlencoded', + }, +}) diff --git a/playground/apps/projects/src/assets/react.svg b/playground/apps/projects/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/playground/apps/projects/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/apps/projects/src/main.tsx b/playground/apps/projects/src/main.tsx new file mode 100644 index 0000000..79f5105 --- /dev/null +++ b/playground/apps/projects/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App.tsx' + +// biome-ignore lint/style/noNonNullAssertion: +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/playground/apps/projects/src/pages/dashboard/index.tsx b/playground/apps/projects/src/pages/dashboard/index.tsx new file mode 100644 index 0000000..1c0ac55 --- /dev/null +++ b/playground/apps/projects/src/pages/dashboard/index.tsx @@ -0,0 +1,5 @@ +const DashboardPage = () => { + return
함산기 - 함수형 프로그래밍을 활용해서 계산기를 만들었어요.
+} + +export default DashboardPage diff --git a/playground/apps/projects/src/pages/entrance/index.tsx b/playground/apps/projects/src/pages/entrance/index.tsx new file mode 100644 index 0000000..8c57251 --- /dev/null +++ b/playground/apps/projects/src/pages/entrance/index.tsx @@ -0,0 +1,35 @@ +import { useReducer } from 'react' +import Cookies from 'js-cookie' + +import viteLogo from '/vite.svg' +import { useNavigate } from 'react-router-dom' + +const EntrancePage = () => { + const [showCookie, toggleCookie] = useReducer((show) => !show, false) + + const getCookieString = () => Cookies.get('hi') ?? '안녕하세요' + + const navigate = useNavigate() + const goDashboardPage = () => navigate('/projects/dashboard') + + return ( + <> +
+ + Vite logo + +
+

다음과 같은 프로젝트를 만들고 있어요

+ + {showCookie &&

{getCookieString()}

} +
+ + + ) +} + +export default EntrancePage diff --git a/playground/apps/projects/src/pages/index.ts b/playground/apps/projects/src/pages/index.ts new file mode 100644 index 0000000..d604612 --- /dev/null +++ b/playground/apps/projects/src/pages/index.ts @@ -0,0 +1,2 @@ +export { default as EntrancePage } from './entrance' +export { default as DashboardPage } from './dashboard' diff --git a/playground/apps/projects/src/router/index.tsx b/playground/apps/projects/src/router/index.tsx new file mode 100644 index 0000000..32e2e4d --- /dev/null +++ b/playground/apps/projects/src/router/index.tsx @@ -0,0 +1,14 @@ +import { Routes, Route } from 'react-router-dom' +import { EntrancePage, DashboardPage } from '@/pages' + +function Router() { + return ( + + } /> + } /> + Other...} /> + + ) +} + +export default Router diff --git a/playground/apps/projects/src/vite-env.d.ts b/playground/apps/projects/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/playground/apps/projects/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/playground/apps/projects/tsconfig.app.json b/playground/apps/projects/tsconfig.app.json new file mode 100644 index 0000000..b416f44 --- /dev/null +++ b/playground/apps/projects/tsconfig.app.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + + "baseUrl": "./", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/playground/apps/projects/tsconfig.json b/playground/apps/projects/tsconfig.json new file mode 100644 index 0000000..d32ff68 --- /dev/null +++ b/playground/apps/projects/tsconfig.json @@ -0,0 +1,4 @@ +{ + "files": [], + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }] +} diff --git a/playground/apps/projects/tsconfig.node.json b/playground/apps/projects/tsconfig.node.json new file mode 100644 index 0000000..c921d97 --- /dev/null +++ b/playground/apps/projects/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/playground/apps/projects/vite.config.ts b/playground/apps/projects/vite.config.ts new file mode 100644 index 0000000..6d6cc01 --- /dev/null +++ b/playground/apps/projects/vite.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' +import federation from '@originjs/vite-plugin-federation' +import * as path from 'node:path' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + react(), + federation({ + name: 'remote-app', + filename: 'projects.js', + // Modules to expose + exposes: { + './ProjectsRoutes': './src/router/index.tsx', + }, + shared: ['react', 'react-dom', 'react-router-dom'], + }), + ], + server: { + port: 3002, + }, + preview: { + port: 3002, + }, + resolve: { + alias: [ + { + find: '@', + replacement: path.resolve(__dirname, 'src'), + }, + ], + }, + build: { + modulePreload: false, + target: 'esnext', + minify: false, + cssCodeSplit: false, + }, +}) diff --git a/playground/eslint.config.js b/playground/eslint.config.js deleted file mode 100644 index 092408a..0000000 --- a/playground/eslint.config.js +++ /dev/null @@ -1,28 +0,0 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' - -export default tseslint.config( - { ignores: ['dist'] }, - { - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, - }, - rules: { - ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, - }, -) diff --git a/playground/packages/esbuild/index.js b/playground/packages/esbuild/index.js new file mode 100644 index 0000000..8d37302 --- /dev/null +++ b/playground/packages/esbuild/index.js @@ -0,0 +1,64 @@ +const { build, context } = require("esbuild"); + +const run = async ({ entryPoints = ["src/index.ts"], pkg, config = {} }) => { + const dev = process.argv.includes("--dev"); + const minify = !dev; + const shouldWatch = process.argv.includes("--watch"); + + const external = Object.keys({ + ...pkg.dependencies, + ...pkg.peerDependencies, + }); + + const baseConfig = { + entryPoints, + bundle: true, + minify, + sourcemap: true, + outdir: "dist", + target: "es2019", + external, + ...config, + }; + + try { + if (shouldWatch) { + // watch 모드일 때는 context를 사용 + const [esmContext, cjsContext] = await Promise.all([ + context({ + ...baseConfig, + format: "esm", + }), + context({ + ...baseConfig, + format: "cjs", + outExtension: { + ".js": ".cjs", + }, + }), + ]); + + await Promise.all([esmContext.watch(), cjsContext.watch()]); + } else { + // 일반 빌드 + await Promise.all([ + build({ + ...baseConfig, + format: "esm", + }), + build({ + ...baseConfig, + format: "cjs", + outExtension: { + ".js": ".cjs", + }, + }), + ]); + } + } catch (error) { + console.error("Build failed:", error); + process.exit(1); + } +}; + +module.exports = run; diff --git a/playground/packages/esbuild/package.json b/playground/packages/esbuild/package.json new file mode 100644 index 0000000..8a226a6 --- /dev/null +++ b/playground/packages/esbuild/package.json @@ -0,0 +1,9 @@ +{ + "name": "@functional-javascript-programming/esbuild-config", + "version": "0.0.2", + "main": "index.js", + "files": ["index.js"], + "dependencies": { + "esbuild": "^0.24.0" + } +} diff --git a/playground/packages/tsconfig/base.json b/playground/packages/tsconfig/base.json new file mode 100644 index 0000000..0f80cfd --- /dev/null +++ b/playground/packages/tsconfig/base.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Default", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "esModuleInterop": true, + "incremental": false, + "isolatedModules": true, + "lib": ["es2022", "DOM", "DOM.Iterable"], + "module": "NodeNext", + "moduleDetection": "force", + "moduleResolution": "NodeNext", + "noUncheckedIndexedAccess": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022" + } +} diff --git a/playground/packages/tsconfig/nextjs.json b/playground/packages/tsconfig/nextjs.json new file mode 100644 index 0000000..44f4289 --- /dev/null +++ b/playground/packages/tsconfig/nextjs.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Next.js", + "extends": "./base.json", + "compilerOptions": { + "plugins": [{ "name": "next" }], + "module": "ESNext", + "moduleResolution": "Bundler", + "allowJs": true, + "jsx": "preserve", + "noEmit": true + } +} diff --git a/playground/packages/tsconfig/package.json b/playground/packages/tsconfig/package.json new file mode 100644 index 0000000..344d3f0 --- /dev/null +++ b/playground/packages/tsconfig/package.json @@ -0,0 +1,4 @@ +{ + "name": "@functional-javascript-programming/typescript-config", + "version": "0.0.1" +} diff --git a/playground/packages/tsconfig/react-library.json b/playground/packages/tsconfig/react-library.json new file mode 100644 index 0000000..44924d9 --- /dev/null +++ b/playground/packages/tsconfig/react-library.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "React Library", + "extends": "./base.json", + "compilerOptions": { + "jsx": "react-jsx" + } +} diff --git a/playground/packages/utils/package.json b/playground/packages/utils/package.json new file mode 100644 index 0000000..391109b --- /dev/null +++ b/playground/packages/utils/package.json @@ -0,0 +1,15 @@ +{ + "name": "@functional-javascript-programming/utils", + "version": "0.0.0", + "private": true, + "exports": { + ".": "./src/index.ts" + }, + "scripts": { + "lint": "biome lint ./src", + "format": "biome format ./src --write" + }, + "devDependencies": { + "@functional-javascript-programming/typescript-config": "workspace:*" + } +} diff --git a/playground/packages/utils/src/add/add.ts b/playground/packages/utils/src/add/add.ts new file mode 100644 index 0000000..c39ee17 --- /dev/null +++ b/playground/packages/utils/src/add/add.ts @@ -0,0 +1,3 @@ +export const addNumbers = (a: number, b: number) => { + return a + b +} diff --git a/playground/packages/utils/src/add/index.ts b/playground/packages/utils/src/add/index.ts new file mode 100644 index 0000000..2bed2c4 --- /dev/null +++ b/playground/packages/utils/src/add/index.ts @@ -0,0 +1 @@ +export * from './add' diff --git a/playground/packages/utils/src/index.ts b/playground/packages/utils/src/index.ts new file mode 100644 index 0000000..2bed2c4 --- /dev/null +++ b/playground/packages/utils/src/index.ts @@ -0,0 +1 @@ +export * from './add' diff --git a/playground/packages/utils/tsconfig.json b/playground/packages/utils/tsconfig.json new file mode 100644 index 0000000..1911fb6 --- /dev/null +++ b/playground/packages/utils/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@functional-javascript-programming/typescript-config/react-library.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["src"] +} diff --git a/playground/src/App.tsx b/playground/src/App.tsx deleted file mode 100644 index 3d7ded3..0000000 --- a/playground/src/App.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' - -function App() { - const [count, setCount] = useState(0) - - return ( - <> - -

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

- - ) -} - -export default App diff --git a/playground/src/index.css b/playground/src/index.css deleted file mode 100644 index 6119ad9..0000000 --- a/playground/src/index.css +++ /dev/null @@ -1,68 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/playground/tsconfig.json b/playground/tsconfig.json deleted file mode 100644 index 1ffef60..0000000 --- a/playground/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ] -} diff --git a/playground/vite.config.ts b/playground/vite.config.ts deleted file mode 100644 index 2328e17..0000000 --- a/playground/vite.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react-swc' - -// https://vite.dev/config/ -export default defineConfig({ - plugins: [react()], -}) diff --git a/playground/web/.gitignore b/playground/web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/playground/web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/playground/web/README.md b/playground/web/README.md new file mode 100644 index 0000000..780c92d --- /dev/null +++ b/playground/web/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ["./tsconfig.node.json", "./tsconfig.app.json"], + tsconfigRootDir: import.meta.dirname, + }, + }, +}); +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from "eslint-plugin-react"; + +export default tseslint.config({ + // Set the react version + settings: { react: { version: "18.3" } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs["jsx-runtime"].rules, + }, +}); +``` diff --git a/playground/web/eslint.config.js b/playground/web/eslint.config.js new file mode 100644 index 0000000..0bbf074 --- /dev/null +++ b/playground/web/eslint.config.js @@ -0,0 +1,28 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, + } +); diff --git a/playground/web/index.html b/playground/web/index.html new file mode 100644 index 0000000..e0d1c84 --- /dev/null +++ b/playground/web/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/playground/package.json b/playground/web/package.json similarity index 58% rename from playground/package.json rename to playground/web/package.json index 2851f67..45a6942 100644 --- a/playground/package.json +++ b/playground/web/package.json @@ -1,5 +1,5 @@ { - "name": "playground", + "name": "web", "private": true, "version": "0.0.0", "type": "module", @@ -10,20 +10,25 @@ "preview": "vite preview" }, "dependencies": { + "axios": "^1.7.9", + "js-cookie": "^3.0.5", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^7.0.2" }, "devDependencies": { - "@eslint/js": "^9.13.0", + "@eslint/js": "^9.15.0", + "@originjs/vite-plugin-federation": "^1.3.6", + "@types/js-cookie": "^3.0.6", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react-swc": "^3.5.0", - "eslint": "^9.13.0", + "eslint": "^9.15.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", - "globals": "^15.11.0", + "globals": "^15.12.0", "typescript": "~5.6.2", - "typescript-eslint": "^8.11.0", - "vite": "^5.4.10" + "typescript-eslint": "^8.15.0", + "vite": "^6.0.1" } } diff --git a/playground/web/public/vite.svg b/playground/web/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/playground/web/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/web/src/App.tsx b/playground/web/src/App.tsx new file mode 100644 index 0000000..1d79560 --- /dev/null +++ b/playground/web/src/App.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import { BrowserRouter } from 'react-router-dom' + +import Router from './router' + +function App() { + return ( + + + + + + ) +} + +export default App diff --git a/playground/web/src/apis/index.ts b/playground/web/src/apis/index.ts new file mode 100644 index 0000000..1e36302 --- /dev/null +++ b/playground/web/src/apis/index.ts @@ -0,0 +1,7 @@ +import axios, { type AxiosInstance } from 'axios' + +const axiosInstance: AxiosInstance = axios.create({ + baseURL: '/api', +}) + +export { axiosInstance } diff --git a/playground/web/src/assets/icons/keyboard-icon.tsx b/playground/web/src/assets/icons/keyboard-icon.tsx new file mode 100644 index 0000000..dd910a3 --- /dev/null +++ b/playground/web/src/assets/icons/keyboard-icon.tsx @@ -0,0 +1,17 @@ +export function KeyboardIcon() { + return ( + + Phrase + + + + + + + + + ) +} diff --git a/playground/web/src/components/index.ts b/playground/web/src/components/index.ts new file mode 100644 index 0000000..8405297 --- /dev/null +++ b/playground/web/src/components/index.ts @@ -0,0 +1,2 @@ +export * as LayoutComponent from './layout' +export * as UiComponent from './ui' diff --git a/playground/web/src/components/layout/Base.tsx b/playground/web/src/components/layout/Base.tsx new file mode 100644 index 0000000..9d5ad0c --- /dev/null +++ b/playground/web/src/components/layout/Base.tsx @@ -0,0 +1,17 @@ +import { Outlet } from 'react-router-dom' +import { UiComponent } from '..' + +function Base() { + return ( + <> + + +
+ +
+ {/* {enabledGlobalLoading && } */} + + ) +} + +export default Base diff --git a/playground/web/src/components/layout/index.ts b/playground/web/src/components/layout/index.ts new file mode 100644 index 0000000..75486f4 --- /dev/null +++ b/playground/web/src/components/layout/index.ts @@ -0,0 +1 @@ +export { default as Base } from './Base' diff --git a/playground/web/src/components/ui/Header/Header.tsx b/playground/web/src/components/ui/Header/Header.tsx new file mode 100644 index 0000000..cdaed13 --- /dev/null +++ b/playground/web/src/components/ui/Header/Header.tsx @@ -0,0 +1,17 @@ +import { useNavigate } from 'react-router-dom' + +function Header() { + const navigate = useNavigate() + const onClickLogoItem = () => { + navigate('/landing') + } + return ( +
+ +
+ ) +} + +export default Header diff --git a/playground/web/src/components/ui/Header/index.ts b/playground/web/src/components/ui/Header/index.ts new file mode 100644 index 0000000..6f8c579 --- /dev/null +++ b/playground/web/src/components/ui/Header/index.ts @@ -0,0 +1 @@ +export { default } from './Header' diff --git a/playground/web/src/components/ui/Navigation/Navigation.tsx b/playground/web/src/components/ui/Navigation/Navigation.tsx new file mode 100644 index 0000000..716effe --- /dev/null +++ b/playground/web/src/components/ui/Navigation/Navigation.tsx @@ -0,0 +1,47 @@ +import { useNavigate, useLocation } from 'react-router-dom' + +const NAV_LIST = [ + { + name: '홈', + path: '/home', + }, + { + name: '멤버 소개', + path: '/members', + }, + { + name: '프로젝트', + path: '/projects', + }, +] + +function Navigation() { + const navigate = useNavigate() + const { pathname } = useLocation() + + const onClickNavItem = (path: string) => { + navigate(path) + } + + return ( + + ) +} + +export default Navigation diff --git a/playground/web/src/components/ui/Navigation/index.ts b/playground/web/src/components/ui/Navigation/index.ts new file mode 100644 index 0000000..e09ebad --- /dev/null +++ b/playground/web/src/components/ui/Navigation/index.ts @@ -0,0 +1 @@ +export { default } from './Navigation' diff --git a/playground/web/src/components/ui/index.ts b/playground/web/src/components/ui/index.ts new file mode 100644 index 0000000..8c65e82 --- /dev/null +++ b/playground/web/src/components/ui/index.ts @@ -0,0 +1,2 @@ +export { default as Header } from './Header' +export { default as Navigation } from './Navigation' diff --git a/playground/web/src/data/path.ts b/playground/web/src/data/path.ts new file mode 100644 index 0000000..c492342 --- /dev/null +++ b/playground/web/src/data/path.ts @@ -0,0 +1,8 @@ +const PATH = { + landing: '/landing', + home: '/home/*', + projects: '/projects/*', + members: '/members/*', +} as const + +export { PATH } diff --git a/playground/web/src/globals.d.ts b/playground/web/src/globals.d.ts new file mode 100644 index 0000000..c53a449 --- /dev/null +++ b/playground/web/src/globals.d.ts @@ -0,0 +1,5 @@ +declare module '*.module.css' + +declare module 'home/HomeRoutes' +declare module 'projects/ProjectsRoutes' +declare module 'members/MembersRoutes' diff --git a/playground/web/src/hooks/index.ts b/playground/web/src/hooks/index.ts new file mode 100644 index 0000000..0380b3a --- /dev/null +++ b/playground/web/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './useQueryParams' diff --git a/playground/web/src/hooks/useQueryParams.ts b/playground/web/src/hooks/useQueryParams.ts new file mode 100644 index 0000000..021176c --- /dev/null +++ b/playground/web/src/hooks/useQueryParams.ts @@ -0,0 +1,62 @@ +import { useState, useEffect, useCallback } from 'react' + +export const useQueryParams = () => { + const [queryParams, setQueryParams] = useState>({}) + + const parseQueryParams = useCallback(() => { + const params = new URLSearchParams(window.location.search) + const parsedParams: Record = {} + params.forEach((value, key) => { + parsedParams[key] = value + }) + setQueryParams(parsedParams) + }, []) + + useEffect(() => { + parseQueryParams() + + const handlePopState = () => { + parseQueryParams() + } + + window.addEventListener('popstate', handlePopState) + + return () => { + window.removeEventListener('popstate', handlePopState) + } + }, [parseQueryParams]) + + const getQueryParam = useCallback( + (key: string): string | null => { + return queryParams[key] || null + }, + [queryParams], + ) + + const setQueryParam = useCallback( + (key: string, value: string) => { + const params = new URLSearchParams(window.location.search) + params.set(key, value) + window.history.pushState({}, '', `${window.location.pathname}?${params.toString()}`) + parseQueryParams() + }, + [parseQueryParams], + ) + + const removeQueryParam = useCallback( + (key: string) => { + const params = new URLSearchParams(window.location.search) + params.delete(key) + window.history.pushState({}, '', `${window.location.pathname}?${params.toString()}`) + parseQueryParams() + }, + [parseQueryParams], + ) + + return { + queryParams, + getQueryParam, + setQueryParam, + removeQueryParam, + } +} diff --git a/playground/web/src/index.css b/playground/web/src/index.css new file mode 100644 index 0000000..b3016d3 --- /dev/null +++ b/playground/web/src/index.css @@ -0,0 +1,89 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +body { + margin: 0; + display: flex; + place-items: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +ul { + list-style: none; +} + +header { + position: fixed; + height: 60px; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + background-color: cadetblue; + padding: 0 2rem; +} + +aside { + position: fixed; + top: 60px; + left: 0; + height: 100%; + width: 20%; + color: black; + background-color: antiquewhite; + font-size: 18px; + font-weight: 700; +} + +aside ul { + display: flex; + flex-direction: column; + gap: 12px; + padding-top: 100px; +} + +aside ul li { + cursor: pointer; +} + +main { + position: absolute; + top: 60px; + left: 20%; + max-height: calc(100% - 60px); + max-width: calc(100% - 20%); + padding: 2rem; +} + +button { + border: none; + outline: none; + background-color: aquamarine; + cursor: pointer; +} + +.active { + color: darkorange; +} diff --git a/playground/web/src/main.tsx b/playground/web/src/main.tsx new file mode 100644 index 0000000..44ed599 --- /dev/null +++ b/playground/web/src/main.tsx @@ -0,0 +1,12 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App' + +import './index.css' + +// biome-ignore lint/style/noNonNullAssertion: +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/playground/web/src/pages/index.ts b/playground/web/src/pages/index.ts new file mode 100644 index 0000000..a25780d --- /dev/null +++ b/playground/web/src/pages/index.ts @@ -0,0 +1 @@ +export { default } from './landing' diff --git a/playground/web/src/pages/landing/index.tsx b/playground/web/src/pages/landing/index.tsx new file mode 100644 index 0000000..86f9cc7 --- /dev/null +++ b/playground/web/src/pages/landing/index.tsx @@ -0,0 +1,21 @@ +import Cookies from 'js-cookie' +import { useNavigate } from 'react-router-dom' + +function LandingContent() { + const navigate = useNavigate() + const requestLogin = () => { + Cookies.set('hi', 'Hola!') + navigate('/projects') + } + + return ( +
+

안녕하세요 함수형 프로그래밍 스터디입니다.

+ +
+ ) +} + +export default LandingContent diff --git a/playground/web/src/router/index.tsx b/playground/web/src/router/index.tsx new file mode 100644 index 0000000..5ad7080 --- /dev/null +++ b/playground/web/src/router/index.tsx @@ -0,0 +1,11 @@ +import { useRoutes } from 'react-router-dom' + +import { publicRoutes } from './routes/public' + +function Router() { + const routes = useRoutes([publicRoutes]) + + return routes +} + +export default Router diff --git a/playground/web/src/router/routes/public.tsx b/playground/web/src/router/routes/public.tsx new file mode 100644 index 0000000..3699e90 --- /dev/null +++ b/playground/web/src/router/routes/public.tsx @@ -0,0 +1,39 @@ +import { type RouteObject, Navigate } from 'react-router-dom' + +import HomeRoutes from 'home/HomeRoutes' +import ProjectsRoutes from 'projects/ProjectsRoutes' +import MembersRoutes from 'members/MembersRoutes' + +import LandingContent from '@/pages' +import { LayoutComponent } from '@/components' +import { PATH } from '@/data/path' + +export const publicRoutes: RouteObject = { + element: , + children: [ + { + children: [ + { + path: PATH.landing, + element: , + }, + { + path: PATH.home, + element: , + }, + { + path: PATH.members, + element: , + }, + { + path: PATH.projects, + element: , + }, + { + path: '/', + element: , + }, + ], + }, + ], +} diff --git a/playground/web/src/types/auth.ts b/playground/web/src/types/auth.ts new file mode 100644 index 0000000..3fabe44 --- /dev/null +++ b/playground/web/src/types/auth.ts @@ -0,0 +1,4 @@ +export interface IToken { + accessToken: string + refreshToken: string +} diff --git a/playground/web/src/types/index.ts b/playground/web/src/types/index.ts new file mode 100644 index 0000000..f140b2e --- /dev/null +++ b/playground/web/src/types/index.ts @@ -0,0 +1 @@ +export * from './auth' diff --git a/playground/web/src/vite-env.d.ts b/playground/web/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/playground/web/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/playground/web/tsconfig.app.json b/playground/web/tsconfig.app.json new file mode 100644 index 0000000..b416f44 --- /dev/null +++ b/playground/web/tsconfig.app.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + + "baseUrl": "./", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/playground/web/tsconfig.json b/playground/web/tsconfig.json new file mode 100644 index 0000000..d32ff68 --- /dev/null +++ b/playground/web/tsconfig.json @@ -0,0 +1,4 @@ +{ + "files": [], + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }] +} diff --git a/playground/web/tsconfig.node.json b/playground/web/tsconfig.node.json new file mode 100644 index 0000000..c921d97 --- /dev/null +++ b/playground/web/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/playground/web/vite.config.ts b/playground/web/vite.config.ts new file mode 100644 index 0000000..8592d34 --- /dev/null +++ b/playground/web/vite.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' +import federation from '@originjs/vite-plugin-federation' +import * as path from 'node:path' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + react(), + federation({ + name: 'host-app', + remotes: { + home: 'http://localhost:3001/assets/home.js', + projects: 'http://localhost:3002/assets/projects.js', + members: 'http://localhost:3003/assets/members.js', + }, + shared: ['react', 'react-dom', 'react-router-dom'], + }), + ], + server: { + port: 3000, + }, + preview: { + port: 3000, + }, + resolve: { + alias: [ + { + find: '@', + replacement: path.resolve(__dirname, 'src'), + }, + ], + }, + build: { + modulePreload: false, + target: 'esnext', + minify: false, + cssCodeSplit: false, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d7a4766 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2329 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@biomejs/biome': + specifier: 1.7.3 + version: 1.7.3 + '@types/node': + specifier: 20.13.0 + version: 20.13.0 + husky: + specifier: ^9.0.11 + version: 9.1.7 + nano-staged: + specifier: ^0.8.0 + version: 0.8.0 + turbo: + specifier: ^2.0.7 + version: 2.3.3 + typescript: + specifier: ^5.4.5 + version: 5.6.3 + + playground/apps/home: + dependencies: + '@functional-javascript-programming/utils': + specifier: workspace:* + version: link:../../packages/utils + axios: + specifier: ^1.7.9 + version: 1.7.9 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: ^7.0.2 + version: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@eslint/js': + specifier: ^9.15.0 + version: 9.17.0 + '@originjs/vite-plugin-federation': + specifier: ^1.3.6 + version: 1.3.6 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/react': + specifier: ^18.3.12 + version: 18.3.17 + '@types/react-dom': + specifier: ^18.3.1 + version: 18.3.5(@types/react@18.3.17) + '@vitejs/plugin-react-swc': + specifier: ^3.5.0 + version: 3.7.2(vite@6.0.3(@types/node@20.13.0)) + eslint: + specifier: ^9.15.0 + version: 9.17.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.17.0) + eslint-plugin-react-refresh: + specifier: ^0.4.14 + version: 0.4.16(eslint@9.17.0) + globals: + specifier: ^15.12.0 + version: 15.13.0 + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.15.0 + version: 8.18.1(eslint@9.17.0)(typescript@5.6.3) + vite: + specifier: ^6.0.1 + version: 6.0.3(@types/node@20.13.0) + + playground/apps/members: + dependencies: + '@functional-javascript-programming/utils': + specifier: workspace:* + version: link:../../packages/utils + axios: + specifier: ^1.7.9 + version: 1.7.9 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: ^7.0.2 + version: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@eslint/js': + specifier: ^9.15.0 + version: 9.17.0 + '@originjs/vite-plugin-federation': + specifier: ^1.3.6 + version: 1.3.6 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/react': + specifier: ^18.3.12 + version: 18.3.17 + '@types/react-dom': + specifier: ^18.3.1 + version: 18.3.5(@types/react@18.3.17) + '@vitejs/plugin-react-swc': + specifier: ^3.5.0 + version: 3.7.2(vite@6.0.3(@types/node@20.13.0)) + eslint: + specifier: ^9.15.0 + version: 9.17.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.17.0) + eslint-plugin-react-refresh: + specifier: ^0.4.14 + version: 0.4.16(eslint@9.17.0) + globals: + specifier: ^15.12.0 + version: 15.13.0 + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.15.0 + version: 8.18.1(eslint@9.17.0)(typescript@5.6.3) + vite: + specifier: ^6.0.1 + version: 6.0.3(@types/node@20.13.0) + + playground/apps/projects: + dependencies: + '@functional-javascript-programming/utils': + specifier: workspace:* + version: link:../../packages/utils + axios: + specifier: ^1.7.9 + version: 1.7.9 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: ^7.0.2 + version: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@eslint/js': + specifier: ^9.15.0 + version: 9.17.0 + '@originjs/vite-plugin-federation': + specifier: ^1.3.6 + version: 1.3.6 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/react': + specifier: ^18.3.12 + version: 18.3.17 + '@types/react-dom': + specifier: ^18.3.1 + version: 18.3.5(@types/react@18.3.17) + '@vitejs/plugin-react-swc': + specifier: ^3.5.0 + version: 3.7.2(vite@6.0.3(@types/node@20.13.0)) + eslint: + specifier: ^9.15.0 + version: 9.17.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.17.0) + eslint-plugin-react-refresh: + specifier: ^0.4.14 + version: 0.4.16(eslint@9.17.0) + globals: + specifier: ^15.12.0 + version: 15.13.0 + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.15.0 + version: 8.18.1(eslint@9.17.0)(typescript@5.6.3) + vite: + specifier: ^6.0.1 + version: 6.0.3(@types/node@20.13.0) + + playground/packages/esbuild: + dependencies: + esbuild: + specifier: ^0.24.0 + version: 0.24.0 + + playground/packages/tsconfig: {} + + playground/packages/utils: + devDependencies: + '@functional-javascript-programming/typescript-config': + specifier: workspace:* + version: link:../tsconfig + + playground/web: + dependencies: + axios: + specifier: ^1.7.9 + version: 1.7.9 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: ^7.0.2 + version: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@eslint/js': + specifier: ^9.15.0 + version: 9.17.0 + '@originjs/vite-plugin-federation': + specifier: ^1.3.6 + version: 1.3.6 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/react': + specifier: ^18.3.12 + version: 18.3.17 + '@types/react-dom': + specifier: ^18.3.1 + version: 18.3.5(@types/react@18.3.17) + '@vitejs/plugin-react-swc': + specifier: ^3.5.0 + version: 3.7.2(vite@6.0.3(@types/node@20.13.0)) + eslint: + specifier: ^9.15.0 + version: 9.17.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.17.0) + eslint-plugin-react-refresh: + specifier: ^0.4.14 + version: 0.4.16(eslint@9.17.0) + globals: + specifier: ^15.12.0 + version: 15.13.0 + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.15.0 + version: 8.18.1(eslint@9.17.0)(typescript@5.6.3) + vite: + specifier: ^6.0.1 + version: 6.0.3(@types/node@20.13.0) + +packages: + + '@biomejs/biome@1.7.3': + resolution: {integrity: sha512-ogFQI+fpXftr+tiahA6bIXwZ7CSikygASdqMtH07J2cUzrpjyTMVc9Y97v23c7/tL1xCZhM+W9k4hYIBm7Q6cQ==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.7.3': + resolution: {integrity: sha512-eDvLQWmGRqrPIRY7AIrkPHkQ3visEItJKkPYSHCscSDdGvKzYjmBJwG1Gu8+QC5ed6R7eiU63LEC0APFBobmfQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.7.3': + resolution: {integrity: sha512-JXCaIseKRER7dIURsVlAJacnm8SG5I0RpxZ4ya3dudASYUc68WGl4+FEN03ABY3KMIq7hcK1tzsJiWlmXyosZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.7.3': + resolution: {integrity: sha512-c8AlO45PNFZ1BYcwaKzdt46kYbuP6xPGuGQ6h4j3XiEDpyseRRUy/h+6gxj07XovmyxKnSX9GSZ6nVbZvcVUAw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.7.3': + resolution: {integrity: sha512-phNTBpo7joDFastnmZsFjYcDYobLTx4qR4oPvc9tJ486Bd1SfEVPHEvJdNJrMwUQK56T+TRClOQd/8X1nnjA9w==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.7.3': + resolution: {integrity: sha512-UdEHKtYGWEX3eDmVWvQeT+z05T9/Sdt2+F/7zmMOFQ7boANeX8pcO6EkJPK3wxMudrApsNEKT26rzqK6sZRTRA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.7.3': + resolution: {integrity: sha512-vnedYcd5p4keT3iD48oSKjOIRPYcjSNNbd8MO1bKo9ajg3GwQXZLAH+0Cvlr+eMsO67/HddWmscSQwTFrC/uPA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.7.3': + resolution: {integrity: sha512-unNCDqUKjujYkkSxs7gFIfdasttbDC4+z0kYmcqzRk6yWVoQBL4dNLcCbdnJS+qvVDNdI9rHp2NwpQ0WAdla4Q==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.7.3': + resolution: {integrity: sha512-ZmByhbrnmz/UUFYB622CECwhKIPjJLLPr5zr3edhu04LzbfcOrz16VYeNq5dpO1ADG70FORhAJkaIGdaVBG00w==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.19.1': + resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.9.1': + resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.2.0': + resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.17.0': + resolution: {integrity: sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.5': + resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.4': + resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + engines: {node: '>=18.18'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@originjs/vite-plugin-federation@1.3.6': + resolution: {integrity: sha512-tHLMjdMJFPFMSJrUuJJiv8l7OFRvM19E9O1B9dhbk+04i3RnYwE9A6oNtSUM1dnvkalzCLwZIuMpti28/tnh8g==} + engines: {node: '>=14.0.0', pnpm: '>=7.0.1'} + + '@rollup/rollup-android-arm-eabi@4.28.1': + resolution: {integrity: sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.28.1': + resolution: {integrity: sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.28.1': + resolution: {integrity: sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.28.1': + resolution: {integrity: sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.28.1': + resolution: {integrity: sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.28.1': + resolution: {integrity: sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.28.1': + resolution: {integrity: sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.28.1': + resolution: {integrity: sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.28.1': + resolution: {integrity: sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.28.1': + resolution: {integrity: sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.28.1': + resolution: {integrity: sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.28.1': + resolution: {integrity: sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.28.1': + resolution: {integrity: sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.28.1': + resolution: {integrity: sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.28.1': + resolution: {integrity: sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.28.1': + resolution: {integrity: sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.28.1': + resolution: {integrity: sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.28.1': + resolution: {integrity: sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.28.1': + resolution: {integrity: sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==} + cpu: [x64] + os: [win32] + + '@swc/core-darwin-arm64@1.10.1': + resolution: {integrity: sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.10.1': + resolution: {integrity: sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.10.1': + resolution: {integrity: sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.10.1': + resolution: {integrity: sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.10.1': + resolution: {integrity: sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.10.1': + resolution: {integrity: sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.10.1': + resolution: {integrity: sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.10.1': + resolution: {integrity: sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.10.1': + resolution: {integrity: sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.10.1': + resolution: {integrity: sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.10.1': + resolution: {integrity: sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.17': + resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/js-cookie@3.0.6': + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@20.13.0': + resolution: {integrity: sha512-FM6AOb3khNkNIXPnHFDYaHerSv8uN22C91z098AnGccVu+Pcdhi+pNUFDi0iLmPIsVE0JBD0KVS7mzUYt4nRzQ==} + + '@types/prop-types@15.7.14': + resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + + '@types/react-dom@18.3.5': + resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.17': + resolution: {integrity: sha512-opAQ5no6LqJNo9TqnxBKsgnkIYHozW9KSTlFVoSUJYh1Fl/sswkEoqIugRSm7tbh6pABtYjGAjW+GOS23j8qbw==} + + '@typescript-eslint/eslint-plugin@8.18.1': + resolution: {integrity: sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/parser@8.18.1': + resolution: {integrity: sha512-rBnTWHCdbYM2lh7hjyXqxk70wvon3p2FyaniZuey5TrcGBpfhVp0OxOa6gxr9Q9YhZFKyfbEnxc24ZnVbbUkCA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/scope-manager@8.18.1': + resolution: {integrity: sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.18.1': + resolution: {integrity: sha512-jAhTdK/Qx2NJPNOTxXpMwlOiSymtR2j283TtPqXkKBdH8OAMmhiUfP0kJjc/qSE51Xrq02Gj9NY7MwK+UxVwHQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/types@8.18.1': + resolution: {integrity: sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.18.1': + resolution: {integrity: sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/utils@8.18.1': + resolution: {integrity: sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/visitor-keys@8.18.1': + resolution: {integrity: sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-react-swc@3.7.2': + resolution: {integrity: sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==} + peerDependencies: + vite: ^4 || ^5 || ^6 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.9: + resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react-hooks@5.1.0: + resolution: {integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.16: + resolution: {integrity: sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==} + peerDependencies: + eslint: '>=8.40' + + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.17.0: + resolution: {integrity: sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.2: + resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.13.0: + resolution: {integrity: sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==} + engines: {node: '>=18'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + husky@9.1.7: + resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} + engines: {node: '>=18'} + hasBin: true + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nano-staged@0.8.0: + resolution: {integrity: sha512-QSEqPGTCJbkHU2yLvfY6huqYPjdBrOaTMKatO1F8nCSrkQGXeKwtCiCnsdxnuMhbg3DTVywKaeWLGCE5oJpq0g==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-router-dom@7.0.2: + resolution: {integrity: sha512-VJOQ+CDWFDGaWdrG12Nl+d7yHtLaurNgAQZVgaIy7/Xd+DojgmYLosFfZdGz1wpxmjJIAkAMVTKWcvkx1oggAw==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.0.2: + resolution: {integrity: sha512-m5AcPfTRUcjwmhBzOJGEl6Y7+Crqyju0+TgTQxoS4SO+BkWbhOrcfZNq6wSWdl2BBbJbsAoBUb8ZacOFT+/JlA==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.28.1: + resolution: {integrity: sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + turbo-darwin-64@2.3.3: + resolution: {integrity: sha512-bxX82xe6du/3rPmm4aCC5RdEilIN99VUld4HkFQuw+mvFg6darNBuQxyWSHZTtc25XgYjQrjsV05888w1grpaA==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.3.3: + resolution: {integrity: sha512-DYbQwa3NsAuWkCUYVzfOUBbSUBVQzH5HWUFy2Kgi3fGjIWVZOFk86ss+xsWu//rlEAfYwEmopigsPYSmW4X15A==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.3.3: + resolution: {integrity: sha512-eHj9OIB0dFaP6BxB88jSuaCLsOQSYWBgmhy2ErCu6D2GG6xW3b6e2UWHl/1Ho9FsTg4uVgo4DB9wGsKa5erjUA==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.3.3: + resolution: {integrity: sha512-NmDE/NjZoDj1UWBhMtOPmqFLEBKhzGS61KObfrDEbXvU3lekwHeoPvAMfcovzswzch+kN2DrtbNIlz+/rp8OCg==} + cpu: [arm64] + os: [linux] + + turbo-stream@2.4.0: + resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} + + turbo-windows-64@2.3.3: + resolution: {integrity: sha512-O2+BS4QqjK3dOERscXqv7N2GXNcqHr9hXumkMxDj/oGx9oCatIwnnwx34UmzodloSnJpgSqjl8iRWiY65SmYoQ==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.3.3: + resolution: {integrity: sha512-dW4ZK1r6XLPNYLIKjC4o87HxYidtRRcBeo/hZ9Wng2XM/MqqYkAyzJXJGgRMsc0MMEN9z4+ZIfnSNBrA0b08ag==} + cpu: [arm64] + os: [win32] + + turbo@2.3.3: + resolution: {integrity: sha512-DUHWQAcC8BTiUZDRzAYGvpSpGLiaOQPfYXlCieQbwUvmml/LRGIe3raKdrOPOoiX0DYlzxs2nH6BoWJoZrj8hA==} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.18.1: + resolution: {integrity: sha512-Mlaw6yxuaDEPQvb/2Qwu3/TfgeBHy9iTJ3mTwe7OvpPmF6KPQjVOfGyEJpPv6Ez2C34OODChhXrzYw/9phI0MQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite@6.0.3: + resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@biomejs/biome@1.7.3': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.7.3 + '@biomejs/cli-darwin-x64': 1.7.3 + '@biomejs/cli-linux-arm64': 1.7.3 + '@biomejs/cli-linux-arm64-musl': 1.7.3 + '@biomejs/cli-linux-x64': 1.7.3 + '@biomejs/cli-linux-x64-musl': 1.7.3 + '@biomejs/cli-win32-arm64': 1.7.3 + '@biomejs/cli-win32-x64': 1.7.3 + + '@biomejs/cli-darwin-arm64@1.7.3': + optional: true + + '@biomejs/cli-darwin-x64@1.7.3': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.7.3': + optional: true + + '@biomejs/cli-linux-arm64@1.7.3': + optional: true + + '@biomejs/cli-linux-x64-musl@1.7.3': + optional: true + + '@biomejs/cli-linux-x64@1.7.3': + optional: true + + '@biomejs/cli-win32-arm64@1.7.3': + optional: true + + '@biomejs/cli-win32-x64@1.7.3': + optional: true + + '@esbuild/aix-ppc64@0.24.0': + optional: true + + '@esbuild/android-arm64@0.24.0': + optional: true + + '@esbuild/android-arm@0.24.0': + optional: true + + '@esbuild/android-x64@0.24.0': + optional: true + + '@esbuild/darwin-arm64@0.24.0': + optional: true + + '@esbuild/darwin-x64@0.24.0': + optional: true + + '@esbuild/freebsd-arm64@0.24.0': + optional: true + + '@esbuild/freebsd-x64@0.24.0': + optional: true + + '@esbuild/linux-arm64@0.24.0': + optional: true + + '@esbuild/linux-arm@0.24.0': + optional: true + + '@esbuild/linux-ia32@0.24.0': + optional: true + + '@esbuild/linux-loong64@0.24.0': + optional: true + + '@esbuild/linux-mips64el@0.24.0': + optional: true + + '@esbuild/linux-ppc64@0.24.0': + optional: true + + '@esbuild/linux-riscv64@0.24.0': + optional: true + + '@esbuild/linux-s390x@0.24.0': + optional: true + + '@esbuild/linux-x64@0.24.0': + optional: true + + '@esbuild/netbsd-x64@0.24.0': + optional: true + + '@esbuild/openbsd-arm64@0.24.0': + optional: true + + '@esbuild/openbsd-x64@0.24.0': + optional: true + + '@esbuild/sunos-x64@0.24.0': + optional: true + + '@esbuild/win32-arm64@0.24.0': + optional: true + + '@esbuild/win32-ia32@0.24.0': + optional: true + + '@esbuild/win32-x64@0.24.0': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)': + dependencies: + eslint: 9.17.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.1': + dependencies: + '@eslint/object-schema': 2.1.5 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.9.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.2.0': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.17.0': {} + + '@eslint/object-schema@2.1.5': {} + + '@eslint/plugin-kit@0.2.4': + dependencies: + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@originjs/vite-plugin-federation@1.3.6': + dependencies: + estree-walker: 3.0.3 + magic-string: 0.27.0 + + '@rollup/rollup-android-arm-eabi@4.28.1': + optional: true + + '@rollup/rollup-android-arm64@4.28.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.28.1': + optional: true + + '@rollup/rollup-darwin-x64@4.28.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.28.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.28.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.28.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.28.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.28.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.28.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.28.1': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.28.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.28.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.28.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.28.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.28.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.28.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.28.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.28.1': + optional: true + + '@swc/core-darwin-arm64@1.10.1': + optional: true + + '@swc/core-darwin-x64@1.10.1': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.10.1': + optional: true + + '@swc/core-linux-arm64-gnu@1.10.1': + optional: true + + '@swc/core-linux-arm64-musl@1.10.1': + optional: true + + '@swc/core-linux-x64-gnu@1.10.1': + optional: true + + '@swc/core-linux-x64-musl@1.10.1': + optional: true + + '@swc/core-win32-arm64-msvc@1.10.1': + optional: true + + '@swc/core-win32-ia32-msvc@1.10.1': + optional: true + + '@swc/core-win32-x64-msvc@1.10.1': + optional: true + + '@swc/core@1.10.1': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.17 + optionalDependencies: + '@swc/core-darwin-arm64': 1.10.1 + '@swc/core-darwin-x64': 1.10.1 + '@swc/core-linux-arm-gnueabihf': 1.10.1 + '@swc/core-linux-arm64-gnu': 1.10.1 + '@swc/core-linux-arm64-musl': 1.10.1 + '@swc/core-linux-x64-gnu': 1.10.1 + '@swc/core-linux-x64-musl': 1.10.1 + '@swc/core-win32-arm64-msvc': 1.10.1 + '@swc/core-win32-ia32-msvc': 1.10.1 + '@swc/core-win32-x64-msvc': 1.10.1 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.17': + dependencies: + '@swc/counter': 0.1.3 + + '@types/cookie@0.6.0': {} + + '@types/estree@1.0.6': {} + + '@types/js-cookie@3.0.6': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@20.13.0': + dependencies: + undici-types: 5.26.5 + + '@types/prop-types@15.7.14': {} + + '@types/react-dom@18.3.5(@types/react@18.3.17)': + dependencies: + '@types/react': 18.3.17 + + '@types/react@18.3.17': + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + + '@typescript-eslint/eslint-plugin@8.18.1(@typescript-eslint/parser@8.18.1(eslint@9.17.0)(typescript@5.6.3))(eslint@9.17.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.18.1(eslint@9.17.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.18.1 + '@typescript-eslint/type-utils': 8.18.1(eslint@9.17.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.18.1(eslint@9.17.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.18.1 + eslint: 9.17.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.18.1(eslint@9.17.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.18.1 + '@typescript-eslint/types': 8.18.1 + '@typescript-eslint/typescript-estree': 8.18.1(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.18.1 + debug: 4.4.0 + eslint: 9.17.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.18.1': + dependencies: + '@typescript-eslint/types': 8.18.1 + '@typescript-eslint/visitor-keys': 8.18.1 + + '@typescript-eslint/type-utils@8.18.1(eslint@9.17.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.18.1(typescript@5.6.3) + '@typescript-eslint/utils': 8.18.1(eslint@9.17.0)(typescript@5.6.3) + debug: 4.4.0 + eslint: 9.17.0 + ts-api-utils: 1.4.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.18.1': {} + + '@typescript-eslint/typescript-estree@8.18.1(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.18.1 + '@typescript-eslint/visitor-keys': 8.18.1 + debug: 4.4.0 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.18.1(eslint@9.17.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@typescript-eslint/scope-manager': 8.18.1 + '@typescript-eslint/types': 8.18.1 + '@typescript-eslint/typescript-estree': 8.18.1(typescript@5.6.3) + eslint: 9.17.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.18.1': + dependencies: + '@typescript-eslint/types': 8.18.1 + eslint-visitor-keys: 4.2.0 + + '@vitejs/plugin-react-swc@3.7.2(vite@6.0.3(@types/node@20.13.0))': + dependencies: + '@swc/core': 1.10.1 + vite: 6.0.3(@types/node@20.13.0) + transitivePeerDependencies: + - '@swc/helpers' + + acorn-jsx@5.3.2(acorn@8.14.0): + dependencies: + acorn: 8.14.0 + + acorn@8.14.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + asynckit@0.4.0: {} + + axios@1.7.9: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + callsites@3.1.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + cookie@1.0.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + delayed-stream@1.0.0: {} + + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@5.1.0(eslint@9.17.0): + dependencies: + eslint: 9.17.0 + + eslint-plugin-react-refresh@0.4.16(eslint@9.17.0): + dependencies: + eslint: 9.17.0 + + eslint-scope@8.2.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.17.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.1 + '@eslint/core': 0.9.1 + '@eslint/eslintrc': 3.2.0 + '@eslint/js': 9.17.0 + '@eslint/plugin-kit': 0.2.4 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.2 + keyv: 4.5.4 + + flatted@3.3.2: {} + + follow-redirects@1.15.9: {} + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fsevents@2.3.3: + optional: true + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@15.13.0: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + husky@9.1.7: {} + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + js-cookie@3.0.5: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + magic-string@0.27.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + ms@2.1.3: {} + + nano-staged@0.8.0: + dependencies: + picocolors: 1.1.1 + + nanoid@3.3.8: {} + + natural-compare@1.4.0: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-router-dom@7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + react-router@7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@types/cookie': 0.6.0 + cookie: 1.0.2 + react: 18.3.1 + set-cookie-parser: 2.7.1 + turbo-stream: 2.4.0 + optionalDependencies: + react-dom: 18.3.1(react@18.3.1) + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + resolve-from@4.0.0: {} + + reusify@1.0.4: {} + + rollup@4.28.1: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.28.1 + '@rollup/rollup-android-arm64': 4.28.1 + '@rollup/rollup-darwin-arm64': 4.28.1 + '@rollup/rollup-darwin-x64': 4.28.1 + '@rollup/rollup-freebsd-arm64': 4.28.1 + '@rollup/rollup-freebsd-x64': 4.28.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.28.1 + '@rollup/rollup-linux-arm-musleabihf': 4.28.1 + '@rollup/rollup-linux-arm64-gnu': 4.28.1 + '@rollup/rollup-linux-arm64-musl': 4.28.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.28.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.28.1 + '@rollup/rollup-linux-riscv64-gnu': 4.28.1 + '@rollup/rollup-linux-s390x-gnu': 4.28.1 + '@rollup/rollup-linux-x64-gnu': 4.28.1 + '@rollup/rollup-linux-x64-musl': 4.28.1 + '@rollup/rollup-win32-arm64-msvc': 4.28.1 + '@rollup/rollup-win32-ia32-msvc': 4.28.1 + '@rollup/rollup-win32-x64-msvc': 4.28.1 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@7.6.3: {} + + set-cookie-parser@2.7.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + source-map-js@1.2.1: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@1.4.3(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + + turbo-darwin-64@2.3.3: + optional: true + + turbo-darwin-arm64@2.3.3: + optional: true + + turbo-linux-64@2.3.3: + optional: true + + turbo-linux-arm64@2.3.3: + optional: true + + turbo-stream@2.4.0: {} + + turbo-windows-64@2.3.3: + optional: true + + turbo-windows-arm64@2.3.3: + optional: true + + turbo@2.3.3: + optionalDependencies: + turbo-darwin-64: 2.3.3 + turbo-darwin-arm64: 2.3.3 + turbo-linux-64: 2.3.3 + turbo-linux-arm64: 2.3.3 + turbo-windows-64: 2.3.3 + turbo-windows-arm64: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.18.1(eslint@9.17.0)(typescript@5.6.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.18.1(@typescript-eslint/parser@8.18.1(eslint@9.17.0)(typescript@5.6.3))(eslint@9.17.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.18.1(eslint@9.17.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.18.1(eslint@9.17.0)(typescript@5.6.3) + eslint: 9.17.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + typescript@5.6.3: {} + + undici-types@5.26.5: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite@6.0.3(@types/node@20.13.0): + dependencies: + esbuild: 0.24.0 + postcss: 8.4.49 + rollup: 4.28.1 + optionalDependencies: + '@types/node': 20.13.0 + fsevents: 2.3.3 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..ab333b1 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,4 @@ +packages: + - "playground/web" + - "playground/apps/*" + - "playground/packages/*" diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000..4083c9b --- /dev/null +++ b/turbo.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://turbo.build/schema.json", + "ui": "tui", + "globalDependencies": ["**/.env.*local"], + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": [".next/**", "!.next/cache/**"] + }, + "lint": { + "dependsOn": ["^lint"] + }, + "format": { + "dependsOn": ["^format"] + }, + "dev": { + "cache": false, + "persistent": true + }, + "start": { + "dependsOn": ["build"], + "cache": false, + "persistent": true + } + } +}