diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 00000000..98d931ca
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,19 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:react-hooks/recommended",
+ ],
+ ignorePatterns: ["dist", ".eslintrc.cjs"],
+ parser: "@typescript-eslint/parser",
+ plugins: ["react-refresh"],
+ rules: {
+ "react-refresh/only-export-components": [
+ "warn",
+ { allowConstantExport: true },
+ ],
+ semi: "warn",
+ },
+};
diff --git "a/.github/ISSUE_TEMPLATE/\342\234\205feature.md" "b/.github/ISSUE_TEMPLATE/\342\234\205feature.md"
new file mode 100644
index 00000000..85d14716
--- /dev/null
+++ "b/.github/ISSUE_TEMPLATE/\342\234\205feature.md"
@@ -0,0 +1,18 @@
+---
+name: "✅FEATURE"
+about: Feature 작업 사항을 입력해주세요.
+title: "✅[Feat]"
+labels: ''
+assignees: ''
+
+---
+
+## Description
+대략적인 기능 설명을 작성해 주세요.
+
+## Todo
+- [ ] todo
+- [ ] todo
+
+## ETC
+기타사항
diff --git "a/.github/ISSUE_TEMPLATE/\360\237\220\236bug.md" "b/.github/ISSUE_TEMPLATE/\360\237\220\236bug.md"
new file mode 100644
index 00000000..a43c19d8
--- /dev/null
+++ "b/.github/ISSUE_TEMPLATE/\360\237\220\236bug.md"
@@ -0,0 +1,18 @@
+---
+name: "\U0001F41EBUG"
+about: BUG 발생 시 작성해주세요
+title: "\U0001F41E[BUG]"
+labels: ''
+assignees: ''
+
+---
+
+## Description
+설명을 작성해 주세요
+
+## Todo
+- [ ] todo
+- [ ] todo
+
+## ETC
+기타사항
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..1649a804
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,5 @@
+## Summary
+
+## Describe your changes
+
+## Issue number and link
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..d823d0d1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+# 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?
+
+
+.env
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..ebe0fa17
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,9 @@
+{
+ "printWidth": 80,
+ "singleQuote": false,
+ "jsxSingleQuote": false,
+ "tabWidth": 2,
+ "semi": true,
+ "trailingComma": "all",
+ "bracketSpacing": true
+}
diff --git a/README.md b/README.md
index d6c98571..4e7b61e0 100644
--- a/README.md
+++ b/README.md
@@ -1,203 +1,405 @@
-# **📅 직원들을 위한 위키 사이트**
+# 직원들을 위한 위키 사이트 - 9굴 WIKI
-직원 들을 위한 위키 사이트를 만들어보세요!
-위키 사이트에는 위키 뿐 아니라 여러 기능이 추가되어야 합니다!
+## 💁 프로젝트 정보
-### **[과제 수행 및 제출 방법]**
+> **회사 공지와 이미지들을 쉽게 수정하고 확인할 수 있고,
+> 출퇴근 시간을 확인할 수 있는 직원들을 위한 위키 사이트 입니다.**
+> 개발기간: 2023.09.15 ~ 2023.09.22
+>
-1. 현재 저장소를 로컬에 클론(Clone)합니다.
-2. 자신의 팀명으로 브랜치를 생성합니다.(구분 가능하도록 팀명을 꼭 파스칼케이스로 표시하세요, git branch Y_FE_Toy1_Team13)
-3. 자신의 팀명 브랜치에서 과제를 수행합니다.
-4. 과제 수행이 완료되면, 자신의 팀명 브랜치를 원격 저장소에 푸시(Push)합니다.(main 브랜치에 푸시하지 않도록 꼭 주의하세요, git push origin Y_FE_Toy1_Team13)
-5. 저장소에서 main 브랜치를 대상으로 Pull Request 생성하면, 과제 제출이 완료됩니다!(E.g, main <== Y_FE_Toy1_Team13)
-6. Pull Request 링크를 LMS로도 제출해 주셔야 합니다.
-7. main 혹은 다른 사람의 브랜치로 절대 병합하지 않도록 주의하세요!
-8. Pull Request에서 보이는 설명을 다른 사람들이 이해하기 쉽도록 꼼꼼하게 작성하세요!
-9. Pull Request에서 과제 제출 후 절대 병합(Merge)하지 않도록 주의하세요!
-10. 과제 수행 및 제출 과정에서 문제가 발생한 경우, 바로 담당 멘토나 강사님께 얘기하세요!
+
-### **[필수 구현사항]**
+## 🌐 배포 주소
-- 문서편집, revision 기능을 제공하여 업무일지를 작성할 수 있는 직원들을 위한 위키사이트 구현(마크다운 형식)
-- firebase database (Firestore) 이용
-- 모달을 활용한 근무 시간을 표시하는 시계 및 타이머 창 구현
-- 캐러셀을 활용한 회사 공지 페이지
-- **갤러리 페이지 / 업무일지 페이지 등 메뉴를 필터링 또는 카테고리화 하는 선택바 구현**
-- netlify 등을 이용한 정적 페이지 배포
-- TypeScript 사용 필수
-- 과제에 대한 설명을 포함한 `README.md` 파일 작성
- - 팀원별로 구현한 부분 소개
+> 배포 주소: https://chipper-puppy-71c021.netlify.app
+>
-### **[선택 구현사항]**
+
-- React 사용은 선택
-- 기타 동작이 완료되기 전에 로딩 애니메이션 구현
-- 페이지네이션
-- 관련된 기타 기능도 고려
-- eslint 설정, 커밋컨벤션, 문서화 등 팀프로젝트시 필요한 추가 작업들
+## 🚖 개발 팀 소개
----
+| 이용훈 | 이승연 | 양재준 | 김소정 | 서지수 |
+| :--------------------------------------------------------: | :--------------------------------------------------------: | :-------------------------------------------------------: | :--------------------------------------------------------: | :-------------------------------------------------------: |
+| [@2YH02](https://github.com/2YH02) | [@ewinkite](https://github.com/ewinkite) | [@yangjaejun](https://github.com/yangjaejun) | [@KSJT](https://github.com/KSJT) | [@jseo9732](https://github.com/jseo9732) |
+|  |  |  |  |  |
+| 갤러리 페이지 CRUD 및 세부 기능 | 로그인 페이지 로그인, 회원가입 기능 및 유저 플로우 작성 | WIKI 페이지 CRUD 및 세부 기능 | 메인 페이지 이미지, WIKI 연동 및 세부 기능 | 메인 페이지 출퇴근 기록 및 세부기능 |
-## 가이드
+
-아래 예시는 모두 하나의 의견입니다!
+## 💻 개발 스택
-따라하는게 아니라 자신만의 결과물을 만들어보세요.
+### 🌙 환경
-### 공지사항
-[영상 1]
+
+### 🌙 개발
-### **모달 타이머**
-[영상 2]
+
+### 🌙 소통
-https://github.com/KDT1-FE/Y_FE_Toy1/assets/38754963/20c18d28-5a01-4163-876c-be74a24f62db
+
+
+
+## 💡 User Flow
+
-### **마크다운 위키사이트**
-[영상 3]
+
+## 🗂 디렉토리 구조
-https://github.com/KDT1-FE/Y_FE_Toy1/assets/38754963/08e3efca-8137-44d8-a0af-c62a668b810b
+```
+📦 public
+📦 src
+ ┣📦 components 공통 또는 페이지별로 활용되는 컴포넌트가 포함된 폴더입니다.
+ ┃ ┣ 📦 common
+ ┃ ┣ 📦 gallery
+ ┃ ┣ 📦 home
+ ┃ ┣ 📦 login
+ ┃ ┣ 📦 wiki
+ ┃ ┣ 📦 styles
+ ┃ ┣ 📦 utils
+ ┣📦 db/wiki
+ ┣📦 pages Router를 사용하여 이동할 큰 단위의 컴포넌트가 포함된 폴더입니다.
+ ┃ ┣ 📦 gallery
+ ┃ ┣ 📦 home
+ ┃ ┣ 📦 login
+ ┃ ┣ 📦 wiki
+ ┃ ┣ 📦 styles
+ ┃ ┣ 📦 utils
+ ┣📜 App.tsx
+ ┣📜 AppRouter.tsx
+ ┣📜 main.tsx
+ ...
+```
+
+
+
+
+## 🤝 협업 방식
+
+커밋 컨벤션, 코딩 컨벤션, 깃허브 규칙 등의 내용은 아래의 노션 페이지를 참고해주세요!
+
+### [🔗 노션 페이지](https://www.notion.so/2a7d2563e69f48ae93f71c4f4e382e45?pvs=4)
+
+
+
+
+## 🛠️ 주요기능
+
+### ⭐ 출퇴근 기록
+
+- 출근 시간과 퇴근 시간을 기록할 수 있고 헤더에 출근 경과시간이 표시됩니다.
+
+### ⭐ 메인페이지 와 WIKI, Gallery 페이지 연동
+
+- 메인 페이지에서 WIKI에 있는 중요한 공지사항을 슬라이드로 보여줍니다.
+- 메인 페이지에서 Gallery 페이지에 등록된 최신 사진 3개를 가져와 보여줍니다.
+### ⭐ 회원가입, 로그인 기능 및 인증
+- 회원가입과 로그인이 가능합니다.
+- 인증이 안된 유저가 다른 페이지로 접근할 시 로그인 페이지로 이동됩니다.
-### **갤러리**
-[영상 4]
+### ⭐ WIKI 페이지 게시물 CRUD
----
+- WIKI 페이지에서 게시물을 CRUD 할 수 있습니다.
-# **[Firestore]**
+### ⭐ Gallery 페이지 게시물 CRUD
-Firestore에 대한 가이드입니다.
+- Gallery 페이지에서 게시물을 CRUD 할 수 있습니다.
+
-자세한 내용은 [공식 홈페이지](https://firebase.google.com/?hl=ko) 를 찾아보길 적극 권장합니다!
+
-### **App init**
+## 🔍 팀원별 세부 구현 사항
-```jsx
-import { getFirestore } from "firebase/firestore";
+
+이용훈: 📷 갤러리 페이지
+
+
+### 1. 카테고리 추가
+
+#### 앨범 상위 카테고리 추가
+
+
-export const db = getFirestore(fireBaseApp);
```
+💡 카테고리 편집에서 원하는 앨범 카테고리를 만들 수 있습니다.
+카테고리를 생성하면 파이어베이스 데이터베이스에 생성 날짜와 고유한 ID 값을 가지고 저장이 됩니다.
+```
+
+### 2. 앨범 추가
-### Firestore 데이터 추가하기
+#### 이미지들을 저장할 앨범 카테고리(폴더) 생성
-Firestore의 데이터를 추가하는 방법은 크게 두가지이다.
+
-1. Firebase console에서 손수 데이터 추가해주기
-2. 코드로 데이터 추가하기
+```
+💡 카테고리 편집에서 원하는 앨범을 만들 수 있습니다. 앨범을 생성하면
+파이어베이스 데이터베이스에 생성 날짜, 상위 카테고리 ID, ID 값을 가지고 저장이 됩니다.
+```
-### 1. Firebase console에서 손수 데이터 추가해주기
+### 3. 이미지 추가
-1. [Firebase console](https://console.firebase.google.com/u/0/?hl=ko)에 접속한다.
-2. 자신의 프로젝트를 선택한다.
-3. 왼쪽 메뉴에서 `Firestore Database`를 선택한다.
-4. `+ 버튼`을 눌러 컬렉션 > 문서를 마음대로 추가해준다.
-5. 필드를 추가하여 문서에 데이터를 넣어준다.
+#### 앨범 폴더 내부에 이미지 추가
-### 2. 코드로 데이터 추가하기
+
-Firestore는 `setDoc`, `addDoc` 두 가지 함수로 데이터를 추가할 수 있다.
+```
+💡 원하는 앨범 카테고리에 원하는 이미지를 드래그나 클릭으로 추가합니다.
+추가 시 이미지 미리보기, 이름, 용량, 파일타입이 화면에 보이고,
+파이어베이스 스토리지에 해당 앨범의 ID 값을 이름으로 하는 폴더에 저장됩니다.
+```
-이제 원하는 데이터를 추가해보자.
+### 4. 이미지 삭제
-**1. `addDoc`**
+#### 앨범 폴더 내부에 이미지 삭제
-`addDoc`은 아래와 같이 사용하여 원하는 데이터를 추가할 수 있다.
+
```
-import { addDoc, collection } from "firebase/firestore";
+💡 앨범에 있는 이미지를 삭제합니다.
+삭제 시 파이어베이스 스토리지에 저장 돼 있던 해당 이미지가 삭제됩니다
+```
+
+### 5. 이미지 상세보기
+
+#### 이미지 방향 전환 및 크기 조절
-const writtenDoc = await addDoc(collection(db, "wiki"), {
- title: "LGH",
- description: "허먼밀러...사고싶다...",
-});
+
-console.log("Document written with ID: ", writtenDoc.id);
-// 새로 생성된 Document의 ID를 반환한다.
```
+💡 이미지 클릭 시 상세보기가 가능하고 버튼 클릭과 화살표 키보드로 다음 이미지로의 방향 전환이 가능합니다.
+또한 이미지 크기 조절이 가능하도록 기능을 추가하였습니다.
+```
+
+
+
+
+
-원하는 데이터를 추가하기 위해선 먼저 원하는 collection을 선택해야 한다. 위 예제의 `addDoc` 안에서 사용한 `collection` 함수는 db상에 있는 collection을 선택하거나 없을 경우 새로운 collection을 생성하여 반환한다.
+
+이승연: 🔑 로그인 페이지
+
-Firebase의 Doc는 기본적으로 ID를 가져야 하는데, addDoc을 사용하면 ID를 자동으로 만든다. 또한, 이미 존재하는 Doc에 `addDoc`을 사용하면 에러가 발생한다.
+### 1. 접근 제한 라우팅
-**2. `setDoc`**
+#### 로그인 여부에 따른 제한 접근 라우팅
-`setDoc`은 아래와 같이 사용하여 원하는 데이터를 추가할 수 있다.
+
```
-import { setDoc, doc } from "firebase/firestore";
+💡 해당 홈페이지는 사내 사이트로, 로그인 정보가 없는 경우 login페이지로 이동합니다.
+로그아웃하지 않았다면 탭 종료 후 재접속하여도 로그인 상태를 유지합니다.
+```
+
+### 2. 회원 가입
+
+#### 회원 가입
-await setDoc(doc(db, "wiki", "new-id"), {
- title: "LGH",
- description: "허먼밀러...사고싶다...",
-});
+
+
+```
+💡 회원 가입 버튼 클릭시 회원 가입이 가능한 다이얼로그가 노출됩니다.
+ID와 PW 값을 입력후 가입하기 버튼을 클릭시 User로 저장되며 해당 계정으로 사이트 로그인이 가능합니다.
```
-`addDoc`과의 차이점은
+#### 회원가입 유효성 검사
+
+
+
+```
+💡 프로세스에 따라 회원가입 유효성 검사 후 얼럿을 노출합니다.
+정상적으로 입력이 완료되었다면 로그인 페이지로 진입합니다.
+```
-1. **id** 를 지정해줘야함
-2. `collection` 대신 `doc`을 사용함
-3. 이미 존재하는 Doc에 사용가능
+### 3. 로그인
-3가지 이다.
+#### 로그인
-`setDoc`은 `addDoc`과 달리 collection이 아니라 doc를 선택해야 한다. 이는 `setDoc`이 데이터의 추가 뿐 아니라 데이터 덮어쓰기 기능도 가지고 있기 때문이다. 러프하게 생각해보면 `setDoc`은 데이터를 추가할 때
+
-1. doc을 선택하거나 새로운 doc을 생성
-2. doc의 내용을 덮어씀
+```
+💡 회원가입한 계정의 ID와 PW 값을 입력후 들어가기 버튼을 클릭하여 사이트 로그인이 가능합니다.
+```
-의 방식으로 동작하는 것이다.
+#### 로그인 유효성 검사
-Doc을 선택하는 방법은 `doc` 함수를 사용하는 것이다. `[doc()](https://firebase.google.com/docs/reference/js/firestore_.md?hl=ko#doc)` 함수는 `DocumentReference` instance를 반환한다. 절대 경로를 사용하여 원하는 Document를 선택할 수 있다. 위에서 만들어둔 `wiki > completed` 문서는 아래처럼 불러올 수 있다.
+
```
-import { doc } from "firebase/firestore";
+💡 프로세스에 따라 로그인 유효성 검사 후 얼럿을 노출합니다.
+정상적으로 입력이 완료되었다면 메인 페이지로 진입합니다.
+```
+
+### 4. 로그인 정보 전달
+
+#### 로그인한 유저 정보 전달
+
+
-const docRef = doc(db, "wiki", "completed");
```
+💡 현재 사이트 로그인 중인 User 정보를 전달합니다.
+이를 통해 Header와 WIKI페이지의 등록/수정/삭제 등의 기능 구현을 지원합니다.
+```
+
+
+
-`doc` 함수의 3번째 인자가 바로 **id** 이다. id는 이미 존재하는 Doc의 id를 사용할 수도 있고, 새로운 id를 사용할 수도 있다. 존재하는 id를 사용하는 경우에는 해당 Doc의 데이터를 덮어쓰게 된다. 그렇지 않은 경우엔 새로운 Doc를 생성한다.
+
-어쨌거나 데이터를 새로 추가할 수 있는 것이다.
+
+양재준: 📂 WIKI 페이지
+
-### Firestore 데이터 수정하기
+### 1. 위키 페이지 로딩 & 초기화
-Firestore의 데이터를 수정하는 방법은 크게 두가지이다.
+#### 위키 데이터 로딩 및 초기 설정
-1. Firebase console에서 손수 데이터 수정해주기
-1. 코드로 데이터 수정하기
+
-1번은 데이터 생성과 비슷하게 진행하면 된다.
+```
+💡 사용자가 위키 페이지에 접속하면, 확인할 위키를 선택 할 수 있는 사이드 메뉴와 위키의 내용을 확인하고 편집 할 수 있는 화면이 표시됩니다.
+데이터베이스의 부하를 방지 하기 위해 상위 위키 항목들만 사이드 메뉴에 표시되며, 그 중 첫번째 위키가 우측 화면에 표시됩니다.
+```
-**2. 코드로 데이터 수정하기**
+### 2. 하위 위키 항목 표시
-Firestore는 `setDoc`, `update` 두 가지 함수로 데이터를 추가할 수 있다.
+#### 하위 위키 항목 표시
-`setDoc`을 사용하는 방법은 위에 적혀있다.
+
-### `update`
-`setDoc`은 데이터를 덮어쓴다. 따라서 기존의 문서를 유지한 채 일부분의 데이터만 변경하고 싶어도 이전의 데이터를 모두 새로 입력해야 한다.
+```
+💡 사용자가 상위 위키의 화살표 버튼을 클릭하면, 해당 위키의 하위 위키 항목들을 불러옵니다.
+사용자는 상위 위키를 하위 위키들을 묶는 카테고리 개념으로 활용할 수 있으며, 위키의 계층적 구조와 연관된 내용을 한눈에 파악할 수 있습니다.
+```
-그러나 `update`는 기존의 데이터를 유지한 채 일부분의 데이터만 변경할 수 있다.
+### 3. 위키 작성
-```jsx
-import { updateDoc, doc } from "firebase/firestore";
+#### 새로운 위키 작성
-await updateDoc(doc(db, "wiki", "new-id"), {
- description: "허먼밀러...200만원...",
-});
+
+
+
+```
+💡 사용자는 '등록' 버튼을 통해 새로운 위키를 작성할 수 있습니다.
+작성된 위키 항목은 파이어베이스 데이터베이스에 저장되며, 고유한 ID와 함께 등록됩니다.
+위키는 마크다운 형식으로 작성이 가능하며, 사용자가 폼에 입력하는 내용은 실시간으로 상태에 반영됩니다.
+이를 통해 사용자는 입력 내용을 동적으로 관리하고 확인할 수 있습니다.
+또한, 드롭다운 메뉴를 통해 상위 위키를 선택하여 해당 위키의 하위 항목으로 등록이 가능합니다.
+```
+
+### 4. 위키 편집
+
+#### 선택한 위키 항목의 내용 수정
+
+
+
+```
+💡 사용자는 '수정' 버튼을 클릭하여 해당 항목의 내용을 수정할 수 있습니다.
+수정이 완료되면 '저장' 버튼을 클릭하여 변경 내용을 데이터베이스에 업데이트합니다.
+드롭다운 메뉴를 통해 상위 위키를 선택 및 변경 할 수 있습니다. 이떄, 하위 위키가 등록된 상위 위키의 경우 다른 위키의 하위 위키로는 등록 할 수 없습니다.
+```
+
+### 5. 위키 삭제
+
+
+
+#### 위키 항목 삭제
+
+```
+💡 '삭제' 버튼을 클릭하면, 해당 항목을 데이터베이스에서 완전히 제거할 수 있습니다.
+삭제하기 전에 사용자에게 확인 절차를 거칩니다, 이를 통해 실수로 인한 삭제를 방지할 수 있습니다.
+하위 위키가 등록된 상위 위키의 경우 하위 위키가 삭제 될 수 있음을 알리는 메시지를 표시하고, '확인'을 클릭 할 시 해당 위키의 하위 위키도 동시에 삭제됩니다.
```
-위와 같이 코드를 작성하면 `new-id`라는 id를 가진 문서의 description만 변경된다.
+
+
+
+
+
+
+서지수: 🌐 헤더 및 메인 페이지
+
+
+### 1. 헤더 통근 다이얼로그
+#### 출근 기능
+ 
+ 
+
+ ```
+ 💡 통근 다이얼로그에서 출근 버튼을 클릭하면 파이어스토어에 출근 시간이 저장되고 헤더에 근무 시간(근무 타이머)가 표시됩니다.
+ 로그아웃, 새로고침을 해도 파이어스토어에서 출근 및 퇴근 시간을 요청하여 표시해줍니다.
+ ```
+
+#### 퇴근 기능
+ 
+
+ ```
+ 💡 통근 다이얼로그에서 퇴근 버튼을 클릭하면 파이어스토어에 퇴근 시간이 저장되고 헤더에 총 근무한 시간이 표시됩니다.
+ ```
+
+### 2. 로그아웃 기능
+ 
+
+ ```
+ 💡 파이어베이스의 `signOut`기능을 이용하여 로그아웃을 한 뒤 로그인 페이지로 이동합니다.
+ ```
+
+### 3. 최근 작성 위키 조회 기능
+ 
+ ```
+ 💡 파이어스토어에 저장된 위키 중 가장 최근에 작성된 2개의 게시글을 요청하여 표시해줍니다.
+ 게시물을 클릭하면 해당 게시글로 이동합니다.
+ ```
+
+
+
+
+
+
+
+김소정: 🌐 메인 페이지
+
+
+### 1. 메인 캐러셀
+
+#### 홈 화면 공지사항을 보여주는 캐러셀 구현
+
+
+
+```
+💡 캐러셀이 3초마다 다음 슬라이드를 보여줍니다.
+```
+
+
+
+```
+💡 하단의 버튼을 클릭하면 해당 인덱스의 슬라이드로 캐러셀이 점프합니다.
+```
+
+
+
+```
+💡 윈도우가 resize할 때마다 캐러셀의 width가 변화합니다.
+```
+
+### 2. 홈 화면 갤러리 미리보기 구현
+
+
+
+
+```
+💡 갤러리에 최근 업데이트 된 사진을 3개까지 미리 보여줍니다.
+클릭하면 갤러리 페이지로 이동합니다. 최초 로딩 시에는 스켈레톤 애니메이션이 보입니다.
+```
----
-### *참고 링크
+
+
-- **[Firebase](https://firebase.google.com/docs?hl=ko)**
-- [**프로토타입 프로젝트**](https://stfe.vercel.app/)
+
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..ef69eacf
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ 9굴 WIKI
+
+
+
+
+
+
diff --git a/netlify.toml b/netlify.toml
new file mode 100644
index 00000000..e1a655d4
--- /dev/null
+++ b/netlify.toml
@@ -0,0 +1,7 @@
+[build]
+ command = "npm run build"
+ publish = "dist"
+[[redirects]]
+ from = "/*"
+ to = "/index.html"
+ status = 200
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..f697019d
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,5955 @@
+{
+ "name": "vite-project",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "vite-project",
+ "version": "0.0.0",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^6.4.2",
+ "@fortawesome/free-solid-svg-icons": "^6.4.2",
+ "@fortawesome/react-fontawesome": "^0.2.0",
+ "@toast-ui/react-editor": "^3.2.3",
+ "firebase": "^10.3.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.15.0",
+ "styled-components": "^6.0.7"
+ },
+ "devDependencies": {
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@types/styled-components": "^5.1.27",
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
+ "@typescript-eslint/parser": "^6.0.0",
+ "@vitejs/plugin-react": "^4.0.3",
+ "eslint": "^8.45.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.3",
+ "typescript": "^5.0.2",
+ "vite": "^4.4.5"
+ }
+ },
+ "node_modules/@aashutoshrathi/word-wrap": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/cli": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.15.tgz",
+ "integrity": "sha512-prtg5f6zCERIaECeTZzd2fMtVjlfjhUcO+fBLQ6DXXdq5FljN+excVitJ2nogsusdf31LeqkjAfXZ7Xq+HmN8g==",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "commander": "^4.0.1",
+ "convert-source-map": "^1.1.0",
+ "fs-readdir-recursive": "^1.1.0",
+ "glob": "^7.2.0",
+ "make-dir": "^2.1.0",
+ "slash": "^2.0.0"
+ },
+ "bin": {
+ "babel": "bin/babel.js",
+ "babel-external-helpers": "bin/babel-external-helpers.js"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "optionalDependencies": {
+ "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3",
+ "chokidar": "^3.4.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/cli/node_modules/slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "dependencies": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz",
+ "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.20.tgz",
+ "integrity": "sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA==",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.22.15",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-module-transforms": "^7.22.20",
+ "@babel/helpers": "^7.22.15",
+ "@babel/parser": "^7.22.16",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.22.20",
+ "@babel/types": "^7.22.19",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz",
+ "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==",
+ "dependencies": {
+ "@babel/types": "^7.22.15",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+ "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz",
+ "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==",
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
+ "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.9",
+ "@babel/helper-validator-option": "^7.22.15",
+ "browserslist": "^4.21.9",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz",
+ "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-environment-visitor": "^7.22.5",
+ "@babel/helper-function-name": "^7.22.5",
+ "@babel/helper-member-expression-to-functions": "^7.22.15",
+ "@babel/helper-optimise-call-expression": "^7.22.5",
+ "@babel/helper-replace-supers": "^7.22.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz",
+ "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "regexpu-core": "^5.3.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz",
+ "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.22.6",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
+ "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+ "dependencies": {
+ "@babel/template": "^7.22.5",
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz",
+ "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==",
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.20.tgz",
+ "integrity": "sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
+ "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+ "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz",
+ "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-wrap-function": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz",
+ "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-member-expression-to-functions": "^7.22.15",
+ "@babel/helper-optimise-call-expression": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
+ "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
+ "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz",
+ "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==",
+ "dependencies": {
+ "@babel/helper-function-name": "^7.22.5",
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.22.19"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz",
+ "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==",
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.22.16",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz",
+ "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==",
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz",
+ "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz",
+ "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+ "@babel/plugin-transform-optional-chaining": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-external-helpers": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.22.5.tgz",
+ "integrity": "sha512-ngnNEWxmykPk82mH4ajZT0qTztr3Je6hrMuKAslZVM8G1YZTENJSYwrIGtt6KOtznug3exmAtF4so/nPqJuA4A==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-properties": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
+ "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
+ "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.",
+ "dependencies": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-plugin-utils": "^7.20.2",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.21.0-placeholder-for-preset-env.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz",
+ "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz",
+ "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
+ "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz",
+ "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz",
+ "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz",
+ "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==",
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-remap-async-to-generator": "^7.22.9",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz",
+ "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-remap-async-to-generator": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz",
+ "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz",
+ "integrity": "sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz",
+ "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz",
+ "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.22.11",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz",
+ "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-environment-visitor": "^7.22.5",
+ "@babel/helper-function-name": "^7.22.5",
+ "@babel/helper-optimise-call-expression": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-replace-supers": "^7.22.9",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz",
+ "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/template": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz",
+ "integrity": "sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz",
+ "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz",
+ "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz",
+ "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz",
+ "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==",
+ "dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz",
+ "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz",
+ "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz",
+ "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.22.5",
+ "@babel/helper-function-name": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-json-strings": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz",
+ "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-json-strings": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz",
+ "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz",
+ "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz",
+ "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz",
+ "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz",
+ "integrity": "sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-simple-access": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz",
+ "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==",
+ "dependencies": {
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-module-transforms": "^7.22.9",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz",
+ "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz",
+ "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz",
+ "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz",
+ "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz",
+ "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz",
+ "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.9",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz",
+ "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-replace-supers": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz",
+ "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.15.tgz",
+ "integrity": "sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz",
+ "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz",
+ "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.22.11",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz",
+ "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.22.11",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz",
+ "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-display-name": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz",
+ "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz",
+ "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-jsx": "^7.22.5",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-development": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz",
+ "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==",
+ "dependencies": {
+ "@babel/plugin-transform-react-jsx": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz",
+ "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz",
+ "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-pure-annotations": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz",
+ "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.22.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz",
+ "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "regenerator-transform": "^0.15.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz",
+ "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz",
+ "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz",
+ "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz",
+ "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz",
+ "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz",
+ "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz",
+ "integrity": "sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-typescript": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.22.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz",
+ "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-property-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz",
+ "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz",
+ "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz",
+ "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.20.tgz",
+ "integrity": "sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.20",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-validator-option": "^7.22.15",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15",
+ "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-import-assertions": "^7.22.5",
+ "@babel/plugin-syntax-import-attributes": "^7.22.5",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+ "@babel/plugin-transform-arrow-functions": "^7.22.5",
+ "@babel/plugin-transform-async-generator-functions": "^7.22.15",
+ "@babel/plugin-transform-async-to-generator": "^7.22.5",
+ "@babel/plugin-transform-block-scoped-functions": "^7.22.5",
+ "@babel/plugin-transform-block-scoping": "^7.22.15",
+ "@babel/plugin-transform-class-properties": "^7.22.5",
+ "@babel/plugin-transform-class-static-block": "^7.22.11",
+ "@babel/plugin-transform-classes": "^7.22.15",
+ "@babel/plugin-transform-computed-properties": "^7.22.5",
+ "@babel/plugin-transform-destructuring": "^7.22.15",
+ "@babel/plugin-transform-dotall-regex": "^7.22.5",
+ "@babel/plugin-transform-duplicate-keys": "^7.22.5",
+ "@babel/plugin-transform-dynamic-import": "^7.22.11",
+ "@babel/plugin-transform-exponentiation-operator": "^7.22.5",
+ "@babel/plugin-transform-export-namespace-from": "^7.22.11",
+ "@babel/plugin-transform-for-of": "^7.22.15",
+ "@babel/plugin-transform-function-name": "^7.22.5",
+ "@babel/plugin-transform-json-strings": "^7.22.11",
+ "@babel/plugin-transform-literals": "^7.22.5",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.22.11",
+ "@babel/plugin-transform-member-expression-literals": "^7.22.5",
+ "@babel/plugin-transform-modules-amd": "^7.22.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.22.15",
+ "@babel/plugin-transform-modules-systemjs": "^7.22.11",
+ "@babel/plugin-transform-modules-umd": "^7.22.5",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
+ "@babel/plugin-transform-new-target": "^7.22.5",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11",
+ "@babel/plugin-transform-numeric-separator": "^7.22.11",
+ "@babel/plugin-transform-object-rest-spread": "^7.22.15",
+ "@babel/plugin-transform-object-super": "^7.22.5",
+ "@babel/plugin-transform-optional-catch-binding": "^7.22.11",
+ "@babel/plugin-transform-optional-chaining": "^7.22.15",
+ "@babel/plugin-transform-parameters": "^7.22.15",
+ "@babel/plugin-transform-private-methods": "^7.22.5",
+ "@babel/plugin-transform-private-property-in-object": "^7.22.11",
+ "@babel/plugin-transform-property-literals": "^7.22.5",
+ "@babel/plugin-transform-regenerator": "^7.22.10",
+ "@babel/plugin-transform-reserved-words": "^7.22.5",
+ "@babel/plugin-transform-shorthand-properties": "^7.22.5",
+ "@babel/plugin-transform-spread": "^7.22.5",
+ "@babel/plugin-transform-sticky-regex": "^7.22.5",
+ "@babel/plugin-transform-template-literals": "^7.22.5",
+ "@babel/plugin-transform-typeof-symbol": "^7.22.5",
+ "@babel/plugin-transform-unicode-escapes": "^7.22.10",
+ "@babel/plugin-transform-unicode-property-regex": "^7.22.5",
+ "@babel/plugin-transform-unicode-regex": "^7.22.5",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "@babel/types": "^7.22.19",
+ "babel-plugin-polyfill-corejs2": "^0.4.5",
+ "babel-plugin-polyfill-corejs3": "^0.8.3",
+ "babel-plugin-polyfill-regenerator": "^0.5.2",
+ "core-js-compat": "^3.31.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-env/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/preset-react": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.15.tgz",
+ "integrity": "sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-validator-option": "^7.22.15",
+ "@babel/plugin-transform-react-display-name": "^7.22.5",
+ "@babel/plugin-transform-react-jsx": "^7.22.15",
+ "@babel/plugin-transform-react-jsx-development": "^7.22.5",
+ "@babel/plugin-transform-react-pure-annotations": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-typescript": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.15.tgz",
+ "integrity": "sha512-HblhNmh6yM+cU4VwbBRpxFhxsTdfS1zsvH9W+gEjD0ARV9+8B4sNfpI6GuhePti84nuvhiwKS539jKPFHskA9A==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/helper-validator-option": "^7.22.15",
+ "@babel/plugin-syntax-jsx": "^7.22.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.22.15",
+ "@babel/plugin-transform-typescript": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz",
+ "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.20.tgz",
+ "integrity": "sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==",
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.22.15",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.22.5",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.22.16",
+ "@babel/types": "^7.22.19",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.22.19",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz",
+ "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.19",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
+ "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
+ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz",
+ "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
+ "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "13.22.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz",
+ "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.49.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz",
+ "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@firebase/analytics": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.0.tgz",
+ "integrity": "sha512-Locv8gAqx0e+GX/0SI3dzmBY5e9kjVDtD+3zCFLJ0tH2hJwuCAiL+5WkHuxKj92rqQj/rvkBUCfA1ewlX2hehg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/analytics-compat": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.6.tgz",
+ "integrity": "sha512-4MqpVLFkGK7NJf/5wPEEP7ePBJatwYpyjgJ+wQHQGHfzaCDgntOnl9rL2vbVGGKCnRqWtZDIWhctB86UWXaX2Q==",
+ "dependencies": {
+ "@firebase/analytics": "0.10.0",
+ "@firebase/analytics-types": "0.8.0",
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/analytics-types": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz",
+ "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw=="
+ },
+ "node_modules/@firebase/app": {
+ "version": "0.9.19",
+ "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.19.tgz",
+ "integrity": "sha512-t/SHyZ3xWkR77ZU9VMoobDNFLdDKQ5xqoCAn4o16gTsA1C8sJ6ZOMZ02neMOPxNHuQXVE4tA8ukilnDbnK7uJA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "idb": "7.1.1",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/app-check": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.0.tgz",
+ "integrity": "sha512-dRDnhkcaC2FspMiRK/Vbp+PfsOAEP6ZElGm9iGFJ9fDqHoPs0HOPn7dwpJ51lCFi1+2/7n5pRPGhqF/F03I97g==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/app-check-compat": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.7.tgz",
+ "integrity": "sha512-cW682AxsyP1G+Z0/P7pO/WT2CzYlNxoNe5QejVarW2o5ZxeWSSPAiVEwpEpQR/bUlUmdeWThYTMvBWaopdBsqw==",
+ "dependencies": {
+ "@firebase/app-check": "0.8.0",
+ "@firebase/app-check-types": "0.5.0",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/app-check-interop-types": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz",
+ "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg=="
+ },
+ "node_modules/@firebase/app-check-types": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz",
+ "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ=="
+ },
+ "node_modules/@firebase/app-compat": {
+ "version": "0.2.19",
+ "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.19.tgz",
+ "integrity": "sha512-QkJDqYqjhvs4fTMcRVXQkP9hbo5yfoJXDWkhU4VA5Vzs8Qsp76VPzYbqx5SD5OmBy+bz/Ot1UV8qySPGI4aKuw==",
+ "dependencies": {
+ "@firebase/app": "0.9.19",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/app-types": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz",
+ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q=="
+ },
+ "node_modules/@firebase/auth": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.3.0.tgz",
+ "integrity": "sha512-vjK4CHbY9aWdiVOrKi6mpa8z6uxeaf7LB/MZTHuZOiGHMcUoTGB6TeMbRShyqk1uaMrxhhZ5Ar/dR0965E1qyA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x",
+ "@react-native-async-storage/async-storage": "^1.18.1"
+ },
+ "peerDependenciesMeta": {
+ "@react-native-async-storage/async-storage": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@firebase/auth-compat": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.6.tgz",
+ "integrity": "sha512-pKp1d4fSf+yoy1EBjTx9ISxlunqhW0vTICk0ByZ3e+Lp6ZIXThfUy4F1hAJlEafD/arM0oepRiAh7LXS1xn/BA==",
+ "dependencies": {
+ "@firebase/auth": "1.3.0",
+ "@firebase/auth-types": "0.12.0",
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/auth-interop-types": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz",
+ "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg=="
+ },
+ "node_modules/@firebase/auth-types": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz",
+ "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/component": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz",
+ "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==",
+ "dependencies": {
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/database": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.1.tgz",
+ "integrity": "sha512-VAhF7gYwunW4Lw/+RQZvW8dlsf2r0YYqV9W0Gi2Mz8+0TGg1mBJWoUtsHfOr8kPJXhcLsC4eP/z3x6L/Fvjk/A==",
+ "dependencies": {
+ "@firebase/auth-interop-types": "0.2.1",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "faye-websocket": "0.11.4",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/database-compat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.1.tgz",
+ "integrity": "sha512-ky82yLIboLxtAIWyW/52a6HLMVTzD2kpZlEilVDok73pNPLjkJYowj8iaIWK5nTy7+6Gxt7d00zfjL6zckGdXQ==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/database": "1.0.1",
+ "@firebase/database-types": "1.0.0",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/database-types": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.0.tgz",
+ "integrity": "sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg==",
+ "dependencies": {
+ "@firebase/app-types": "0.9.0",
+ "@firebase/util": "1.9.3"
+ }
+ },
+ "node_modules/@firebase/firestore": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.2.0.tgz",
+ "integrity": "sha512-iKZqIdOBJpJUcwY5airLX0W04TLrQSJuActOP1HG5WoIY5oyGTQE4Ml7hl5GW7mBqFieT4ojtUuDXj6MLrn1lA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "@firebase/webchannel-wrapper": "0.10.3",
+ "@grpc/grpc-js": "~1.9.0",
+ "@grpc/proto-loader": "^0.7.8",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/firestore-compat": {
+ "version": "0.3.18",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.18.tgz",
+ "integrity": "sha512-hkqv4mb1oScKbEtzfcK8Go8c0VpDWmbAvbD6B6XnphLqi27pkXgo9Rp+aSKlD7cBL29VMEekP5bEm9lSVfZpNw==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/firestore": "4.2.0",
+ "@firebase/firestore-types": "3.0.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/firestore-types": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.0.tgz",
+ "integrity": "sha512-Meg4cIezHo9zLamw0ymFYBD4SMjLb+ZXIbuN7T7ddXN6MGoICmOTq3/ltdCGoDCS2u+H1XJs2u/cYp75jsX9Qw==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/functions": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.10.0.tgz",
+ "integrity": "sha512-2U+fMNxTYhtwSpkkR6WbBcuNMOVaI7MaH3cZ6UAeNfj7AgEwHwMIFLPpC13YNZhno219F0lfxzTAA0N62ndWzA==",
+ "dependencies": {
+ "@firebase/app-check-interop-types": "0.3.0",
+ "@firebase/auth-interop-types": "0.2.1",
+ "@firebase/component": "0.6.4",
+ "@firebase/messaging-interop-types": "0.2.0",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/functions-compat": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.5.tgz",
+ "integrity": "sha512-uD4jwgwVqdWf6uc3NRKF8cSZ0JwGqSlyhPgackyUPe+GAtnERpS4+Vr66g0b3Gge0ezG4iyHo/EXW/Hjx7QhHw==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/functions": "0.10.0",
+ "@firebase/functions-types": "0.6.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/functions-types": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz",
+ "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw=="
+ },
+ "node_modules/@firebase/installations": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.4.tgz",
+ "integrity": "sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "idb": "7.0.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.4.tgz",
+ "integrity": "sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/installations-types": "0.5.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations-types": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz",
+ "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x"
+ }
+ },
+ "node_modules/@firebase/installations/node_modules/idb": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz",
+ "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg=="
+ },
+ "node_modules/@firebase/logger": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz",
+ "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/messaging": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.4.tgz",
+ "integrity": "sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/messaging-interop-types": "0.2.0",
+ "@firebase/util": "1.9.3",
+ "idb": "7.0.1",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/messaging-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.4.tgz",
+ "integrity": "sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/messaging": "0.12.4",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/messaging-interop-types": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz",
+ "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ=="
+ },
+ "node_modules/@firebase/messaging/node_modules/idb": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz",
+ "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg=="
+ },
+ "node_modules/@firebase/performance": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.4.tgz",
+ "integrity": "sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/performance-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.4.tgz",
+ "integrity": "sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/performance": "0.6.4",
+ "@firebase/performance-types": "0.2.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/performance-types": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz",
+ "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA=="
+ },
+ "node_modules/@firebase/remote-config": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.4.tgz",
+ "integrity": "sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/installations": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/remote-config-compat": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz",
+ "integrity": "sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/remote-config": "0.4.4",
+ "@firebase/remote-config-types": "0.3.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/remote-config-types": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz",
+ "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA=="
+ },
+ "node_modules/@firebase/storage": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.2.tgz",
+ "integrity": "sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/util": "1.9.3",
+ "node-fetch": "2.6.7",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app": "0.x"
+ }
+ },
+ "node_modules/@firebase/storage-compat": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.2.tgz",
+ "integrity": "sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/storage": "0.11.2",
+ "@firebase/storage-types": "0.8.0",
+ "@firebase/util": "1.9.3",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@firebase/app-compat": "0.x"
+ }
+ },
+ "node_modules/@firebase/storage-types": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz",
+ "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==",
+ "peerDependencies": {
+ "@firebase/app-types": "0.x",
+ "@firebase/util": "1.x"
+ }
+ },
+ "node_modules/@firebase/util": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz",
+ "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@firebase/webchannel-wrapper": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.3.tgz",
+ "integrity": "sha512-+ZplYUN3HOpgCfgInqgdDAbkGGVzES1cs32JJpeqoh87SkRobGXElJx+1GZSaDqzFL+bYiX18qEcBK76mYs8uA=="
+ },
+ "node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz",
+ "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==",
+ "hasInstallScript": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz",
+ "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.4.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-solid-svg-icons": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz",
+ "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.4.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/react-fontawesome": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
+ "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
+ "dependencies": {
+ "prop-types": "^15.8.1"
+ },
+ "peerDependencies": {
+ "@fortawesome/fontawesome-svg-core": "~1 || ~6",
+ "react": ">=16.3"
+ }
+ },
+ "node_modules/@grpc/grpc-js": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.3.tgz",
+ "integrity": "sha512-b8iWtdrYIeT5fdZdS4Br/6h/kuk0PW5EVBUGk1amSbrpL8DlktJD43CdcCWwRdd6+jgwHhADSbL9CsNnm6EUPA==",
+ "dependencies": {
+ "@grpc/proto-loader": "^0.7.8",
+ "@types/node": ">=12.12.47"
+ },
+ "engines": {
+ "node": "^8.13.0 || >=10.10.0"
+ }
+ },
+ "node_modules/@grpc/proto-loader": {
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz",
+ "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==",
+ "dependencies": {
+ "lodash.camelcase": "^4.3.0",
+ "long": "^5.0.0",
+ "protobufjs": "^7.2.4",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
+ "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nicolo-ribaudo/chokidar-2": {
+ "version": "2.1.8-no-fsevents.3",
+ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz",
+ "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==",
+ "optional": true
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz",
+ "integrity": "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@toast-ui/editor": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@toast-ui/editor/-/editor-3.2.2.tgz",
+ "integrity": "sha512-ASX7LFjN2ZYQJrwmkUajPs7DRr9FsM1+RQ82CfTO0Y5ZXorBk1VZS4C2Dpxinx9kl55V4F8/A2h2QF4QMDtRbA==",
+ "dependencies": {
+ "dompurify": "^2.3.3",
+ "prosemirror-commands": "^1.1.9",
+ "prosemirror-history": "^1.1.3",
+ "prosemirror-inputrules": "^1.1.3",
+ "prosemirror-keymap": "^1.1.4",
+ "prosemirror-model": "^1.14.1",
+ "prosemirror-state": "^1.3.4",
+ "prosemirror-view": "^1.18.7"
+ }
+ },
+ "node_modules/@toast-ui/react-editor": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@toast-ui/react-editor/-/react-editor-3.2.3.tgz",
+ "integrity": "sha512-86QdgiOkBeSwRBEUWRKsTpnm6yu5j9HNJ3EfQN8EGcd7kI8k8AhExXyUJ3NNgNTzN7FfSKMw+1VaCDDC+aZ3dw==",
+ "dependencies": {
+ "@toast-ui/editor": "^3.2.2"
+ },
+ "peerDependencies": {
+ "react": "^17.0.1"
+ }
+ },
+ "node_modules/@types/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-YIQtIg4PKr7ZyqNPZObpxfHsHEmuB8dXCxd6qVcGuQVDK2bpsF7bYNnBJ4Nn7giuACZg+WewExgrtAJ3XnA4Xw==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.13",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
+ "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "20.6.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz",
+ "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA=="
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.6",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.6.tgz",
+ "integrity": "sha512-RK/kBbYOQQHLYj9Z95eh7S6t7gq4Ojt/NT8HTk8bWVhA5DaF+5SMnxHKkP4gPNN3wAZkKP+VjAf0ebtYzf+fxg==",
+ "dev": true
+ },
+ "node_modules/@types/react": {
+ "version": "18.2.22",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.22.tgz",
+ "integrity": "sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA==",
+ "dev": true,
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.2.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz",
+ "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.3",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
+ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
+ "dev": true
+ },
+ "node_modules/@types/semver": {
+ "version": "7.5.2",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz",
+ "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==",
+ "dev": true
+ },
+ "node_modules/@types/styled-components": {
+ "version": "5.1.27",
+ "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.27.tgz",
+ "integrity": "sha512-oY9c1SdztRRF0QDQdwXEenfAjGN4WGUkaMpx5hvdTbYYqw01qoY2GrHi+kAR6SVofynzD6KbGoF5ITP0zh5pvg==",
+ "dev": true,
+ "dependencies": {
+ "@types/hoist-non-react-statics": "*",
+ "@types/react": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw=="
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz",
+ "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.7.2",
+ "@typescript-eslint/type-utils": "6.7.2",
+ "@typescript-eslint/utils": "6.7.2",
+ "@typescript-eslint/visitor-keys": "6.7.2",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz",
+ "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "6.7.2",
+ "@typescript-eslint/types": "6.7.2",
+ "@typescript-eslint/typescript-estree": "6.7.2",
+ "@typescript-eslint/visitor-keys": "6.7.2",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz",
+ "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.7.2",
+ "@typescript-eslint/visitor-keys": "6.7.2"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz",
+ "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "6.7.2",
+ "@typescript-eslint/utils": "6.7.2",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz",
+ "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==",
+ "dev": true,
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz",
+ "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.7.2",
+ "@typescript-eslint/visitor-keys": "6.7.2",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz",
+ "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.7.2",
+ "@typescript-eslint/types": "6.7.2",
+ "@typescript-eslint/typescript-estree": "6.7.2",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.7.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz",
+ "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.7.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.4.tgz",
+ "integrity": "sha512-7wU921ABnNYkETiMaZy7XqpueMnpu5VxvVps13MjmCo+utBdD79sZzrApHawHtVX66cCJQQTXFcjH0y9dSUK8g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.22.9",
+ "@babel/plugin-transform-react-jsx-self": "^7.22.5",
+ "@babel/plugin-transform-react-jsx-source": "^7.22.5",
+ "react-refresh": "^0.14.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "optional": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz",
+ "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.6",
+ "@babel/helper-define-polyfill-provider": "^0.4.2",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz",
+ "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.4.2",
+ "core-js-compat": "^3.31.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz",
+ "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.4.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "devOptional": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.11",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz",
+ "integrity": "sha512-xn1UXOKUz7DjdGlg9RrUr0GGiWzI97UQJnugHtH0OLDfJB7jMgoIkYvRIEO1l9EeEERVqeqLYOcFBW9ldjypbQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001538",
+ "electron-to-chromium": "^1.4.526",
+ "node-releases": "^2.0.13",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001538",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz",
+ "integrity": "sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "optional": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "optional": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.32.2",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz",
+ "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==",
+ "dependencies": {
+ "browserslist": "^4.21.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/css-to-react-native": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+ "dependencies": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dompurify": {
+ "version": "2.4.7",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
+ "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ=="
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.527",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.527.tgz",
+ "integrity": "sha512-EafxEiEDzk2aLrdbtVczylHflHdHkNrpGNHIgDyA63sUQLQVS2ayj2hPw3RsVB42qkwURH+T2OxV7kGPUuYszA=="
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.49.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz",
+ "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.2",
+ "@eslint/js": "8.49.0",
+ "@humanwhocodes/config-array": "^0.11.11",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
+ "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz",
+ "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==",
+ "dev": true,
+ "peerDependencies": {
+ "eslint": ">=7"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/globals": {
+ "version": "13.22.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz",
+ "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
+ "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "devOptional": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/firebase": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.4.0.tgz",
+ "integrity": "sha512-3Z8WsNwA7kbcKGZ+nrTZ/ES518pk0K440ZJYD8nUNKN5hV6ll+unhUw30t1msedN6yIFjhsC/9OwT4Z0ohwO2w==",
+ "dependencies": {
+ "@firebase/analytics": "0.10.0",
+ "@firebase/analytics-compat": "0.2.6",
+ "@firebase/app": "0.9.19",
+ "@firebase/app-check": "0.8.0",
+ "@firebase/app-check-compat": "0.3.7",
+ "@firebase/app-compat": "0.2.19",
+ "@firebase/app-types": "0.9.0",
+ "@firebase/auth": "1.3.0",
+ "@firebase/auth-compat": "0.4.6",
+ "@firebase/database": "1.0.1",
+ "@firebase/database-compat": "1.0.1",
+ "@firebase/firestore": "4.2.0",
+ "@firebase/firestore-compat": "0.3.18",
+ "@firebase/functions": "0.10.0",
+ "@firebase/functions-compat": "0.3.5",
+ "@firebase/installations": "0.6.4",
+ "@firebase/installations-compat": "0.2.4",
+ "@firebase/messaging": "0.12.4",
+ "@firebase/messaging-compat": "0.2.4",
+ "@firebase/performance": "0.6.4",
+ "@firebase/performance-compat": "0.2.4",
+ "@firebase/remote-config": "0.4.4",
+ "@firebase/remote-config-compat": "0.2.4",
+ "@firebase/storage": "0.11.2",
+ "@firebase/storage-compat": "0.3.2",
+ "@firebase/util": "1.9.3"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz",
+ "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.7",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.9",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
+ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
+ "dev": true
+ },
+ "node_modules/fs-readdir-recursive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+ "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA=="
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dev": true,
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/http-parser-js": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
+ "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q=="
+ },
+ "node_modules/idb": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
+ "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "optional": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
+ "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "devOptional": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
+ "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/long": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+ "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "dev": true,
+ "dependencies": {
+ "@aashutoshrathi/word-wrap": "^1.2.3",
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/orderedmap": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
+ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g=="
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.30",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
+ "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/prosemirror-commands": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz",
+ "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==",
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-history": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.3.2.tgz",
+ "integrity": "sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==",
+ "dependencies": {
+ "prosemirror-state": "^1.2.2",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.31.0",
+ "rope-sequence": "^1.3.0"
+ }
+ },
+ "node_modules/prosemirror-inputrules": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.2.1.tgz",
+ "integrity": "sha512-3LrWJX1+ULRh5SZvbIQlwZafOXqp1XuV21MGBu/i5xsztd+9VD15x6OtN6mdqSFI7/8Y77gYUbQ6vwwJ4mr6QQ==",
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-keymap": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz",
+ "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==",
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "w3c-keyname": "^2.2.0"
+ }
+ },
+ "node_modules/prosemirror-model": {
+ "version": "1.19.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.3.tgz",
+ "integrity": "sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ==",
+ "dependencies": {
+ "orderedmap": "^2.0.0"
+ }
+ },
+ "node_modules/prosemirror-state": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
+ "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.27.0"
+ }
+ },
+ "node_modules/prosemirror-transform": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.7.5.tgz",
+ "integrity": "sha512-U/fWB6frEzY7dzwJUo+ir8dU1JEanaI/RwL12Imy9js/527N0v/IRUKewocP1kTq998JNT18IGtThaDLwLOBxQ==",
+ "dependencies": {
+ "prosemirror-model": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-view": {
+ "version": "1.31.8",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.31.8.tgz",
+ "integrity": "sha512-VQrEIdiPJ4YV65Ifj2kWISwaiqocMHy7cpUKVQYt19C/87FepoqnwVW3kMKRpeY/nQzED8L+vyOaYDBn0WqT7w==",
+ "dependencies": {
+ "prosemirror-model": "^1.16.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0"
+ }
+ },
+ "node_modules/protobufjs": {
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz",
+ "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
+ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz",
+ "integrity": "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==",
+ "dependencies": {
+ "@remix-run/router": "1.9.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.16.0.tgz",
+ "integrity": "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==",
+ "dependencies": {
+ "@remix-run/router": "1.9.0",
+ "react-router": "6.16.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "optional": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz",
+ "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==",
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ },
+ "node_modules/regenerator-transform": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
+ "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
+ "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "dependencies": {
+ "@babel/regjsgen": "^0.8.0",
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.1.0",
+ "regjsparser": "^0.9.1",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsparser": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
+ "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.6",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
+ "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.29.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz",
+ "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rope-sequence": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
+ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ=="
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/styled-components": {
+ "version": "6.0.8",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.8.tgz",
+ "integrity": "sha512-AwI02MTWZwqjzfXgR5QcbmcSn5xVjY4N2TLjSuYnmuBGF3y7GicHz3ysbpUq2EMJP5M8/Nc22vcmF3V3WNZDFA==",
+ "dependencies": {
+ "@babel/cli": "^7.21.0",
+ "@babel/core": "^7.21.0",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/plugin-external-helpers": "^7.18.6",
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
+ "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
+ "@babel/preset-env": "^7.20.2",
+ "@babel/preset-react": "^7.18.6",
+ "@babel/preset-typescript": "^7.21.0",
+ "@babel/traverse": "^7.21.2",
+ "@emotion/is-prop-valid": "^1.2.1",
+ "@emotion/unitless": "^0.8.0",
+ "@types/stylis": "^4.0.2",
+ "css-to-react-native": "^3.2.0",
+ "csstype": "^3.1.2",
+ "postcss": "^8.4.23",
+ "shallowequal": "^1.1.0",
+ "stylis": "^4.3.0",
+ "tslib": "^2.5.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/styled-components"
+ },
+ "peerDependencies": {
+ "babel-plugin-styled-components": ">= 2",
+ "react": ">= 16.8.0",
+ "react-dom": ">= 16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-styled-components": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/stylis": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz",
+ "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ=="
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "devOptional": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
+ "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "4.4.9",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
+ "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.18.10",
+ "postcss": "^8.4.27",
+ "rollup": "^3.27.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/w3c-keyname": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..f0d6d15b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "vite-project",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^6.4.2",
+ "@fortawesome/free-solid-svg-icons": "^6.4.2",
+ "@fortawesome/react-fontawesome": "^0.2.0",
+ "@toast-ui/react-editor": "^3.2.3",
+ "firebase": "^10.3.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.15.0",
+ "styled-components": "^6.0.7"
+ },
+ "devDependencies": {
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@types/styled-components": "^5.1.27",
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
+ "@typescript-eslint/parser": "^6.0.0",
+ "@vitejs/plugin-react": "^4.0.3",
+ "eslint": "^8.45.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.3",
+ "typescript": "^5.0.2",
+ "vite": "^4.4.5"
+ }
+}
diff --git a/public/icon/favicon-16x16.png b/public/icon/favicon-16x16.png
new file mode 100644
index 00000000..8e12f11e
Binary files /dev/null and b/public/icon/favicon-16x16.png differ
diff --git a/public/images/free-icon-x.png b/public/images/free-icon-x.png
new file mode 100644
index 00000000..0f88813d
Binary files /dev/null and b/public/images/free-icon-x.png differ
diff --git a/public/images/github-logo.png b/public/images/github-logo.png
new file mode 100644
index 00000000..6c3b3cd1
Binary files /dev/null and b/public/images/github-logo.png differ
diff --git a/public/images/notification01.jpg b/public/images/notification01.jpg
new file mode 100644
index 00000000..3da850ae
Binary files /dev/null and b/public/images/notification01.jpg differ
diff --git a/public/images/notification01.png b/public/images/notification01.png
new file mode 100644
index 00000000..a4c244b7
Binary files /dev/null and b/public/images/notification01.png differ
diff --git a/public/images/notification02.jpg b/public/images/notification02.jpg
new file mode 100644
index 00000000..d2bde267
Binary files /dev/null and b/public/images/notification02.jpg differ
diff --git a/public/images/notification02.png b/public/images/notification02.png
new file mode 100644
index 00000000..b3d28069
Binary files /dev/null and b/public/images/notification02.png differ
diff --git a/public/images/notification03.jpg b/public/images/notification03.jpg
new file mode 100644
index 00000000..f9552b9b
Binary files /dev/null and b/public/images/notification03.jpg differ
diff --git a/public/images/notification03.png b/public/images/notification03.png
new file mode 100644
index 00000000..c5e0e9a3
Binary files /dev/null and b/public/images/notification03.png differ
diff --git a/public/images/notification04.jpg b/public/images/notification04.jpg
new file mode 100644
index 00000000..6cf1b97a
Binary files /dev/null and b/public/images/notification04.jpg differ
diff --git a/public/images/notification04.png b/public/images/notification04.png
new file mode 100644
index 00000000..557d5321
Binary files /dev/null and b/public/images/notification04.png differ
diff --git a/public/images/notification05.png b/public/images/notification05.png
new file mode 100644
index 00000000..a47d627b
Binary files /dev/null and b/public/images/notification05.png differ
diff --git a/public/images/upload-image.png b/public/images/upload-image.png
new file mode 100644
index 00000000..96926f6c
Binary files /dev/null and b/public/images/upload-image.png differ
diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 00000000..8ef070a0
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,33 @@
+import AppRouter from "./AppRouter";
+import { useEffect, useState } from "react";
+import { auth } from "./firebase/firebase";
+
+export type Props = {
+ uid?: string;
+ email: string;
+};
+
+function App() {
+ const [uid, setUid] = useState("");
+ const [email, setEmail] = useState("");
+
+ useEffect(() => {
+ auth.onAuthStateChanged((user) => {
+ if (user !== null) {
+ setUid(user.uid);
+ const email = user.email;
+ if (email !== null) {
+ setEmail(email);
+ }
+ }
+ });
+ }, []);
+
+ return (
+ <>
+
+ >
+ );
+}
+
+export default App;
diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx
new file mode 100644
index 00000000..72d697da
--- /dev/null
+++ b/src/AppRouter.tsx
@@ -0,0 +1,22 @@
+import { BrowserRouter, Routes, Route } from "react-router-dom";
+import { Home, Gallery, Login, Wiki } from "./pages/pageIndex";
+import Header from "./components/common/Header";
+import RootPage from "./components/common/RootPage";
+import Footer from "./components/common/Footer";
+import { Props } from "./App";
+
+export default function AppRouter({ email, uid }: Props) {
+ return (
+
+
+
+ } />
+ } />
+ } />
+ } />
+
+
+
+
+ );
+}
diff --git a/src/components/common/Button.tsx b/src/components/common/Button.tsx
new file mode 100644
index 00000000..9dae9210
--- /dev/null
+++ b/src/components/common/Button.tsx
@@ -0,0 +1,31 @@
+import * as style from "./buttonStyle";
+
+interface Props {
+ text: string;
+ margin?: string;
+ padding: string;
+ normal?: string;
+ disabled?: boolean;
+ onClick?: () => void;
+}
+
+export default function Button({
+ text,
+ padding,
+ margin,
+ normal,
+ disabled,
+ onClick,
+}: Props) {
+ return (
+
+ {text}
+
+ );
+}
diff --git a/src/components/common/CommuteModal.tsx b/src/components/common/CommuteModal.tsx
new file mode 100644
index 00000000..d96dfca1
--- /dev/null
+++ b/src/components/common/CommuteModal.tsx
@@ -0,0 +1,141 @@
+import { useEffect, useRef, useState } from "react";
+import Button from "./Button";
+import * as style from "./commuteModalStyle";
+import { doc, setDoc } from "firebase/firestore";
+import { db } from "@/firebase/firebase";
+
+interface Props {
+ showModal: boolean;
+ setShowModal: React.Dispatch>;
+ startTime: Date | null;
+ setStartTime: React.Dispatch>;
+ endTime: Date | null;
+ setEndTime: React.Dispatch>;
+ workingHours: number;
+ workingMinutes: number;
+ setWorkedHours: React.Dispatch>;
+ setWorkedMinutes: React.Dispatch>;
+ disabledEndBtn: boolean;
+ setDisabledEndBtn: React.Dispatch>;
+ uid: string | undefined;
+}
+
+export default function CommuteModal({
+ showModal,
+ setShowModal,
+ startTime,
+ setStartTime,
+ endTime,
+ setEndTime,
+ workingHours,
+ workingMinutes,
+ setWorkedHours,
+ setWorkedMinutes,
+ disabledEndBtn,
+ setDisabledEndBtn,
+ uid,
+}: Props) {
+ const [time, setTime] = useState(new Date());
+
+ useEffect(() => {
+ const id = setInterval(() => {
+ setTime(new Date());
+ }, 1000);
+ return () => clearInterval(id);
+ }, []);
+
+ const node = useRef(null);
+ useEffect(() => {
+ const clickOutside = (e: MouseEvent) => {
+ // 모달이 열려 있고 모달의 바깥쪽을 눌렀을 때 창 닫기
+ if (
+ showModal &&
+ node.current &&
+ !node.current.contains(e.target as Node)
+ ) {
+ setShowModal(false);
+ }
+ };
+
+ document.addEventListener("mousedown", clickOutside);
+
+ return () => {
+ document.removeEventListener("mousedown", clickOutside);
+ };
+ }, [showModal]);
+
+ const onStartClick = async () => {
+ if (uid) {
+ await setDoc(doc(db, "Commute", uid), {
+ start: time,
+ });
+ }
+ setStartTime(time);
+ setDisabledEndBtn(false);
+ };
+ const onEndClick = async () => {
+ if (uid) {
+ await setDoc(
+ doc(db, "Commute", uid),
+ {
+ end: time,
+ workingHours: workingHours,
+ workingMinutes: workingMinutes,
+ },
+ { merge: true },
+ );
+ }
+ setEndTime(time);
+ setDisabledEndBtn(true);
+ setWorkedHours(workingHours);
+ setWorkedMinutes(workingMinutes);
+ };
+
+ window.addEventListener("keydown", (e) => {
+ e.key === "Escape" && setShowModal(false);
+ });
+
+ return (
+
+
+ setShowModal(false)}
+ >
+ 출퇴근 처리
+
+
+ {time.getFullYear()}.{time.getMonth() + 1}.{time.getDate()}
+
+ {time.toLocaleTimeString()}
+
+
+
+
+ 오늘의 출근 시간:{" "}
+ {startTime ? startTime.toLocaleTimeString() : "--:--:--"}
+
+
+ 오늘의 퇴근 시간:{" "}
+ {endTime ? endTime.toLocaleTimeString() : "--:--:--"}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/common/Footer.tsx b/src/components/common/Footer.tsx
new file mode 100644
index 00000000..426968e2
--- /dev/null
+++ b/src/components/common/Footer.tsx
@@ -0,0 +1,39 @@
+import { useLocation } from "react-router-dom";
+import * as style from "./FooterStyle";
+
+export default function Footer() {
+ const location = useLocation();
+ if (location.pathname === "/login") return null;
+ return (
+
+
+
+ 9굴 WIKI
+
+
+
+ 서지수
{" "}
+
+
+ 이승연
{" "}
+
+
+ 김소정
{" "}
+
+
+ 양재준
{" "}
+
+
+ 이용훈
{" "}
+
+
+
+
+
+
+
+
+ {/* 4 */}
+
+ );
+}
diff --git a/src/components/common/FooterStyle.ts b/src/components/common/FooterStyle.ts
new file mode 100644
index 00000000..289f1021
--- /dev/null
+++ b/src/components/common/FooterStyle.ts
@@ -0,0 +1,60 @@
+import styled from "styled-components";
+
+export const FooterWrap = styled.div`
+ margin-top: 2.5rem;
+ background-color: var(--color-main);
+ padding: 0.3125rem 5rem;
+ color: var(--color-white);
+ opacity: 20%;
+`;
+
+export const FooterTop = styled.div`
+ padding: 0.625rem 0;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+export const FooterTopLeft = styled.div`
+ & > span {
+ font-size: 1rem;
+ letter-spacing: -0.05rem;
+ }
+`;
+
+export const FooterTopMid = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ & > a > p {
+ margin: 0 0.625rem;
+ font-size: 0.8rem;
+ letter-spacing: -0.04rem;
+ }
+
+ & > a > p:hover {
+ border-bottom: 1px solid #fff;
+ }
+`;
+
+export const FooterTopRight = styled.div`
+ & > a {
+ display: inline-block;
+ width: 1.875rem;
+ height: 1.875rem;
+ }
+
+ & img {
+ color: white;
+ width: 100%;
+ vertical-align: bottom;
+ }
+`;
+
+export const FooterBottom = styled.div`
+ border: 0.0625rem solid yellow;
+ padding: 0.625rem 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx
new file mode 100644
index 00000000..0279a6cf
--- /dev/null
+++ b/src/components/common/Header.tsx
@@ -0,0 +1,151 @@
+import Button from "./Button";
+import * as style from "./headerStyle";
+import { useLocation } from "react-router-dom";
+import CommuteModal from "./CommuteModal";
+import { useEffect, useState } from "react";
+import { signOut } from "firebase/auth";
+import { auth, db } from "@/firebase/firebase";
+import { Props } from "../../App";
+import { deleteDoc, doc, getDoc } from "firebase/firestore";
+import convertTimestampToDate from "@/utils/convertTimestampToDate";
+
+export default function Header({ uid, email }: Props) {
+ const [showModal, setShowModal] = useState(false);
+ const onCommuteClick = () => {
+ setShowModal(!showModal);
+ };
+ const [startTime, setStartTime] = useState(null);
+ const [endTime, setEndTime] = useState(null);
+
+ const [workingHours, setWorkingHours] = useState(0);
+ const [workingMinutes, setWorkingMinutes] = useState(0);
+ useEffect(() => {
+ if (startTime) {
+ const id = setInterval(() => {
+ const diffMSec = new Date().getTime() - startTime.getTime();
+ const diffHour = Math.floor(diffMSec / (60 * 60 * 1000));
+ const diffMin = Math.floor((diffMSec / (60 * 1000)) % 60);
+ setWorkingHours(diffHour);
+ setWorkingMinutes(diffMin);
+ }, 1000);
+ return () => clearInterval(id);
+ }
+ }, [startTime]);
+
+ const logout = async () => {
+ await signOut(auth);
+ window.location.replace("/login");
+ };
+
+ const [workedHours, setWorkedHours] = useState(0);
+ const [workedMinutes, setWorkedMinutes] = useState(0);
+
+ const isSameDate = (date1: Date, date2: Date) => {
+ return (
+ date1.getFullYear() === date2.getFullYear() &&
+ date1.getMonth() === date2.getMonth() &&
+ date1.getDate() === date2.getDate()
+ );
+ };
+
+ const [disabledEndBtn, setDisabledEndBtn] = useState(true);
+
+ useEffect(() => {
+ const getCommuteTime = async () => {
+ if (uid) {
+ const docRef = doc(db, "Commute", uid);
+ const docSnap = await getDoc(docRef);
+
+ if (docSnap.exists()) {
+ if (docSnap.data().start) {
+ const startData = convertTimestampToDate(docSnap.data().start);
+ if (isSameDate(startData!, new Date())) {
+ setStartTime(convertTimestampToDate(docSnap.data().start));
+ setDisabledEndBtn(false);
+ } else {
+ await deleteDoc(doc(db, "Commute", uid));
+ }
+ if (docSnap.data().end) {
+ const endData = convertTimestampToDate(docSnap.data().end);
+ if (isSameDate(endData!, new Date())) {
+ setEndTime(convertTimestampToDate(docSnap.data().end));
+ setWorkedHours(docSnap.data().workingHours);
+ setWorkedMinutes(docSnap.data().workingMinutes);
+ setDisabledEndBtn(true);
+ } else {
+ await deleteDoc(doc(db, "Commute", uid));
+ }
+ }
+ }
+ }
+ }
+ };
+ getCommuteTime();
+ }, [uid]);
+
+ const location = useLocation();
+ if (location.pathname === "/login") return null;
+ return (
+ <>
+
+
+
+ 9굴 WIKI
+
+
+ {email}
+ {startTime && !endTime ? (
+
+ {String(workingHours).padStart(2, "0")}:
+ {String(workingMinutes).padStart(2, "0")} 근무 중
+
+ ) : (
+ startTime &&
+ endTime && (
+
+ {String(workedHours).padStart(2, "0")}:
+ {String(workedMinutes).padStart(2, "0")} 근무 완료
+
+ )
+ )}
+
+ LOGOUT
+
+
+
+
+ HOME
+
+
+
+ WIKI
+
+ GALLERY
+
+
+
+ {showModal && (
+
+ )}
+ >
+ );
+}
diff --git a/src/components/common/Input.tsx b/src/components/common/Input.tsx
new file mode 100644
index 00000000..49400124
--- /dev/null
+++ b/src/components/common/Input.tsx
@@ -0,0 +1,36 @@
+import * as style from "./InputStyle";
+
+interface Props {
+ type: string;
+ id: string;
+ onChange?: (e: React.ChangeEvent) => void;
+ onKeyPress?: (e: React.KeyboardEvent) => void;
+ placeholder?: string;
+ forwardedRef?: React.Ref;
+ value?: string;
+ width?: string;
+}
+
+export default function Input({
+ type,
+ id,
+ onChange,
+ onKeyPress,
+ placeholder,
+ forwardedRef,
+ value,
+ width,
+}: Props) {
+ return (
+
+ );
+}
diff --git a/src/components/common/InputStyle.ts b/src/components/common/InputStyle.ts
new file mode 100644
index 00000000..338dc9f5
--- /dev/null
+++ b/src/components/common/InputStyle.ts
@@ -0,0 +1,14 @@
+import styled from "styled-components";
+
+export const Input = styled.input<{ width?: string }>`
+ font-family: inherit;
+ padding: 0.2rem;
+ border: 1px solid var(--color-medium-gray);
+ outline: none;
+ border-radius: 0.2rem;
+ width: ${({ width }) => width};
+
+ &:focus {
+ border: 1px solid var(--color-main);
+ }
+`;
diff --git a/src/components/common/RootPage.tsx b/src/components/common/RootPage.tsx
new file mode 100644
index 00000000..c83c2971
--- /dev/null
+++ b/src/components/common/RootPage.tsx
@@ -0,0 +1,25 @@
+import { useLocation } from "react-router-dom";
+import { useEffect } from "react";
+import { auth } from "@/firebase/firebase";
+
+export default function RootPage() {
+ const Root = () => {
+ const location = useLocation();
+ useEffect(() => {
+ const interval = setInterval(() => {
+ auth.onAuthStateChanged((user) => {
+ if (location.pathname !== "/login" && user == null) {
+ setTimeout(() => window.location.replace("/login"), 800);
+ }
+ });
+ });
+ return () => {
+ clearInterval(interval);
+ };
+ }, []);
+ };
+
+ Root();
+
+ return <>>;
+}
diff --git a/src/components/common/buttonStyle.ts b/src/components/common/buttonStyle.ts
new file mode 100644
index 00000000..fe437dce
--- /dev/null
+++ b/src/components/common/buttonStyle.ts
@@ -0,0 +1,38 @@
+import styled from "styled-components";
+
+export const Container = styled.button<{
+ $padding: string;
+ $margin?: string;
+ $normal?: string;
+}>`
+ border: ${({ $normal }) =>
+ $normal === "reverse"
+ ? "0.0625rem solid var(--color-light-gray)"
+ : "0.0625rem solid var(--color-main)"};
+
+ border-radius: 0.25rem;
+ background: var(--color-white);
+
+ margin: ${({ $margin }) => $margin};
+ padding: ${({ $padding }) => $padding};
+
+ cursor: pointer;
+
+ color: ${({ $normal }) =>
+ $normal === "reverse" ? "#000" : "var(--color-main)"};
+ font-size: 0.875rem;
+ line-height: normal;
+ text-align: center;
+
+ &:hover {
+ background-color: var(--color-main);
+ color: var(--color-white);
+ }
+
+ &:disabled {
+ background: #f9f9f9;
+ border: 1px solid var(--color-light-gray);
+ color: var(--color-disabled);
+ cursor: not-allowed;
+ }
+`;
diff --git a/src/components/common/commuteModalStyle.ts b/src/components/common/commuteModalStyle.ts
new file mode 100644
index 00000000..4ad74f90
--- /dev/null
+++ b/src/components/common/commuteModalStyle.ts
@@ -0,0 +1,101 @@
+import styled from "styled-components";
+
+export const Container = styled.div`
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ z-index: 1002;
+
+ background: #0000007f;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const ModalWrapper = styled.div`
+ width: 40%;
+
+ border-radius: 15px;
+ background: var(--color-white);
+
+ padding: 2.4375rem 3.375rem;
+
+ display: flex;
+ flex-direction: column;
+
+ position: relative;
+`;
+
+export const Xicon = styled.img`
+ position: absolute;
+ width: 0.8125rem;
+ height: 0.8125rem;
+
+ top: 1.875rem;
+ right: 1.875rem;
+
+ cursor: pointer;
+`;
+
+export const Title = styled.span`
+ color: var(--color-gray);
+ font-weight: 700;
+ font-size: 1.125rem;
+ line-height: normal;
+ text-align: center;
+
+ margin-bottom: 2.1875rem;
+`;
+
+export const TimeBox = styled.div`
+ border-radius: 15px;
+ background: var(--color-white);
+ border: 1px solid var(--color-light-gray);
+
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ padding: 2.5625rem;
+
+ margin-bottom: 2.375rem;
+`;
+
+export const Date = styled.span`
+ color: var(--color-gray);
+ font-weight: 500;
+ font-size: 0.875rem;
+ line-height: normal;
+`;
+
+export const NowTime = styled.time`
+ color: var(--color-gray);
+ font-weight: 500;
+ font-size: 2.375rem;
+ line-height: normal;
+`;
+
+export const CommuteTimeWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 7px;
+
+ margin-bottom: 2.5rem;
+`;
+
+export const CommuteTime = styled.span`
+ color: var(--color-gray);
+ font-weight: 500;
+ font-size: 0.875rem;
+ line-height: normal;
+`;
+
+export const BtnWrapper = styled.div`
+ display: flex;
+ gap: 0.3125rem;
+ justify-content: center;
+`;
diff --git a/src/components/common/headerStyle.ts b/src/components/common/headerStyle.ts
new file mode 100644
index 00000000..421e6f2d
--- /dev/null
+++ b/src/components/common/headerStyle.ts
@@ -0,0 +1,122 @@
+import styled from "styled-components";
+import { Link, NavLink } from "react-router-dom";
+
+export const Container = styled.div`
+ position: sticky;
+ top: 0;
+ z-index: 1001;
+`;
+
+export const Top = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ height: 3.375rem;
+ padding: 0rem 5rem;
+
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-white);
+`;
+
+export const Wrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
+
+export const Logo = styled(Link)`
+ color: var(--color-dark-gray);
+ font-weight: 700;
+ font-size: 1.13rem;
+ line-height: normal;
+ text-align: left;
+`;
+
+export const UserName = styled.span`
+ color: var(--color-dark-gray);
+ font-size: 0.88rem;
+ line-height: normal;
+ text-align: left;
+
+ margin-right: 1.25rem;
+`;
+
+export const WorkingTime = styled.div`
+ border-radius: 4px;
+ border: 1px solid var(--color-medium-gray);
+
+ background: var(--color-white);
+
+ padding: 0.3125rem 0.6875rem;
+ margin-right: 0.4375rem;
+
+ color: var(--color-dark-gray);
+ font-weight: 400;
+ font-size: 0.875rem;
+ line-height: normal;
+`;
+
+export const WorkedTime = styled(WorkingTime)`
+ border: 1px solid #fd0d29;
+`;
+
+export const LogoutBtn = styled.button`
+ display: flex;
+ align-items: center;
+
+ background-color: var(--color-white);
+ color: var(--color-dark-gray);
+
+ border: 0;
+
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ cursor: pointer;
+
+ margin-left: 1.25rem;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ &::before {
+ content: "";
+ background: #c8c8c8;
+
+ width: 1px;
+ height: 0.875rem;
+
+ display: block;
+
+ position: relative;
+ left: -1.25rem;
+ }
+`;
+
+export const Bottom = styled.nav`
+ background: var(--color-main);
+ border: 0.06rem solid var(--color-white);
+
+ height: 3.375rem;
+ padding: 0rem 5rem;
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+export const NavSpan = styled(NavLink)<{ margin_r?: string }>`
+ color: var(--color-white);
+ font-weight: 500;
+ font-size: 1rem;
+ line-height: normal;
+ margin-right: ${({ margin_r }) => margin_r};
+ border-bottom: 3px solid transparent;
+ transition: 0.1s;
+
+ &.active {
+ border-bottom-color: var(--color-white);
+ }
+ &:hover {
+ border-bottom-color: var(--color-white);
+ }
+`;
diff --git a/src/components/gallery/AddImg.tsx b/src/components/gallery/AddImg.tsx
new file mode 100644
index 00000000..16f27b3d
--- /dev/null
+++ b/src/components/gallery/AddImg.tsx
@@ -0,0 +1,185 @@
+import * as style from "./AddImgStyle";
+import { useState } from "react";
+import Button from "../common/Button";
+import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";
+import { app } from "@/firebase/firebase";
+
+interface AddImgProps {
+ albumId: string;
+ imagePaths: string[];
+ setAddImg: React.Dispatch>;
+ setImgLoad: React.Dispatch>;
+ setImagePaths: React.Dispatch>;
+}
+
+interface FileInfoProps {
+ uploadedInfo: {
+ name: string;
+ size: string;
+ type: string;
+ imageUrl?: string;
+ };
+}
+
+function FileInfo({ uploadedInfo }: FileInfoProps) {
+ // console.log(uploadedInfo.imageUrl);
+ return (
+
+
+
+ {Object.entries(uploadedInfo).map(([key, value]) => (
+
+ {key}
+ {value}
+
+ ))}
+
+
+ );
+}
+
+function Logo() {
+ return (
+
+
+
+ );
+}
+
+export function AddImg({
+ albumId,
+ imagePaths,
+ setAddImg,
+ setImgLoad,
+ setImagePaths,
+}: AddImgProps) {
+ const [isActive, setActive] = useState(false);
+ const [uploadedInfo, setUploadedInfo] = useState<{
+ name: string;
+ size: string;
+ type: string;
+ imageUrl?: string;
+ } | null>(null);
+
+ const [uploadedFile, setUploadedFile] = useState(null);
+
+ const setFileInfo = (file: File) => {
+ const { name, type } = file;
+ const isImage = type.includes("image");
+ const size = (file.size / (1024 * 1024)).toFixed(2) + "mb";
+
+ if (!isImage) {
+ setUploadedInfo({ name, size, type });
+ return;
+ }
+ const reader = new FileReader();
+ reader.onload = () => {
+ setUploadedInfo({ name, size, type, imageUrl: String(reader.result) });
+ };
+ reader.readAsDataURL(file);
+ };
+
+ const handleDragStart = (e: React.DragEvent) => {
+ e.preventDefault();
+ setActive(true);
+ };
+
+ const handleDragEnd = (e: React.DragEvent) => {
+ e.preventDefault();
+ setActive(false);
+ };
+
+ const handleDrop = (e: React.DragEvent) => {
+ e.preventDefault();
+ setActive(false);
+
+ const file = e.dataTransfer.files[0];
+ setFileInfo(file);
+ setUploadedFile(file);
+ };
+
+ const handleUpload = (e: React.ChangeEvent) => {
+ if (e.target.files) {
+ const file = e.target.files[0];
+ setFileInfo(file);
+ setUploadedFile(file);
+ }
+ };
+
+ const clickSaveBtn = async () => {
+ setImgLoad(true);
+ const storage = getStorage(app);
+ const storageRef = ref(storage, `Gallery/${albumId}/${uploadedInfo?.name}`);
+
+ try {
+ const metadata = {
+ customMetadata: {
+ timestamp: new Date().toString(),
+ },
+ };
+
+ await uploadBytes(storageRef, uploadedFile as File, metadata);
+
+ const downloadURL = await getDownloadURL(storageRef);
+
+ const copy = [...imagePaths];
+ copy.push(downloadURL);
+ setImagePaths(copy);
+
+ setAddImg(false);
+ console.log("이미지 업로드 성공!");
+ } catch (error) {
+ console.error("이미지 업로드 실패:", error);
+ }
+ setImgLoad(false);
+ };
+
+ return (
+
+
+
+
+
+ {uploadedInfo && }
+ {!uploadedInfo && (
+ <>
+
+
+ 클릭 혹은 드래그를 통하여 파일을 올리세요!
+
+ >
+ )}
+
+
+
+
+ {
+ setAddImg(false);
+ }}
+ />
+
+
+
+ );
+}
diff --git a/src/components/gallery/AddImgStyle.tsx b/src/components/gallery/AddImgStyle.tsx
new file mode 100644
index 00000000..2f1fd542
--- /dev/null
+++ b/src/components/gallery/AddImgStyle.tsx
@@ -0,0 +1,99 @@
+import styled from "styled-components";
+
+export const Container = styled.div`
+ z-index: 10000;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const Form = styled.div`
+ border-radius: 0.5rem;
+ width: 30rem;
+ height: 23rem;
+ padding: 1.4rem;
+ background-color: var(--color-white);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const InputWrap = styled.div`
+ width: 100%;
+ height: 100%;
+ margin-bottom: 1rem;
+`;
+
+export const ImgLabel = styled.label`
+ z-index: 1000;
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ border: 3px dashed var(--color-medium-gray);
+
+ &:hover,
+ &.active {
+ border: 3px dashed var(--color-main);
+ background-color: var(--color-area);
+ }
+
+ & > .preview_msg {
+ margin-top: 1rem;
+ font-weight: 500;
+ color: var(--color-main);
+ }
+`;
+
+export const ImgFile = styled.input`
+ display: none;
+`;
+
+export const FileInfoContainer = styled.div<{
+ background?: string;
+}>`
+ // border: 1px solid red;
+ padding: 1rem;
+ width: 100%;
+ height: 100%;
+ display: flex;
+
+ & > .img_preview {
+ // border: 1px solid red;
+ // padding: 1rem;
+ width: 50%;
+ background-image: url(${({ background }) => background});
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-position: center;
+ }
+`;
+
+export const FileInfoWrap = styled.ul`
+ // border: 1px solid red;
+ width: 50%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ & > li {
+ padding-left: 10px;
+ margin: 0.3rem;
+ }
+ & > li:last-of-type {
+ display: none;
+ }
+ & > li > div:first-of-type {
+ font-weight: bold;
+ }
+`;
diff --git a/src/components/gallery/AddList.tsx b/src/components/gallery/AddList.tsx
new file mode 100644
index 00000000..42aed0cf
--- /dev/null
+++ b/src/components/gallery/AddList.tsx
@@ -0,0 +1,90 @@
+import * as style from "./AddListStyle";
+import Input from "../common/Input";
+import Button from "../common/Button";
+import { useState } from "react";
+import { collection, addDoc, getFirestore } from "firebase/firestore";
+import { app } from "@/firebase/firebase";
+
+const firestore = getFirestore(app);
+
+interface Folders {
+ createdAt: Date;
+ id: string;
+ sub: string[];
+ title: string;
+}
+
+interface GallerySideProps {
+ closeAddListModal: () => void;
+ galleryData: Folders[];
+ setGalleryData: React.Dispatch>;
+}
+
+export default function Addlist({
+ closeAddListModal,
+ galleryData,
+ setGalleryData,
+}: GallerySideProps) {
+ const [inputValue, setInputValue] = useState("");
+
+ const createGallery = async () => {
+ try {
+ const timestamp = new Date().getTime();
+ const randomValue = Math.random();
+ const uniqueId = `${timestamp}-${randomValue}`;
+
+ const newData = {
+ title: inputValue,
+ createdAt: new Date(),
+ sub: [],
+ id: uniqueId,
+ };
+
+ const docRef = await addDoc(collection(firestore, "Gallery"), newData);
+
+ const copy = [...galleryData];
+ copy.push(newData);
+ setGalleryData(copy);
+ closeAddListModal();
+ console.log("새로운 Gallery 문서가 생성되었습니다. 문서 ID:", docRef.id);
+ } catch (error) {
+ console.error("Gallery 생성 중 오류 발생:", error);
+ }
+ };
+
+ const setValue = (e: React.ChangeEvent): void => {
+ setInputValue(e.target.value);
+ };
+
+ const saveTitle = () => {
+ console.log(inputValue);
+ createGallery();
+ };
+
+ return (
+
+
+
+
+ 이름
+
+ setValue(e)} />
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/gallery/AddListStyle.tsx b/src/components/gallery/AddListStyle.tsx
new file mode 100644
index 00000000..d3967d70
--- /dev/null
+++ b/src/components/gallery/AddListStyle.tsx
@@ -0,0 +1,25 @@
+import styled from "styled-components";
+
+export const Container = styled.div`
+ z-index: 10000;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const Form = styled.div`
+ border-radius: 0.5rem;
+ width: 20rem;
+ height: 13rem;
+ background-color: var(--color-white);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+`;
diff --git a/src/components/gallery/CurrentImg.tsx b/src/components/gallery/CurrentImg.tsx
new file mode 100644
index 00000000..0d657192
--- /dev/null
+++ b/src/components/gallery/CurrentImg.tsx
@@ -0,0 +1,168 @@
+import { useEffect, useState } from "react";
+import * as style from "./CurrentImgStyle";
+import { getStorage, ref, deleteObject } from "firebase/storage";
+import { app } from "@/firebase/firebase";
+
+const storage = getStorage(app);
+
+interface CurrentImgProps {
+ curImg: string;
+ imagePaths: string[];
+ setViewImg: React.Dispatch>;
+ setCurImg: React.Dispatch>;
+ setImagePaths: React.Dispatch>;
+}
+
+export default function CurrentImg({
+ setViewImg,
+ setCurImg,
+ setImagePaths,
+ curImg,
+ imagePaths,
+}: CurrentImgProps) {
+ const [prevBtn, setPrevBtn] = useState(true);
+ const [nextBtn, setNextBtn] = useState(true);
+ const [curIndex, setCurIndex] = useState(0);
+ const [imgScale, setImgScale] = useState(1);
+
+ useEffect(() => {
+ const index = imagePaths.findIndex((imagePath) => imagePath === curImg);
+ setCurIndex(index);
+ }, [curIndex]);
+
+ const nextImg = () => {
+ console.log(curIndex);
+ if (curIndex >= imagePaths.length - 2) {
+ const cur = imagePaths[curIndex + 1];
+ let num = curIndex;
+ num++;
+ setCurIndex(num);
+ setCurImg(cur);
+ setNextBtn(false);
+ } else {
+ setNextBtn(true);
+ let num = curIndex;
+ num++;
+ setCurIndex(num);
+ const cur = imagePaths[curIndex + 1];
+ setCurImg(cur);
+ }
+
+ if (curIndex >= 0) {
+ setPrevBtn(true);
+ }
+ };
+
+ const prevtImg = () => {
+ console.log(curIndex);
+ if (curIndex <= 1) {
+ let num = curIndex;
+ num--;
+ setCurIndex(num);
+ const cur = imagePaths[curIndex - 1];
+ setCurImg(cur);
+ setPrevBtn(false);
+ } else {
+ let num = curIndex;
+ num--;
+ setCurIndex(num);
+ const cur = imagePaths[curIndex - 1];
+ setCurImg(cur);
+ }
+
+ if (curIndex <= imagePaths.length - 1) {
+ setNextBtn(true);
+ }
+
+ if (curIndex === 1) {
+ setNextBtn(true);
+ }
+ };
+
+ const imgPlus = () => {
+ if (imgScale <= 1.8) {
+ let scale = imgScale;
+ scale += 0.2;
+ setImgScale(scale);
+ }
+ };
+
+ const imgMinus = () => {
+ if (imgScale >= 1.2) {
+ let scale = imgScale;
+ scale -= 0.2;
+ setImgScale(scale);
+ }
+ };
+
+ const deleteBtn = () => {
+ const startIndex = curImg.indexOf("/o/") + 3; // '/o/' 다음 인덱스
+ const endIndex = curImg.indexOf("?alt=media&token="); // '?alt=media&token=' 이전 인덱스
+
+ const storagePath = decodeURIComponent(
+ curImg.substring(startIndex, endIndex),
+ );
+
+ const imageRef = ref(storage, storagePath);
+
+ deleteObject(imageRef)
+ .then(() => {
+ console.log("이미지 삭제 성공");
+ })
+ .catch((error) => {
+ console.error("이미지 삭제 실패", error);
+ });
+ const copy = [...imagePaths];
+ const index = copy.indexOf(curImg);
+ copy.splice(index, 1);
+
+ setImagePaths(copy);
+ setViewImg(false);
+ };
+
+ useEffect(() => {
+ const handleKeyPress = (e: KeyboardEvent) => {
+ if (e.key === "ArrowRight") {
+ if (curIndex !== imagePaths.length - 1) nextImg();
+ } else if (e.key === "ArrowLeft") {
+ if (curIndex !== 0) prevtImg();
+ }
+ };
+
+ document.addEventListener("keydown", handleKeyPress);
+
+ return () => {
+ document.removeEventListener("keydown", handleKeyPress);
+ };
+ }, [curIndex]);
+
+ return (
+
+ 삭제하기
+ {
+ setViewImg(false);
+ }}
+ >
+ X
+
+
+
+
+ {prevBtn && curIndex !== 0 ? (
+
+ ) : null}
+ {nextBtn && curIndex !== imagePaths.length - 1 ? (
+
+ ) : null}
+
+
+ -
+
+
+ +
+
+
+
+ );
+}
diff --git a/src/components/gallery/CurrentImgStyle.tsx b/src/components/gallery/CurrentImgStyle.tsx
new file mode 100644
index 00000000..2e1517c7
--- /dev/null
+++ b/src/components/gallery/CurrentImgStyle.tsx
@@ -0,0 +1,141 @@
+import styled from "styled-components";
+
+export const CurrentImgBg = styled.div<{ scale: number }>`
+ z-index: 10000;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.5);
+
+ & div {
+ user-select: none;
+ }
+
+ & img {
+ height: 100%;
+ transform: scale(${({ scale }) => scale});
+ // object-fit: cover;
+ }
+`;
+// ><›‹→←
+
+export const ImgWrap = styled.div`
+ // border: 1px solid red;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 40%;
+ height: 65%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const Exit = styled.div`
+ z-index: 1000;
+ cursor: pointer;
+ position: fixed;
+ top: 8%;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: rgba(0, 0, 0, 0.8);
+ width: 30px;
+ height: 30px;
+ color: #fff;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 50%;
+
+ &:hover {
+ background-color: rgba(150, 150, 150, 0.9);
+ }
+`;
+
+export const Prev = styled.div`
+ cursor: pointer;
+ position: fixed;
+ top: 50%;
+ left: 5%;
+ transform: translateY(-50%);
+ width: 50px;
+ height: 50px;
+ background-color: rgba(0, 0, 0, 0.8);
+ border-radius: 50%;
+ color: #fff;
+
+ &::after {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ content: "←";
+ }
+
+ &:hover {
+ background-color: rgba(150, 150, 150, 0.9);
+ }
+`;
+
+export const Next = styled(Prev)`
+ left: auto;
+ right: 5%;
+ &::after {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ content: "→";
+ }
+`;
+
+export const Size = styled.div`
+ position: fixed;
+ bottom: 5%;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: rgba(0, 0, 0, 0.8);
+ // width: 130px;
+ // height: 40px;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ color: #fff;
+ font-size: 1.3rem;
+ border-radius: 3rem;
+
+ & > div {
+ cursor: pointer;
+ border-radius: 50%;
+ width: 30px;
+ height: 30px;
+ margin: 5px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ & > div:hover {
+ background-color: rgba(150, 150, 150, 0.9);
+ }
+`;
+
+export const DeleteBtn = styled.div`
+ // border: 1px solid red;
+ border-radius: 0.85rem;
+ background-color: rgba(0, 0, 0, 0.8);
+ cursor: pointer;
+ color: #fff;
+ font-weight: bold;
+ padding: 10px 20px;
+ position: fixed;
+ top: 2%;
+ right: 2%;
+
+ &:hover {
+ background-color: rgba(150, 150, 150, 0.9);
+ }
+`;
diff --git a/src/components/gallery/GalleryHeader.tsx b/src/components/gallery/GalleryHeader.tsx
new file mode 100644
index 00000000..b9c6fc4d
--- /dev/null
+++ b/src/components/gallery/GalleryHeader.tsx
@@ -0,0 +1,5 @@
+import * as style from "./GalleryHeaderStyle";
+
+export default function GalleryHeader() {
+ return GALLERY ;
+}
diff --git a/src/components/gallery/GalleryHeaderStyle.ts b/src/components/gallery/GalleryHeaderStyle.ts
new file mode 100644
index 00000000..70f4b82d
--- /dev/null
+++ b/src/components/gallery/GalleryHeaderStyle.ts
@@ -0,0 +1,11 @@
+import styled from "styled-components";
+
+export const GalleryHeader = styled.div`
+ // border: 1px solid blue;
+ margin-bottom: 1.45rem;
+ color: var(--color-dark-gray);
+ font-weight: medium;
+ font-size: 1.25rem;
+ line-height: normal;
+ text-align: left;
+`;
diff --git a/src/components/gallery/GalleryMain.tsx b/src/components/gallery/GalleryMain.tsx
new file mode 100644
index 00000000..dac1f3e7
--- /dev/null
+++ b/src/components/gallery/GalleryMain.tsx
@@ -0,0 +1,76 @@
+import * as style from "./GalleryMainStyle";
+import Button from "../common/Button";
+import { useEffect } from "react";
+
+interface GalleryMainProps {
+ album: string;
+ imagePaths: string[];
+ viewImg: boolean;
+ imgLoad: boolean;
+ setViewImg: React.Dispatch>;
+ setCurImg: React.Dispatch>;
+ setAddImg: React.Dispatch>;
+ setImgLoad: React.Dispatch>;
+}
+
+export default function GalleryMain({
+ album,
+ imagePaths,
+ imgLoad,
+ setViewImg,
+ setCurImg,
+ setAddImg,
+ setImgLoad,
+}: GalleryMainProps) {
+ useEffect(() => {
+ setImgLoad(true);
+ }, []);
+
+ const clickImgHandle = (e: React.MouseEvent) => {
+ const backgroundStyle = window
+ .getComputedStyle(e.currentTarget)
+ .getPropertyValue("background-image");
+ const curImg = backgroundStyle.match(/url\("([^"]+)"\)/);
+ if (curImg) {
+ // console.log(curImg[1]);
+ setCurImg(curImg[1]);
+ }
+ setViewImg(true);
+ };
+ return (
+ <>
+
+
+ {album}
+ {
+ console.log(album);
+ setAddImg(true);
+ }}
+ />
+
+
+ {imgLoad ? (
+
+ ) : (
+
+ {imagePaths.map((img, i) => {
+ return (
+
+
+
+ );
+ })}
+
+ )}
+
+ >
+ );
+}
diff --git a/src/components/gallery/GalleryMainStyle.ts b/src/components/gallery/GalleryMainStyle.ts
new file mode 100644
index 00000000..af34eb01
--- /dev/null
+++ b/src/components/gallery/GalleryMainStyle.ts
@@ -0,0 +1,91 @@
+import styled from "styled-components";
+
+export const GalleryMain = styled.div`
+ // border: 1px solid gold;
+ padding: 2rem;
+ border: 0.06rem solid var(--color-light-gray);
+ border-radius: 0.94rem;
+ background-color: var(--color-white);
+ width: 100%;
+ height: 44.75rem;
+ overflow: auto;
+`;
+
+export const Container = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 2rem;
+`;
+
+export const Title = styled.div`
+ color: #4a4a4a;
+ font-weight: bold;
+ font-size: 1.13rem;
+ line-height: normal;
+ text-align: left;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const ImgContainer = styled.div`
+ // border: 1px solid red;
+ display: grid;
+ // place-items: center;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 10px;
+ @media screen and (max-width: 1230px) {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ @media screen and (max-width: 912px) {
+ grid-template-columns: repeat(1, 1fr);
+ }
+`;
+
+export const ImgWrap = styled.div`
+ // border: 1px solid green;
+ height: 22rem;
+ // width: 18rem;
+ display: flex;
+ justify-content: center;
+ algin-items: center;
+`;
+
+export const Img = styled.div<{ img?: string; background?: string }>`
+ cursor: pointer;
+ border: 0.06rem solid var(--color-light-gray);
+ border-radius: 0.94rem;
+ height: 100%;
+ width: 100%;
+ background-color: ${({ img }) => img};
+ background-image: url(${({ background }) => background});
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-position: center;
+ overflow: hidden;
+
+ &:hover {
+ box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
+ }
+`;
+
+export const Loading = styled.div`
+ width: 30px;
+ height: 30px;
+ margin: 100px auto;
+ border: 4px solid var(--color-main);
+ border-top-color: transparent;
+ border-radius: 50%;
+ animation: loader 1s infinite linear;
+
+ @keyframes loader {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+`;
diff --git a/src/components/gallery/GallerySide.tsx b/src/components/gallery/GallerySide.tsx
new file mode 100644
index 00000000..4d78fae1
--- /dev/null
+++ b/src/components/gallery/GallerySide.tsx
@@ -0,0 +1,276 @@
+import { useState, useEffect, useRef } from "react";
+import {
+ getFirestore,
+ query,
+ where,
+ collection,
+ addDoc,
+ updateDoc,
+ getDocs,
+} from "firebase/firestore";
+import { app } from "@/firebase/firebase";
+import * as style from "./GallerySideStyle";
+import Button from "../common/Button";
+import Input from "../common/Input";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faChevronUp, faChevronDown } from "@fortawesome/free-solid-svg-icons";
+
+const firestore = getFirestore(app);
+
+interface Folders {
+ createdAt: Date;
+ id: string;
+ sub: string[];
+ title: string;
+}
+
+interface GallerySideProps {
+ openAddListModal: () => void;
+ galleryData: Folders[];
+ addListModal: boolean;
+ configList: boolean;
+ album: string;
+ setConfigList: React.Dispatch>;
+ setGalleryData: React.Dispatch>;
+ setAlbum: React.Dispatch>;
+ setAlbumId: React.Dispatch>;
+ setImgLoad: React.Dispatch>;
+}
+
+export default function GallerySide({
+ openAddListModal,
+ galleryData,
+ configList,
+ album,
+ setConfigList,
+ setGalleryData,
+ setAlbum,
+ setAlbumId,
+ setImgLoad,
+}: GallerySideProps) {
+ type Drop = boolean[];
+ type AlbumName = string[];
+ const [drop, setDrop] = useState([]);
+ const [albumName, setAlbumName] = useState([]);
+ const [prevAlbum, setPrevAlbum] = useState("album1");
+
+ const inputRef = useRef(null);
+
+ useEffect(() => {
+ const copy = galleryData.map(() => {
+ return true;
+ });
+ setDrop(copy);
+
+ const copy2 = galleryData.map(() => {
+ return "";
+ });
+ setAlbumName(copy2);
+ }, [galleryData]);
+
+ const dropHandle = (i: number) => {
+ const copy = [...drop];
+ copy[i] = !copy[i];
+ setDrop(copy);
+ };
+
+ const openConfigListHandle = () => {
+ const copy = [...drop];
+ drop.forEach((_, i) => {
+ copy[i] = true;
+ });
+ setDrop(copy);
+ setConfigList(true);
+ };
+
+ const closeConfigListHandle = () => {
+ setConfigList(false);
+ };
+
+ const handleKeyPress = (
+ e: React.KeyboardEvent,
+ id?: string,
+ value?: string,
+ ) => {
+ if (e.key === "Enter") {
+ const copy2 = galleryData.map(() => {
+ return "";
+ });
+ setAlbumName(copy2);
+ addAlbum(id, value);
+
+ if (inputRef.current) {
+ inputRef.current.value = "";
+ }
+ const copy = [...galleryData];
+ const find = copy.map((item) => {
+ if (item.id === id) {
+ return {
+ ...item,
+ sub: [...item.sub, value],
+ };
+ }
+ return item;
+ });
+
+ setGalleryData(find as Folders[]);
+ }
+ };
+
+ const addAlbum = (id?: string, value?: string) => {
+ console.log(id);
+ console.log(value);
+ const galleryRef = collection(firestore, "Gallery");
+ const galleryQuery = query(galleryRef, where("id", "==", id));
+
+ const fetchAndUpdateData = async () => {
+ try {
+ const querySnapshot = await getDocs(galleryQuery);
+ querySnapshot.forEach(async (doc) => {
+ const subArray: string[] = doc.data().sub || [];
+ subArray.push(value as string);
+
+ await updateDoc(doc.ref, { sub: subArray });
+ console.log("문서 업데이트 성공");
+ });
+
+ const gallerySubRef = collection(firestore, "GallerySub");
+ const newGallerySubDocData = {
+ host: id,
+ title: value,
+ };
+
+ await addDoc(gallerySubRef, newGallerySubDocData);
+ console.log("GallerySub 문서 추가 성공");
+ } catch (error) {
+ console.error("작업 실패:", error);
+ }
+ };
+
+ fetchAndUpdateData();
+ };
+
+ const fetchData = async (title: string) => {
+ try {
+ const q = query(
+ collection(firestore, "GallerySub"),
+ where("title", "==", title),
+ );
+
+ const querySnapshot = await getDocs(q);
+
+ querySnapshot.forEach((doc) => {
+ setAlbumId(doc.id);
+ });
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ }
+ };
+
+ const albumClickHandle = async (title: string) => {
+ try {
+ setPrevAlbum(title);
+
+ if (title === prevAlbum || title === album) {
+ setImgLoad(false);
+ }
+
+ await fetchData(title);
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ }
+ };
+
+ return (
+ <>
+
+
+ {galleryData.map((data, index) => {
+ return (
+
+ {
+ dropHandle(index);
+ }}
+ >
+ {data.title}
+
+ {configList ? (
+ 🔧
+ ) : drop[index] ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+
+ {data.sub?.map((v, i) => {
+ return drop[index] ? (
+ {
+ setImgLoad(true);
+ setAlbum(v);
+ albumClickHandle(v);
+ }}
+ >
+
+ {v}
+
+ ) : null;
+ })}
+
+ {configList ? (
+
+
+ {
+ const copy = [...albumName];
+ copy[index] = e.target.value;
+ setAlbumName(copy);
+ }}
+ onKeyPress={(e) => {
+ handleKeyPress(e, data.id, albumName[index]);
+ }}
+ // forwardedRef={inputRef}
+ value={albumName[index]}
+ width="10rem"
+ />
+
+ ) : null}
+
+ );
+ })}
+ {configList ? (
+ +
+ ) : null}
+
+
+ {configList ? (
+
+ ) : (
+
+ )}
+
+
+ >
+ );
+}
diff --git a/src/components/gallery/GallerySideStyle.ts b/src/components/gallery/GallerySideStyle.ts
new file mode 100644
index 00000000..ec583737
--- /dev/null
+++ b/src/components/gallery/GallerySideStyle.ts
@@ -0,0 +1,110 @@
+import styled from "styled-components";
+
+export const GallerySide = styled.div`
+ border: 1px solid green;
+ padding-top: 1.88rem;
+ margin-right: 1.88rem;
+ border: 0.06rem solid var(--color-light-gray);
+ border-radius: 0.94rem;
+ background-color: var(--color-white);
+ min-width: 15rem;
+ height: 44.75rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+
+ & > #add-sub {
+ border: 1px solid red;
+ }
+`;
+
+export const AddList = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ padding: 0.4rem 1rem;
+ color: #4a4a4a;
+ font-weight: medium;
+ font-size: 1rem;
+ line-height: normal;
+ text-align: left;
+ &:hover,
+ &.active {
+ // font-weight: bold;
+ }
+ margin-top: 1rem;
+ background: #0016500c;
+`;
+
+export const ListWrap = styled.ul`
+ display: flex;
+ flex-direction: column;
+ user-select: none;
+`;
+
+export const List = styled.li`
+ display: flex;
+ // justify-content: space-between;
+ height: 3rem;
+ align-items: center;
+ position: relative;
+ cursor: pointer;
+ padding: 8px 0;
+ color: var(--color-gray);
+ font-weight: 500;
+ font-size: 1rem;
+ line-height: normal;
+ text-align: left;
+ padding-left: 2.63rem;
+ user-select: none;
+
+ &:hover {
+ background: #0016500c;
+ }
+
+ &.active {
+ background: #0016500c;
+ }
+
+ &.bold {
+ justify-content: space-between;
+ font-weight: 500;
+ padding-left: 1.88rem;
+ }
+
+ &.add-list {
+ background: #0016500c;
+ font-weight: 500;
+ }
+`;
+
+export const icon = styled.div`
+ width: 4.5px;
+ height: 4px;
+ border-left: 1px solid var(--color-light-gray);
+ border-bottom: 1px solid var(--color-light-gray);
+ margin-right: 0.59rem;
+`;
+
+export const Arrow = styled.span`
+ // height: 100%;
+`;
+
+export const ButtonWrap = styled.div`
+ margin-bottom: 1.88rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
+
+export const ArrowIcon = styled.div`
+ cursor: pointer;
+ font-size: 1rem;
+ color: #b4b4b4;
+ margin-right: 1rem;
+ margin-left: 1rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
diff --git a/src/components/home/Carousel.tsx b/src/components/home/Carousel.tsx
new file mode 100644
index 00000000..2a341b88
--- /dev/null
+++ b/src/components/home/Carousel.tsx
@@ -0,0 +1,98 @@
+import * as style from "./CarouselStyle";
+import { useState, useEffect, useRef, useCallback } from "react";
+import carouselData from "../../db/wiki/CarouselData";
+
+const Carousel = () => {
+ const vw = window.innerWidth;
+ const initialCarouselWidth = (vw * 62) / 100;
+
+ const [currentindex, setCurrentindex] = useState(0);
+ const [carouselwidth, setCarouselwidth] =
+ useState(initialCarouselWidth);
+
+ const docRef = useRef(null);
+ const carouselRef = useRef(null);
+
+ window.addEventListener("resize", () => {
+ const vw = window.innerWidth;
+ const vw62 = (vw * 62) / 100;
+ const parentWidth = carouselRef.current ? vw62 : 938;
+ setCarouselwidth(parentWidth);
+ });
+
+ const goToNext = useCallback(() => {
+ const isLastSlide = currentindex === carouselData.length - 1;
+ const newIndex = isLastSlide ? 0 : currentindex + 1;
+ setCurrentindex(newIndex);
+ }, [currentindex]);
+
+ useEffect(() => {
+ if (docRef.current !== null) {
+ clearTimeout(docRef.current);
+ }
+ docRef.current = window.setTimeout(() => {
+ goToNext();
+ }, 3000);
+
+ return () => {
+ if (docRef.current !== null) {
+ clearTimeout(docRef.current);
+ }
+ };
+ }, [goToNext]);
+
+ const goToCarousel = (pageindex: number) => {
+ setCurrentindex(pageindex);
+ };
+
+ return (
+ <>
+
+
+
+
+
+ {carouselData[currentindex].title}
+
+
+ {carouselData[currentindex].text}
+
+
+
+ {carouselData.map((data, pageindex) => {
+ return (
+
+
+ 자세히 보기
+
+
+ );
+ })}
+
+
+
+ {carouselData.map((data, pageindex) => (
+ goToCarousel(pageindex)}
+ />
+ ))}
+
+
+
+ >
+ );
+};
+
+export default Carousel;
+
diff --git a/src/components/home/CarouselStyle.ts b/src/components/home/CarouselStyle.ts
new file mode 100644
index 00000000..939946e5
--- /dev/null
+++ b/src/components/home/CarouselStyle.ts
@@ -0,0 +1,124 @@
+import styled from "styled-components";
+import carouselData from "../../db/wiki/CarouselData";
+
+export const CarouselWrapper = styled.div`
+ width: 100%;
+ display: inline-block;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ border-radius: 10px;
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
+
+ @media (min-height: 920px) {
+ height: 90vh;
+ }
+`;
+
+export const CarouselContainer = styled.div<{
+ $currentIndex: number;
+ $carouselWidth: number;
+}>`
+ height: 100%;
+ width: ${({ $carouselWidth }) => `${$carouselWidth * 5}px`};
+ display: flex;
+ overflow: hidden;
+ transform: ${({ $currentIndex, $carouselWidth }) =>
+ `translateX(${-$currentIndex * $carouselWidth}px)`};
+ transition: 0.5s ease-in-out;
+ border-radius: 5px;
+`;
+
+export const CarouselTitle = styled.a`
+ position: absolute;
+ display: inline-block;
+ top: 25%;
+ left: 3rem;
+ z-index: 2;
+ font-size: 1.8rem;
+ font-weight: 500;
+ color: var(--color-main);
+`;
+
+export const CarouselText = styled.a`
+ position: absolute;
+ display: inline-block;
+ width: 35%;
+ top: 35%;
+ left: 3rem;
+ z-index: 2;
+ font-size: 1rem;
+ color: var(--color-black);
+`;
+
+export const CarouselContent = styled.div<{
+ $pageIndex: number;
+ $carouselWidth: number;
+}>`
+ background-image: ${({ $pageIndex }) =>
+ `url(${carouselData[$pageIndex].url})`};
+ height: 100%;
+ width: ${({ $carouselWidth }) => `${$carouselWidth}px`};
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ border-radius: 10px;
+ position: relative;
+`;
+
+export const CarouselLeftBackDrop = styled.div`
+ width: 40%;
+ height: 27%;
+ background-color: rgba(255, 255, 255, 0.3);
+ left: 0.5rem;
+ top: 20%;
+ position: absolute;
+ z-index: 2;
+ border-radius: 20px;
+ border-top-left-radius: 10px;
+ border-bottom-left-radius: 10px;
+`;
+
+export const CarouselDotContainer = styled.div`
+ display: flex;
+ justify-self: center;
+ align-items: center;
+ text-align: center;
+ position: absolute;
+ bottom: 1.5rem;
+ gap: 0.6rem;
+ left: 50%;
+ transform: translate(-50%, 0);
+ z-index: 4;
+`;
+
+export const CarouselDot = styled.div`
+ width: 1.7rem;
+ height: 0.6rem;
+ border-radius: 5px;
+ transition: 0.3s;
+ background-color: var(--color-main);
+ cursor: pointer;
+ &:hover {
+ transform: scaleX(1.5);
+ margin: 0 0.5rem;
+ border-radius: 4px;
+ }
+`;
+
+export const CarouselPageButton = styled.a`
+ display: inline-block;
+ width: 8rem;
+ height: 2.6rem;
+ position: absolute;
+ top: 52%;
+ left: 3rem;
+ z-index: 5;
+ text-align: center;
+ vertical-align: center;
+ padding: 0.5rem;
+ border-radius: 5px;
+ color: var(--color-white);
+ cursor: pointer;
+ background-color: var(--color-main);
+`;
diff --git a/src/components/home/GalleryPreview.tsx b/src/components/home/GalleryPreview.tsx
new file mode 100644
index 00000000..071854c4
--- /dev/null
+++ b/src/components/home/GalleryPreview.tsx
@@ -0,0 +1,171 @@
+import { useState, useEffect, useRef, useCallback } from "react";
+import { useNavigate } from "react-router-dom";
+import styled from "styled-components";
+import { app } from "@/firebase/firebase";
+import {
+ getStorage,
+ ref,
+ listAll,
+ getMetadata,
+ getDownloadURL,
+} from "firebase/storage";
+
+interface GalleryPreviewStyle {
+ imagePaths: string[];
+ currentindex: number;
+}
+
+export default function GalleryPreview() {
+ const navigate = useNavigate();
+
+ const goToGallery = () => {
+ navigate("/gallery");
+ };
+
+ interface ImageInfo {
+ url: string;
+ metadata: {
+ customMetadata?: {
+ timestamp?: string;
+ };
+ };
+ }
+
+ const [imagepaths, setImagepaths] = useState();
+ const [currentindex, setCurrentindex] = useState(0);
+
+ useEffect(() => {
+ const fetchImages = async () => {
+ try {
+ const storage = getStorage(app);
+ const imagesRef = ref(storage, `Gallery/0jL7NLzNrPzOuqeuJSk2`);
+ const imageList = await listAll(imagesRef);
+
+ const paths = imageList.items.map(async (item) => {
+ const url = await getDownloadURL(item);
+ const metadata = await getMetadata(item);
+
+ return { url, metadata };
+ });
+
+ const imageInfoList: ImageInfo[] = await Promise.all(paths);
+ const sortedImages = imageInfoList.sort((a, b) => {
+ const timestampA = a.metadata.customMetadata?.timestamp || "";
+ const timestampB = b.metadata.customMetadata?.timestamp || "";
+ if (timestampA && timestampB) {
+ return (
+ new Date(timestampB).getTime() - new Date(timestampA).getTime()
+ );
+ } else {
+ return 0;
+ }
+ });
+
+ const urls = sortedImages.map((item) => item.url).slice(0, 3);
+ setImagepaths(urls);
+ } catch (error) {
+ console.error("이미지 목록을 가져오는 중 오류 발생:", error);
+ }
+ };
+
+ fetchImages();
+ }, []);
+
+ const galleryImagesRef = useRef(null);
+
+ const goToNext = useCallback(() => {
+ const isLastSlide = currentindex === imagepaths!.length - 1;
+ const newIndex = isLastSlide ? 0 : currentindex + 1;
+ setCurrentindex(newIndex);
+ }, [currentindex, imagepaths]);
+
+ useEffect(() => {
+ if (galleryImagesRef.current !== null) {
+ clearTimeout(galleryImagesRef.current);
+ }
+ galleryImagesRef.current = window.setTimeout(() => {
+ goToNext();
+ }, 3000);
+
+ return () => {
+ if (galleryImagesRef.current !== null) {
+ clearTimeout(galleryImagesRef.current);
+ }
+ };
+ }, [goToNext]);
+
+ return (
+ <>
+ {imagepaths ? (
+ <>
+
+
+
+ >
+ ) : (
+
+ )}
+ >
+ );
+}
+
+const GalleryPreviewSkeleton = styled.div`
+ &.skeleton {
+ position: relative;
+ width: 100%;
+ height: 15rem;
+ overflow: hidden;
+ }
+ &::after {
+ content: "";
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border-radius: 15px;
+ color: rgba(0, 0, 0, 0);
+ background-image: linear-gradient(
+ 100deg,
+ rgba(0, 0, 0, 0.1),
+ rgba(0, 0, 0, 0.1),
+ rgba(0, 0, 0, 0),
+ rgba(0, 0, 0, 0.1),
+ rgba(0, 0, 0, 0.1)
+ );
+ background-size: 400% 100%;
+ animation: skeleton-loading 7s linear infinite;
+
+ @keyframes skeleton-loading {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+ }
+ }
+`;
+
+const GalleryPreviewStyle = styled.div<{
+ $imagePaths: string[];
+ $currentIndex: number;
+}>`
+ background-image: ${({ $imagePaths, $currentIndex }) =>
+ `url(${$imagePaths[$currentIndex]})`};
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ border-radius: 10px;
+ cursor: pointer;
+ overflow: hidden;
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
+
+ @media (min-height: 920px) {
+ height: 30vh;
+ }
+`;
diff --git a/src/components/home/WikiPreview.tsx b/src/components/home/WikiPreview.tsx
new file mode 100644
index 00000000..6b03437a
--- /dev/null
+++ b/src/components/home/WikiPreview.tsx
@@ -0,0 +1,36 @@
+import { useEffect, useState } from "react";
+import { Wiki } from "../wiki/types/WikiCommonType";
+import * as style from "./wikiPreviewtyle";
+import { doc, getDoc } from "firebase/firestore";
+import { db } from "@/firebase/firebase";
+
+interface Props {
+ wikiData: Wiki;
+}
+
+export default function WikiPreview({ wikiData }: Props) {
+ const { parentID, wikiID, title, content } = wikiData;
+ const [parentTitle, setParentTitle] = useState("");
+ useEffect(() => {
+ const getParentTitle = async () => {
+ if (parentID) {
+ const docRef = doc(db, "Wiki", parentID);
+ const docSnap = await getDoc(docRef);
+ if (docSnap.exists()) {
+ setParentTitle(docSnap.data().title);
+ }
+ } else {
+ setParentTitle("전체");
+ }
+ };
+ getParentTitle();
+ }, []);
+
+ return (
+
+ {parentTitle}
+ {title}
+ {content}
+
+ );
+}
diff --git a/src/components/home/wikiPreviewtyle.ts b/src/components/home/wikiPreviewtyle.ts
new file mode 100644
index 00000000..df030d9c
--- /dev/null
+++ b/src/components/home/wikiPreviewtyle.ts
@@ -0,0 +1,47 @@
+import { Link } from "react-router-dom";
+import styled from "styled-components";
+
+export const Container = styled(Link)`
+ width: 100%;
+
+ border-radius: 15px;
+ background: var(--color-white);
+ border: 1px solid var(--color-light-gray);
+
+ padding: 1.875rem 2.125rem 1.875rem 2.125rem;
+
+ display: flex;
+ flex-direction: column;
+
+ &:hover {
+ border: 1px solid var(--color-main);
+ box-shadow: 0px 4px 4px 0px #00000026;
+ }
+
+ @media (min-height: 920px) {
+ height: 25vh;
+ }
+`;
+
+export const WikiCategory = styled.span`
+ color: var(--color-gray);
+ font-weight: 500;
+ font-size: 0.875rem;
+ line-height: normal;
+ text-align: left;
+
+ margin-bottom: 0.375rem;
+`;
+
+export const WikiTitle = styled(WikiCategory)`
+ font-weight: 700;
+ font-size: 1.125rem;
+`;
+
+export const WikiDescription = styled(WikiCategory)`
+ text-overflow: ellipsis;
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+`;
diff --git a/src/components/login/SignIn.tsx b/src/components/login/SignIn.tsx
new file mode 100644
index 00000000..cbecab3f
--- /dev/null
+++ b/src/components/login/SignIn.tsx
@@ -0,0 +1,99 @@
+import React, { useState, useCallback } from "react";
+import { useNavigate } from "react-router-dom";
+import { signInWithEmailAndPassword } from "@firebase/auth";
+import { auth } from "@/firebase/firebase";
+import Modal from "./SignUp";
+import * as style from "./signinStyle";
+
+export default function SignIn() {
+ const navigate = useNavigate();
+
+ /** 모달 위한 선언 */
+
+ const [isOpenModal, setOpenModal] = useState(false);
+
+ const onClickToggleModal = useCallback(() => {
+ setOpenModal(!isOpenModal);
+ }, [isOpenModal]);
+
+ /** 로그인 위한 선언 */
+ const [email, setEmail] = useState("");
+ const [pwd, setPwd] = useState("");
+
+ const handleEmail = (e: React.ChangeEvent) => {
+ e.preventDefault();
+ setEmail(e.target.value);
+ };
+
+ const handlePwd = (e: React.ChangeEvent) => {
+ e.preventDefault();
+ setPwd(e.target.value);
+ };
+
+ const handleClickCreate = (e: React.MouseEvent) => {
+ e.preventDefault();
+ signInWithEmailAndPassword(auth, email, pwd)
+ .then(() => {
+ navigate("/");
+ })
+ .catch((e) => {
+ if (e.code == "auth/invalid-email") {
+ alert("아이디는 이메일 형식으로 입력해주세요.");
+ }
+ if (e.code == "auth/user-not-found") {
+ alert("등록되지 않은 아이디입니다.");
+ }
+ if (e.code == "auth/wrong-password") {
+ alert("비밀번호를 다시 확인해주세요.");
+ }
+ if (e.code == "auth/too-many-requests") {
+ alert(
+ "비밀번호 오류 횟수를 초과하였습니다. 잠시 후 다시 시도해주세요. ",
+ );
+ }
+ });
+ };
+
+ return (
+ <>
+ {isOpenModal && }
+
+ 로그인
+
+
+
+ ID (email)
+
+
+
+
+ PW
+
+
+
+
+
+
+ {" "}
+ 들어가기
+
+
+ 회원가입
+
+
+
+ >
+ );
+}
diff --git a/src/components/login/SignUp.tsx b/src/components/login/SignUp.tsx
new file mode 100644
index 00000000..ff4795e7
--- /dev/null
+++ b/src/components/login/SignUp.tsx
@@ -0,0 +1,136 @@
+import React, { PropsWithChildren, useState } from "react";
+import { createUserWithEmailAndPassword } from "@firebase/auth";
+import { auth } from "@/firebase/firebase";
+
+import * as style from "./signupStyle";
+
+interface ModalDefaultType {
+ onClickToggleModal: () => void;
+}
+
+function Modal({
+ onClickToggleModal,
+ children,
+}: PropsWithChildren) {
+ /** 회원가입 위한 선언 */
+ const [email, setEmail] = useState("");
+ const [pwd, setPwd] = useState("");
+
+ const handleEmail = (e: React.ChangeEvent) => {
+ e.preventDefault();
+ setEmail(e.target.value);
+ };
+
+ const handlePwd = (e: React.ChangeEvent) => {
+ e.preventDefault();
+ setPwd(e.target.value);
+ };
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ };
+
+ const handleClickCreate = (e: React.MouseEvent) => {
+ e.preventDefault();
+ createUserWithEmailAndPassword(auth, email, pwd)
+ .then(() => {
+ alert("회원가입에 성공하였습니다. 로그인 페이지로 이동합니다.");
+ if (onClickToggleModal) {
+ onClickToggleModal();
+ }
+ })
+ .catch((e) => {
+ if (e.code == "auth/email-already-in-use") {
+ alert("이미 사용 중인 이메일입니다.");
+ }
+ if (e.code == "auth/weak-password") {
+ alert("비밀번호는 6글자 이상이어야 합니다.");
+ }
+ if (e.code == "auth/network-request-failed") {
+ alert("네트워크 연결에 실패 하였습니다. 잠시 후 다시 시도해주세요.");
+ }
+ if (e.code == "auth/invalid-email") {
+ alert("잘못된 이메일 형식입니다.");
+ }
+ });
+ };
+
+ return (
+
+
+ {children}
+
+ 회원가입
+
+
+ 반갑습니다! 🙋♀️
+ 9굴 직원 여러분 안녕하세요. {"\n"}
+ 원활한 업무를 위하여 WIKI페이지를 신설하였사오니, {"\n"}
+ 많은 활동 부탁드립니다.{"\n"}
+ {"\n"}
+ 이용을 위해선 회원가입이 필수이므로,{"\n"}
+ 아래의 규칙을 참고하셔서 가입 후 접속해주세요.{"\n"}
+ {"\n"}
+ 📌 ID(아이디)는 이메일 형태로 입력해야 합니다.{"\n"}
+ 📌 PW(비밀번호)는 6자 이상 입력해야 합니다.{"\n"}
+ {"\n"}
+ 비밀번호 찾기 기능은 현재 개발중입니다.{"\n"}
+ 비밀번호 재발급을 원하신다면 아래로 연락주세요.{"\n"}
+ 💌 ewinkite@gmail.com {"\n"}
+
+
+
+ ID (email)
+
+
+
+
+ PW
+
+
+
+
+ {" "}
+ 가입하기
+
+ {
+ e.preventDefault();
+
+ if (onClickToggleModal) {
+ onClickToggleModal();
+ }
+ }}
+ >
+ 돌아가기 🥺
+
+
+
+
+
+
+ {
+ e.preventDefault();
+
+ if (onClickToggleModal) {
+ onClickToggleModal();
+ }
+ }}
+ />
+
+ );
+}
+
+export default Modal;
diff --git a/src/components/login/signinStyle.ts b/src/components/login/signinStyle.ts
new file mode 100644
index 00000000..a65a60f6
--- /dev/null
+++ b/src/components/login/signinStyle.ts
@@ -0,0 +1,70 @@
+import styled from "styled-components";
+
+export const LoginBox = styled.div`
+ margin: 5rem 3.38rem 5rem 3.38rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1.8rem;
+`;
+
+export const Title = styled.h3`
+ font-size: 1.13rem;
+ line-height: normal;
+ letter-spacing: -0.1rem;
+`;
+
+export const Form = styled.form`
+ display: flex;
+ flex-direction: column;
+`;
+
+export const InputWrap = styled.div`
+ color: var(--color-gray);
+ font-weight: medium;
+ font-size: 0.88rem;
+ line-height: normal;
+ margin-bottom: 0.69rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.69rem;
+`;
+
+export const Input = styled.input`
+ border-radius: 0.25rem;
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-light-gray);
+ width: 15.88rem;
+ height: 2.5rem;
+ gap: 1.81rem;
+`;
+
+export const ButtonWrap = styled.div``;
+
+export const HighlightButton = styled.button`
+ border-radius: 0.25rem;
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-main);
+ width: 15.88rem;
+ height: 2.5rem;
+ color: var(--color-main);
+
+ &:hover {
+ cursor: pointer;
+ box-shadow: 0 0 5px rgba(30, 30, 30, 0.1);
+ }
+`;
+
+export const NormalButton = styled.button`
+ border-radius: 0.25rem;
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-medium-gray);
+ width: 15.88rem;
+ height: 2.5rem;
+ color: var(--color-dark-gray);
+ margin-top: 0.31rem;
+
+ &:hover {
+ cursor: pointer;
+ box-shadow: 0 0 5px rgba(30, 30, 30, 0.1);
+ }
+`;
diff --git a/src/components/login/signupStyle.ts b/src/components/login/signupStyle.ts
new file mode 100644
index 00000000..e0bda701
--- /dev/null
+++ b/src/components/login/signupStyle.ts
@@ -0,0 +1,152 @@
+import styled from "styled-components";
+
+export const ModalContainer = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+`;
+
+export const DialogBox = styled.dialog`
+ width: 51.88rem;
+ height: 31.25rem;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ border: none;
+ border-radius: 0.94rem;
+ box-sizing: border-box;
+ background-color: var(--color-white);
+ z-index: 10000;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+
+ animation: modaldown 0.5s linear;
+
+ @keyframes modaldown {
+ from {
+ transform: translate(-50%, -60%);
+ }
+ to {
+ transform: translate(-50%, -50%);
+ }
+ }
+
+ .close {
+ position: absolute;
+ right: 15px;
+ top: 5px;
+ cursor: pointer;
+ font-size: 25px;
+ }
+`;
+
+export const ModalTitle = styled.div`
+ font-size: 1.13rem;
+ font-weight: 500;
+ margin: 2rem 0 0 0;
+ letter-spacing: -0.1rem;
+`;
+
+export const Backdrop = styled.div`
+ width: 100vw;
+ height: 100vh;
+ position: fixed;
+ top: 0;
+ z-index: 9999;
+ background-color: rgba(0, 0, 0, 0.4);
+`;
+
+export const JoinBox = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1.81rem;
+`;
+
+export const Content = styled.div`
+ display: flex;
+ justify-content: center;
+ padding: 1.1rem 3.38rem 3.19rem 3.13rem;
+ gap: 7.06rem;
+`;
+
+export const Info = styled.div`
+ white-space: pre-line;
+ font-size: 0.88rem;
+ border-radius: 0.94rem;
+ background: #fcfcfc;
+ border: 0.06rem solid var(--color-light-gray);
+ padding: 0.88rem 2.06rem 1rem 1rem;
+`;
+
+export const InfoTitle = styled.div`
+ display: flex;
+ flex-direction: column;
+ font-size: 1.5rem;
+ margin-bottom: 0.5rem;
+`;
+
+export const Form = styled.form`
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+`;
+
+export const InputWrap = styled.div`
+ color: var(--color-gray);
+ font-weight: medium;
+ font-size: 0.88rem;
+ line-height: normal;
+ margin-bottom: 0.69rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.69rem;
+`;
+
+export const Input = styled.input`
+ border-radius: 0.25rem;
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-light-gray);
+ width: 15.88rem;
+ height: 2.5rem;
+ gap: 1.81rem;
+`;
+
+export const ButtonWrap = styled.div``;
+
+export const HighlightButton = styled.button`
+ margin-top: 1.81rem;
+ border-radius: 0.25rem;
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-main);
+ width: 15.88rem;
+ height: 2.5rem;
+ color: var(--color-main);
+
+ &:hover {
+ cursor: pointer;
+ box-shadow: 0 0 5px rgba(30, 30, 30, 0.1);
+ }
+`;
+
+export const NormalButton = styled.button`
+ border-radius: 0.25rem;
+ background: var(--color-white);
+ border: 0.06rem solid var(--color-medium-gray);
+ width: 15.88rem;
+ height: 2.5rem;
+ color: var(--color-dark-gray);
+ margin-top: 0.31rem;
+
+ &:hover {
+ cursor: pointer;
+ box-shadow: 0 0 5px rgba(30, 30, 30, 0.1);
+ }
+`;
diff --git a/src/components/wiki/buttons/WikiButton.tsx b/src/components/wiki/buttons/WikiButton.tsx
new file mode 100644
index 00000000..c3a257e8
--- /dev/null
+++ b/src/components/wiki/buttons/WikiButton.tsx
@@ -0,0 +1,30 @@
+import * as Styled from "./WikiButtonStyle";
+
+interface Props {
+ text: string;
+ margin?: string;
+ padding: string;
+ isDisabled?: boolean;
+ onClick?: () => void;
+}
+
+function WikiButton({
+ text,
+ padding,
+ margin,
+ isDisabled = false,
+ onClick,
+}: Props) {
+ return (
+
+ {text}
+
+ );
+}
+
+export default WikiButton;
diff --git a/src/components/wiki/buttons/WikiButtonStyle.ts b/src/components/wiki/buttons/WikiButtonStyle.ts
new file mode 100644
index 00000000..61326453
--- /dev/null
+++ b/src/components/wiki/buttons/WikiButtonStyle.ts
@@ -0,0 +1,31 @@
+import styled from "styled-components";
+
+export const WikiButton = styled.button<{
+ $padding: string;
+ $margin?: string;
+}>`
+ border: 0.0625rem solid var(--color-medium-gray);
+ border-radius: 0.25rem;
+
+ color: var(--color-dark-gray);
+ background: var(--color-white);
+
+ margin: ${({ $margin }) => $margin};
+ padding: ${({ $padding }) => $padding};
+
+ cursor: pointer;
+ font-size: 0.88rem;
+ line-height: normal;
+ text-align: center;
+
+ &:hover {
+ background-color: var(--color-main);
+ color: var(--color-white);
+ }
+
+ &:disabled {
+ background-color: var(--color-light-gray);
+ border: 0.0625rem solid var(--color-medium-gray);
+ color: rgba(34, 34, 34, 0.7);
+ }
+`;
diff --git a/src/components/wiki/category/ChildWikiItem.tsx b/src/components/wiki/category/ChildWikiItem.tsx
new file mode 100644
index 00000000..2313c46c
--- /dev/null
+++ b/src/components/wiki/category/ChildWikiItem.tsx
@@ -0,0 +1,18 @@
+import { Wiki } from "@/components/wiki/types/WikiCommonType";
+import * as Styled from "./WikiCategoryListStyle";
+
+interface ChildWikiItemProps {
+ wiki: Wiki;
+ selectedWikiId: string | null;
+}
+
+const ChildWikiItem = ({ wiki, selectedWikiId }: ChildWikiItemProps) => (
+ <>
+
+
+ {wiki.title}
+
+ >
+);
+
+export default ChildWikiItem;
diff --git a/src/components/wiki/category/ParentWikiItem.tsx b/src/components/wiki/category/ParentWikiItem.tsx
new file mode 100644
index 00000000..33679b3e
--- /dev/null
+++ b/src/components/wiki/category/ParentWikiItem.tsx
@@ -0,0 +1,37 @@
+import { HasChildMap, Wiki } from "@/components/wiki/types/WikiCommonType";
+import * as Styled from "./WikiCategoryListStyle";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faChevronUp, faChevronDown } from "@fortawesome/free-solid-svg-icons";
+
+interface ParentWikiItemProps {
+ wiki: Wiki;
+ selectedWikiId: string | null;
+ hasChildMap: HasChildMap;
+ onArrowClick: (wiki: Wiki) => void;
+ isUnfolded: (wikiId: string) => boolean;
+}
+
+const ParentWikiItem = ({
+ wiki,
+ selectedWikiId,
+ hasChildMap,
+ onArrowClick,
+ isUnfolded,
+}: ParentWikiItemProps) => (
+
+
+ {wiki.title}
+
+ {hasChildMap[wiki.wikiID] && (
+ onArrowClick(wiki)}>
+ {isUnfolded(wiki.wikiID) ? (
+
+ ) : (
+
+ )}
+
+ )}
+
+);
+
+export default ParentWikiItem;
diff --git a/src/components/wiki/category/WikiCategoryList.tsx b/src/components/wiki/category/WikiCategoryList.tsx
new file mode 100644
index 00000000..c8c4b7a5
--- /dev/null
+++ b/src/components/wiki/category/WikiCategoryList.tsx
@@ -0,0 +1,60 @@
+import * as Styled from "./WikiCategoryListStyle";
+import { useState } from "react";
+import {
+ Wiki,
+ WikiCategoryProps,
+} from "@/components/wiki/types/WikiCommonType";
+import WikiCategoryListItem from "./WikiCategoryListItem";
+
+const WikiCategoryList = ({
+ WiKiList,
+ hasChildMap,
+ onEntryClick,
+ onArrowClick,
+ isVisible,
+}: WikiCategoryProps) => {
+ const firstParentWikiId =
+ WiKiList.find((wiki) => !wiki.parentID)?.wikiID || null;
+
+ const [selectedWikiId, setSelectedWikiId] = useState(
+ firstParentWikiId,
+ );
+
+ const [unfoldedWikiIds, setUnfoldedWikiIds] = useState([]);
+
+ const handleArrowClick = (wiki: Wiki) => {
+ if (unfoldedWikiIds.includes(wiki.wikiID)) {
+ setUnfoldedWikiIds((prev) => prev.filter((id) => id !== wiki.wikiID));
+ } else {
+ setUnfoldedWikiIds((prev) => [...prev, wiki.wikiID]);
+ }
+ onArrowClick(wiki);
+ };
+
+ const handleEntryClickInternal = (wiki: Wiki) => {
+ setSelectedWikiId(wiki.wikiID);
+ onEntryClick(wiki);
+ };
+
+ const isUnfolded = (wikiId: string) => unfoldedWikiIds.includes(wikiId);
+
+ return (
+
+
+ {WiKiList.map((wiki) => (
+
+ ))}
+
+
+ );
+};
+
+export default WikiCategoryList;
diff --git a/src/components/wiki/category/WikiCategoryListItem.tsx b/src/components/wiki/category/WikiCategoryListItem.tsx
new file mode 100644
index 00000000..0f355709
--- /dev/null
+++ b/src/components/wiki/category/WikiCategoryListItem.tsx
@@ -0,0 +1,29 @@
+import { HasChildMap, Wiki } from "@/components/wiki/types/WikiCommonType";
+import * as Styled from "./WikiCategoryListStyle";
+import ParentWikiItem from "./ParentWikiItem";
+import ChildWikiItem from "./ChildWikiItem";
+
+interface WikiCategoryListItemProps {
+ wiki: Wiki;
+ selectedWikiId: string | null;
+ hasChildMap: HasChildMap;
+ onArrowClick: (wiki: Wiki) => void;
+ onEntryClick: (wiki: Wiki) => void;
+ isUnfolded: (wikiId: string) => boolean;
+}
+
+const WikiCategoryListItem = (props: WikiCategoryListItemProps) => {
+ const { wiki, onEntryClick } = props;
+
+ return (
+ onEntryClick(wiki)}>
+ {wiki.parentID === "" ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default WikiCategoryListItem;
diff --git a/src/components/wiki/category/WikiCategoryListStyle.ts b/src/components/wiki/category/WikiCategoryListStyle.ts
new file mode 100644
index 00000000..054e6043
--- /dev/null
+++ b/src/components/wiki/category/WikiCategoryListStyle.ts
@@ -0,0 +1,75 @@
+import styled from "styled-components";
+
+interface isSelectedWiki {
+ selected: boolean;
+}
+
+export const Wrapper = styled.div<{ $isVisible: boolean }>`
+ display: ${(props) => (props.$isVisible ? "block" : "none")};
+ padding-top: 1.88rem;
+ margin-right: 1.88rem;
+ background-color: var(--color-white);
+ width: 15rem;
+ height: 44.75rem;
+ border: 1px solid var(--color-light-gray);
+ border-radius: 0.94rem;
+ overflow-x: hidden;
+`;
+
+export const WikiList = styled.ul`
+ font-size: 1rem;
+ color: var(--color-gray);
+ cursor: pointer;
+`;
+
+export const WikiItem = styled.li`
+ display: flex;
+ align-items: center;
+ padding: 0.5rem 1.88rem;
+ padding-right: 0;
+ overflow: hidden;
+ height: 3rem;
+
+ &:hover {
+ background-color: rgba(0, 22, 80, 0.05);
+ }
+`;
+
+export const ParentWikiWrapper = styled.div`
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+`;
+
+export const ChildWikiWrapper = styled.div``;
+
+export const WikiTitle = styled.span`
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ color: ${(props) =>
+ props.selected ? "var(--color-main)" : "var(--color-gray)"};
+ font-weight: ${(props) => (props.selected ? 600 : 500)};
+`;
+
+export const ChildWikiTitle = styled(WikiTitle)`
+ && {
+ padding-right: 2.5rem;
+ }
+`;
+
+export const DepthSymbol = styled.div`
+ width: 4.5px;
+ height: 4px;
+ border-left: 1px solid var(--color-light-gray);
+ border-bottom: 1px solid var(--color-light-gray);
+ margin-right: 0.59rem;
+`;
+
+export const ArrowIcon = styled.div`
+ cursor: pointer;
+ font-size: 1rem;
+ color: #b4b4b4;
+ margin-right: 1rem;
+ margin-left: 1rem;
+`;
diff --git a/src/components/wiki/content/RenderNoWiki.tsx b/src/components/wiki/content/RenderNoWiki.tsx
new file mode 100644
index 00000000..a64eab0c
--- /dev/null
+++ b/src/components/wiki/content/RenderNoWiki.tsx
@@ -0,0 +1,3 @@
+export default function RenderNoWiki() {
+ return 등록된 위키가 없습니다.
;
+}
diff --git a/src/components/wiki/content/RenderWikiContent.tsx b/src/components/wiki/content/RenderWikiContent.tsx
new file mode 100644
index 00000000..50824da0
--- /dev/null
+++ b/src/components/wiki/content/RenderWikiContent.tsx
@@ -0,0 +1,87 @@
+import * as Styled from "./WikiContentStyle";
+import WikiEditButton from "../buttons/WikiButton";
+import { RenderWikiContentProps } from "../types/WikiCommonType";
+
+import formatDateToCustomFormat from "@/utils/formatDateToCustomFormat";
+import convertTimestampToDate from "@/utils/convertTimestampToDate";
+import { MarkdownViewer } from "../markdown/MarkdownViewer";
+
+export default function RenderWikiContent({
+ currentUser,
+ Wiki,
+ onWikiEditButtonClick,
+ onWikiDeleteButtonClick,
+ toggleEditMode,
+}: RenderWikiContentProps) {
+ function onEditButtonClick() {
+ onWikiEditButtonClick();
+ toggleEditMode();
+ }
+ const createdAtDate = Wiki?.createdAt
+ ? convertTimestampToDate(Wiki.createdAt)
+ : null;
+ const formattedCreatedAt = createdAtDate
+ ? formatDateToCustomFormat(createdAtDate, "yyyy.MM.dd HH:mm:ss")
+ : "";
+
+ const updatedAtDate = Wiki?.updatedAt
+ ? convertTimestampToDate(Wiki.updatedAt)
+ : null;
+ const formattedUpdatedAt = updatedAtDate
+ ? formatDateToCustomFormat(updatedAtDate, "yyyy.MM.dd HH:mm:ss")
+ : "";
+
+ const isAdmin = (currentUser: string | undefined) =>
+ currentUser === "admin@9oogle.com";
+
+ const isAuthor = (
+ currentUser: string | undefined,
+ wikiAuthorID: string | undefined,
+ ) => currentUser && wikiAuthorID === currentUser;
+
+ const isDisabled = (
+ currentUser: string | undefined,
+ wikiAuthorID: string | undefined,
+ ): boolean => {
+ if (isAdmin(currentUser)) return false;
+ if (isAuthor(currentUser, wikiAuthorID)) return false;
+ return true;
+ };
+ const disabledStatus = isDisabled(currentUser, Wiki?.authorID);
+
+ return (
+ <>
+
+ {Wiki?.title}
+
+ {Wiki?.updatedAt
+ ? `최종수정일: ${formattedUpdatedAt}`
+ : `작성일: ${formattedCreatedAt}`}
+
+ {Wiki?.lastUpdatedBy
+ ? `최종수정자: ${Wiki?.lastUpdatedBy}`
+ : `작성자: ${Wiki?.authorID}`}
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/wiki/content/RenderWikiForm.tsx b/src/components/wiki/content/RenderWikiForm.tsx
new file mode 100644
index 00000000..fc0d133b
--- /dev/null
+++ b/src/components/wiki/content/RenderWikiForm.tsx
@@ -0,0 +1,59 @@
+import * as Styled from "./WikiContentStyle";
+import * as FormStyled from "./RenderWikiFormStyle";
+import { WikiFormProps } from "@/components/wiki/types/WikiCommonType";
+import "@toast-ui/editor/dist/i18n/ko-kr";
+import { MarkdownEditor } from "../markdown/MarkdownEditor";
+
+export default function WikiForm({
+ form,
+ onFormChange,
+ editorRef,
+ parents,
+ hasChildMap,
+}: WikiFormProps) {
+ const handleParentChange = async (
+ e: React.ChangeEvent,
+ ) => {
+ const newParentID = e.target.value;
+ const isNewWiki = () => form.wikiID === "";
+
+ const hasChild = hasChildMap[form.wikiID];
+
+ // 현재 위키가 자식을 가지고 있지 않고, 선택한 parentID가 현재 위키의 자식 위키가 아니면 변경 허용
+ if (isNewWiki() || (!hasChild && newParentID !== form.wikiID)) {
+ onFormChange("parentID", newParentID);
+ } else {
+ alert(
+ "선택한 위키로 이동할 수 없습니다.\n하위 위키를 먼저 이동시킨 후 이동시켜 주세요.",
+ );
+ }
+ };
+
+ return (
+ <>
+
+
+
+ 전체
+ {parents.map((parent) => (
+
+ {parent.title}
+
+ ))}
+
+ onFormChange("title", e.target.value)}
+ placeholder="제목 입력"
+ />
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/wiki/content/RenderWikiFormStyle.ts b/src/components/wiki/content/RenderWikiFormStyle.ts
new file mode 100644
index 00000000..9b696111
--- /dev/null
+++ b/src/components/wiki/content/RenderWikiFormStyle.ts
@@ -0,0 +1,63 @@
+import styled from "styled-components";
+import { TitleText } from "./WikiContentStyle";
+
+export const FormTitle = styled(TitleText)`
+ & {
+ width: 100%;
+ }
+`;
+
+export const Input = styled.input`
+ width: 100%;
+ padding: 0.5rem;
+ border: none;
+ border-radius: 0.25rem;
+
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--color-gray);
+
+ &:focus {
+ outline: none;
+ }
+`;
+
+export const Textarea = styled.textarea`
+ width: 100%;
+ height: 550px;
+ overflow-y: auto;
+ resize: none;
+
+ padding: 0.5rem;
+
+ border: 1px solid var(--color-light-gray);
+ border-radius: 0.25rem;
+
+ font-size: 14px;
+ font-weight: 500;
+
+ &:focus {
+ outline: none;
+ }
+`;
+
+export const Select = styled.select`
+ width: 8rem;
+ height: 1.88rem;
+ padding: 0.2rem;
+ margin-right: 1rem;
+
+ border-radius: 0.25rem;
+ background-color: var(--color-white);
+
+ font-size: 14px;
+ font-weight: 400;
+ color: #b4b4b4;
+
+ &:focus {
+ outline: none;
+ }
+ option:checked {
+ background-color: var(--color-light-gray);
+ }
+`;
diff --git a/src/components/wiki/content/WikiContent.tsx b/src/components/wiki/content/WikiContent.tsx
new file mode 100644
index 00000000..4b8ff2f9
--- /dev/null
+++ b/src/components/wiki/content/WikiContent.tsx
@@ -0,0 +1,53 @@
+import RenderWikiForm from "./RenderWikiForm";
+import RenderNoWiki from "./RenderNoWiki";
+import RenderWikiContent from "./RenderWikiContent";
+import * as Styled from "./WikiContentStyle";
+import { WikiContentProps } from "@/components/wiki/types/WikiCommonType";
+
+export default function WikiContent({
+ currentUser,
+ Wiki,
+ form,
+ parents,
+ hasChildMap,
+ isEditMode,
+ isLoading,
+ editorRef,
+ toggleEditMode,
+ onFormChange,
+ onWikiEditButtonClick,
+ onWikiDeleteButtonClick,
+}: WikiContentProps) {
+ const wikiFormProps = {
+ form,
+ editorRef,
+ parents,
+ hasChildMap,
+ onFormChange,
+ };
+ const wikiContentProps = {
+ Wiki,
+ onWikiEditButtonClick,
+ onWikiDeleteButtonClick,
+ toggleEditMode,
+ };
+
+ if (isLoading) {
+ return Loading... ;
+ }
+
+ return (
+
+ {isEditMode ? (
+
+ ) : Wiki === null ? (
+
+ ) : (
+
+ )}
+
+ );
+}
diff --git a/src/components/wiki/content/WikiContentStyle.ts b/src/components/wiki/content/WikiContentStyle.ts
new file mode 100644
index 00000000..c89a783f
--- /dev/null
+++ b/src/components/wiki/content/WikiContentStyle.ts
@@ -0,0 +1,33 @@
+import styled from "styled-components";
+
+export const ContentsWrapper = styled.div`
+ height: 44.75rem;
+ overflow-y: scroll;
+ flex: 1;
+ padding: 1.88rem 2.5rem;
+ background-color: var(--color-white);
+ border: 1px solid var(--color-light-gray);
+ border-radius: 0.94rem;
+`;
+
+export const ContentsTitle = styled.div`
+ display: flex;
+ justify-content: space-between;
+
+ padding-bottom: 1rem;
+ margin-bottom: 1.28rem;
+
+ border-bottom: 1px solid #e4e4e4;
+`;
+export const TitleText = styled.div`
+ display: flex;
+ align-items: center;
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--color-gray);
+`;
+
+export const EditDetails = styled.span`
+ margin-left: 1.06rem;
+ margin-right: 1.06rem;
+`;
diff --git a/src/components/wiki/markdown/MarkdownEditor.tsx b/src/components/wiki/markdown/MarkdownEditor.tsx
new file mode 100644
index 00000000..ba0f201b
--- /dev/null
+++ b/src/components/wiki/markdown/MarkdownEditor.tsx
@@ -0,0 +1,29 @@
+import "@toast-ui/editor/dist/toastui-editor.css";
+import { Editor } from "@toast-ui/react-editor";
+import "@toast-ui/editor/dist/i18n/ko-kr";
+import { Wiki } from "../types/WikiCommonType";
+
+type MarkdownEditorProps = {
+ form: Wiki;
+ editorRef: React.MutableRefObject;
+};
+
+export const MarkdownEditor = ({ form, editorRef }: MarkdownEditorProps) => {
+ return (
+
+ );
+};
diff --git a/src/components/wiki/markdown/MarkdownViewer.tsx b/src/components/wiki/markdown/MarkdownViewer.tsx
new file mode 100644
index 00000000..eadea7da
--- /dev/null
+++ b/src/components/wiki/markdown/MarkdownViewer.tsx
@@ -0,0 +1,16 @@
+import { Viewer } from "@toast-ui/react-editor";
+
+type MarkdownViewerProps = {
+ content?: string;
+};
+
+export const MarkdownViewer = ({ content }: MarkdownViewerProps) => {
+ return (
+
+ );
+};
diff --git a/src/components/wiki/top/WikiTop.tsx b/src/components/wiki/top/WikiTop.tsx
new file mode 100644
index 00000000..1226c305
--- /dev/null
+++ b/src/components/wiki/top/WikiTop.tsx
@@ -0,0 +1,33 @@
+import WikiTopButton from "../buttons/WikiButton";
+import { WikiTopProps } from "../types/WikiCommonType";
+import * as Styled from "./WikiTopStyle";
+
+export default function WikiTop({
+ title,
+ isEditMode,
+ isBackButtonVisible,
+ onSave,
+ onRegister,
+ onBack,
+}: WikiTopProps) {
+ return (
+
+ {title}
+
+ {isBackButtonVisible && (
+
+ )}
+
+
+
+ );
+}
diff --git a/src/components/wiki/top/WikiTopStyle.ts b/src/components/wiki/top/WikiTopStyle.ts
new file mode 100644
index 00000000..13d10fd3
--- /dev/null
+++ b/src/components/wiki/top/WikiTopStyle.ts
@@ -0,0 +1,40 @@
+import styled from "styled-components";
+//import Button from "../common/Button";
+
+export const WikiTop = styled.div`
+ display: flex;
+ justify-content: space-between;
+ padding: 0;
+ margin-bottom: 1.05rem;
+`;
+
+export const WikiTitle = styled.span`
+ font-size: 1.25rem;
+ font-weight: 500;
+ color: var(--color-dark-gray);
+`;
+
+export const Container = styled.button<{ padding: string; margin?: string }>`
+ border: 0.0625rem solid var(--color-main);
+ border-radius: 0.25rem;
+ background: var(--color-white);
+
+ margin: ${({ margin }) => margin};
+ padding: ${({ padding }) => padding};
+
+ cursor: pointer;
+
+ color: var(--color-main);
+ font-size: 0.88rem;
+ line-height: normal;
+ text-align: center;
+
+ &:hover {
+ background-color: var(--color-main);
+ color: var(--color-white);
+ }
+`;
+
+export const WikiButton = styled(Container)`
+ color: white;
+`;
diff --git a/src/components/wiki/types/WikiCommonType.ts b/src/components/wiki/types/WikiCommonType.ts
new file mode 100644
index 00000000..8156dbad
--- /dev/null
+++ b/src/components/wiki/types/WikiCommonType.ts
@@ -0,0 +1,74 @@
+import { Editor } from "@toast-ui/react-editor";
+
+export type WikiList = {
+ wikiID: string;
+ parentID: string;
+ title: string;
+};
+
+interface Timestamp {
+ seconds: number;
+ nanoseconds: number;
+}
+export type Wiki = {
+ wikiID: string;
+ parentID: string;
+ title: string;
+ content: string;
+ authorID: string;
+ createdAt: Timestamp | null;
+ updatedAt: Timestamp | null;
+ lastUpdatedBy: string;
+};
+
+export type WikiTopProps = {
+ title: string;
+ isEditMode: boolean;
+ isBackButtonVisible: boolean;
+ onRegister: () => void;
+ onSave: () => void;
+ onBack?: () => void;
+};
+
+export type WikiCategoryProps = {
+ WiKiList: Wiki[];
+ hasChildMap: HasChildMap;
+ onEntryClick: (entry: Wiki) => void;
+ onArrowClick: (entry: Wiki) => void;
+ isVisible: boolean;
+};
+
+export type WikiFormProps = {
+ form: Wiki;
+ parents: Wiki[];
+ hasChildMap: HasChildMap;
+ onFormChange: (key: keyof Wiki, value: string) => void;
+ editorRef: React.MutableRefObject;
+};
+
+export type WikiContentProps = {
+ currentUser: string;
+ Wiki: Wiki | null;
+ form: Wiki;
+ parents: Wiki[];
+ hasChildMap: HasChildMap;
+ isEditMode: boolean;
+ isLoading: boolean;
+ onFormChange: (key: keyof Wiki, value: string) => void;
+ onWikiEditButtonClick: () => void;
+ onWikiDeleteButtonClick: () => void;
+ toggleEditMode: () => void;
+ editorRef: React.MutableRefObject;
+};
+
+export type RenderWikiContentProps = {
+ currentUser: string;
+ Wiki: Wiki | null;
+ onWikiEditButtonClick: () => void;
+ onWikiDeleteButtonClick: () => void;
+ toggleEditMode: () => void;
+};
+
+export type HasChildMap = {
+ [wikiID: string]: boolean;
+};
diff --git a/src/db/wiki/CarouselData.tsx b/src/db/wiki/CarouselData.tsx
new file mode 100644
index 00000000..7ce8c126
--- /dev/null
+++ b/src/db/wiki/CarouselData.tsx
@@ -0,0 +1,46 @@
+
+const CarouselData = [
+
+ {
+ id: 0,
+ title: "2023년 프로젝트 안내",
+ text: "2023년에 진행될 프로젝트를 안내 드립니다. 올해도 작년에 이어 기업이 발전 할 수 있도록 임직원 여러분의 많은 노력과 관심 부탁드립니다.",
+ url: "/images/notification01.png",
+ link: "wiki?wikiID=egJBjpktC5m7mzP5KFBA"
+ },
+
+ {
+ id: 1,
+ title: "조직 개편 안내",
+ text: "9굴 임직원 여러분, 2023년 조직 개편 사항을 안내드리오니 업무에 참고 부탁드립니다.",
+ url: "/images/notification02.png",
+ link: "wiki?wikiID=4XEcLRkFpzVWmXGyglld"
+ },
+
+ {
+ id: 2,
+ title: "9굴에서 일 잘하는 법 11가지",
+ text: "1. 9시 1분은 9시가 아니다. 2. 업무는 수직적, 인간적인 관계는 수평적.",
+ url: "/images/notification03.png",
+ link: "wiki?wikiID=owcPdSFRsUmFBVMrTq62"
+ },
+
+ {
+ id: 3,
+ title: "개발팀 규칙",
+ text: "1. Git git commit convention 제목 제목은 간단하게 해당 커밋의 목적을 요약해서 작성합니다.",
+ url: "/images/notification04.png",
+ link: "wiki?wikiID=IMOryxzff38FWXIHe71R"
+ },
+
+ {
+ id: 4,
+ title: "9월 일정 안내",
+ text: "9굴 임직원 여러분, 2023년 9월 일정을 안내드리오니 업무에 참고 부탁드립니다. <9월 일정 안내>",
+ url: "/images/notification05.png",
+ link: "wiki?wikiID=8Dvc4OoK5781neTyvYKD"
+ }
+
+]
+
+export default CarouselData;
\ No newline at end of file
diff --git a/src/firebase/firebase.ts b/src/firebase/firebase.ts
new file mode 100644
index 00000000..eddeab1e
--- /dev/null
+++ b/src/firebase/firebase.ts
@@ -0,0 +1,17 @@
+import { initializeApp } from "firebase/app";
+import { getFirestore } from "firebase/firestore";
+import { getAuth } from "firebase/auth";
+
+const firebaseConfig = {
+ apiKey: import.meta.env.VITE_APP_FIREBASE_API_KEY,
+ authDomain: "toy-1-1dfe1.firebaseapp.com",
+ projectId: "toy-1-1dfe1",
+ storageBucket: "toy-1-1dfe1.appspot.com",
+ messagingSenderId: "6124898264",
+ appId: import.meta.env.VITE_APP_FIREBASE_APP_ID,
+ measurementId: "G-GFE642HZGF",
+};
+
+export const app = initializeApp(firebaseConfig);
+export const auth = getAuth(app);
+export const db = getFirestore(app);
diff --git a/src/firebase/services/wikiService.ts b/src/firebase/services/wikiService.ts
new file mode 100644
index 00000000..7aa8c278
--- /dev/null
+++ b/src/firebase/services/wikiService.ts
@@ -0,0 +1,98 @@
+import {
+ doc,
+ addDoc,
+ setDoc,
+ getDoc,
+ collection,
+ query,
+ where,
+ orderBy,
+ getDocs,
+ deleteDoc,
+} from "firebase/firestore";
+import { db } from "@/firebase/firebase";
+import { Wiki } from "@/components/wiki/types/WikiCommonType";
+
+export const loadWikiByID = async (id: string) => {
+ const wikiRef = doc(db, "Wiki", id);
+ const wikiSnap = await getDoc(wikiRef);
+ if (wikiSnap.exists()) {
+ return wikiSnap.data() as Wiki;
+ } else {
+ console.warn(`Wiki ID ${id}가 존재하지 않습니다.`);
+ return null;
+ }
+};
+
+export const loadRootWikis = async () => {
+ const q = query(
+ collection(db, "Wiki"),
+ where("parentID", "==", ""),
+ orderBy("createdAt", "asc"),
+ );
+ const docs = await getDocs(q);
+ return docs.docs.map((doc) => doc.data() as Wiki);
+};
+
+export const loadChildrenWikis = async (
+ parentWikiID: string,
+): Promise => {
+ const q = query(
+ collection(db, "Wiki"),
+ where("parentID", "==", parentWikiID),
+ orderBy("createdAt", "asc"),
+ );
+ const docs = await getDocs(q);
+ return docs.docs.map((doc) => doc.data() as Wiki);
+};
+
+export const hasChildWikis = async (wikiID: string) => {
+ const wikisCollection = collection(db, "Wiki");
+ const q = query(wikisCollection, where("parentID", "==", wikiID));
+ const snapshot = await getDocs(q);
+ return !snapshot.empty;
+};
+
+export const saveWiki = async (newForm: Wiki) => {
+ const EMPTY_STRING = "";
+
+ let linkWikiID;
+ if (newForm.wikiID && newForm.wikiID !== EMPTY_STRING) {
+ const wikiRef = doc(db, "Wiki", newForm.wikiID);
+ await setDoc(wikiRef, newForm, { merge: true });
+ linkWikiID = newForm.wikiID;
+ } else {
+ const wikiCollection = collection(db, "Wiki");
+ const newDocRef = await addDoc(wikiCollection, newForm);
+
+ // Firestore에서 자동으로 생성된 문서 ID를 가져옴
+ const generatedID = newDocRef.id;
+
+ // 생성된 ID를 newForm의 wikiID에 할당하고 다시 저장
+ await setDoc(
+ newDocRef,
+ { ...newForm, wikiID: generatedID },
+ { merge: true },
+ );
+ linkWikiID = generatedID;
+ }
+ return linkWikiID;
+};
+
+export const deleteWiki = async (wikiID: string) => {
+ const wikiRef = doc(db, "Wiki", wikiID);
+ await deleteDoc(wikiRef);
+};
+
+export const deleteChildWikis = async (parentWikiID: string) => {
+ const q = query(
+ collection(db, "Wiki"),
+ where("parentID", "==", parentWikiID),
+ );
+ const docs = await getDocs(q);
+ const childWikis = docs.docs.map((doc) => doc.data() as Wiki);
+ for (const childWiki of childWikis) {
+ const childWikiRef = doc(db, "Wiki", childWiki.wikiID);
+ await deleteDoc(childWikiRef);
+ }
+};
diff --git a/src/main.tsx b/src/main.tsx
new file mode 100644
index 00000000..169cf74c
--- /dev/null
+++ b/src/main.tsx
@@ -0,0 +1,12 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App.tsx";
+import "./styles/fonts/font.css";
+import GlobalStyle from "./styles/globalStyle";
+
+ReactDOM.createRoot(document.getElementById("root")!).render(
+
+
+
+ ,
+);
diff --git a/src/pages/gallery/Gallery.tsx b/src/pages/gallery/Gallery.tsx
new file mode 100644
index 00000000..385284e5
--- /dev/null
+++ b/src/pages/gallery/Gallery.tsx
@@ -0,0 +1,172 @@
+import * as style from "./galleryStyle";
+import { useState, useEffect } from "react";
+import GalleryHeader from "@components/gallery/GalleryHeader";
+import GallerySide from "@components/gallery/GallerySide";
+import GalleryMain from "@components/gallery/GalleryMain";
+import Addlist from "@components/gallery/AddList";
+import CurrentImg from "@/components/gallery/CurrentImg";
+import { AddImg } from "@/components/gallery/AddImg";
+import {
+ getFirestore,
+ collection,
+ getDocs,
+ Timestamp,
+} from "firebase/firestore";
+import { app } from "@/firebase/firebase";
+import {
+ getStorage,
+ ref,
+ listAll,
+ getDownloadURL,
+ getMetadata,
+ FullMetadata,
+} from "firebase/storage";
+
+const firestore = getFirestore(app);
+const storage = getStorage(app);
+
+interface Folders {
+ createdAt: Date;
+ id: string;
+ sub: string[];
+ title: string;
+}
+
+interface ImageInfo {
+ url: string;
+ metadata: FullMetadata;
+}
+
+export default function Gallery() {
+ const [addListModal, setAddListModal] = useState(false);
+ const [configList, setConfigList] = useState(false);
+ const [galleryData, setGalleryData] = useState([]);
+ const [album, setAlbum] = useState("개발팀");
+ const [albumId, setAlbumId] = useState("0jL7NLzNrPzOuqeuJSk2");
+ const [imagePaths, setImagePaths] = useState([]);
+ const [curImg, setCurImg] = useState("");
+ const [viewImg, setViewImg] = useState(false);
+ const [imgLoad, setImgLoad] = useState(true);
+ const [addImg, setAddImg] = useState(false);
+
+ useEffect(() => {
+ fetchImages();
+ }, [albumId]);
+
+ useEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchImages = async () => {
+ try {
+ const imagesRef = ref(storage, `Gallery/${albumId}`);
+ const imageList = await listAll(imagesRef);
+
+ const paths = imageList.items.map(async (item) => {
+ const url = await getDownloadURL(item);
+ const metadata = await getMetadata(item);
+
+ return { url, metadata };
+ });
+
+ const imageInfoList: ImageInfo[] = await Promise.all(paths);
+ const sortedImages = imageInfoList.sort((a, b) => {
+ if (a.metadata.customMetadata) {
+ }
+ const timestampA = a.metadata.customMetadata!.timestamp;
+ const timestampB = b.metadata.customMetadata!.timestamp;
+ return new Date(timestampA).getTime() - new Date(timestampB).getTime();
+ });
+
+ const urls = sortedImages.map((item) => item.url);
+ setImagePaths(urls);
+ setImgLoad(false);
+ } catch (error) {
+ console.error("이미지 목록을 가져오는 중 오류 발생:", error);
+ }
+ };
+
+ const fetchData = async () => {
+ const galleryRef = collection(firestore, "Gallery");
+ const querySnapshot = await getDocs(galleryRef);
+
+ const galleryArray: Folders[] = [];
+
+ querySnapshot.forEach((doc) => {
+ const data = doc.data();
+
+ galleryArray.push({
+ createdAt: (data.createdAt as Timestamp).toDate(),
+ id: data.id,
+ sub: data.sub,
+ title: data.title,
+ });
+ });
+
+ galleryArray.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
+
+ setGalleryData(galleryArray);
+ };
+
+ const openAddListModal = (): void => {
+ setAddListModal(true);
+ };
+
+ const closeAddListModal = (): void => {
+ setAddListModal(false);
+ };
+ return (
+
+
+
+
+
+
+ {addListModal ? (
+
+ ) : null}
+ {viewImg ? (
+
+ ) : null}
+ {addImg ? (
+
+ ) : null}
+
+ );
+}
diff --git a/src/pages/gallery/galleryStyle.ts b/src/pages/gallery/galleryStyle.ts
new file mode 100644
index 00000000..d2fbdd55
--- /dev/null
+++ b/src/pages/gallery/galleryStyle.ts
@@ -0,0 +1,12 @@
+import styled from "styled-components";
+
+export const Gallery = styled.div`
+ // border: 1px solid red;
+ // margin: 0 5.6% 5.6% 5.6%;
+ padding: 1.25rem 5rem;
+`;
+
+export const MainWrap = styled.div`
+ display: flex;
+ justify-content: space-between;
+`;
diff --git a/src/pages/home/Home.tsx b/src/pages/home/Home.tsx
new file mode 100644
index 00000000..994692cc
--- /dev/null
+++ b/src/pages/home/Home.tsx
@@ -0,0 +1,74 @@
+import * as style from "./homeStyle";
+import Carousel from "../../components/home/Carousel";
+import GalleryPreview from "../../components/home/GalleryPreview";
+import WikiPreview from "@/components/home/WikiPreview";
+import {
+ collection,
+ query,
+ orderBy,
+ limit,
+ onSnapshot,
+} from "firebase/firestore";
+import { useEffect, useState } from "react";
+import { db } from "@/firebase/firebase";
+import { Wiki } from "@/components/wiki/types/WikiCommonType";
+
+export default function Home() {
+ const [lastestWikis, setLastestWikis] = useState();
+ useEffect(() => {
+ const aa = async () => {
+ const q = query(
+ collection(db, "Wiki"),
+ orderBy("createdAt", "desc"),
+ limit(2),
+ );
+
+ onSnapshot(q, (snapshot) => {
+ setLastestWikis(snapshot.docs.map((doc) => doc.data() as Wiki));
+ });
+ };
+ aa();
+ }, []);
+
+ return (
+ <>
+
+
+ 공지사항
+
+
+
+
+
+ 최근 업데이트 된 WIKI
+ 더보기 >
+
+ {lastestWikis ? (
+ <>
+ {lastestWikis?.map((lastestWiki) => {
+ return (
+
+
+
+ );
+ })}
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
+
+ 최근 업데이트 된 GALLERY
+ 더보기 >
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/pages/home/homeStyle.ts b/src/pages/home/homeStyle.ts
new file mode 100644
index 00000000..b2e59c8c
--- /dev/null
+++ b/src/pages/home/homeStyle.ts
@@ -0,0 +1,90 @@
+import { Link } from "react-router-dom";
+import styled from "styled-components";
+
+export const Temp = styled.div`
+ display: grid;
+ grid-template-columns: 2fr 1fr;
+ grid-template-rows: auto auto auto auto auto;
+ margin: 1.4rem 5rem;
+ gap: 30px;
+`;
+export const GridBox = styled.div`
+ width: 100%;
+ height: 100%;
+`;
+export const MainNotificationTitle = styled.div`
+ grid-row-start: 1;
+ grid-row-end: 1;
+`;
+export const MainCarousel = styled.div`
+ grid-row-start: 2;
+ grid-row-end: 6;
+ position: relative;
+`;
+export const Item3 = styled.div`
+ grid-row-start: 1;
+ grid-row-end: 1;
+`;
+export const Item4 = styled.div`
+ grid-row-start: 2;
+ grid-row-end: 2;
+`;
+export const Item5 = styled.div`
+ grid-row-start: 3;
+ grid-row-end: 3;
+`;
+export const MainGalleryTitle = styled.div`
+ grid-row-start: 4;
+ grid-row-end: 4;
+`;
+export const MainGalleryPreview = styled.div`
+ grid-row-start: 5;
+ grid-row-end: 5;
+`;
+export const MainTitleWrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+export const MainTitle = styled.div`
+ color: var(--color-dark-gray);
+ font-weight: 500;
+ font-size: 1.25rem;
+ line-height: normal;
+ text-align: left;
+`;
+export const SideSkeleton = styled.div`
+ width: 100%;
+ height: 168px;
+ border-radius: 15px;
+ color: rgba(0, 0, 0, 0);
+ background-image: linear-gradient(
+ 100deg,
+ rgba(0, 0, 0, 0.1),
+ rgba(0, 0, 0, 0.1),
+ rgba(0, 0, 0, 0),
+ rgba(0, 0, 0, 0.1),
+ rgba(0, 0, 0, 0.1)
+ );
+ background-size: 400% 100%;
+ animation: skeleton-loading 7s linear infinite;
+
+ @keyframes skeleton-loading {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+ }
+`;
+export const MoreBtn = styled(Link)`
+ color: var(--color-gray);
+ font-weight: 500;
+ font-size: 0.875rem;
+ line-height: normal;
+
+ &:hover {
+ text-decoration: underline;
+ }
+`;
diff --git a/src/pages/login/Login.tsx b/src/pages/login/Login.tsx
new file mode 100644
index 00000000..b2401470
--- /dev/null
+++ b/src/pages/login/Login.tsx
@@ -0,0 +1,22 @@
+import SignIn from "@components/login/SignIn";
+
+import * as style from "./loginStyle";
+
+const LoginPage = () => {
+ return (
+
+
+
+ 9굴
+ WIKI
+
+
+
+
+
+
+
+ );
+};
+
+export default LoginPage;
diff --git a/src/pages/login/context/authContext.tsx b/src/pages/login/context/authContext.tsx
new file mode 100644
index 00000000..6991a5d0
--- /dev/null
+++ b/src/pages/login/context/authContext.tsx
@@ -0,0 +1,6 @@
+/** createContext()를 사용하여 firebase에서 제공하는 User객체 넘겨주기 위함 */
+
+import React from "react";
+import {User} from "@firebase/auth";
+
+export const AuthContext = React.createContext(null);
diff --git a/src/pages/login/context/authProvider.tsx b/src/pages/login/context/authProvider.tsx
new file mode 100644
index 00000000..720de211
--- /dev/null
+++ b/src/pages/login/context/authProvider.tsx
@@ -0,0 +1,26 @@
+/** 유저 정보 내려주기 위함 */
+
+import { User } from "@firebase/auth";
+import { useEffect, useState } from "react";
+import { AuthContext } from "./authContext";
+import { auth } from "@/firebase/firebase";
+
+interface AuthProviderProps {
+ children: React.ReactNode;
+}
+
+const AuthProvider: React.FC = ({ children }) => {
+ const [user, setUser] = useState(null);
+
+ useEffect(() => {
+ const subscribe = auth.onAuthStateChanged((fbUser) => {
+ console.log(`구독 실행`, fbUser);
+ setUser(fbUser);
+ });
+ return subscribe;
+ }, []);
+
+ return {children} ;
+};
+
+export default AuthProvider;
diff --git a/src/pages/login/loginStyle.ts b/src/pages/login/loginStyle.ts
new file mode 100644
index 00000000..624f1d0a
--- /dev/null
+++ b/src/pages/login/loginStyle.ts
@@ -0,0 +1,46 @@
+import styled from "styled-components";
+
+export const Container = styled.section`
+ overflow: hidden;
+ display: flex;
+ background-color: var(--color-main);
+ justify-content: center;
+`;
+
+export const Content = styled.div`
+ width: 22.88em;
+ height: 31.25rem;
+ background-color: var(--color-white);
+ border-radius: 0 0.94rem 0.94rem 0;
+ margin: 15rem 19.06rem 15rem 0;
+`;
+
+export const Info = styled.div`
+ width: 29rem;
+ height: 31.25rem;
+ background-color: rgba(255, 255, 255, 0.05);
+ border: 0.06rem solid #42537e;
+ border-radius: 0.94rem 0 0 0.94rem;
+ margin: 15rem 0 15rem 19.06rem;
+`;
+
+export const Logo = styled.div``;
+
+export const CompanyName = styled.div`
+ color: var(--color-white);
+ font-size: 1.88rem;
+ line-height: normal;
+ text-align: left;
+ letter-spacing: -0.1rem;
+ margin: 11.69rem 0 0 5.38rem;
+`;
+
+export const ServiceName = styled.div`
+ color: var(--color-white);
+ font-weight: bold;
+ font-size: 3.13rem;
+ line-height: normal;
+ text-align: left;
+ letter-spacing: -0.1rem;
+ margin: 0 17rem 11.75rem 5.38rem;
+`;
diff --git a/src/pages/pageIndex.ts b/src/pages/pageIndex.ts
new file mode 100644
index 00000000..2a1c2cc3
--- /dev/null
+++ b/src/pages/pageIndex.ts
@@ -0,0 +1,4 @@
+export { default as Login } from "./login/Login";
+export { default as Home } from "./home/Home";
+export { default as Wiki } from "./wiki/Wiki";
+export { default as Gallery } from "./gallery/Gallery";
diff --git a/src/pages/wiki/Wiki.tsx b/src/pages/wiki/Wiki.tsx
new file mode 100644
index 00000000..da9a9964
--- /dev/null
+++ b/src/pages/wiki/Wiki.tsx
@@ -0,0 +1,287 @@
+import { useState, useEffect, useRef, useMemo } from "react";
+import { useLocation } from "react-router";
+import { useNavigate } from "react-router-dom";
+import { Editor } from "@toast-ui/react-editor";
+import { Timestamp } from "firebase/firestore";
+import WikiContent from "@/components/wiki/content/WikiContent";
+import WikiCategoryList from "@/components/wiki/category/WikiCategoryList";
+import WikiTop from "@/components/wiki/top/WikiTop";
+import * as S from "./WikiStyle";
+
+import { HasChildMap, Wiki } from "../../components/wiki/types/WikiCommonType";
+import { Props } from "@/App";
+import {
+ deleteWiki,
+ deleteChildWikis,
+ hasChildWikis,
+ loadRootWikis,
+ loadWikiByID,
+ saveWiki,
+ loadChildrenWikis,
+} from "@/firebase/services/wikiService";
+
+const EMPTY_STRING = "";
+const initializeForm = () => {
+ return {
+ wikiID: EMPTY_STRING,
+ parentID: EMPTY_STRING,
+ title: EMPTY_STRING,
+ content: EMPTY_STRING,
+ authorID: EMPTY_STRING,
+ createdAt: null,
+ updatedAt: null,
+ lastUpdatedBy: EMPTY_STRING,
+ };
+};
+export default function WikiPage({ email }: Props) {
+ const [wikiData, setWikiData] = useState([]);
+ const [isEditMode, setIsEditMode] = useState(false);
+ const [sideMenuVisible, setSideMenuVisible] = useState(true);
+ const [isLoading, setIsLoading] = useState(true);
+ const parents = wikiData.filter((wiki) => !wiki.parentID);
+ const initialFormValue = useMemo(initializeForm, []);
+ const [form, setForm] = useState(initialFormValue);
+ const [selectedEntry, setSelectedEntry] = useState(null);
+ const editorRef = useRef(null);
+
+ const queryString = new URLSearchParams(useLocation().search).get("wikiID");
+ const wikiIDFromQuery = queryString ? queryString : EMPTY_STRING;
+
+ const [hasChildMap, setHasChildMap] = useState({});
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ useEffect(() => {
+ const fetchChildrenStatus = async () => {
+ const promises = wikiData.map(async (wiki) => {
+ return wiki.parentID === EMPTY_STRING
+ ? { [wiki.wikiID]: await hasChildWikis(wiki.wikiID) }
+ : { [wiki.wikiID]: false };
+ });
+
+ const results = await Promise.all(promises);
+ const newMap = results.reduce((acc, curr) => ({ ...acc, ...curr }), {});
+ setHasChildMap(newMap);
+ };
+
+ fetchChildrenStatus();
+ }, [wikiData]);
+
+ useEffect(() => {
+ loadRootWikis().then((wikis) => {
+ setWikiData(wikis);
+ setIsLoading(false);
+ });
+ }, []);
+
+ useEffect(() => {
+ if (wikiData.length > 0 && (!selectedEntry || !form)) {
+ setSelectedEntry(wikiData[0]);
+ setForm(wikiData[0]);
+ }
+ }, [wikiData, selectedEntry, form]);
+
+ useEffect(() => {
+ if (wikiIDFromQuery !== EMPTY_STRING) {
+ loadWikiByID(wikiIDFromQuery).then((wiki) => {
+ if (wiki) {
+ setSelectedEntry(wiki);
+ setForm(wiki);
+ }
+ });
+ }
+ }, [wikiIDFromQuery]);
+
+ function handleEntryClick(entry: Wiki) {
+ setSelectedEntry(entry);
+ setForm(entry);
+ clearQueryParams();
+ }
+
+ async function toggleChildWikis(parentWiki: Wiki) {
+ const existingChildWikis = wikiData.filter(
+ (wiki) => wiki.parentID === parentWiki.wikiID,
+ );
+ if (existingChildWikis.length > 0) {
+ setWikiData((prev) => {
+ const parentIndex = prev.findIndex(
+ (wiki) => wiki.wikiID === parentWiki.wikiID,
+ );
+ if (
+ parentIndex !== -1 &&
+ prev[parentIndex + 1] &&
+ prev[parentIndex + 1].parentID === parentWiki.wikiID
+ ) {
+ return [
+ ...prev.slice(0, parentIndex + 1),
+ ...prev.slice(parentIndex + 1 + existingChildWikis.length),
+ ];
+ } else {
+ return [
+ ...prev.slice(0, parentIndex + 1),
+ ...existingChildWikis,
+ ...prev.slice(parentIndex + 1),
+ ];
+ }
+ });
+ } else {
+ const childWikis = await loadChildrenWikis(parentWiki.wikiID);
+ setWikiData((prev) => {
+ const parentIndex = prev.findIndex(
+ (wiki) => wiki.wikiID === parentWiki.wikiID,
+ );
+ return [
+ ...prev.slice(0, parentIndex + 1),
+ ...childWikis,
+ ...prev.slice(parentIndex + 1),
+ ];
+ });
+ }
+ }
+ function handleWikiEditButtonClick() {
+ setSideMenuVisible(!sideMenuVisible);
+ }
+
+ function toggleEditMode() {
+ setIsEditMode((prev) => !prev);
+ }
+
+ function handleRegisterClick() {
+ setIsEditMode(true);
+ setSideMenuVisible(false);
+ setForm(initializeForm());
+ }
+
+ async function handleSaveClick() {
+ const markDownContent =
+ editorRef.current?.getInstance().getMarkdown() || EMPTY_STRING;
+ const currentTime = Timestamp.now();
+
+ const newForm = {
+ ...form,
+ content: markDownContent,
+ authorID: form.authorID || email,
+ createdAt: form.createdAt || currentTime,
+ updatedAt: currentTime,
+ lastUpdatedBy: email,
+ };
+ try {
+ const linkWikiID = await saveWiki(newForm);
+ loadWikiByID(linkWikiID);
+ setSelectedEntry(newForm);
+ setForm(newForm);
+ alert("위키를 저장하였습니다.");
+ } catch (error) {
+ console.error("Error saving wiki:", error);
+ alert("위키 저장 중 오류가 발생했습니다.");
+ } finally {
+ loadRootWikis().then((wikis) => {
+ setWikiData(wikis);
+ setIsLoading(false);
+ setIsEditMode(false);
+ setSideMenuVisible(true);
+ });
+ clearQueryParams();
+ }
+ }
+
+ async function handleWikiDeleteClick() {
+ const deleteTargetWiki = form.wikiID;
+ const hasChild = hasChildMap[deleteTargetWiki];
+
+ let deleteConfirmMessage = "해당 위키를 삭제 하시겠습니까?";
+ if (hasChild) {
+ deleteConfirmMessage +=
+ "\n주의: 이 위키를 삭제 할 경우, 하위 위키도 함께 삭제됩니다.";
+ }
+
+ const deleteConfirm = confirm(deleteConfirmMessage);
+
+ if (!deleteConfirm) return;
+
+ if (form.wikiID !== EMPTY_STRING) {
+ try {
+ if (hasChild) deleteChildWikis(deleteTargetWiki);
+ await deleteWiki(deleteTargetWiki);
+
+ setWikiData((prev) =>
+ prev.filter(
+ (wiki) =>
+ wiki.wikiID !== form.wikiID && wiki.parentID !== form.wikiID,
+ ),
+ );
+
+ if (wikiData.length > 0) {
+ setSelectedEntry(wikiData[0]);
+ setForm(wikiData[0]);
+ } else {
+ setSelectedEntry(null);
+ setForm(initializeForm());
+ }
+
+ alert("위키를 삭제하였습니다.");
+ } catch (error) {
+ console.error("Error deleting wiki:", error);
+ alert("위키 삭제 중 오류가 발생했습니다.");
+ } finally {
+ setIsEditMode(false);
+ setSideMenuVisible(true);
+ }
+ }
+ }
+
+ function handleFormChange(key: keyof typeof form, value: string) {
+ setForm((prev) => ({
+ ...prev,
+ [key]: value,
+ }));
+ }
+
+ function handleBackClick() {
+ setIsEditMode(false);
+ setSideMenuVisible(true);
+ }
+
+ function clearQueryParams() {
+ navigate(location.pathname);
+ }
+ return (
+ <>
+
+
+
+
+ {
+
+ }
+
+
+ >
+ );
+}
diff --git a/src/pages/wiki/WikiStyle.ts b/src/pages/wiki/WikiStyle.ts
new file mode 100644
index 00000000..2b827d8b
--- /dev/null
+++ b/src/pages/wiki/WikiStyle.ts
@@ -0,0 +1,10 @@
+import styled from "styled-components";
+
+export const WikiWrapper = styled.div`
+ background-color: var(--color-area);
+ padding: 1.25rem 5rem;
+`;
+
+export const Container = styled.div`
+ display: flex;
+`;
diff --git a/src/styles/fonts/NotoSansKR-Bold.woff b/src/styles/fonts/NotoSansKR-Bold.woff
new file mode 100644
index 00000000..74b20d49
Binary files /dev/null and b/src/styles/fonts/NotoSansKR-Bold.woff differ
diff --git a/src/styles/fonts/NotoSansKR-Medium.woff b/src/styles/fonts/NotoSansKR-Medium.woff
new file mode 100644
index 00000000..e15aae09
Binary files /dev/null and b/src/styles/fonts/NotoSansKR-Medium.woff differ
diff --git a/src/styles/fonts/NotoSansKR-Regular.woff b/src/styles/fonts/NotoSansKR-Regular.woff
new file mode 100644
index 00000000..40fab257
Binary files /dev/null and b/src/styles/fonts/NotoSansKR-Regular.woff differ
diff --git a/src/styles/fonts/font.css b/src/styles/fonts/font.css
new file mode 100644
index 00000000..ac50b1f6
--- /dev/null
+++ b/src/styles/fonts/font.css
@@ -0,0 +1,18 @@
+@font-face {
+ font-family: "Noto Sans KR";
+ font-style: normal;
+ font-weight: 400;
+ src: url(./NotoSansKR-Regular.woff) format("woff");
+}
+@font-face {
+ font-family: "Noto Sans KR";
+ font-style: normal;
+ font-weight: 500;
+ src: url(./NotoSansKR-Medium.woff) format("woff");
+}
+@font-face {
+ font-family: "Noto Sans KR";
+ font-style: normal;
+ font-weight: 700;
+ src: url(./NotoSansKR-Bold.woff) format("woff");
+}
diff --git a/src/styles/globalStyle.ts b/src/styles/globalStyle.ts
new file mode 100644
index 00000000..3b8cc2ef
--- /dev/null
+++ b/src/styles/globalStyle.ts
@@ -0,0 +1,79 @@
+import { createGlobalStyle } from "styled-components";
+
+export const GlobalStyle = createGlobalStyle`
+ * {
+ font-family: "Noto Sans KR";
+ line-height: 1.5;
+ font-size: 16px;
+ box-sizing: border-box;
+ }
+
+ #root {
+ position: relative;
+ }
+
+ html {
+ --color-main: #001650;
+ --color-secondary: #253256;
+ --color-white: #ffffff;
+ --color-dark-gray: #222222;
+ --color-gray: #4a4a4a;
+ --color-disabled: #adadad;
+ --color-medium-gray: #d3d3d3;
+ --color-light-gray: #e6e6e6;
+ --color-area: #f0f2f7;
+ }
+
+ * {
+ padding: 0;
+ margin: 0;
+ }
+
+ body {
+ background-color: #f0f2f7;
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ div,
+ li,
+ section {
+ box-sizing: border-box;
+ }
+
+ ul,
+ li {
+ list-style: none;
+ }
+
+ input {
+ color: inherit;
+ font-family: inherit;
+ }
+
+ textarea {
+ color: inherit;
+ font-family: inherit;
+ }
+
+ ::-webkit-scrollbar {
+ width: 0.5rem;
+ }
+ ::-webkit-scrollbar-thumb {
+ background: var(--color-medium-gray);
+ border: 0;
+ border-radius: 12px 12px 12px 12px;
+ }
+
+ .tui-editor-contents {
+ font-family: "Noto Sans KR";
+ line-height: 1.5;
+ font-size: 16px;
+ }
+
+`;
+
+export default GlobalStyle;
diff --git a/src/utils/convertTimestampToDate.ts b/src/utils/convertTimestampToDate.ts
new file mode 100644
index 00000000..24d04c81
--- /dev/null
+++ b/src/utils/convertTimestampToDate.ts
@@ -0,0 +1,9 @@
+interface Timestamp {
+ seconds: number;
+ nanoseconds: number;
+}
+
+export default function convertTimestampToDate(timestamp: Timestamp | null) {
+ if (!timestamp || !timestamp.seconds) return null;
+ return new Date(timestamp.seconds * 1000);
+}
diff --git a/src/utils/formatDateToCustomFormat.ts b/src/utils/formatDateToCustomFormat.ts
new file mode 100644
index 00000000..acb681d5
--- /dev/null
+++ b/src/utils/formatDateToCustomFormat.ts
@@ -0,0 +1,20 @@
+export default function formatDateToCustomFormat(
+ date: Date,
+ format: string,
+): string {
+ if (!date) return "";
+ const year = String(date.getFullYear());
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ const seconds = String(date.getSeconds()).padStart(2, "0");
+
+ return format
+ .replace("yyyy", year)
+ .replace("dd", day)
+ .replace("MM", month)
+ .replace("HH", hours)
+ .replace("mm", minutes)
+ .replace("ss", seconds);
+}
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..257f7590
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,34 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "types": ["vite/client"],
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* base url*/
+ "baseUrl": "src",
+ "paths": {
+ "@/*": ["*"],
+ "@pages/*": ["pages/*"],
+ "@components/*": ["components/*"]
+ },
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 00000000..42872c59
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 00000000..a169f586
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import path from "path";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+ resolve: {
+ alias: [
+ { find: "@", replacement: path.resolve(__dirname, "src") },
+ { find: "@pages", replacement: path.resolve(__dirname, "src/pages") },
+ {
+ find: "@components",
+ replacement: path.resolve(__dirname, "src/components"),
+ },
+ ],
+ },
+});