Spaces:
Sleeping
Sleeping
김민용
commited on
Commit
·
c5d0166
1
Parent(s):
c1ac65c
feat: Next.js 기반 마크다운 포털로 전체 리뉴얼
Browse files- README.md +44 -23
- content +1 -0
- package-lock.json +1241 -43
- package.json +12 -5
- src/app/api/content/route.ts +35 -0
- src/app/api/git/route.ts +144 -0
- src/app/api/search/route.ts +40 -0
- src/app/categories/[category]/page.tsx +81 -0
- src/app/page.tsx +75 -99
- src/app/posts/[...slug]/page.tsx +91 -0
- src/app/search/page.tsx +94 -0
- src/app/tags/[tag]/page.tsx +81 -0
- src/app/versions/page.tsx +143 -0
- src/components/JsonLd.tsx +16 -0
- src/components/Search.tsx +119 -0
- src/content/articles/getting-started.md +63 -0
- src/content/articles/markdown-guide.md +88 -0
- src/content/articles/welcome.md +41 -0
- src/content/docs/api-reference.md +98 -0
- src/lib/git.ts +99 -0
- src/lib/markdown.ts +105 -0
- src/types/jsonld.ts +45 -0
- tailwind.config.ts +23 -0
README.md
CHANGED
|
@@ -1,36 +1,57 @@
|
|
| 1 |
-
|
| 2 |
|
| 3 |
-
|
| 4 |
|
| 5 |
-
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
```
|
| 16 |
|
| 17 |
-
|
| 18 |
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
-
|
| 22 |
|
| 23 |
-
|
|
|
|
|
|
|
| 24 |
|
| 25 |
-
|
|
|
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
-
|
| 31 |
|
| 32 |
-
|
| 33 |
|
| 34 |
-
|
| 35 |
|
| 36 |
-
|
|
|
|
|
|
| 1 |
+
# AI Tree Portal
|
| 2 |
|
| 3 |
+
Next.js 기반의 마크다운 문서 관리 포털입니다.
|
| 4 |
|
| 5 |
+
## 주요 기능
|
| 6 |
|
| 7 |
+
- ✍️ 마크다운 기반 문서 작성
|
| 8 |
+
- 🏷️ 태그 및 카테고리 관리
|
| 9 |
+
- 🔍 전체 텍스트 검색
|
| 10 |
+
- 📊 JSON-LD 구조화 데이터 지원
|
| 11 |
+
- 📝 Git 기반 버전 관리
|
| 12 |
+
- 변경 이력 추적
|
| 13 |
+
- 문서 버전 비교
|
| 14 |
+
- 롤백 기능
|
|
|
|
| 15 |
|
| 16 |
+
## 기술 스택
|
| 17 |
|
| 18 |
+
- **Frontend**: Next.js 15, React, TypeScript, Tailwind CSS
|
| 19 |
+
- **Backend**: Next.js API Routes
|
| 20 |
+
- **데이터 저장**: 마크다운 파일, Git
|
| 21 |
+
- **검색**: 전체 텍스트 검색, 태그/카테고리 필터링
|
| 22 |
+
- **SEO**: JSON-LD, 동적 메타데이터
|
| 23 |
|
| 24 |
+
## 설치 및 실행
|
| 25 |
|
| 26 |
+
```bash
|
| 27 |
+
# 의존성 설치
|
| 28 |
+
npm install
|
| 29 |
|
| 30 |
+
# 개발 서버 실행
|
| 31 |
+
npm run dev
|
| 32 |
|
| 33 |
+
# 프로덕션 빌드
|
| 34 |
+
npm run build
|
| 35 |
+
npm start
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
## 프로젝트 구조
|
| 39 |
+
|
| 40 |
+
```
|
| 41 |
+
src/
|
| 42 |
+
├── app/ # Next.js 페이지 및 레이아웃
|
| 43 |
+
├── components/ # React 컴포넌트
|
| 44 |
+
├── lib/ # 유틸리티 함수
|
| 45 |
+
└── types/ # TypeScript 타입 정의
|
| 46 |
+
|
| 47 |
+
content/ # 마크다운 문서 저장소
|
| 48 |
+
```
|
| 49 |
|
| 50 |
+
## 라이선스
|
| 51 |
|
| 52 |
+
MIT License
|
| 53 |
|
| 54 |
+
## 작성자
|
| 55 |
|
| 56 |
+
- richard-kim-79
|
| 57 |
+
- Email: [email protected]
|
content
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
Subproject commit 794f345c1724b059684761fc8d9f356b60eb69b5
|
package-lock.json
CHANGED
|
@@ -8,9 +8,16 @@
|
|
| 8 |
"name": "aitree_1",
|
| 9 |
"version": "0.1.0",
|
| 10 |
"dependencies": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
"next": "15.2.4",
|
| 12 |
"react": "^19.0.0",
|
| 13 |
-
"react-dom": "^19.0.0"
|
|
|
|
|
|
|
| 14 |
},
|
| 15 |
"devDependencies": {
|
| 16 |
"@eslint/eslintrc": "^3",
|
|
@@ -1119,6 +1126,21 @@
|
|
| 1119 |
"tailwindcss": "4.1.3"
|
| 1120 |
}
|
| 1121 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1122 |
"node_modules/@tybys/wasm-util": {
|
| 1123 |
"version": "0.9.0",
|
| 1124 |
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
|
|
@@ -1130,6 +1152,15 @@
|
|
| 1130 |
"tslib": "^2.4.0"
|
| 1131 |
}
|
| 1132 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1133 |
"node_modules/@types/estree": {
|
| 1134 |
"version": "1.0.7",
|
| 1135 |
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
|
@@ -1137,6 +1168,15 @@
|
|
| 1137 |
"dev": true,
|
| 1138 |
"license": "MIT"
|
| 1139 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1140 |
"node_modules/@types/json-schema": {
|
| 1141 |
"version": "7.0.15",
|
| 1142 |
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
|
@@ -1151,6 +1191,27 @@
|
|
| 1151 |
"dev": true,
|
| 1152 |
"license": "MIT"
|
| 1153 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1154 |
"node_modules/@types/node": {
|
| 1155 |
"version": "20.17.30",
|
| 1156 |
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz",
|
|
@@ -1181,6 +1242,12 @@
|
|
| 1181 |
"@types/react": "^19.0.0"
|
| 1182 |
}
|
| 1183 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1184 |
"node_modules/@typescript-eslint/eslint-plugin": {
|
| 1185 |
"version": "8.29.0",
|
| 1186 |
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.0.tgz",
|
|
@@ -1417,6 +1484,12 @@
|
|
| 1417 |
"url": "https://opencollective.com/typescript-eslint"
|
| 1418 |
}
|
| 1419 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1420 |
"node_modules/@unrs/resolver-binding-darwin-arm64": {
|
| 1421 |
"version": "1.3.3",
|
| 1422 |
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.3.3.tgz",
|
|
@@ -1914,6 +1987,16 @@
|
|
| 1914 |
"node": ">= 0.4"
|
| 1915 |
}
|
| 1916 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1917 |
"node_modules/balanced-match": {
|
| 1918 |
"version": "1.0.2",
|
| 1919 |
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
@@ -2036,6 +2119,16 @@
|
|
| 2036 |
],
|
| 2037 |
"license": "CC-BY-4.0"
|
| 2038 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2039 |
"node_modules/chalk": {
|
| 2040 |
"version": "4.1.2",
|
| 2041 |
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
|
@@ -2053,6 +2146,36 @@
|
|
| 2053 |
"url": "https://github.com/chalk/chalk?sponsor=1"
|
| 2054 |
}
|
| 2055 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2056 |
"node_modules/client-only": {
|
| 2057 |
"version": "0.0.1",
|
| 2058 |
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
|
@@ -2104,6 +2227,16 @@
|
|
| 2104 |
"simple-swizzle": "^0.2.2"
|
| 2105 |
}
|
| 2106 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2107 |
"node_modules/concat-map": {
|
| 2108 |
"version": "0.0.1",
|
| 2109 |
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
@@ -2126,6 +2259,18 @@
|
|
| 2126 |
"node": ">= 8"
|
| 2127 |
}
|
| 2128 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2129 |
"node_modules/csstype": {
|
| 2130 |
"version": "3.1.3",
|
| 2131 |
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
|
@@ -2194,11 +2339,20 @@
|
|
| 2194 |
"url": "https://github.com/sponsors/ljharb"
|
| 2195 |
}
|
| 2196 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2197 |
"node_modules/debug": {
|
| 2198 |
"version": "4.4.0",
|
| 2199 |
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
| 2200 |
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
| 2201 |
-
"dev": true,
|
| 2202 |
"license": "MIT",
|
| 2203 |
"dependencies": {
|
| 2204 |
"ms": "^2.1.3"
|
|
@@ -2212,6 +2366,19 @@
|
|
| 2212 |
}
|
| 2213 |
}
|
| 2214 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2215 |
"node_modules/deep-is": {
|
| 2216 |
"version": "0.1.4",
|
| 2217 |
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
|
@@ -2255,6 +2422,15 @@
|
|
| 2255 |
"url": "https://github.com/sponsors/ljharb"
|
| 2256 |
}
|
| 2257 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2258 |
"node_modules/detect-libc": {
|
| 2259 |
"version": "2.0.3",
|
| 2260 |
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
|
@@ -2265,6 +2441,19 @@
|
|
| 2265 |
"node": ">=8"
|
| 2266 |
}
|
| 2267 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2268 |
"node_modules/doctrine": {
|
| 2269 |
"version": "2.1.0",
|
| 2270 |
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
|
@@ -2881,6 +3070,19 @@
|
|
| 2881 |
"url": "https://opencollective.com/eslint"
|
| 2882 |
}
|
| 2883 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2884 |
"node_modules/esquery": {
|
| 2885 |
"version": "1.6.0",
|
| 2886 |
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
|
|
@@ -2927,6 +3129,24 @@
|
|
| 2927 |
"node": ">=0.10.0"
|
| 2928 |
}
|
| 2929 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2930 |
"node_modules/fast-deep-equal": {
|
| 2931 |
"version": "3.1.3",
|
| 2932 |
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
|
@@ -3249,6 +3469,43 @@
|
|
| 3249 |
"dev": true,
|
| 3250 |
"license": "MIT"
|
| 3251 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3252 |
"node_modules/has-bigints": {
|
| 3253 |
"version": "1.1.0",
|
| 3254 |
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
|
@@ -3343,6 +3600,67 @@
|
|
| 3343 |
"node": ">= 0.4"
|
| 3344 |
}
|
| 3345 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3346 |
"node_modules/ignore": {
|
| 3347 |
"version": "5.3.2",
|
| 3348 |
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
|
@@ -3547,6 +3865,15 @@
|
|
| 3547 |
"url": "https://github.com/sponsors/ljharb"
|
| 3548 |
}
|
| 3549 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3550 |
"node_modules/is-extglob": {
|
| 3551 |
"version": "2.1.1",
|
| 3552 |
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
|
@@ -3645,6 +3972,18 @@
|
|
| 3645 |
"url": "https://github.com/sponsors/ljharb"
|
| 3646 |
}
|
| 3647 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3648 |
"node_modules/is-regex": {
|
| 3649 |
"version": "1.2.1",
|
| 3650 |
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
|
@@ -3912,6 +4251,15 @@
|
|
| 3912 |
"json-buffer": "3.0.1"
|
| 3913 |
}
|
| 3914 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3915 |
"node_modules/language-subtag-registry": {
|
| 3916 |
"version": "0.3.23",
|
| 3917 |
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
|
|
@@ -4201,13 +4549,40 @@
|
|
| 4201 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 4202 |
}
|
| 4203 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4204 |
"node_modules/lodash.merge": {
|
| 4205 |
"version": "4.6.2",
|
| 4206 |
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
| 4207 |
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
| 4208 |
-
"dev": true,
|
| 4209 |
"license": "MIT"
|
| 4210 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4211 |
"node_modules/loose-envify": {
|
| 4212 |
"version": "1.4.0",
|
| 4213 |
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
@@ -4231,61 +4606,595 @@
|
|
| 4231 |
"node": ">= 0.4"
|
| 4232 |
}
|
| 4233 |
},
|
| 4234 |
-
"node_modules/
|
| 4235 |
-
"version": "
|
| 4236 |
-
"resolved": "https://registry.npmjs.org/
|
| 4237 |
-
"integrity": "sha512-
|
| 4238 |
-
"dev": true,
|
| 4239 |
"license": "MIT",
|
| 4240 |
-
"
|
| 4241 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4242 |
}
|
| 4243 |
},
|
| 4244 |
-
"node_modules/
|
| 4245 |
-
"version": "4.0
|
| 4246 |
-
"resolved": "https://registry.npmjs.org/
|
| 4247 |
-
"integrity": "sha512-
|
| 4248 |
-
"dev": true,
|
| 4249 |
"license": "MIT",
|
| 4250 |
"dependencies": {
|
| 4251 |
-
"
|
| 4252 |
-
"
|
| 4253 |
},
|
| 4254 |
-
"
|
| 4255 |
-
"
|
|
|
|
| 4256 |
}
|
| 4257 |
},
|
| 4258 |
-
"node_modules/
|
| 4259 |
-
"version": "
|
| 4260 |
-
"resolved": "https://registry.npmjs.org/
|
| 4261 |
-
"integrity": "sha512-
|
| 4262 |
-
"
|
| 4263 |
-
"license": "ISC",
|
| 4264 |
"dependencies": {
|
| 4265 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4266 |
},
|
| 4267 |
-
"
|
| 4268 |
-
"
|
|
|
|
| 4269 |
}
|
| 4270 |
},
|
| 4271 |
-
"node_modules/
|
| 4272 |
-
"version": "1.2
|
| 4273 |
-
"resolved": "https://registry.npmjs.org/
|
| 4274 |
-
"integrity": "sha512-
|
| 4275 |
-
"dev": true,
|
| 4276 |
"license": "MIT",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4277 |
"funding": {
|
| 4278 |
-
"
|
|
|
|
| 4279 |
}
|
| 4280 |
},
|
| 4281 |
-
"node_modules/
|
| 4282 |
-
"version": "
|
| 4283 |
-
"resolved": "https://registry.npmjs.org/
|
| 4284 |
-
"integrity": "sha512-
|
| 4285 |
-
"
|
| 4286 |
-
"
|
| 4287 |
-
|
| 4288 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4289 |
"version": "3.3.11",
|
| 4290 |
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
| 4291 |
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
|
@@ -4681,6 +5590,19 @@
|
|
| 4681 |
"node": "^10 || ^12 || >=14"
|
| 4682 |
}
|
| 4683 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4684 |
"node_modules/prelude-ls": {
|
| 4685 |
"version": "1.2.1",
|
| 4686 |
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
|
@@ -4703,6 +5625,16 @@
|
|
| 4703 |
"react-is": "^16.13.1"
|
| 4704 |
}
|
| 4705 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4706 |
"node_modules/punycode": {
|
| 4707 |
"version": "2.3.1",
|
| 4708 |
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
|
@@ -4806,6 +5738,70 @@
|
|
| 4806 |
"url": "https://github.com/sponsors/ljharb"
|
| 4807 |
}
|
| 4808 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4809 |
"node_modules/resolve": {
|
| 4810 |
"version": "1.22.10",
|
| 4811 |
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
|
@@ -4943,6 +5939,19 @@
|
|
| 4943 |
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
| 4944 |
"license": "MIT"
|
| 4945 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4946 |
"node_modules/semver": {
|
| 4947 |
"version": "7.7.1",
|
| 4948 |
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
|
@@ -5163,6 +6172,22 @@
|
|
| 5163 |
"node": ">=0.10.0"
|
| 5164 |
}
|
| 5165 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5166 |
"node_modules/stable-hash": {
|
| 5167 |
"version": "0.0.5",
|
| 5168 |
"resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
|
|
@@ -5291,6 +6316,20 @@
|
|
| 5291 |
"url": "https://github.com/sponsors/ljharb"
|
| 5292 |
}
|
| 5293 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5294 |
"node_modules/strip-bom": {
|
| 5295 |
"version": "3.0.0",
|
| 5296 |
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
|
@@ -5301,6 +6340,15 @@
|
|
| 5301 |
"node": ">=4"
|
| 5302 |
}
|
| 5303 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5304 |
"node_modules/strip-json-comments": {
|
| 5305 |
"version": "3.1.1",
|
| 5306 |
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
|
@@ -5367,7 +6415,6 @@
|
|
| 5367 |
"version": "4.1.3",
|
| 5368 |
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz",
|
| 5369 |
"integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==",
|
| 5370 |
-
"dev": true,
|
| 5371 |
"license": "MIT"
|
| 5372 |
},
|
| 5373 |
"node_modules/tapable": {
|
|
@@ -5438,6 +6485,26 @@
|
|
| 5438 |
"node": ">=8.0"
|
| 5439 |
}
|
| 5440 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5441 |
"node_modules/ts-api-utils": {
|
| 5442 |
"version": "2.1.0",
|
| 5443 |
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
|
@@ -5601,6 +6668,93 @@
|
|
| 5601 |
"dev": true,
|
| 5602 |
"license": "MIT"
|
| 5603 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5604 |
"node_modules/unrs-resolver": {
|
| 5605 |
"version": "1.3.3",
|
| 5606 |
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.3.3.tgz",
|
|
@@ -5638,6 +6792,40 @@
|
|
| 5638 |
"punycode": "^2.1.0"
|
| 5639 |
}
|
| 5640 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5641 |
"node_modules/which": {
|
| 5642 |
"version": "2.0.2",
|
| 5643 |
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
|
@@ -5765,6 +6953,16 @@
|
|
| 5765 |
"funding": {
|
| 5766 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 5767 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5768 |
}
|
| 5769 |
}
|
| 5770 |
}
|
|
|
|
| 8 |
"name": "aitree_1",
|
| 9 |
"version": "0.1.0",
|
| 10 |
"dependencies": {
|
| 11 |
+
"@tailwindcss/typography": "^0.5.16",
|
| 12 |
+
"@types/lodash": "^4.17.16",
|
| 13 |
+
"date-fns": "^4.1.0",
|
| 14 |
+
"gray-matter": "^4.0.3",
|
| 15 |
+
"lodash": "^4.17.21",
|
| 16 |
"next": "15.2.4",
|
| 17 |
"react": "^19.0.0",
|
| 18 |
+
"react-dom": "^19.0.0",
|
| 19 |
+
"remark": "^15.0.1",
|
| 20 |
+
"remark-html": "^16.0.1"
|
| 21 |
},
|
| 22 |
"devDependencies": {
|
| 23 |
"@eslint/eslintrc": "^3",
|
|
|
|
| 1126 |
"tailwindcss": "4.1.3"
|
| 1127 |
}
|
| 1128 |
},
|
| 1129 |
+
"node_modules/@tailwindcss/typography": {
|
| 1130 |
+
"version": "0.5.16",
|
| 1131 |
+
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
|
| 1132 |
+
"integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
|
| 1133 |
+
"license": "MIT",
|
| 1134 |
+
"dependencies": {
|
| 1135 |
+
"lodash.castarray": "^4.4.0",
|
| 1136 |
+
"lodash.isplainobject": "^4.0.6",
|
| 1137 |
+
"lodash.merge": "^4.6.2",
|
| 1138 |
+
"postcss-selector-parser": "6.0.10"
|
| 1139 |
+
},
|
| 1140 |
+
"peerDependencies": {
|
| 1141 |
+
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
|
| 1142 |
+
}
|
| 1143 |
+
},
|
| 1144 |
"node_modules/@tybys/wasm-util": {
|
| 1145 |
"version": "0.9.0",
|
| 1146 |
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
|
|
|
|
| 1152 |
"tslib": "^2.4.0"
|
| 1153 |
}
|
| 1154 |
},
|
| 1155 |
+
"node_modules/@types/debug": {
|
| 1156 |
+
"version": "4.1.12",
|
| 1157 |
+
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
| 1158 |
+
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
|
| 1159 |
+
"license": "MIT",
|
| 1160 |
+
"dependencies": {
|
| 1161 |
+
"@types/ms": "*"
|
| 1162 |
+
}
|
| 1163 |
+
},
|
| 1164 |
"node_modules/@types/estree": {
|
| 1165 |
"version": "1.0.7",
|
| 1166 |
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
|
|
|
| 1168 |
"dev": true,
|
| 1169 |
"license": "MIT"
|
| 1170 |
},
|
| 1171 |
+
"node_modules/@types/hast": {
|
| 1172 |
+
"version": "3.0.4",
|
| 1173 |
+
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
| 1174 |
+
"integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
|
| 1175 |
+
"license": "MIT",
|
| 1176 |
+
"dependencies": {
|
| 1177 |
+
"@types/unist": "*"
|
| 1178 |
+
}
|
| 1179 |
+
},
|
| 1180 |
"node_modules/@types/json-schema": {
|
| 1181 |
"version": "7.0.15",
|
| 1182 |
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
|
|
|
| 1191 |
"dev": true,
|
| 1192 |
"license": "MIT"
|
| 1193 |
},
|
| 1194 |
+
"node_modules/@types/lodash": {
|
| 1195 |
+
"version": "4.17.16",
|
| 1196 |
+
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz",
|
| 1197 |
+
"integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==",
|
| 1198 |
+
"license": "MIT"
|
| 1199 |
+
},
|
| 1200 |
+
"node_modules/@types/mdast": {
|
| 1201 |
+
"version": "4.0.4",
|
| 1202 |
+
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
|
| 1203 |
+
"integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
|
| 1204 |
+
"license": "MIT",
|
| 1205 |
+
"dependencies": {
|
| 1206 |
+
"@types/unist": "*"
|
| 1207 |
+
}
|
| 1208 |
+
},
|
| 1209 |
+
"node_modules/@types/ms": {
|
| 1210 |
+
"version": "2.1.0",
|
| 1211 |
+
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
| 1212 |
+
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
|
| 1213 |
+
"license": "MIT"
|
| 1214 |
+
},
|
| 1215 |
"node_modules/@types/node": {
|
| 1216 |
"version": "20.17.30",
|
| 1217 |
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz",
|
|
|
|
| 1242 |
"@types/react": "^19.0.0"
|
| 1243 |
}
|
| 1244 |
},
|
| 1245 |
+
"node_modules/@types/unist": {
|
| 1246 |
+
"version": "3.0.3",
|
| 1247 |
+
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
| 1248 |
+
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
|
| 1249 |
+
"license": "MIT"
|
| 1250 |
+
},
|
| 1251 |
"node_modules/@typescript-eslint/eslint-plugin": {
|
| 1252 |
"version": "8.29.0",
|
| 1253 |
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.0.tgz",
|
|
|
|
| 1484 |
"url": "https://opencollective.com/typescript-eslint"
|
| 1485 |
}
|
| 1486 |
},
|
| 1487 |
+
"node_modules/@ungap/structured-clone": {
|
| 1488 |
+
"version": "1.3.0",
|
| 1489 |
+
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
|
| 1490 |
+
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
|
| 1491 |
+
"license": "ISC"
|
| 1492 |
+
},
|
| 1493 |
"node_modules/@unrs/resolver-binding-darwin-arm64": {
|
| 1494 |
"version": "1.3.3",
|
| 1495 |
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.3.3.tgz",
|
|
|
|
| 1987 |
"node": ">= 0.4"
|
| 1988 |
}
|
| 1989 |
},
|
| 1990 |
+
"node_modules/bail": {
|
| 1991 |
+
"version": "2.0.2",
|
| 1992 |
+
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
|
| 1993 |
+
"integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
|
| 1994 |
+
"license": "MIT",
|
| 1995 |
+
"funding": {
|
| 1996 |
+
"type": "github",
|
| 1997 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 1998 |
+
}
|
| 1999 |
+
},
|
| 2000 |
"node_modules/balanced-match": {
|
| 2001 |
"version": "1.0.2",
|
| 2002 |
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
|
|
| 2119 |
],
|
| 2120 |
"license": "CC-BY-4.0"
|
| 2121 |
},
|
| 2122 |
+
"node_modules/ccount": {
|
| 2123 |
+
"version": "2.0.1",
|
| 2124 |
+
"resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
|
| 2125 |
+
"integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
|
| 2126 |
+
"license": "MIT",
|
| 2127 |
+
"funding": {
|
| 2128 |
+
"type": "github",
|
| 2129 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2130 |
+
}
|
| 2131 |
+
},
|
| 2132 |
"node_modules/chalk": {
|
| 2133 |
"version": "4.1.2",
|
| 2134 |
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
|
|
|
| 2146 |
"url": "https://github.com/chalk/chalk?sponsor=1"
|
| 2147 |
}
|
| 2148 |
},
|
| 2149 |
+
"node_modules/character-entities": {
|
| 2150 |
+
"version": "2.0.2",
|
| 2151 |
+
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
|
| 2152 |
+
"integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
|
| 2153 |
+
"license": "MIT",
|
| 2154 |
+
"funding": {
|
| 2155 |
+
"type": "github",
|
| 2156 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2157 |
+
}
|
| 2158 |
+
},
|
| 2159 |
+
"node_modules/character-entities-html4": {
|
| 2160 |
+
"version": "2.1.0",
|
| 2161 |
+
"resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
|
| 2162 |
+
"integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
|
| 2163 |
+
"license": "MIT",
|
| 2164 |
+
"funding": {
|
| 2165 |
+
"type": "github",
|
| 2166 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2167 |
+
}
|
| 2168 |
+
},
|
| 2169 |
+
"node_modules/character-entities-legacy": {
|
| 2170 |
+
"version": "3.0.0",
|
| 2171 |
+
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
|
| 2172 |
+
"integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
|
| 2173 |
+
"license": "MIT",
|
| 2174 |
+
"funding": {
|
| 2175 |
+
"type": "github",
|
| 2176 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2177 |
+
}
|
| 2178 |
+
},
|
| 2179 |
"node_modules/client-only": {
|
| 2180 |
"version": "0.0.1",
|
| 2181 |
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
|
|
|
| 2227 |
"simple-swizzle": "^0.2.2"
|
| 2228 |
}
|
| 2229 |
},
|
| 2230 |
+
"node_modules/comma-separated-tokens": {
|
| 2231 |
+
"version": "2.0.3",
|
| 2232 |
+
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
| 2233 |
+
"integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
|
| 2234 |
+
"license": "MIT",
|
| 2235 |
+
"funding": {
|
| 2236 |
+
"type": "github",
|
| 2237 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2238 |
+
}
|
| 2239 |
+
},
|
| 2240 |
"node_modules/concat-map": {
|
| 2241 |
"version": "0.0.1",
|
| 2242 |
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
|
|
| 2259 |
"node": ">= 8"
|
| 2260 |
}
|
| 2261 |
},
|
| 2262 |
+
"node_modules/cssesc": {
|
| 2263 |
+
"version": "3.0.0",
|
| 2264 |
+
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
| 2265 |
+
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
| 2266 |
+
"license": "MIT",
|
| 2267 |
+
"bin": {
|
| 2268 |
+
"cssesc": "bin/cssesc"
|
| 2269 |
+
},
|
| 2270 |
+
"engines": {
|
| 2271 |
+
"node": ">=4"
|
| 2272 |
+
}
|
| 2273 |
+
},
|
| 2274 |
"node_modules/csstype": {
|
| 2275 |
"version": "3.1.3",
|
| 2276 |
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
|
|
|
| 2339 |
"url": "https://github.com/sponsors/ljharb"
|
| 2340 |
}
|
| 2341 |
},
|
| 2342 |
+
"node_modules/date-fns": {
|
| 2343 |
+
"version": "4.1.0",
|
| 2344 |
+
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
| 2345 |
+
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
|
| 2346 |
+
"license": "MIT",
|
| 2347 |
+
"funding": {
|
| 2348 |
+
"type": "github",
|
| 2349 |
+
"url": "https://github.com/sponsors/kossnocorp"
|
| 2350 |
+
}
|
| 2351 |
+
},
|
| 2352 |
"node_modules/debug": {
|
| 2353 |
"version": "4.4.0",
|
| 2354 |
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
| 2355 |
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
|
|
|
| 2356 |
"license": "MIT",
|
| 2357 |
"dependencies": {
|
| 2358 |
"ms": "^2.1.3"
|
|
|
|
| 2366 |
}
|
| 2367 |
}
|
| 2368 |
},
|
| 2369 |
+
"node_modules/decode-named-character-reference": {
|
| 2370 |
+
"version": "1.1.0",
|
| 2371 |
+
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
|
| 2372 |
+
"integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
|
| 2373 |
+
"license": "MIT",
|
| 2374 |
+
"dependencies": {
|
| 2375 |
+
"character-entities": "^2.0.0"
|
| 2376 |
+
},
|
| 2377 |
+
"funding": {
|
| 2378 |
+
"type": "github",
|
| 2379 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2380 |
+
}
|
| 2381 |
+
},
|
| 2382 |
"node_modules/deep-is": {
|
| 2383 |
"version": "0.1.4",
|
| 2384 |
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
|
|
|
| 2422 |
"url": "https://github.com/sponsors/ljharb"
|
| 2423 |
}
|
| 2424 |
},
|
| 2425 |
+
"node_modules/dequal": {
|
| 2426 |
+
"version": "2.0.3",
|
| 2427 |
+
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
| 2428 |
+
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
| 2429 |
+
"license": "MIT",
|
| 2430 |
+
"engines": {
|
| 2431 |
+
"node": ">=6"
|
| 2432 |
+
}
|
| 2433 |
+
},
|
| 2434 |
"node_modules/detect-libc": {
|
| 2435 |
"version": "2.0.3",
|
| 2436 |
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
|
|
|
| 2441 |
"node": ">=8"
|
| 2442 |
}
|
| 2443 |
},
|
| 2444 |
+
"node_modules/devlop": {
|
| 2445 |
+
"version": "1.1.0",
|
| 2446 |
+
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
|
| 2447 |
+
"integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
|
| 2448 |
+
"license": "MIT",
|
| 2449 |
+
"dependencies": {
|
| 2450 |
+
"dequal": "^2.0.0"
|
| 2451 |
+
},
|
| 2452 |
+
"funding": {
|
| 2453 |
+
"type": "github",
|
| 2454 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 2455 |
+
}
|
| 2456 |
+
},
|
| 2457 |
"node_modules/doctrine": {
|
| 2458 |
"version": "2.1.0",
|
| 2459 |
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
|
|
|
| 3070 |
"url": "https://opencollective.com/eslint"
|
| 3071 |
}
|
| 3072 |
},
|
| 3073 |
+
"node_modules/esprima": {
|
| 3074 |
+
"version": "4.0.1",
|
| 3075 |
+
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
| 3076 |
+
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
| 3077 |
+
"license": "BSD-2-Clause",
|
| 3078 |
+
"bin": {
|
| 3079 |
+
"esparse": "bin/esparse.js",
|
| 3080 |
+
"esvalidate": "bin/esvalidate.js"
|
| 3081 |
+
},
|
| 3082 |
+
"engines": {
|
| 3083 |
+
"node": ">=4"
|
| 3084 |
+
}
|
| 3085 |
+
},
|
| 3086 |
"node_modules/esquery": {
|
| 3087 |
"version": "1.6.0",
|
| 3088 |
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
|
|
|
|
| 3129 |
"node": ">=0.10.0"
|
| 3130 |
}
|
| 3131 |
},
|
| 3132 |
+
"node_modules/extend": {
|
| 3133 |
+
"version": "3.0.2",
|
| 3134 |
+
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
| 3135 |
+
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
| 3136 |
+
"license": "MIT"
|
| 3137 |
+
},
|
| 3138 |
+
"node_modules/extend-shallow": {
|
| 3139 |
+
"version": "2.0.1",
|
| 3140 |
+
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
| 3141 |
+
"integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
|
| 3142 |
+
"license": "MIT",
|
| 3143 |
+
"dependencies": {
|
| 3144 |
+
"is-extendable": "^0.1.0"
|
| 3145 |
+
},
|
| 3146 |
+
"engines": {
|
| 3147 |
+
"node": ">=0.10.0"
|
| 3148 |
+
}
|
| 3149 |
+
},
|
| 3150 |
"node_modules/fast-deep-equal": {
|
| 3151 |
"version": "3.1.3",
|
| 3152 |
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
|
|
|
| 3469 |
"dev": true,
|
| 3470 |
"license": "MIT"
|
| 3471 |
},
|
| 3472 |
+
"node_modules/gray-matter": {
|
| 3473 |
+
"version": "4.0.3",
|
| 3474 |
+
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
|
| 3475 |
+
"integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
|
| 3476 |
+
"license": "MIT",
|
| 3477 |
+
"dependencies": {
|
| 3478 |
+
"js-yaml": "^3.13.1",
|
| 3479 |
+
"kind-of": "^6.0.2",
|
| 3480 |
+
"section-matter": "^1.0.0",
|
| 3481 |
+
"strip-bom-string": "^1.0.0"
|
| 3482 |
+
},
|
| 3483 |
+
"engines": {
|
| 3484 |
+
"node": ">=6.0"
|
| 3485 |
+
}
|
| 3486 |
+
},
|
| 3487 |
+
"node_modules/gray-matter/node_modules/argparse": {
|
| 3488 |
+
"version": "1.0.10",
|
| 3489 |
+
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
| 3490 |
+
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
| 3491 |
+
"license": "MIT",
|
| 3492 |
+
"dependencies": {
|
| 3493 |
+
"sprintf-js": "~1.0.2"
|
| 3494 |
+
}
|
| 3495 |
+
},
|
| 3496 |
+
"node_modules/gray-matter/node_modules/js-yaml": {
|
| 3497 |
+
"version": "3.14.1",
|
| 3498 |
+
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
| 3499 |
+
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
| 3500 |
+
"license": "MIT",
|
| 3501 |
+
"dependencies": {
|
| 3502 |
+
"argparse": "^1.0.7",
|
| 3503 |
+
"esprima": "^4.0.0"
|
| 3504 |
+
},
|
| 3505 |
+
"bin": {
|
| 3506 |
+
"js-yaml": "bin/js-yaml.js"
|
| 3507 |
+
}
|
| 3508 |
+
},
|
| 3509 |
"node_modules/has-bigints": {
|
| 3510 |
"version": "1.1.0",
|
| 3511 |
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
|
|
|
| 3600 |
"node": ">= 0.4"
|
| 3601 |
}
|
| 3602 |
},
|
| 3603 |
+
"node_modules/hast-util-sanitize": {
|
| 3604 |
+
"version": "5.0.2",
|
| 3605 |
+
"resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz",
|
| 3606 |
+
"integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==",
|
| 3607 |
+
"license": "MIT",
|
| 3608 |
+
"dependencies": {
|
| 3609 |
+
"@types/hast": "^3.0.0",
|
| 3610 |
+
"@ungap/structured-clone": "^1.0.0",
|
| 3611 |
+
"unist-util-position": "^5.0.0"
|
| 3612 |
+
},
|
| 3613 |
+
"funding": {
|
| 3614 |
+
"type": "opencollective",
|
| 3615 |
+
"url": "https://opencollective.com/unified"
|
| 3616 |
+
}
|
| 3617 |
+
},
|
| 3618 |
+
"node_modules/hast-util-to-html": {
|
| 3619 |
+
"version": "9.0.5",
|
| 3620 |
+
"resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
|
| 3621 |
+
"integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
|
| 3622 |
+
"license": "MIT",
|
| 3623 |
+
"dependencies": {
|
| 3624 |
+
"@types/hast": "^3.0.0",
|
| 3625 |
+
"@types/unist": "^3.0.0",
|
| 3626 |
+
"ccount": "^2.0.0",
|
| 3627 |
+
"comma-separated-tokens": "^2.0.0",
|
| 3628 |
+
"hast-util-whitespace": "^3.0.0",
|
| 3629 |
+
"html-void-elements": "^3.0.0",
|
| 3630 |
+
"mdast-util-to-hast": "^13.0.0",
|
| 3631 |
+
"property-information": "^7.0.0",
|
| 3632 |
+
"space-separated-tokens": "^2.0.0",
|
| 3633 |
+
"stringify-entities": "^4.0.0",
|
| 3634 |
+
"zwitch": "^2.0.4"
|
| 3635 |
+
},
|
| 3636 |
+
"funding": {
|
| 3637 |
+
"type": "opencollective",
|
| 3638 |
+
"url": "https://opencollective.com/unified"
|
| 3639 |
+
}
|
| 3640 |
+
},
|
| 3641 |
+
"node_modules/hast-util-whitespace": {
|
| 3642 |
+
"version": "3.0.0",
|
| 3643 |
+
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
|
| 3644 |
+
"integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
|
| 3645 |
+
"license": "MIT",
|
| 3646 |
+
"dependencies": {
|
| 3647 |
+
"@types/hast": "^3.0.0"
|
| 3648 |
+
},
|
| 3649 |
+
"funding": {
|
| 3650 |
+
"type": "opencollective",
|
| 3651 |
+
"url": "https://opencollective.com/unified"
|
| 3652 |
+
}
|
| 3653 |
+
},
|
| 3654 |
+
"node_modules/html-void-elements": {
|
| 3655 |
+
"version": "3.0.0",
|
| 3656 |
+
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
|
| 3657 |
+
"integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
|
| 3658 |
+
"license": "MIT",
|
| 3659 |
+
"funding": {
|
| 3660 |
+
"type": "github",
|
| 3661 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 3662 |
+
}
|
| 3663 |
+
},
|
| 3664 |
"node_modules/ignore": {
|
| 3665 |
"version": "5.3.2",
|
| 3666 |
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
|
|
|
| 3865 |
"url": "https://github.com/sponsors/ljharb"
|
| 3866 |
}
|
| 3867 |
},
|
| 3868 |
+
"node_modules/is-extendable": {
|
| 3869 |
+
"version": "0.1.1",
|
| 3870 |
+
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
| 3871 |
+
"integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
|
| 3872 |
+
"license": "MIT",
|
| 3873 |
+
"engines": {
|
| 3874 |
+
"node": ">=0.10.0"
|
| 3875 |
+
}
|
| 3876 |
+
},
|
| 3877 |
"node_modules/is-extglob": {
|
| 3878 |
"version": "2.1.1",
|
| 3879 |
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
|
|
|
| 3972 |
"url": "https://github.com/sponsors/ljharb"
|
| 3973 |
}
|
| 3974 |
},
|
| 3975 |
+
"node_modules/is-plain-obj": {
|
| 3976 |
+
"version": "4.1.0",
|
| 3977 |
+
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
|
| 3978 |
+
"integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
|
| 3979 |
+
"license": "MIT",
|
| 3980 |
+
"engines": {
|
| 3981 |
+
"node": ">=12"
|
| 3982 |
+
},
|
| 3983 |
+
"funding": {
|
| 3984 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 3985 |
+
}
|
| 3986 |
+
},
|
| 3987 |
"node_modules/is-regex": {
|
| 3988 |
"version": "1.2.1",
|
| 3989 |
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
|
|
|
| 4251 |
"json-buffer": "3.0.1"
|
| 4252 |
}
|
| 4253 |
},
|
| 4254 |
+
"node_modules/kind-of": {
|
| 4255 |
+
"version": "6.0.3",
|
| 4256 |
+
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
| 4257 |
+
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
| 4258 |
+
"license": "MIT",
|
| 4259 |
+
"engines": {
|
| 4260 |
+
"node": ">=0.10.0"
|
| 4261 |
+
}
|
| 4262 |
+
},
|
| 4263 |
"node_modules/language-subtag-registry": {
|
| 4264 |
"version": "0.3.23",
|
| 4265 |
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
|
|
|
|
| 4549 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 4550 |
}
|
| 4551 |
},
|
| 4552 |
+
"node_modules/lodash": {
|
| 4553 |
+
"version": "4.17.21",
|
| 4554 |
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
| 4555 |
+
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
| 4556 |
+
"license": "MIT"
|
| 4557 |
+
},
|
| 4558 |
+
"node_modules/lodash.castarray": {
|
| 4559 |
+
"version": "4.4.0",
|
| 4560 |
+
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
|
| 4561 |
+
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
|
| 4562 |
+
"license": "MIT"
|
| 4563 |
+
},
|
| 4564 |
+
"node_modules/lodash.isplainobject": {
|
| 4565 |
+
"version": "4.0.6",
|
| 4566 |
+
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
| 4567 |
+
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
| 4568 |
+
"license": "MIT"
|
| 4569 |
+
},
|
| 4570 |
"node_modules/lodash.merge": {
|
| 4571 |
"version": "4.6.2",
|
| 4572 |
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
| 4573 |
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
|
|
|
| 4574 |
"license": "MIT"
|
| 4575 |
},
|
| 4576 |
+
"node_modules/longest-streak": {
|
| 4577 |
+
"version": "3.1.0",
|
| 4578 |
+
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
|
| 4579 |
+
"integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
|
| 4580 |
+
"license": "MIT",
|
| 4581 |
+
"funding": {
|
| 4582 |
+
"type": "github",
|
| 4583 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 4584 |
+
}
|
| 4585 |
+
},
|
| 4586 |
"node_modules/loose-envify": {
|
| 4587 |
"version": "1.4.0",
|
| 4588 |
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
|
|
| 4606 |
"node": ">= 0.4"
|
| 4607 |
}
|
| 4608 |
},
|
| 4609 |
+
"node_modules/mdast-util-from-markdown": {
|
| 4610 |
+
"version": "2.0.2",
|
| 4611 |
+
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
|
| 4612 |
+
"integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
|
|
|
|
| 4613 |
"license": "MIT",
|
| 4614 |
+
"dependencies": {
|
| 4615 |
+
"@types/mdast": "^4.0.0",
|
| 4616 |
+
"@types/unist": "^3.0.0",
|
| 4617 |
+
"decode-named-character-reference": "^1.0.0",
|
| 4618 |
+
"devlop": "^1.0.0",
|
| 4619 |
+
"mdast-util-to-string": "^4.0.0",
|
| 4620 |
+
"micromark": "^4.0.0",
|
| 4621 |
+
"micromark-util-decode-numeric-character-reference": "^2.0.0",
|
| 4622 |
+
"micromark-util-decode-string": "^2.0.0",
|
| 4623 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 4624 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4625 |
+
"micromark-util-types": "^2.0.0",
|
| 4626 |
+
"unist-util-stringify-position": "^4.0.0"
|
| 4627 |
+
},
|
| 4628 |
+
"funding": {
|
| 4629 |
+
"type": "opencollective",
|
| 4630 |
+
"url": "https://opencollective.com/unified"
|
| 4631 |
}
|
| 4632 |
},
|
| 4633 |
+
"node_modules/mdast-util-phrasing": {
|
| 4634 |
+
"version": "4.1.0",
|
| 4635 |
+
"resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
|
| 4636 |
+
"integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
|
|
|
|
| 4637 |
"license": "MIT",
|
| 4638 |
"dependencies": {
|
| 4639 |
+
"@types/mdast": "^4.0.0",
|
| 4640 |
+
"unist-util-is": "^6.0.0"
|
| 4641 |
},
|
| 4642 |
+
"funding": {
|
| 4643 |
+
"type": "opencollective",
|
| 4644 |
+
"url": "https://opencollective.com/unified"
|
| 4645 |
}
|
| 4646 |
},
|
| 4647 |
+
"node_modules/mdast-util-to-hast": {
|
| 4648 |
+
"version": "13.2.0",
|
| 4649 |
+
"resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
|
| 4650 |
+
"integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
|
| 4651 |
+
"license": "MIT",
|
|
|
|
| 4652 |
"dependencies": {
|
| 4653 |
+
"@types/hast": "^3.0.0",
|
| 4654 |
+
"@types/mdast": "^4.0.0",
|
| 4655 |
+
"@ungap/structured-clone": "^1.0.0",
|
| 4656 |
+
"devlop": "^1.0.0",
|
| 4657 |
+
"micromark-util-sanitize-uri": "^2.0.0",
|
| 4658 |
+
"trim-lines": "^3.0.0",
|
| 4659 |
+
"unist-util-position": "^5.0.0",
|
| 4660 |
+
"unist-util-visit": "^5.0.0",
|
| 4661 |
+
"vfile": "^6.0.0"
|
| 4662 |
},
|
| 4663 |
+
"funding": {
|
| 4664 |
+
"type": "opencollective",
|
| 4665 |
+
"url": "https://opencollective.com/unified"
|
| 4666 |
}
|
| 4667 |
},
|
| 4668 |
+
"node_modules/mdast-util-to-markdown": {
|
| 4669 |
+
"version": "2.1.2",
|
| 4670 |
+
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
|
| 4671 |
+
"integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
|
|
|
|
| 4672 |
"license": "MIT",
|
| 4673 |
+
"dependencies": {
|
| 4674 |
+
"@types/mdast": "^4.0.0",
|
| 4675 |
+
"@types/unist": "^3.0.0",
|
| 4676 |
+
"longest-streak": "^3.0.0",
|
| 4677 |
+
"mdast-util-phrasing": "^4.0.0",
|
| 4678 |
+
"mdast-util-to-string": "^4.0.0",
|
| 4679 |
+
"micromark-util-classify-character": "^2.0.0",
|
| 4680 |
+
"micromark-util-decode-string": "^2.0.0",
|
| 4681 |
+
"unist-util-visit": "^5.0.0",
|
| 4682 |
+
"zwitch": "^2.0.0"
|
| 4683 |
+
},
|
| 4684 |
"funding": {
|
| 4685 |
+
"type": "opencollective",
|
| 4686 |
+
"url": "https://opencollective.com/unified"
|
| 4687 |
}
|
| 4688 |
},
|
| 4689 |
+
"node_modules/mdast-util-to-string": {
|
| 4690 |
+
"version": "4.0.0",
|
| 4691 |
+
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
|
| 4692 |
+
"integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
|
| 4693 |
+
"license": "MIT",
|
| 4694 |
+
"dependencies": {
|
| 4695 |
+
"@types/mdast": "^4.0.0"
|
| 4696 |
+
},
|
| 4697 |
+
"funding": {
|
| 4698 |
+
"type": "opencollective",
|
| 4699 |
+
"url": "https://opencollective.com/unified"
|
| 4700 |
+
}
|
| 4701 |
+
},
|
| 4702 |
+
"node_modules/merge2": {
|
| 4703 |
+
"version": "1.4.1",
|
| 4704 |
+
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
| 4705 |
+
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
| 4706 |
+
"dev": true,
|
| 4707 |
+
"license": "MIT",
|
| 4708 |
+
"engines": {
|
| 4709 |
+
"node": ">= 8"
|
| 4710 |
+
}
|
| 4711 |
+
},
|
| 4712 |
+
"node_modules/micromark": {
|
| 4713 |
+
"version": "4.0.2",
|
| 4714 |
+
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
|
| 4715 |
+
"integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
|
| 4716 |
+
"funding": [
|
| 4717 |
+
{
|
| 4718 |
+
"type": "GitHub Sponsors",
|
| 4719 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4720 |
+
},
|
| 4721 |
+
{
|
| 4722 |
+
"type": "OpenCollective",
|
| 4723 |
+
"url": "https://opencollective.com/unified"
|
| 4724 |
+
}
|
| 4725 |
+
],
|
| 4726 |
+
"license": "MIT",
|
| 4727 |
+
"dependencies": {
|
| 4728 |
+
"@types/debug": "^4.0.0",
|
| 4729 |
+
"debug": "^4.0.0",
|
| 4730 |
+
"decode-named-character-reference": "^1.0.0",
|
| 4731 |
+
"devlop": "^1.0.0",
|
| 4732 |
+
"micromark-core-commonmark": "^2.0.0",
|
| 4733 |
+
"micromark-factory-space": "^2.0.0",
|
| 4734 |
+
"micromark-util-character": "^2.0.0",
|
| 4735 |
+
"micromark-util-chunked": "^2.0.0",
|
| 4736 |
+
"micromark-util-combine-extensions": "^2.0.0",
|
| 4737 |
+
"micromark-util-decode-numeric-character-reference": "^2.0.0",
|
| 4738 |
+
"micromark-util-encode": "^2.0.0",
|
| 4739 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 4740 |
+
"micromark-util-resolve-all": "^2.0.0",
|
| 4741 |
+
"micromark-util-sanitize-uri": "^2.0.0",
|
| 4742 |
+
"micromark-util-subtokenize": "^2.0.0",
|
| 4743 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4744 |
+
"micromark-util-types": "^2.0.0"
|
| 4745 |
+
}
|
| 4746 |
+
},
|
| 4747 |
+
"node_modules/micromark-core-commonmark": {
|
| 4748 |
+
"version": "2.0.3",
|
| 4749 |
+
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
|
| 4750 |
+
"integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
|
| 4751 |
+
"funding": [
|
| 4752 |
+
{
|
| 4753 |
+
"type": "GitHub Sponsors",
|
| 4754 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4755 |
+
},
|
| 4756 |
+
{
|
| 4757 |
+
"type": "OpenCollective",
|
| 4758 |
+
"url": "https://opencollective.com/unified"
|
| 4759 |
+
}
|
| 4760 |
+
],
|
| 4761 |
+
"license": "MIT",
|
| 4762 |
+
"dependencies": {
|
| 4763 |
+
"decode-named-character-reference": "^1.0.0",
|
| 4764 |
+
"devlop": "^1.0.0",
|
| 4765 |
+
"micromark-factory-destination": "^2.0.0",
|
| 4766 |
+
"micromark-factory-label": "^2.0.0",
|
| 4767 |
+
"micromark-factory-space": "^2.0.0",
|
| 4768 |
+
"micromark-factory-title": "^2.0.0",
|
| 4769 |
+
"micromark-factory-whitespace": "^2.0.0",
|
| 4770 |
+
"micromark-util-character": "^2.0.0",
|
| 4771 |
+
"micromark-util-chunked": "^2.0.0",
|
| 4772 |
+
"micromark-util-classify-character": "^2.0.0",
|
| 4773 |
+
"micromark-util-html-tag-name": "^2.0.0",
|
| 4774 |
+
"micromark-util-normalize-identifier": "^2.0.0",
|
| 4775 |
+
"micromark-util-resolve-all": "^2.0.0",
|
| 4776 |
+
"micromark-util-subtokenize": "^2.0.0",
|
| 4777 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4778 |
+
"micromark-util-types": "^2.0.0"
|
| 4779 |
+
}
|
| 4780 |
+
},
|
| 4781 |
+
"node_modules/micromark-factory-destination": {
|
| 4782 |
+
"version": "2.0.1",
|
| 4783 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
|
| 4784 |
+
"integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
|
| 4785 |
+
"funding": [
|
| 4786 |
+
{
|
| 4787 |
+
"type": "GitHub Sponsors",
|
| 4788 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4789 |
+
},
|
| 4790 |
+
{
|
| 4791 |
+
"type": "OpenCollective",
|
| 4792 |
+
"url": "https://opencollective.com/unified"
|
| 4793 |
+
}
|
| 4794 |
+
],
|
| 4795 |
+
"license": "MIT",
|
| 4796 |
+
"dependencies": {
|
| 4797 |
+
"micromark-util-character": "^2.0.0",
|
| 4798 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4799 |
+
"micromark-util-types": "^2.0.0"
|
| 4800 |
+
}
|
| 4801 |
+
},
|
| 4802 |
+
"node_modules/micromark-factory-label": {
|
| 4803 |
+
"version": "2.0.1",
|
| 4804 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
|
| 4805 |
+
"integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
|
| 4806 |
+
"funding": [
|
| 4807 |
+
{
|
| 4808 |
+
"type": "GitHub Sponsors",
|
| 4809 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4810 |
+
},
|
| 4811 |
+
{
|
| 4812 |
+
"type": "OpenCollective",
|
| 4813 |
+
"url": "https://opencollective.com/unified"
|
| 4814 |
+
}
|
| 4815 |
+
],
|
| 4816 |
+
"license": "MIT",
|
| 4817 |
+
"dependencies": {
|
| 4818 |
+
"devlop": "^1.0.0",
|
| 4819 |
+
"micromark-util-character": "^2.0.0",
|
| 4820 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4821 |
+
"micromark-util-types": "^2.0.0"
|
| 4822 |
+
}
|
| 4823 |
+
},
|
| 4824 |
+
"node_modules/micromark-factory-space": {
|
| 4825 |
+
"version": "2.0.1",
|
| 4826 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
|
| 4827 |
+
"integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
|
| 4828 |
+
"funding": [
|
| 4829 |
+
{
|
| 4830 |
+
"type": "GitHub Sponsors",
|
| 4831 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4832 |
+
},
|
| 4833 |
+
{
|
| 4834 |
+
"type": "OpenCollective",
|
| 4835 |
+
"url": "https://opencollective.com/unified"
|
| 4836 |
+
}
|
| 4837 |
+
],
|
| 4838 |
+
"license": "MIT",
|
| 4839 |
+
"dependencies": {
|
| 4840 |
+
"micromark-util-character": "^2.0.0",
|
| 4841 |
+
"micromark-util-types": "^2.0.0"
|
| 4842 |
+
}
|
| 4843 |
+
},
|
| 4844 |
+
"node_modules/micromark-factory-title": {
|
| 4845 |
+
"version": "2.0.1",
|
| 4846 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
|
| 4847 |
+
"integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
|
| 4848 |
+
"funding": [
|
| 4849 |
+
{
|
| 4850 |
+
"type": "GitHub Sponsors",
|
| 4851 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4852 |
+
},
|
| 4853 |
+
{
|
| 4854 |
+
"type": "OpenCollective",
|
| 4855 |
+
"url": "https://opencollective.com/unified"
|
| 4856 |
+
}
|
| 4857 |
+
],
|
| 4858 |
+
"license": "MIT",
|
| 4859 |
+
"dependencies": {
|
| 4860 |
+
"micromark-factory-space": "^2.0.0",
|
| 4861 |
+
"micromark-util-character": "^2.0.0",
|
| 4862 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4863 |
+
"micromark-util-types": "^2.0.0"
|
| 4864 |
+
}
|
| 4865 |
+
},
|
| 4866 |
+
"node_modules/micromark-factory-whitespace": {
|
| 4867 |
+
"version": "2.0.1",
|
| 4868 |
+
"resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
|
| 4869 |
+
"integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
|
| 4870 |
+
"funding": [
|
| 4871 |
+
{
|
| 4872 |
+
"type": "GitHub Sponsors",
|
| 4873 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4874 |
+
},
|
| 4875 |
+
{
|
| 4876 |
+
"type": "OpenCollective",
|
| 4877 |
+
"url": "https://opencollective.com/unified"
|
| 4878 |
+
}
|
| 4879 |
+
],
|
| 4880 |
+
"license": "MIT",
|
| 4881 |
+
"dependencies": {
|
| 4882 |
+
"micromark-factory-space": "^2.0.0",
|
| 4883 |
+
"micromark-util-character": "^2.0.0",
|
| 4884 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4885 |
+
"micromark-util-types": "^2.0.0"
|
| 4886 |
+
}
|
| 4887 |
+
},
|
| 4888 |
+
"node_modules/micromark-util-character": {
|
| 4889 |
+
"version": "2.1.1",
|
| 4890 |
+
"resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
|
| 4891 |
+
"integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
|
| 4892 |
+
"funding": [
|
| 4893 |
+
{
|
| 4894 |
+
"type": "GitHub Sponsors",
|
| 4895 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4896 |
+
},
|
| 4897 |
+
{
|
| 4898 |
+
"type": "OpenCollective",
|
| 4899 |
+
"url": "https://opencollective.com/unified"
|
| 4900 |
+
}
|
| 4901 |
+
],
|
| 4902 |
+
"license": "MIT",
|
| 4903 |
+
"dependencies": {
|
| 4904 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4905 |
+
"micromark-util-types": "^2.0.0"
|
| 4906 |
+
}
|
| 4907 |
+
},
|
| 4908 |
+
"node_modules/micromark-util-chunked": {
|
| 4909 |
+
"version": "2.0.1",
|
| 4910 |
+
"resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
|
| 4911 |
+
"integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
|
| 4912 |
+
"funding": [
|
| 4913 |
+
{
|
| 4914 |
+
"type": "GitHub Sponsors",
|
| 4915 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4916 |
+
},
|
| 4917 |
+
{
|
| 4918 |
+
"type": "OpenCollective",
|
| 4919 |
+
"url": "https://opencollective.com/unified"
|
| 4920 |
+
}
|
| 4921 |
+
],
|
| 4922 |
+
"license": "MIT",
|
| 4923 |
+
"dependencies": {
|
| 4924 |
+
"micromark-util-symbol": "^2.0.0"
|
| 4925 |
+
}
|
| 4926 |
+
},
|
| 4927 |
+
"node_modules/micromark-util-classify-character": {
|
| 4928 |
+
"version": "2.0.1",
|
| 4929 |
+
"resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
|
| 4930 |
+
"integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
|
| 4931 |
+
"funding": [
|
| 4932 |
+
{
|
| 4933 |
+
"type": "GitHub Sponsors",
|
| 4934 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4935 |
+
},
|
| 4936 |
+
{
|
| 4937 |
+
"type": "OpenCollective",
|
| 4938 |
+
"url": "https://opencollective.com/unified"
|
| 4939 |
+
}
|
| 4940 |
+
],
|
| 4941 |
+
"license": "MIT",
|
| 4942 |
+
"dependencies": {
|
| 4943 |
+
"micromark-util-character": "^2.0.0",
|
| 4944 |
+
"micromark-util-symbol": "^2.0.0",
|
| 4945 |
+
"micromark-util-types": "^2.0.0"
|
| 4946 |
+
}
|
| 4947 |
+
},
|
| 4948 |
+
"node_modules/micromark-util-combine-extensions": {
|
| 4949 |
+
"version": "2.0.1",
|
| 4950 |
+
"resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
|
| 4951 |
+
"integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
|
| 4952 |
+
"funding": [
|
| 4953 |
+
{
|
| 4954 |
+
"type": "GitHub Sponsors",
|
| 4955 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4956 |
+
},
|
| 4957 |
+
{
|
| 4958 |
+
"type": "OpenCollective",
|
| 4959 |
+
"url": "https://opencollective.com/unified"
|
| 4960 |
+
}
|
| 4961 |
+
],
|
| 4962 |
+
"license": "MIT",
|
| 4963 |
+
"dependencies": {
|
| 4964 |
+
"micromark-util-chunked": "^2.0.0",
|
| 4965 |
+
"micromark-util-types": "^2.0.0"
|
| 4966 |
+
}
|
| 4967 |
+
},
|
| 4968 |
+
"node_modules/micromark-util-decode-numeric-character-reference": {
|
| 4969 |
+
"version": "2.0.2",
|
| 4970 |
+
"resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
|
| 4971 |
+
"integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
|
| 4972 |
+
"funding": [
|
| 4973 |
+
{
|
| 4974 |
+
"type": "GitHub Sponsors",
|
| 4975 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4976 |
+
},
|
| 4977 |
+
{
|
| 4978 |
+
"type": "OpenCollective",
|
| 4979 |
+
"url": "https://opencollective.com/unified"
|
| 4980 |
+
}
|
| 4981 |
+
],
|
| 4982 |
+
"license": "MIT",
|
| 4983 |
+
"dependencies": {
|
| 4984 |
+
"micromark-util-symbol": "^2.0.0"
|
| 4985 |
+
}
|
| 4986 |
+
},
|
| 4987 |
+
"node_modules/micromark-util-decode-string": {
|
| 4988 |
+
"version": "2.0.1",
|
| 4989 |
+
"resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
|
| 4990 |
+
"integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
|
| 4991 |
+
"funding": [
|
| 4992 |
+
{
|
| 4993 |
+
"type": "GitHub Sponsors",
|
| 4994 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 4995 |
+
},
|
| 4996 |
+
{
|
| 4997 |
+
"type": "OpenCollective",
|
| 4998 |
+
"url": "https://opencollective.com/unified"
|
| 4999 |
+
}
|
| 5000 |
+
],
|
| 5001 |
+
"license": "MIT",
|
| 5002 |
+
"dependencies": {
|
| 5003 |
+
"decode-named-character-reference": "^1.0.0",
|
| 5004 |
+
"micromark-util-character": "^2.0.0",
|
| 5005 |
+
"micromark-util-decode-numeric-character-reference": "^2.0.0",
|
| 5006 |
+
"micromark-util-symbol": "^2.0.0"
|
| 5007 |
+
}
|
| 5008 |
+
},
|
| 5009 |
+
"node_modules/micromark-util-encode": {
|
| 5010 |
+
"version": "2.0.1",
|
| 5011 |
+
"resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
|
| 5012 |
+
"integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
|
| 5013 |
+
"funding": [
|
| 5014 |
+
{
|
| 5015 |
+
"type": "GitHub Sponsors",
|
| 5016 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5017 |
+
},
|
| 5018 |
+
{
|
| 5019 |
+
"type": "OpenCollective",
|
| 5020 |
+
"url": "https://opencollective.com/unified"
|
| 5021 |
+
}
|
| 5022 |
+
],
|
| 5023 |
+
"license": "MIT"
|
| 5024 |
+
},
|
| 5025 |
+
"node_modules/micromark-util-html-tag-name": {
|
| 5026 |
+
"version": "2.0.1",
|
| 5027 |
+
"resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
|
| 5028 |
+
"integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
|
| 5029 |
+
"funding": [
|
| 5030 |
+
{
|
| 5031 |
+
"type": "GitHub Sponsors",
|
| 5032 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5033 |
+
},
|
| 5034 |
+
{
|
| 5035 |
+
"type": "OpenCollective",
|
| 5036 |
+
"url": "https://opencollective.com/unified"
|
| 5037 |
+
}
|
| 5038 |
+
],
|
| 5039 |
+
"license": "MIT"
|
| 5040 |
+
},
|
| 5041 |
+
"node_modules/micromark-util-normalize-identifier": {
|
| 5042 |
+
"version": "2.0.1",
|
| 5043 |
+
"resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
|
| 5044 |
+
"integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
|
| 5045 |
+
"funding": [
|
| 5046 |
+
{
|
| 5047 |
+
"type": "GitHub Sponsors",
|
| 5048 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5049 |
+
},
|
| 5050 |
+
{
|
| 5051 |
+
"type": "OpenCollective",
|
| 5052 |
+
"url": "https://opencollective.com/unified"
|
| 5053 |
+
}
|
| 5054 |
+
],
|
| 5055 |
+
"license": "MIT",
|
| 5056 |
+
"dependencies": {
|
| 5057 |
+
"micromark-util-symbol": "^2.0.0"
|
| 5058 |
+
}
|
| 5059 |
+
},
|
| 5060 |
+
"node_modules/micromark-util-resolve-all": {
|
| 5061 |
+
"version": "2.0.1",
|
| 5062 |
+
"resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
|
| 5063 |
+
"integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
|
| 5064 |
+
"funding": [
|
| 5065 |
+
{
|
| 5066 |
+
"type": "GitHub Sponsors",
|
| 5067 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5068 |
+
},
|
| 5069 |
+
{
|
| 5070 |
+
"type": "OpenCollective",
|
| 5071 |
+
"url": "https://opencollective.com/unified"
|
| 5072 |
+
}
|
| 5073 |
+
],
|
| 5074 |
+
"license": "MIT",
|
| 5075 |
+
"dependencies": {
|
| 5076 |
+
"micromark-util-types": "^2.0.0"
|
| 5077 |
+
}
|
| 5078 |
+
},
|
| 5079 |
+
"node_modules/micromark-util-sanitize-uri": {
|
| 5080 |
+
"version": "2.0.1",
|
| 5081 |
+
"resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
|
| 5082 |
+
"integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
|
| 5083 |
+
"funding": [
|
| 5084 |
+
{
|
| 5085 |
+
"type": "GitHub Sponsors",
|
| 5086 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5087 |
+
},
|
| 5088 |
+
{
|
| 5089 |
+
"type": "OpenCollective",
|
| 5090 |
+
"url": "https://opencollective.com/unified"
|
| 5091 |
+
}
|
| 5092 |
+
],
|
| 5093 |
+
"license": "MIT",
|
| 5094 |
+
"dependencies": {
|
| 5095 |
+
"micromark-util-character": "^2.0.0",
|
| 5096 |
+
"micromark-util-encode": "^2.0.0",
|
| 5097 |
+
"micromark-util-symbol": "^2.0.0"
|
| 5098 |
+
}
|
| 5099 |
+
},
|
| 5100 |
+
"node_modules/micromark-util-subtokenize": {
|
| 5101 |
+
"version": "2.1.0",
|
| 5102 |
+
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
|
| 5103 |
+
"integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
|
| 5104 |
+
"funding": [
|
| 5105 |
+
{
|
| 5106 |
+
"type": "GitHub Sponsors",
|
| 5107 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5108 |
+
},
|
| 5109 |
+
{
|
| 5110 |
+
"type": "OpenCollective",
|
| 5111 |
+
"url": "https://opencollective.com/unified"
|
| 5112 |
+
}
|
| 5113 |
+
],
|
| 5114 |
+
"license": "MIT",
|
| 5115 |
+
"dependencies": {
|
| 5116 |
+
"devlop": "^1.0.0",
|
| 5117 |
+
"micromark-util-chunked": "^2.0.0",
|
| 5118 |
+
"micromark-util-symbol": "^2.0.0",
|
| 5119 |
+
"micromark-util-types": "^2.0.0"
|
| 5120 |
+
}
|
| 5121 |
+
},
|
| 5122 |
+
"node_modules/micromark-util-symbol": {
|
| 5123 |
+
"version": "2.0.1",
|
| 5124 |
+
"resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
|
| 5125 |
+
"integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
|
| 5126 |
+
"funding": [
|
| 5127 |
+
{
|
| 5128 |
+
"type": "GitHub Sponsors",
|
| 5129 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5130 |
+
},
|
| 5131 |
+
{
|
| 5132 |
+
"type": "OpenCollective",
|
| 5133 |
+
"url": "https://opencollective.com/unified"
|
| 5134 |
+
}
|
| 5135 |
+
],
|
| 5136 |
+
"license": "MIT"
|
| 5137 |
+
},
|
| 5138 |
+
"node_modules/micromark-util-types": {
|
| 5139 |
+
"version": "2.0.2",
|
| 5140 |
+
"resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
|
| 5141 |
+
"integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
|
| 5142 |
+
"funding": [
|
| 5143 |
+
{
|
| 5144 |
+
"type": "GitHub Sponsors",
|
| 5145 |
+
"url": "https://github.com/sponsors/unifiedjs"
|
| 5146 |
+
},
|
| 5147 |
+
{
|
| 5148 |
+
"type": "OpenCollective",
|
| 5149 |
+
"url": "https://opencollective.com/unified"
|
| 5150 |
+
}
|
| 5151 |
+
],
|
| 5152 |
+
"license": "MIT"
|
| 5153 |
+
},
|
| 5154 |
+
"node_modules/micromatch": {
|
| 5155 |
+
"version": "4.0.8",
|
| 5156 |
+
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
| 5157 |
+
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
| 5158 |
+
"dev": true,
|
| 5159 |
+
"license": "MIT",
|
| 5160 |
+
"dependencies": {
|
| 5161 |
+
"braces": "^3.0.3",
|
| 5162 |
+
"picomatch": "^2.3.1"
|
| 5163 |
+
},
|
| 5164 |
+
"engines": {
|
| 5165 |
+
"node": ">=8.6"
|
| 5166 |
+
}
|
| 5167 |
+
},
|
| 5168 |
+
"node_modules/minimatch": {
|
| 5169 |
+
"version": "3.1.2",
|
| 5170 |
+
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
| 5171 |
+
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
| 5172 |
+
"dev": true,
|
| 5173 |
+
"license": "ISC",
|
| 5174 |
+
"dependencies": {
|
| 5175 |
+
"brace-expansion": "^1.1.7"
|
| 5176 |
+
},
|
| 5177 |
+
"engines": {
|
| 5178 |
+
"node": "*"
|
| 5179 |
+
}
|
| 5180 |
+
},
|
| 5181 |
+
"node_modules/minimist": {
|
| 5182 |
+
"version": "1.2.8",
|
| 5183 |
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
| 5184 |
+
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
| 5185 |
+
"dev": true,
|
| 5186 |
+
"license": "MIT",
|
| 5187 |
+
"funding": {
|
| 5188 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 5189 |
+
}
|
| 5190 |
+
},
|
| 5191 |
+
"node_modules/ms": {
|
| 5192 |
+
"version": "2.1.3",
|
| 5193 |
+
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
| 5194 |
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
| 5195 |
+
"license": "MIT"
|
| 5196 |
+
},
|
| 5197 |
+
"node_modules/nanoid": {
|
| 5198 |
"version": "3.3.11",
|
| 5199 |
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
| 5200 |
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
|
|
|
| 5590 |
"node": "^10 || ^12 || >=14"
|
| 5591 |
}
|
| 5592 |
},
|
| 5593 |
+
"node_modules/postcss-selector-parser": {
|
| 5594 |
+
"version": "6.0.10",
|
| 5595 |
+
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
|
| 5596 |
+
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
|
| 5597 |
+
"license": "MIT",
|
| 5598 |
+
"dependencies": {
|
| 5599 |
+
"cssesc": "^3.0.0",
|
| 5600 |
+
"util-deprecate": "^1.0.2"
|
| 5601 |
+
},
|
| 5602 |
+
"engines": {
|
| 5603 |
+
"node": ">=4"
|
| 5604 |
+
}
|
| 5605 |
+
},
|
| 5606 |
"node_modules/prelude-ls": {
|
| 5607 |
"version": "1.2.1",
|
| 5608 |
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
|
|
|
| 5625 |
"react-is": "^16.13.1"
|
| 5626 |
}
|
| 5627 |
},
|
| 5628 |
+
"node_modules/property-information": {
|
| 5629 |
+
"version": "7.0.0",
|
| 5630 |
+
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz",
|
| 5631 |
+
"integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==",
|
| 5632 |
+
"license": "MIT",
|
| 5633 |
+
"funding": {
|
| 5634 |
+
"type": "github",
|
| 5635 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 5636 |
+
}
|
| 5637 |
+
},
|
| 5638 |
"node_modules/punycode": {
|
| 5639 |
"version": "2.3.1",
|
| 5640 |
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
|
|
|
| 5738 |
"url": "https://github.com/sponsors/ljharb"
|
| 5739 |
}
|
| 5740 |
},
|
| 5741 |
+
"node_modules/remark": {
|
| 5742 |
+
"version": "15.0.1",
|
| 5743 |
+
"resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz",
|
| 5744 |
+
"integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==",
|
| 5745 |
+
"license": "MIT",
|
| 5746 |
+
"dependencies": {
|
| 5747 |
+
"@types/mdast": "^4.0.0",
|
| 5748 |
+
"remark-parse": "^11.0.0",
|
| 5749 |
+
"remark-stringify": "^11.0.0",
|
| 5750 |
+
"unified": "^11.0.0"
|
| 5751 |
+
},
|
| 5752 |
+
"funding": {
|
| 5753 |
+
"type": "opencollective",
|
| 5754 |
+
"url": "https://opencollective.com/unified"
|
| 5755 |
+
}
|
| 5756 |
+
},
|
| 5757 |
+
"node_modules/remark-html": {
|
| 5758 |
+
"version": "16.0.1",
|
| 5759 |
+
"resolved": "https://registry.npmjs.org/remark-html/-/remark-html-16.0.1.tgz",
|
| 5760 |
+
"integrity": "sha512-B9JqA5i0qZe0Nsf49q3OXyGvyXuZFDzAP2iOFLEumymuYJITVpiH1IgsTEwTpdptDmZlMDMWeDmSawdaJIGCXQ==",
|
| 5761 |
+
"license": "MIT",
|
| 5762 |
+
"dependencies": {
|
| 5763 |
+
"@types/mdast": "^4.0.0",
|
| 5764 |
+
"hast-util-sanitize": "^5.0.0",
|
| 5765 |
+
"hast-util-to-html": "^9.0.0",
|
| 5766 |
+
"mdast-util-to-hast": "^13.0.0",
|
| 5767 |
+
"unified": "^11.0.0"
|
| 5768 |
+
},
|
| 5769 |
+
"funding": {
|
| 5770 |
+
"type": "opencollective",
|
| 5771 |
+
"url": "https://opencollective.com/unified"
|
| 5772 |
+
}
|
| 5773 |
+
},
|
| 5774 |
+
"node_modules/remark-parse": {
|
| 5775 |
+
"version": "11.0.0",
|
| 5776 |
+
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
|
| 5777 |
+
"integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
|
| 5778 |
+
"license": "MIT",
|
| 5779 |
+
"dependencies": {
|
| 5780 |
+
"@types/mdast": "^4.0.0",
|
| 5781 |
+
"mdast-util-from-markdown": "^2.0.0",
|
| 5782 |
+
"micromark-util-types": "^2.0.0",
|
| 5783 |
+
"unified": "^11.0.0"
|
| 5784 |
+
},
|
| 5785 |
+
"funding": {
|
| 5786 |
+
"type": "opencollective",
|
| 5787 |
+
"url": "https://opencollective.com/unified"
|
| 5788 |
+
}
|
| 5789 |
+
},
|
| 5790 |
+
"node_modules/remark-stringify": {
|
| 5791 |
+
"version": "11.0.0",
|
| 5792 |
+
"resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
|
| 5793 |
+
"integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
|
| 5794 |
+
"license": "MIT",
|
| 5795 |
+
"dependencies": {
|
| 5796 |
+
"@types/mdast": "^4.0.0",
|
| 5797 |
+
"mdast-util-to-markdown": "^2.0.0",
|
| 5798 |
+
"unified": "^11.0.0"
|
| 5799 |
+
},
|
| 5800 |
+
"funding": {
|
| 5801 |
+
"type": "opencollective",
|
| 5802 |
+
"url": "https://opencollective.com/unified"
|
| 5803 |
+
}
|
| 5804 |
+
},
|
| 5805 |
"node_modules/resolve": {
|
| 5806 |
"version": "1.22.10",
|
| 5807 |
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
|
|
|
| 5939 |
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
|
| 5940 |
"license": "MIT"
|
| 5941 |
},
|
| 5942 |
+
"node_modules/section-matter": {
|
| 5943 |
+
"version": "1.0.0",
|
| 5944 |
+
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
| 5945 |
+
"integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
|
| 5946 |
+
"license": "MIT",
|
| 5947 |
+
"dependencies": {
|
| 5948 |
+
"extend-shallow": "^2.0.1",
|
| 5949 |
+
"kind-of": "^6.0.0"
|
| 5950 |
+
},
|
| 5951 |
+
"engines": {
|
| 5952 |
+
"node": ">=4"
|
| 5953 |
+
}
|
| 5954 |
+
},
|
| 5955 |
"node_modules/semver": {
|
| 5956 |
"version": "7.7.1",
|
| 5957 |
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
|
|
|
| 6172 |
"node": ">=0.10.0"
|
| 6173 |
}
|
| 6174 |
},
|
| 6175 |
+
"node_modules/space-separated-tokens": {
|
| 6176 |
+
"version": "2.0.2",
|
| 6177 |
+
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
|
| 6178 |
+
"integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
|
| 6179 |
+
"license": "MIT",
|
| 6180 |
+
"funding": {
|
| 6181 |
+
"type": "github",
|
| 6182 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 6183 |
+
}
|
| 6184 |
+
},
|
| 6185 |
+
"node_modules/sprintf-js": {
|
| 6186 |
+
"version": "1.0.3",
|
| 6187 |
+
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
| 6188 |
+
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
| 6189 |
+
"license": "BSD-3-Clause"
|
| 6190 |
+
},
|
| 6191 |
"node_modules/stable-hash": {
|
| 6192 |
"version": "0.0.5",
|
| 6193 |
"resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
|
|
|
|
| 6316 |
"url": "https://github.com/sponsors/ljharb"
|
| 6317 |
}
|
| 6318 |
},
|
| 6319 |
+
"node_modules/stringify-entities": {
|
| 6320 |
+
"version": "4.0.4",
|
| 6321 |
+
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
|
| 6322 |
+
"integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
|
| 6323 |
+
"license": "MIT",
|
| 6324 |
+
"dependencies": {
|
| 6325 |
+
"character-entities-html4": "^2.0.0",
|
| 6326 |
+
"character-entities-legacy": "^3.0.0"
|
| 6327 |
+
},
|
| 6328 |
+
"funding": {
|
| 6329 |
+
"type": "github",
|
| 6330 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 6331 |
+
}
|
| 6332 |
+
},
|
| 6333 |
"node_modules/strip-bom": {
|
| 6334 |
"version": "3.0.0",
|
| 6335 |
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
|
|
|
| 6340 |
"node": ">=4"
|
| 6341 |
}
|
| 6342 |
},
|
| 6343 |
+
"node_modules/strip-bom-string": {
|
| 6344 |
+
"version": "1.0.0",
|
| 6345 |
+
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
|
| 6346 |
+
"integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
|
| 6347 |
+
"license": "MIT",
|
| 6348 |
+
"engines": {
|
| 6349 |
+
"node": ">=0.10.0"
|
| 6350 |
+
}
|
| 6351 |
+
},
|
| 6352 |
"node_modules/strip-json-comments": {
|
| 6353 |
"version": "3.1.1",
|
| 6354 |
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
|
|
|
| 6415 |
"version": "4.1.3",
|
| 6416 |
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz",
|
| 6417 |
"integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==",
|
|
|
|
| 6418 |
"license": "MIT"
|
| 6419 |
},
|
| 6420 |
"node_modules/tapable": {
|
|
|
|
| 6485 |
"node": ">=8.0"
|
| 6486 |
}
|
| 6487 |
},
|
| 6488 |
+
"node_modules/trim-lines": {
|
| 6489 |
+
"version": "3.0.1",
|
| 6490 |
+
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
|
| 6491 |
+
"integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
|
| 6492 |
+
"license": "MIT",
|
| 6493 |
+
"funding": {
|
| 6494 |
+
"type": "github",
|
| 6495 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 6496 |
+
}
|
| 6497 |
+
},
|
| 6498 |
+
"node_modules/trough": {
|
| 6499 |
+
"version": "2.2.0",
|
| 6500 |
+
"resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
|
| 6501 |
+
"integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
|
| 6502 |
+
"license": "MIT",
|
| 6503 |
+
"funding": {
|
| 6504 |
+
"type": "github",
|
| 6505 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 6506 |
+
}
|
| 6507 |
+
},
|
| 6508 |
"node_modules/ts-api-utils": {
|
| 6509 |
"version": "2.1.0",
|
| 6510 |
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
|
|
|
| 6668 |
"dev": true,
|
| 6669 |
"license": "MIT"
|
| 6670 |
},
|
| 6671 |
+
"node_modules/unified": {
|
| 6672 |
+
"version": "11.0.5",
|
| 6673 |
+
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
|
| 6674 |
+
"integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
|
| 6675 |
+
"license": "MIT",
|
| 6676 |
+
"dependencies": {
|
| 6677 |
+
"@types/unist": "^3.0.0",
|
| 6678 |
+
"bail": "^2.0.0",
|
| 6679 |
+
"devlop": "^1.0.0",
|
| 6680 |
+
"extend": "^3.0.0",
|
| 6681 |
+
"is-plain-obj": "^4.0.0",
|
| 6682 |
+
"trough": "^2.0.0",
|
| 6683 |
+
"vfile": "^6.0.0"
|
| 6684 |
+
},
|
| 6685 |
+
"funding": {
|
| 6686 |
+
"type": "opencollective",
|
| 6687 |
+
"url": "https://opencollective.com/unified"
|
| 6688 |
+
}
|
| 6689 |
+
},
|
| 6690 |
+
"node_modules/unist-util-is": {
|
| 6691 |
+
"version": "6.0.0",
|
| 6692 |
+
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
|
| 6693 |
+
"integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
|
| 6694 |
+
"license": "MIT",
|
| 6695 |
+
"dependencies": {
|
| 6696 |
+
"@types/unist": "^3.0.0"
|
| 6697 |
+
},
|
| 6698 |
+
"funding": {
|
| 6699 |
+
"type": "opencollective",
|
| 6700 |
+
"url": "https://opencollective.com/unified"
|
| 6701 |
+
}
|
| 6702 |
+
},
|
| 6703 |
+
"node_modules/unist-util-position": {
|
| 6704 |
+
"version": "5.0.0",
|
| 6705 |
+
"resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
|
| 6706 |
+
"integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
|
| 6707 |
+
"license": "MIT",
|
| 6708 |
+
"dependencies": {
|
| 6709 |
+
"@types/unist": "^3.0.0"
|
| 6710 |
+
},
|
| 6711 |
+
"funding": {
|
| 6712 |
+
"type": "opencollective",
|
| 6713 |
+
"url": "https://opencollective.com/unified"
|
| 6714 |
+
}
|
| 6715 |
+
},
|
| 6716 |
+
"node_modules/unist-util-stringify-position": {
|
| 6717 |
+
"version": "4.0.0",
|
| 6718 |
+
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
|
| 6719 |
+
"integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
|
| 6720 |
+
"license": "MIT",
|
| 6721 |
+
"dependencies": {
|
| 6722 |
+
"@types/unist": "^3.0.0"
|
| 6723 |
+
},
|
| 6724 |
+
"funding": {
|
| 6725 |
+
"type": "opencollective",
|
| 6726 |
+
"url": "https://opencollective.com/unified"
|
| 6727 |
+
}
|
| 6728 |
+
},
|
| 6729 |
+
"node_modules/unist-util-visit": {
|
| 6730 |
+
"version": "5.0.0",
|
| 6731 |
+
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
|
| 6732 |
+
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
|
| 6733 |
+
"license": "MIT",
|
| 6734 |
+
"dependencies": {
|
| 6735 |
+
"@types/unist": "^3.0.0",
|
| 6736 |
+
"unist-util-is": "^6.0.0",
|
| 6737 |
+
"unist-util-visit-parents": "^6.0.0"
|
| 6738 |
+
},
|
| 6739 |
+
"funding": {
|
| 6740 |
+
"type": "opencollective",
|
| 6741 |
+
"url": "https://opencollective.com/unified"
|
| 6742 |
+
}
|
| 6743 |
+
},
|
| 6744 |
+
"node_modules/unist-util-visit-parents": {
|
| 6745 |
+
"version": "6.0.1",
|
| 6746 |
+
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
|
| 6747 |
+
"integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
|
| 6748 |
+
"license": "MIT",
|
| 6749 |
+
"dependencies": {
|
| 6750 |
+
"@types/unist": "^3.0.0",
|
| 6751 |
+
"unist-util-is": "^6.0.0"
|
| 6752 |
+
},
|
| 6753 |
+
"funding": {
|
| 6754 |
+
"type": "opencollective",
|
| 6755 |
+
"url": "https://opencollective.com/unified"
|
| 6756 |
+
}
|
| 6757 |
+
},
|
| 6758 |
"node_modules/unrs-resolver": {
|
| 6759 |
"version": "1.3.3",
|
| 6760 |
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.3.3.tgz",
|
|
|
|
| 6792 |
"punycode": "^2.1.0"
|
| 6793 |
}
|
| 6794 |
},
|
| 6795 |
+
"node_modules/util-deprecate": {
|
| 6796 |
+
"version": "1.0.2",
|
| 6797 |
+
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
| 6798 |
+
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
| 6799 |
+
"license": "MIT"
|
| 6800 |
+
},
|
| 6801 |
+
"node_modules/vfile": {
|
| 6802 |
+
"version": "6.0.3",
|
| 6803 |
+
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
|
| 6804 |
+
"integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
|
| 6805 |
+
"license": "MIT",
|
| 6806 |
+
"dependencies": {
|
| 6807 |
+
"@types/unist": "^3.0.0",
|
| 6808 |
+
"vfile-message": "^4.0.0"
|
| 6809 |
+
},
|
| 6810 |
+
"funding": {
|
| 6811 |
+
"type": "opencollective",
|
| 6812 |
+
"url": "https://opencollective.com/unified"
|
| 6813 |
+
}
|
| 6814 |
+
},
|
| 6815 |
+
"node_modules/vfile-message": {
|
| 6816 |
+
"version": "4.0.2",
|
| 6817 |
+
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
|
| 6818 |
+
"integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
|
| 6819 |
+
"license": "MIT",
|
| 6820 |
+
"dependencies": {
|
| 6821 |
+
"@types/unist": "^3.0.0",
|
| 6822 |
+
"unist-util-stringify-position": "^4.0.0"
|
| 6823 |
+
},
|
| 6824 |
+
"funding": {
|
| 6825 |
+
"type": "opencollective",
|
| 6826 |
+
"url": "https://opencollective.com/unified"
|
| 6827 |
+
}
|
| 6828 |
+
},
|
| 6829 |
"node_modules/which": {
|
| 6830 |
"version": "2.0.2",
|
| 6831 |
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
|
|
|
| 6953 |
"funding": {
|
| 6954 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 6955 |
}
|
| 6956 |
+
},
|
| 6957 |
+
"node_modules/zwitch": {
|
| 6958 |
+
"version": "2.0.4",
|
| 6959 |
+
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
|
| 6960 |
+
"integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
|
| 6961 |
+
"license": "MIT",
|
| 6962 |
+
"funding": {
|
| 6963 |
+
"type": "github",
|
| 6964 |
+
"url": "https://github.com/sponsors/wooorm"
|
| 6965 |
+
}
|
| 6966 |
}
|
| 6967 |
}
|
| 6968 |
}
|
package.json
CHANGED
|
@@ -9,19 +9,26 @@
|
|
| 9 |
"lint": "next lint"
|
| 10 |
},
|
| 11 |
"dependencies": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
"react": "^19.0.0",
|
| 13 |
"react-dom": "^19.0.0",
|
| 14 |
-
"
|
|
|
|
| 15 |
},
|
| 16 |
"devDependencies": {
|
| 17 |
-
"
|
|
|
|
| 18 |
"@types/node": "^20",
|
| 19 |
"@types/react": "^19",
|
| 20 |
"@types/react-dom": "^19",
|
| 21 |
-
"@tailwindcss/postcss": "^4",
|
| 22 |
-
"tailwindcss": "^4",
|
| 23 |
"eslint": "^9",
|
| 24 |
"eslint-config-next": "15.2.4",
|
| 25 |
-
"
|
|
|
|
| 26 |
}
|
| 27 |
}
|
|
|
|
| 9 |
"lint": "next lint"
|
| 10 |
},
|
| 11 |
"dependencies": {
|
| 12 |
+
"@tailwindcss/typography": "^0.5.16",
|
| 13 |
+
"@types/lodash": "^4.17.16",
|
| 14 |
+
"date-fns": "^4.1.0",
|
| 15 |
+
"gray-matter": "^4.0.3",
|
| 16 |
+
"lodash": "^4.17.21",
|
| 17 |
+
"next": "15.2.4",
|
| 18 |
"react": "^19.0.0",
|
| 19 |
"react-dom": "^19.0.0",
|
| 20 |
+
"remark": "^15.0.1",
|
| 21 |
+
"remark-html": "^16.0.1"
|
| 22 |
},
|
| 23 |
"devDependencies": {
|
| 24 |
+
"@eslint/eslintrc": "^3",
|
| 25 |
+
"@tailwindcss/postcss": "^4",
|
| 26 |
"@types/node": "^20",
|
| 27 |
"@types/react": "^19",
|
| 28 |
"@types/react-dom": "^19",
|
|
|
|
|
|
|
| 29 |
"eslint": "^9",
|
| 30 |
"eslint-config-next": "15.2.4",
|
| 31 |
+
"tailwindcss": "^4",
|
| 32 |
+
"typescript": "^5"
|
| 33 |
}
|
| 34 |
}
|
src/app/api/content/route.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { NextResponse } from 'next/server';
|
| 2 |
+
import { getAllPosts, getPostById, getPostsByTag, getPostsByCategory } from '@/lib/markdown';
|
| 3 |
+
|
| 4 |
+
export async function GET(request: Request) {
|
| 5 |
+
const { searchParams } = new URL(request.url);
|
| 6 |
+
const id = searchParams.get('id');
|
| 7 |
+
const tag = searchParams.get('tag');
|
| 8 |
+
const category = searchParams.get('category');
|
| 9 |
+
|
| 10 |
+
try {
|
| 11 |
+
if (id) {
|
| 12 |
+
const post = await getPostById(id);
|
| 13 |
+
if (!post) {
|
| 14 |
+
return NextResponse.json({ error: 'Post not found' }, { status: 404 });
|
| 15 |
+
}
|
| 16 |
+
return NextResponse.json(post);
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
if (tag) {
|
| 20 |
+
const posts = await getPostsByTag(tag);
|
| 21 |
+
return NextResponse.json(posts);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
if (category) {
|
| 25 |
+
const posts = await getPostsByCategory(category);
|
| 26 |
+
return NextResponse.json(posts);
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
const posts = await getAllPosts();
|
| 30 |
+
return NextResponse.json(posts);
|
| 31 |
+
} catch (error) {
|
| 32 |
+
console.error('API Error:', error);
|
| 33 |
+
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
|
| 34 |
+
}
|
| 35 |
+
}
|
src/app/api/git/route.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { NextResponse } from 'next/server';
|
| 2 |
+
import { exec } from 'node:child_process';
|
| 3 |
+
import { promisify } from 'node:util';
|
| 4 |
+
import path from 'node:path';
|
| 5 |
+
import fs from 'node:fs/promises';
|
| 6 |
+
|
| 7 |
+
const execAsync = promisify(exec);
|
| 8 |
+
const contentDir = path.join(process.cwd(), 'content');
|
| 9 |
+
|
| 10 |
+
export async function GET(request: Request) {
|
| 11 |
+
const { searchParams } = new URL(request.url);
|
| 12 |
+
const action = searchParams.get('action');
|
| 13 |
+
|
| 14 |
+
try {
|
| 15 |
+
switch (action) {
|
| 16 |
+
case 'history':
|
| 17 |
+
const { stdout: historyOutput } = await execAsync(
|
| 18 |
+
'git log --pretty=format:"%H|%an|%ad|%s" --name-status',
|
| 19 |
+
{ cwd: contentDir }
|
| 20 |
+
);
|
| 21 |
+
|
| 22 |
+
const commits = parseGitHistory(historyOutput);
|
| 23 |
+
return NextResponse.json({ commits });
|
| 24 |
+
|
| 25 |
+
case 'diff': {
|
| 26 |
+
const hash1 = searchParams.get('hash1');
|
| 27 |
+
const hash2 = searchParams.get('hash2');
|
| 28 |
+
const filePath = searchParams.get('file') || '.';
|
| 29 |
+
|
| 30 |
+
if (!hash1 || !hash2) {
|
| 31 |
+
return NextResponse.json(
|
| 32 |
+
{ error: '커밋 해시가 필요합니다.' },
|
| 33 |
+
{ status: 400 }
|
| 34 |
+
);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
const { stdout: diffOutput } = await execAsync(
|
| 38 |
+
`git diff ${hash1} ${hash2} -- ${filePath}`,
|
| 39 |
+
{ cwd: contentDir }
|
| 40 |
+
);
|
| 41 |
+
|
| 42 |
+
return NextResponse.json({ diff: diffOutput });
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
default:
|
| 46 |
+
return NextResponse.json(
|
| 47 |
+
{ error: '잘못된 작업입니다.' },
|
| 48 |
+
{ status: 400 }
|
| 49 |
+
);
|
| 50 |
+
}
|
| 51 |
+
} catch (error) {
|
| 52 |
+
console.error('Git API 에러:', error);
|
| 53 |
+
return NextResponse.json(
|
| 54 |
+
{ error: 'Git 작업 중 오류가 발생했습니다.' },
|
| 55 |
+
{ status: 500 }
|
| 56 |
+
);
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
export async function POST(request: Request) {
|
| 61 |
+
try {
|
| 62 |
+
const { action, commitHash, message } = await request.json();
|
| 63 |
+
|
| 64 |
+
switch (action) {
|
| 65 |
+
case 'rollback':
|
| 66 |
+
if (!commitHash) {
|
| 67 |
+
return NextResponse.json(
|
| 68 |
+
{ error: '커밋 해시가 필요합니다.' },
|
| 69 |
+
{ status: 400 }
|
| 70 |
+
);
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
// 백업 생성
|
| 74 |
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
| 75 |
+
const backupDir = path.join(process.cwd(), 'backups', `backup-${timestamp}`);
|
| 76 |
+
await fs.mkdir(backupDir, { recursive: true });
|
| 77 |
+
await execAsync(`git archive HEAD -o "${backupDir}/content.zip"`, { cwd: contentDir });
|
| 78 |
+
|
| 79 |
+
// 롤백 실행
|
| 80 |
+
await execAsync(`git checkout ${commitHash}`, { cwd: contentDir });
|
| 81 |
+
return NextResponse.json({ success: true, backupDir });
|
| 82 |
+
|
| 83 |
+
case 'commit':
|
| 84 |
+
if (!message) {
|
| 85 |
+
return NextResponse.json(
|
| 86 |
+
{ error: '커밋 메시지가 필요합니다.' },
|
| 87 |
+
{ status: 400 }
|
| 88 |
+
);
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
await execAsync('git add .', { cwd: contentDir });
|
| 92 |
+
const { stdout } = await execAsync(`git commit -m "${message}"`, { cwd: contentDir });
|
| 93 |
+
return NextResponse.json({ success: true, message: stdout });
|
| 94 |
+
|
| 95 |
+
default:
|
| 96 |
+
return NextResponse.json(
|
| 97 |
+
{ error: '잘못된 작업입니다.' },
|
| 98 |
+
{ status: 400 }
|
| 99 |
+
);
|
| 100 |
+
}
|
| 101 |
+
} catch (error) {
|
| 102 |
+
console.error('Git API 에러:', error);
|
| 103 |
+
return NextResponse.json(
|
| 104 |
+
{ error: 'Git 작업 중 오류가 발생했습니다.' },
|
| 105 |
+
{ status: 500 }
|
| 106 |
+
);
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
function parseGitHistory(output: string) {
|
| 111 |
+
const commits = [];
|
| 112 |
+
const commitChunks = output.split('\n\n');
|
| 113 |
+
|
| 114 |
+
for (const chunk of commitChunks) {
|
| 115 |
+
if (!chunk.trim()) continue;
|
| 116 |
+
|
| 117 |
+
const [headerLine, ...changes] = chunk.split('\n');
|
| 118 |
+
const [hash, author, date, message] = headerLine.split('|');
|
| 119 |
+
|
| 120 |
+
const changesList = {
|
| 121 |
+
added: [] as string[],
|
| 122 |
+
modified: [] as string[],
|
| 123 |
+
deleted: [] as string[],
|
| 124 |
+
};
|
| 125 |
+
|
| 126 |
+
changes.forEach(change => {
|
| 127 |
+
if (!change.trim()) return;
|
| 128 |
+
const [status, file] = change.split('\t');
|
| 129 |
+
if (status === 'A') changesList.added.push(file);
|
| 130 |
+
else if (status === 'M') changesList.modified.push(file);
|
| 131 |
+
else if (status === 'D') changesList.deleted.push(file);
|
| 132 |
+
});
|
| 133 |
+
|
| 134 |
+
commits.push({
|
| 135 |
+
hash,
|
| 136 |
+
author,
|
| 137 |
+
date,
|
| 138 |
+
message,
|
| 139 |
+
changes: changesList,
|
| 140 |
+
});
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
return commits;
|
| 144 |
+
}
|
src/app/api/search/route.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { NextResponse } from 'next/server';
|
| 2 |
+
import { getAllPosts } from '@/lib/markdown';
|
| 3 |
+
|
| 4 |
+
export async function GET(request: Request) {
|
| 5 |
+
const { searchParams } = new URL(request.url);
|
| 6 |
+
const query = searchParams.get('q') || '';
|
| 7 |
+
const tags = searchParams.get('tags')?.split(',').filter(Boolean) || [];
|
| 8 |
+
const category = searchParams.get('category') || '';
|
| 9 |
+
|
| 10 |
+
const posts = await getAllPosts();
|
| 11 |
+
|
| 12 |
+
const filteredPosts = posts.filter(post => {
|
| 13 |
+
const matchesQuery = query
|
| 14 |
+
? post.title.toLowerCase().includes(query.toLowerCase()) ||
|
| 15 |
+
post.content.toLowerCase().includes(query.toLowerCase())
|
| 16 |
+
: true;
|
| 17 |
+
|
| 18 |
+
const matchesTags = tags.length > 0
|
| 19 |
+
? tags.every(tag => post.tags.includes(tag))
|
| 20 |
+
: true;
|
| 21 |
+
|
| 22 |
+
const matchesCategory = category
|
| 23 |
+
? post.category === category
|
| 24 |
+
: true;
|
| 25 |
+
|
| 26 |
+
return matchesQuery && matchesTags && matchesCategory;
|
| 27 |
+
});
|
| 28 |
+
|
| 29 |
+
return NextResponse.json({
|
| 30 |
+
posts: filteredPosts.map(post => ({
|
| 31 |
+
id: post.id,
|
| 32 |
+
title: post.title,
|
| 33 |
+
date: post.date,
|
| 34 |
+
author: post.author,
|
| 35 |
+
tags: post.tags,
|
| 36 |
+
category: post.category,
|
| 37 |
+
excerpt: post.content.substring(0, 200) + '...'
|
| 38 |
+
}))
|
| 39 |
+
});
|
| 40 |
+
}
|
src/app/categories/[category]/page.tsx
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { getPostsByCategory } from '@/lib/markdown';
|
| 2 |
+
import Link from 'next/link';
|
| 3 |
+
import { notFound } from 'next/navigation';
|
| 4 |
+
|
| 5 |
+
interface CategoryPageProps {
|
| 6 |
+
params: Promise<{
|
| 7 |
+
category: string;
|
| 8 |
+
}>;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
export default async function CategoryPage({ params }: CategoryPageProps) {
|
| 12 |
+
const resolvedParams = await params;
|
| 13 |
+
const { category } = resolvedParams;
|
| 14 |
+
const posts = await getPostsByCategory(category);
|
| 15 |
+
|
| 16 |
+
if (posts.length === 0) {
|
| 17 |
+
notFound();
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
return (
|
| 21 |
+
<main className="min-h-screen p-8">
|
| 22 |
+
<h1 className="text-4xl font-bold mb-8">
|
| 23 |
+
카테고리: {category}
|
| 24 |
+
</h1>
|
| 25 |
+
|
| 26 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
| 27 |
+
{posts.map(post => (
|
| 28 |
+
<article key={post.id} className="border rounded-lg p-6 hover:shadow-lg transition-shadow">
|
| 29 |
+
<h2 className="text-2xl font-semibold mb-2">
|
| 30 |
+
<Link href={`/posts/${post.id}`} className="hover:text-blue-600">
|
| 31 |
+
{post.title}
|
| 32 |
+
</Link>
|
| 33 |
+
</h2>
|
| 34 |
+
|
| 35 |
+
<div className="text-gray-600 mb-4">
|
| 36 |
+
<time>{new Date(post.date).toLocaleDateString()}</time>
|
| 37 |
+
<span className="mx-2">•</span>
|
| 38 |
+
<span>{post.author}</span>
|
| 39 |
+
</div>
|
| 40 |
+
|
| 41 |
+
{post.tags.length > 0 && (
|
| 42 |
+
<div className="flex flex-wrap gap-2 mb-4">
|
| 43 |
+
{post.tags.map(tag => (
|
| 44 |
+
<Link
|
| 45 |
+
key={tag}
|
| 46 |
+
href={`/tags/${tag}`}
|
| 47 |
+
className="bg-gray-100 px-2 py-1 rounded text-sm hover:bg-gray-200"
|
| 48 |
+
>
|
| 49 |
+
#{tag}
|
| 50 |
+
</Link>
|
| 51 |
+
))}
|
| 52 |
+
</div>
|
| 53 |
+
)}
|
| 54 |
+
|
| 55 |
+
{post.category && (
|
| 56 |
+
<Link
|
| 57 |
+
href={`/categories/${post.category}`}
|
| 58 |
+
className={`inline-block px-3 py-1 rounded-full text-sm ${
|
| 59 |
+
post.category === category
|
| 60 |
+
? 'bg-blue-100 text-blue-800'
|
| 61 |
+
: 'bg-gray-100 hover:bg-gray-200'
|
| 62 |
+
}`}
|
| 63 |
+
>
|
| 64 |
+
{post.category}
|
| 65 |
+
</Link>
|
| 66 |
+
)}
|
| 67 |
+
</article>
|
| 68 |
+
))}
|
| 69 |
+
</div>
|
| 70 |
+
|
| 71 |
+
<div className="mt-8">
|
| 72 |
+
<Link
|
| 73 |
+
href="/"
|
| 74 |
+
className="text-blue-600 hover:underline"
|
| 75 |
+
>
|
| 76 |
+
← 목록으로 돌아가기
|
| 77 |
+
</Link>
|
| 78 |
+
</div>
|
| 79 |
+
</main>
|
| 80 |
+
);
|
| 81 |
+
}
|
src/app/page.tsx
CHANGED
|
@@ -1,103 +1,79 @@
|
|
| 1 |
-
import
|
|
|
|
|
|
|
| 2 |
|
| 3 |
-
export default function
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
priority
|
| 14 |
-
/>
|
| 15 |
-
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
|
| 16 |
-
<li className="mb-2 tracking-[-.01em]">
|
| 17 |
-
Get started by editing{" "}
|
| 18 |
-
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
|
| 19 |
-
src/app/page.tsx
|
| 20 |
-
</code>
|
| 21 |
-
.
|
| 22 |
-
</li>
|
| 23 |
-
<li className="tracking-[-.01em]">
|
| 24 |
-
Save and see your changes instantly.
|
| 25 |
-
</li>
|
| 26 |
-
</ol>
|
| 27 |
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
>
|
| 91 |
-
<Image
|
| 92 |
-
aria-hidden
|
| 93 |
-
src="/globe.svg"
|
| 94 |
-
alt="Globe icon"
|
| 95 |
-
width={16}
|
| 96 |
-
height={16}
|
| 97 |
-
/>
|
| 98 |
-
Go to nextjs.org →
|
| 99 |
-
</a>
|
| 100 |
-
</footer>
|
| 101 |
-
</div>
|
| 102 |
);
|
| 103 |
}
|
|
|
|
| 1 |
+
import { getAllPosts, getAllTags, getAllCategories } from '@/lib/markdown';
|
| 2 |
+
import Search from '@/components/Search';
|
| 3 |
+
import Link from 'next/link';
|
| 4 |
|
| 5 |
+
export default async function HomePage() {
|
| 6 |
+
const [posts, tags, categories] = await Promise.all([
|
| 7 |
+
getAllPosts(),
|
| 8 |
+
getAllTags(),
|
| 9 |
+
getAllCategories()
|
| 10 |
+
]);
|
| 11 |
+
|
| 12 |
+
const recentPosts = posts.sort((a, b) =>
|
| 13 |
+
new Date(b.date).getTime() - new Date(a.date).getTime()
|
| 14 |
+
).slice(0, 6);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
+
return (
|
| 17 |
+
<main className="min-h-screen p-8">
|
| 18 |
+
<div className="max-w-6xl mx-auto">
|
| 19 |
+
<h1 className="text-4xl font-bold mb-8 text-center">AI Tree 문서 포털</h1>
|
| 20 |
+
|
| 21 |
+
<Search />
|
| 22 |
+
|
| 23 |
+
<section className="mt-12">
|
| 24 |
+
<h2 className="text-2xl font-semibold mb-6">최신 게시물</h2>
|
| 25 |
+
|
| 26 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
| 27 |
+
{recentPosts.map(post => (
|
| 28 |
+
<article key={post.id} className="border rounded-lg p-6 hover:shadow-lg transition-shadow">
|
| 29 |
+
<h3 className="text-xl font-semibold mb-2">
|
| 30 |
+
<Link href={`/posts/${post.id}`} className="hover:text-blue-600">
|
| 31 |
+
{post.title}
|
| 32 |
+
</Link>
|
| 33 |
+
</h3>
|
| 34 |
+
|
| 35 |
+
<div className="text-gray-600 mb-4">
|
| 36 |
+
<time>{new Date(post.date).toLocaleDateString()}</time>
|
| 37 |
+
<span className="mx-2">•</span>
|
| 38 |
+
<span>{post.author}</span>
|
| 39 |
+
</div>
|
| 40 |
+
|
| 41 |
+
{post.tags.length > 0 && (
|
| 42 |
+
<div className="flex flex-wrap gap-2 mb-4">
|
| 43 |
+
{post.tags.map(tag => (
|
| 44 |
+
<Link
|
| 45 |
+
key={tag}
|
| 46 |
+
href={`/tags/${tag}`}
|
| 47 |
+
className="bg-gray-100 px-2 py-1 rounded text-sm hover:bg-gray-200"
|
| 48 |
+
>
|
| 49 |
+
#{tag}
|
| 50 |
+
</Link>
|
| 51 |
+
))}
|
| 52 |
+
</div>
|
| 53 |
+
)}
|
| 54 |
+
|
| 55 |
+
{post.category && (
|
| 56 |
+
<Link
|
| 57 |
+
href={`/categories/${post.category}`}
|
| 58 |
+
className="inline-block bg-blue-100 px-3 py-1 rounded-full text-sm text-blue-800 hover:bg-blue-200"
|
| 59 |
+
>
|
| 60 |
+
{post.category}
|
| 61 |
+
</Link>
|
| 62 |
+
)}
|
| 63 |
+
</article>
|
| 64 |
+
))}
|
| 65 |
+
</div>
|
| 66 |
+
|
| 67 |
+
<div className="text-center mt-8">
|
| 68 |
+
<Link
|
| 69 |
+
href="/search"
|
| 70 |
+
className="inline-block bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-colors"
|
| 71 |
+
>
|
| 72 |
+
모든 게시물 보기
|
| 73 |
+
</Link>
|
| 74 |
+
</div>
|
| 75 |
+
</section>
|
| 76 |
+
</div>
|
| 77 |
+
</main>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
);
|
| 79 |
}
|
src/app/posts/[...slug]/page.tsx
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { getPostById } from '@/lib/markdown';
|
| 2 |
+
import Link from 'next/link';
|
| 3 |
+
import { notFound } from 'next/navigation';
|
| 4 |
+
import JsonLd from '@/components/JsonLd';
|
| 5 |
+
import { BlogPostingJsonLd } from '@/types/jsonld';
|
| 6 |
+
|
| 7 |
+
interface PostPageProps {
|
| 8 |
+
params: Promise<{
|
| 9 |
+
slug: string[];
|
| 10 |
+
}>;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export default async function PostPage({ params }: PostPageProps) {
|
| 14 |
+
const resolvedParams = await params;
|
| 15 |
+
const id = resolvedParams.slug.join('/');
|
| 16 |
+
const post = await getPostById(id);
|
| 17 |
+
|
| 18 |
+
if (!post) {
|
| 19 |
+
notFound();
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
const jsonLd: BlogPostingJsonLd = {
|
| 23 |
+
'@context': 'https://schema.org',
|
| 24 |
+
'@type': 'BlogPosting',
|
| 25 |
+
'@id': `https://example.com/posts/${id}`,
|
| 26 |
+
headline: post.title,
|
| 27 |
+
datePublished: post.date,
|
| 28 |
+
author: {
|
| 29 |
+
'@type': 'Person',
|
| 30 |
+
name: post.author
|
| 31 |
+
},
|
| 32 |
+
keywords: post.tags,
|
| 33 |
+
articleSection: post.category,
|
| 34 |
+
text: post.content,
|
| 35 |
+
url: `https://example.com/posts/${id}`
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
return (
|
| 39 |
+
<>
|
| 40 |
+
<JsonLd data={jsonLd} />
|
| 41 |
+
<article className="max-w-4xl mx-auto p-8">
|
| 42 |
+
<header className="mb-8">
|
| 43 |
+
<h1 className="text-4xl font-bold mb-4">{post.title}</h1>
|
| 44 |
+
|
| 45 |
+
<div className="flex items-center gap-4 text-gray-600 mb-4">
|
| 46 |
+
<time>{new Date(post.date).toLocaleDateString()}</time>
|
| 47 |
+
<span>•</span>
|
| 48 |
+
<span>{post.author}</span>
|
| 49 |
+
</div>
|
| 50 |
+
|
| 51 |
+
{post.tags.length > 0 && (
|
| 52 |
+
<div className="flex flex-wrap gap-2 mb-4">
|
| 53 |
+
{post.tags.map(tag => (
|
| 54 |
+
<Link
|
| 55 |
+
key={tag}
|
| 56 |
+
href={`/tags/${tag}`}
|
| 57 |
+
className="bg-gray-100 px-2 py-1 rounded text-sm hover:bg-gray-200"
|
| 58 |
+
>
|
| 59 |
+
#{tag}
|
| 60 |
+
</Link>
|
| 61 |
+
))}
|
| 62 |
+
</div>
|
| 63 |
+
)}
|
| 64 |
+
|
| 65 |
+
{post.category && (
|
| 66 |
+
<Link
|
| 67 |
+
href={`/categories/${post.category}`}
|
| 68 |
+
className="inline-block bg-blue-100 px-3 py-1 rounded-full text-sm text-blue-800 hover:bg-blue-200"
|
| 69 |
+
>
|
| 70 |
+
{post.category}
|
| 71 |
+
</Link>
|
| 72 |
+
)}
|
| 73 |
+
</header>
|
| 74 |
+
|
| 75 |
+
<div
|
| 76 |
+
className="prose prose-lg max-w-none dark:prose-invert"
|
| 77 |
+
dangerouslySetInnerHTML={{ __html: post.content }}
|
| 78 |
+
/>
|
| 79 |
+
|
| 80 |
+
<div className="mt-8 pt-8 border-t">
|
| 81 |
+
<Link
|
| 82 |
+
href="/"
|
| 83 |
+
className="text-blue-600 hover:underline"
|
| 84 |
+
>
|
| 85 |
+
← 목록으로 돌아가기
|
| 86 |
+
</Link>
|
| 87 |
+
</div>
|
| 88 |
+
</article>
|
| 89 |
+
</>
|
| 90 |
+
);
|
| 91 |
+
}
|
src/app/search/page.tsx
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { getAllPosts } from '@/lib/markdown';
|
| 2 |
+
import Search from '@/components/Search';
|
| 3 |
+
import Link from 'next/link';
|
| 4 |
+
|
| 5 |
+
interface SearchPageProps {
|
| 6 |
+
searchParams: {
|
| 7 |
+
q?: string;
|
| 8 |
+
tags?: string;
|
| 9 |
+
category?: string;
|
| 10 |
+
};
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export default async function SearchPage({ searchParams }: SearchPageProps) {
|
| 14 |
+
const { q = '', tags = '', category = '' } = searchParams;
|
| 15 |
+
const selectedTags = tags ? tags.split(',') : [];
|
| 16 |
+
|
| 17 |
+
const allPosts = await getAllPosts();
|
| 18 |
+
|
| 19 |
+
const filteredPosts = allPosts.filter(post => {
|
| 20 |
+
const matchesQuery = q
|
| 21 |
+
? post.title.toLowerCase().includes(q.toLowerCase()) ||
|
| 22 |
+
post.content.toLowerCase().includes(q.toLowerCase())
|
| 23 |
+
: true;
|
| 24 |
+
|
| 25 |
+
const matchesTags = selectedTags.length > 0
|
| 26 |
+
? selectedTags.every(tag => post.tags.includes(tag))
|
| 27 |
+
: true;
|
| 28 |
+
|
| 29 |
+
const matchesCategory = category
|
| 30 |
+
? post.category === category
|
| 31 |
+
: true;
|
| 32 |
+
|
| 33 |
+
return matchesQuery && matchesTags && matchesCategory;
|
| 34 |
+
});
|
| 35 |
+
|
| 36 |
+
return (
|
| 37 |
+
<main className="min-h-screen p-8">
|
| 38 |
+
<h1 className="text-4xl font-bold mb-8">검색 결과</h1>
|
| 39 |
+
|
| 40 |
+
<Search
|
| 41 |
+
initialQuery={q}
|
| 42 |
+
initialTags={selectedTags}
|
| 43 |
+
initialCategory={category}
|
| 44 |
+
/>
|
| 45 |
+
|
| 46 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
| 47 |
+
{filteredPosts.map(post => (
|
| 48 |
+
<article key={post.id} className="border rounded-lg p-6 hover:shadow-lg transition-shadow">
|
| 49 |
+
<h2 className="text-2xl font-semibold mb-2">
|
| 50 |
+
<Link href={`/posts/${post.id}`} className="hover:text-blue-600">
|
| 51 |
+
{post.title}
|
| 52 |
+
</Link>
|
| 53 |
+
</h2>
|
| 54 |
+
|
| 55 |
+
<div className="text-gray-600 mb-4">
|
| 56 |
+
<time>{new Date(post.date).toLocaleDateString()}</time>
|
| 57 |
+
<span className="mx-2">•</span>
|
| 58 |
+
<span>{post.author}</span>
|
| 59 |
+
</div>
|
| 60 |
+
|
| 61 |
+
{post.tags.length > 0 && (
|
| 62 |
+
<div className="flex flex-wrap gap-2 mb-4">
|
| 63 |
+
{post.tags.map(tag => (
|
| 64 |
+
<Link
|
| 65 |
+
key={tag}
|
| 66 |
+
href={`/tags/${tag}`}
|
| 67 |
+
className="bg-gray-100 px-2 py-1 rounded text-sm hover:bg-gray-200"
|
| 68 |
+
>
|
| 69 |
+
#{tag}
|
| 70 |
+
</Link>
|
| 71 |
+
))}
|
| 72 |
+
</div>
|
| 73 |
+
)}
|
| 74 |
+
|
| 75 |
+
{post.category && (
|
| 76 |
+
<Link
|
| 77 |
+
href={`/categories/${post.category}`}
|
| 78 |
+
className="inline-block bg-blue-100 px-3 py-1 rounded-full text-sm text-blue-800 hover:bg-blue-200"
|
| 79 |
+
>
|
| 80 |
+
{post.category}
|
| 81 |
+
</Link>
|
| 82 |
+
)}
|
| 83 |
+
</article>
|
| 84 |
+
))}
|
| 85 |
+
</div>
|
| 86 |
+
|
| 87 |
+
{filteredPosts.length === 0 && (
|
| 88 |
+
<div className="text-center text-gray-600 dark:text-gray-400 mt-8">
|
| 89 |
+
검색 결과가 없습니다.
|
| 90 |
+
</div>
|
| 91 |
+
)}
|
| 92 |
+
</main>
|
| 93 |
+
);
|
| 94 |
+
}
|
src/app/tags/[tag]/page.tsx
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { getPostsByTag } from '@/lib/markdown';
|
| 2 |
+
import Link from 'next/link';
|
| 3 |
+
import { notFound } from 'next/navigation';
|
| 4 |
+
|
| 5 |
+
interface TagPageProps {
|
| 6 |
+
params: Promise<{
|
| 7 |
+
tag: string;
|
| 8 |
+
}>;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
export default async function TagPage({ params }: TagPageProps) {
|
| 12 |
+
const resolvedParams = await params;
|
| 13 |
+
const { tag } = resolvedParams;
|
| 14 |
+
const posts = await getPostsByTag(tag);
|
| 15 |
+
|
| 16 |
+
if (posts.length === 0) {
|
| 17 |
+
notFound();
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
return (
|
| 21 |
+
<main className="min-h-screen p-8">
|
| 22 |
+
<h1 className="text-4xl font-bold mb-8">
|
| 23 |
+
태그: #{tag}
|
| 24 |
+
</h1>
|
| 25 |
+
|
| 26 |
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
| 27 |
+
{posts.map(post => (
|
| 28 |
+
<article key={post.id} className="border rounded-lg p-6 hover:shadow-lg transition-shadow">
|
| 29 |
+
<h2 className="text-2xl font-semibold mb-2">
|
| 30 |
+
<Link href={`/posts/${post.id}`} className="hover:text-blue-600">
|
| 31 |
+
{post.title}
|
| 32 |
+
</Link>
|
| 33 |
+
</h2>
|
| 34 |
+
|
| 35 |
+
<div className="text-gray-600 mb-4">
|
| 36 |
+
<time>{new Date(post.date).toLocaleDateString()}</time>
|
| 37 |
+
<span className="mx-2">•</span>
|
| 38 |
+
<span>{post.author}</span>
|
| 39 |
+
</div>
|
| 40 |
+
|
| 41 |
+
{post.tags.length > 0 && (
|
| 42 |
+
<div className="flex flex-wrap gap-2 mb-4">
|
| 43 |
+
{post.tags.map(t => (
|
| 44 |
+
<Link
|
| 45 |
+
key={t}
|
| 46 |
+
href={`/tags/${t}`}
|
| 47 |
+
className={`px-2 py-1 rounded text-sm ${
|
| 48 |
+
t === tag
|
| 49 |
+
? 'bg-blue-100 text-blue-800'
|
| 50 |
+
: 'bg-gray-100 hover:bg-gray-200'
|
| 51 |
+
}`}
|
| 52 |
+
>
|
| 53 |
+
#{t}
|
| 54 |
+
</Link>
|
| 55 |
+
))}
|
| 56 |
+
</div>
|
| 57 |
+
)}
|
| 58 |
+
|
| 59 |
+
{post.category && (
|
| 60 |
+
<Link
|
| 61 |
+
href={`/categories/${post.category}`}
|
| 62 |
+
className="inline-block bg-blue-100 px-3 py-1 rounded-full text-sm text-blue-800 hover:bg-blue-200"
|
| 63 |
+
>
|
| 64 |
+
{post.category}
|
| 65 |
+
</Link>
|
| 66 |
+
)}
|
| 67 |
+
</article>
|
| 68 |
+
))}
|
| 69 |
+
</div>
|
| 70 |
+
|
| 71 |
+
<div className="mt-8">
|
| 72 |
+
<Link
|
| 73 |
+
href="/"
|
| 74 |
+
className="text-blue-600 hover:underline"
|
| 75 |
+
>
|
| 76 |
+
← 목록으로 돌아가기
|
| 77 |
+
</Link>
|
| 78 |
+
</div>
|
| 79 |
+
</main>
|
| 80 |
+
);
|
| 81 |
+
}
|
src/app/versions/page.tsx
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
|
| 3 |
+
import { useState, useEffect } from 'react';
|
| 4 |
+
import { CommitInfo, getCommitHistory, rollbackToCommit, getFileDiff, createBackup } from '@/lib/git';
|
| 5 |
+
import { format } from 'date-fns';
|
| 6 |
+
import { ko } from 'date-fns/locale';
|
| 7 |
+
|
| 8 |
+
export default function VersionsPage() {
|
| 9 |
+
const [commits, setCommits] = useState<CommitInfo[]>([]);
|
| 10 |
+
const [selectedCommit, setSelectedCommit] = useState<string | null>(null);
|
| 11 |
+
const [diffContent, setDiffContent] = useState<string>('');
|
| 12 |
+
const [isLoading, setIsLoading] = useState(true);
|
| 13 |
+
const [error, setError] = useState<string | null>(null);
|
| 14 |
+
|
| 15 |
+
useEffect(() => {
|
| 16 |
+
loadCommitHistory();
|
| 17 |
+
}, []);
|
| 18 |
+
|
| 19 |
+
async function loadCommitHistory() {
|
| 20 |
+
try {
|
| 21 |
+
const history = await getCommitHistory();
|
| 22 |
+
setCommits(history);
|
| 23 |
+
setIsLoading(false);
|
| 24 |
+
} catch (err) {
|
| 25 |
+
setError('커밋 이력을 불러오는데 실패했습니다.');
|
| 26 |
+
setIsLoading(false);
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
async function handleRollback(commitHash: string) {
|
| 31 |
+
if (!confirm('이 버전으로 롤백하시겠습니까? 현재 작업중인 내용이 있다면 먼저 커밋하세요.')) {
|
| 32 |
+
return;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
try {
|
| 36 |
+
await rollbackToCommit(commitHash);
|
| 37 |
+
alert('성공적으로 롤백되었습니다.');
|
| 38 |
+
loadCommitHistory();
|
| 39 |
+
} catch (err) {
|
| 40 |
+
setError('롤백 중 오류가 발생했습니다.');
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
async function handleViewDiff(commitHash: string) {
|
| 45 |
+
try {
|
| 46 |
+
if (commits.length > 1) {
|
| 47 |
+
const currentIndex = commits.findIndex(c => c.hash === commitHash);
|
| 48 |
+
if (currentIndex >= 0 && currentIndex < commits.length - 1) {
|
| 49 |
+
const diff = await getFileDiff(
|
| 50 |
+
'.',
|
| 51 |
+
commitHash,
|
| 52 |
+
commits[currentIndex + 1].hash
|
| 53 |
+
);
|
| 54 |
+
setDiffContent(diff);
|
| 55 |
+
setSelectedCommit(commitHash);
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
} catch (err) {
|
| 59 |
+
setError('변경사항을 불러오는데 실패했습니다.');
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
if (isLoading) {
|
| 64 |
+
return <div className="p-8">로딩 중...</div>;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
if (error) {
|
| 68 |
+
return <div className="p-8 text-red-600">{error}</div>;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
return (
|
| 72 |
+
<main className="min-h-screen p-8">
|
| 73 |
+
<h1 className="text-3xl font-bold mb-8">버전 관리</h1>
|
| 74 |
+
|
| 75 |
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
| 76 |
+
<div className="space-y-4">
|
| 77 |
+
<h2 className="text-xl font-semibold mb-4">커밋 이력</h2>
|
| 78 |
+
{commits.map((commit) => (
|
| 79 |
+
<div
|
| 80 |
+
key={commit.hash}
|
| 81 |
+
className={`p-4 border rounded-lg ${
|
| 82 |
+
selectedCommit === commit.hash ? 'border-blue-500 bg-blue-50' : ''
|
| 83 |
+
}`}
|
| 84 |
+
>
|
| 85 |
+
<div className="flex justify-between items-start mb-2">
|
| 86 |
+
<div className="font-medium">{commit.message}</div>
|
| 87 |
+
<div className="text-sm text-gray-500">
|
| 88 |
+
{format(new Date(commit.date), 'PPP p', { locale: ko })}
|
| 89 |
+
</div>
|
| 90 |
+
</div>
|
| 91 |
+
|
| 92 |
+
<div className="text-sm text-gray-600 mb-2">
|
| 93 |
+
작성자: {commit.author}
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
<div className="space-y-1 text-sm">
|
| 97 |
+
{commit.changes.added.length > 0 && (
|
| 98 |
+
<div className="text-green-600">
|
| 99 |
+
추가: {commit.changes.added.join(', ')}
|
| 100 |
+
</div>
|
| 101 |
+
)}
|
| 102 |
+
{commit.changes.modified.length > 0 && (
|
| 103 |
+
<div className="text-blue-600">
|
| 104 |
+
수정: {commit.changes.modified.join(', ')}
|
| 105 |
+
</div>
|
| 106 |
+
)}
|
| 107 |
+
{commit.changes.deleted.length > 0 && (
|
| 108 |
+
<div className="text-red-600">
|
| 109 |
+
삭제: {commit.changes.deleted.join(', ')}
|
| 110 |
+
</div>
|
| 111 |
+
)}
|
| 112 |
+
</div>
|
| 113 |
+
|
| 114 |
+
<div className="mt-4 space-x-2">
|
| 115 |
+
<button
|
| 116 |
+
onClick={() => handleViewDiff(commit.hash)}
|
| 117 |
+
className="px-3 py-1 text-sm bg-gray-100 hover:bg-gray-200 rounded"
|
| 118 |
+
>
|
| 119 |
+
변경사항 보기
|
| 120 |
+
</button>
|
| 121 |
+
<button
|
| 122 |
+
onClick={() => handleRollback(commit.hash)}
|
| 123 |
+
className="px-3 py-1 text-sm bg-red-100 hover:bg-red-200 text-red-700 rounded"
|
| 124 |
+
>
|
| 125 |
+
이 버전으로 롤백
|
| 126 |
+
</button>
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
))}
|
| 130 |
+
</div>
|
| 131 |
+
|
| 132 |
+
{selectedCommit && (
|
| 133 |
+
<div className="space-y-4">
|
| 134 |
+
<h2 className="text-xl font-semibold mb-4">변경사항</h2>
|
| 135 |
+
<pre className="p-4 bg-gray-50 rounded-lg overflow-x-auto text-sm">
|
| 136 |
+
{diffContent || '변경사항이 없습니다.'}
|
| 137 |
+
</pre>
|
| 138 |
+
</div>
|
| 139 |
+
)}
|
| 140 |
+
</div>
|
| 141 |
+
</main>
|
| 142 |
+
);
|
| 143 |
+
}
|
src/components/JsonLd.tsx
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { JsonLdContext } from '@/types/jsonld';
|
| 2 |
+
|
| 3 |
+
interface JsonLdProps {
|
| 4 |
+
data: JsonLdContext;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
export default function JsonLd({ data }: JsonLdProps) {
|
| 8 |
+
return (
|
| 9 |
+
<script
|
| 10 |
+
type="application/ld+json"
|
| 11 |
+
dangerouslySetInnerHTML={{
|
| 12 |
+
__html: JSON.stringify(data, null, 2)
|
| 13 |
+
}}
|
| 14 |
+
/>
|
| 15 |
+
);
|
| 16 |
+
}
|
src/components/Search.tsx
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
|
| 3 |
+
import { useState, useCallback } from 'react';
|
| 4 |
+
import { useRouter } from 'next/navigation';
|
| 5 |
+
import debounce from 'lodash/debounce';
|
| 6 |
+
|
| 7 |
+
interface SearchProps {
|
| 8 |
+
initialQuery?: string;
|
| 9 |
+
initialTags?: string[];
|
| 10 |
+
initialCategory?: string;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export default function Search({ initialQuery = '', initialTags = [], initialCategory = '' }: SearchProps) {
|
| 14 |
+
const [query, setQuery] = useState(initialQuery);
|
| 15 |
+
const [selectedTags, setSelectedTags] = useState<string[]>(initialTags);
|
| 16 |
+
const [selectedCategory, setSelectedCategory] = useState(initialCategory);
|
| 17 |
+
const router = useRouter();
|
| 18 |
+
|
| 19 |
+
const debouncedSearch = useCallback(
|
| 20 |
+
debounce((searchQuery: string, tags: string[], category: string) => {
|
| 21 |
+
const params = new URLSearchParams();
|
| 22 |
+
|
| 23 |
+
if (searchQuery) {
|
| 24 |
+
params.set('q', searchQuery);
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
if (tags.length > 0) {
|
| 28 |
+
params.set('tags', tags.join(','));
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
if (category) {
|
| 32 |
+
params.set('category', category);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
const queryString = params.toString();
|
| 36 |
+
router.push(`/search${queryString ? `?${queryString}` : ''}`);
|
| 37 |
+
}, 300),
|
| 38 |
+
[]
|
| 39 |
+
);
|
| 40 |
+
|
| 41 |
+
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
|
| 42 |
+
const newQuery = e.target.value;
|
| 43 |
+
setQuery(newQuery);
|
| 44 |
+
debouncedSearch(newQuery, selectedTags, selectedCategory);
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
const toggleTag = (tag: string) => {
|
| 48 |
+
const newTags = selectedTags.includes(tag)
|
| 49 |
+
? selectedTags.filter(t => t !== tag)
|
| 50 |
+
: [...selectedTags, tag];
|
| 51 |
+
|
| 52 |
+
setSelectedTags(newTags);
|
| 53 |
+
debouncedSearch(query, newTags, selectedCategory);
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
const handleCategoryChange = (category: string) => {
|
| 57 |
+
const newCategory = selectedCategory === category ? '' : category;
|
| 58 |
+
setSelectedCategory(newCategory);
|
| 59 |
+
debouncedSearch(query, selectedTags, newCategory);
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
return (
|
| 63 |
+
<div className="w-full max-w-4xl mx-auto space-y-4">
|
| 64 |
+
<div className="relative">
|
| 65 |
+
<input
|
| 66 |
+
type="text"
|
| 67 |
+
value={query}
|
| 68 |
+
onChange={handleSearch}
|
| 69 |
+
placeholder="검색어를 입력하세요..."
|
| 70 |
+
className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
| 71 |
+
/>
|
| 72 |
+
</div>
|
| 73 |
+
|
| 74 |
+
<div className="flex flex-wrap gap-4">
|
| 75 |
+
<div className="flex-1">
|
| 76 |
+
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
| 77 |
+
태그 필터
|
| 78 |
+
</label>
|
| 79 |
+
<div className="flex flex-wrap gap-2">
|
| 80 |
+
{['시작하기', '가이드', '문법', 'API', '참조'].map(tag => (
|
| 81 |
+
<button
|
| 82 |
+
key={tag}
|
| 83 |
+
onClick={() => toggleTag(tag)}
|
| 84 |
+
className={`px-3 py-1 rounded-full text-sm ${
|
| 85 |
+
selectedTags.includes(tag)
|
| 86 |
+
? 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200'
|
| 87 |
+
: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300'
|
| 88 |
+
} hover:opacity-80 transition-opacity`}
|
| 89 |
+
>
|
| 90 |
+
#{tag}
|
| 91 |
+
</button>
|
| 92 |
+
))}
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
<div className="flex-1">
|
| 97 |
+
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
| 98 |
+
카테고리 필터
|
| 99 |
+
</label>
|
| 100 |
+
<div className="flex flex-wrap gap-2">
|
| 101 |
+
{['가이드', '문서', '소개'].map(category => (
|
| 102 |
+
<button
|
| 103 |
+
key={category}
|
| 104 |
+
onClick={() => handleCategoryChange(category)}
|
| 105 |
+
className={`px-3 py-1 rounded-full text-sm ${
|
| 106 |
+
selectedCategory === category
|
| 107 |
+
? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'
|
| 108 |
+
: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300'
|
| 109 |
+
} hover:opacity-80 transition-opacity`}
|
| 110 |
+
>
|
| 111 |
+
{category}
|
| 112 |
+
</button>
|
| 113 |
+
))}
|
| 114 |
+
</div>
|
| 115 |
+
</div>
|
| 116 |
+
</div>
|
| 117 |
+
</div>
|
| 118 |
+
);
|
| 119 |
+
}
|
src/content/articles/getting-started.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: AI 친화적인 포털 시작하기
|
| 3 |
+
date: 2024-03-21
|
| 4 |
+
author: 관리자
|
| 5 |
+
tags: [시작하기, 가이드, 튜토리얼]
|
| 6 |
+
category: 가이드
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
# AI 친화적인 포털 시작하기
|
| 10 |
+
|
| 11 |
+
이 문서는 AI 친화적인 마크다운/JSON 기반 포털을 사용하는 방법을 안내합니다.
|
| 12 |
+
|
| 13 |
+
## 주요 기능
|
| 14 |
+
|
| 15 |
+
- 마크다운 기반 콘텐츠 작성
|
| 16 |
+
- JSON 형식의 메타데이터 관리
|
| 17 |
+
- AI 친화적인 API 엔드포인트
|
| 18 |
+
- 모던한 웹 인터페이스
|
| 19 |
+
|
| 20 |
+
## 콘텐츠 작성 방법
|
| 21 |
+
|
| 22 |
+
1. 마크다운 파일 생성
|
| 23 |
+
```bash
|
| 24 |
+
touch src/content/articles/새로운-문서.md
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
2. YAML Front Matter 추가
|
| 28 |
+
```markdown
|
| 29 |
+
---
|
| 30 |
+
title: 문서 제목
|
| 31 |
+
date: 2024-03-21
|
| 32 |
+
author: 작성자
|
| 33 |
+
tags: [태그1, 태그2]
|
| 34 |
+
category: 카테고리
|
| 35 |
+
---
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
3. 콘텐츠 작성
|
| 39 |
+
- 마크다운 문법을 사용하여 콘텐츠를 작성합니다
|
| 40 |
+
- 코드 블록, 이미지, 링크 등을 활용할 수 있습니다
|
| 41 |
+
|
| 42 |
+
## API 사용 방법
|
| 43 |
+
|
| 44 |
+
```javascript
|
| 45 |
+
// 모든 콘텐츠 조회
|
| 46 |
+
fetch('/api/content')
|
| 47 |
+
.then(response => response.json())
|
| 48 |
+
.then(data => console.log(data));
|
| 49 |
+
|
| 50 |
+
// 특정 콘텐츠 조회
|
| 51 |
+
fetch('/api/content?id=articles/getting-started')
|
| 52 |
+
.then(response => response.json())
|
| 53 |
+
.then(data => console.log(data));
|
| 54 |
+
|
| 55 |
+
// 태그로 필터링
|
| 56 |
+
fetch('/api/content?tag=시작하기')
|
| 57 |
+
.then(response => response.json())
|
| 58 |
+
.then(data => console.log(data));
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
## 도움말
|
| 62 |
+
|
| 63 |
+
더 자세한 정보는 [문서](/docs)를 참조하세요.
|
src/content/articles/markdown-guide.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: 마크다운 작성 가이드
|
| 3 |
+
date: 2024-03-21
|
| 4 |
+
author: 관리자
|
| 5 |
+
tags: [마크다운, 가이드, 문법]
|
| 6 |
+
category: 가이드
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
# 마크다운 작성 가이드
|
| 10 |
+
|
| 11 |
+
이 문서는 마크다운 문법을 사용하여 콘텐츠를 작성하는 방법을 설명합니다.
|
| 12 |
+
|
| 13 |
+
## 기본 문법
|
| 14 |
+
|
| 15 |
+
### 제목
|
| 16 |
+
|
| 17 |
+
```markdown
|
| 18 |
+
# 제목 1
|
| 19 |
+
## 제목 2
|
| 20 |
+
### 제목 3
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
### 텍스트 서식
|
| 24 |
+
|
| 25 |
+
```markdown
|
| 26 |
+
*이탤릭체*
|
| 27 |
+
**볼드체**
|
| 28 |
+
~~취소선~~
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
### 목록
|
| 32 |
+
|
| 33 |
+
```markdown
|
| 34 |
+
- 순서 없는 목록
|
| 35 |
+
- 들여쓰기 목록
|
| 36 |
+
1. 순서 있는 목록
|
| 37 |
+
2. 두 번째 항목
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
### 링크와 이미지
|
| 41 |
+
|
| 42 |
+
```markdown
|
| 43 |
+
[링크 텍스트](https://example.com)
|
| 44 |
+

|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
### 코드
|
| 48 |
+
|
| 49 |
+
```markdown
|
| 50 |
+
`인라인 코드`
|
| 51 |
+
|
| 52 |
+
```javascript
|
| 53 |
+
// 코드 블록
|
| 54 |
+
function hello() {
|
| 55 |
+
console.log('Hello, world!');
|
| 56 |
+
}
|
| 57 |
+
```
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
## 고급 기능
|
| 61 |
+
|
| 62 |
+
### 테이블
|
| 63 |
+
|
| 64 |
+
```markdown
|
| 65 |
+
| 헤더 1 | 헤더 2 |
|
| 66 |
+
|--------|--------|
|
| 67 |
+
| 셀 1 | 셀 2 |
|
| 68 |
+
| 셀 3 | 셀 4 |
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
### 인용문
|
| 72 |
+
|
| 73 |
+
```markdown
|
| 74 |
+
> 인용문입니다.
|
| 75 |
+
> 여러 줄의 인용문도 가능합니다.
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
### 수평선
|
| 79 |
+
|
| 80 |
+
```markdown
|
| 81 |
+
---
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
## 팁과 트릭
|
| 85 |
+
|
| 86 |
+
1. YAML Front Matter를 사용하여 메타데이터를 추가하세요
|
| 87 |
+
2. 이미지는 `public` 디렉토리에 저장하세요
|
| 88 |
+
3. 코드 블록에는 언어를 지정하여 문법 강조를 활성화하세요
|
src/content/articles/welcome.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: AI 친화적인 포털에 오신 것을 환영합니다
|
| 3 |
+
date: 2024-03-21
|
| 4 |
+
author: 관리자
|
| 5 |
+
tags: [시작하기, 소개]
|
| 6 |
+
category: 소개
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
# AI 친화적인 포털에 오신 것을 환영합니다
|
| 10 |
+
|
| 11 |
+
이 포털은 AI가 쉽게 이해하고 활용할 수 있는 마크다운과 JSON 기반의 콘텐츠 관리 시스템입니다.
|
| 12 |
+
|
| 13 |
+
## 주요 특징
|
| 14 |
+
|
| 15 |
+
- 마크다운 기반 콘텐츠 작성
|
| 16 |
+
- JSON 형식의 메타데이터 관리
|
| 17 |
+
- AI 친화적인 API 엔드포인트
|
| 18 |
+
- 모던한 웹 인터페이스
|
| 19 |
+
|
| 20 |
+
## 시작하기
|
| 21 |
+
|
| 22 |
+
1. 콘텐츠 작성
|
| 23 |
+
- 마크다운 형식으로 문서를 작성합니다
|
| 24 |
+
- YAML Front Matter를 사용하여 메타데이터를 추가합니다
|
| 25 |
+
|
| 26 |
+
2. API 활용
|
| 27 |
+
- `/api/content` 엔드포인트를 통해 콘텐츠에 접근
|
| 28 |
+
- `/api/search`를 사용하여 콘텐츠 검색
|
| 29 |
+
|
| 30 |
+
## 예제 코드
|
| 31 |
+
|
| 32 |
+
```javascript
|
| 33 |
+
// API 호출 예제
|
| 34 |
+
fetch('/api/content')
|
| 35 |
+
.then(response => response.json())
|
| 36 |
+
.then(data => console.log(data));
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
## 도움말
|
| 40 |
+
|
| 41 |
+
더 자세한 정보는 [문서](/docs)를 참조하세요.
|
src/content/docs/api-reference.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: API 참조 문서
|
| 3 |
+
date: 2024-03-21
|
| 4 |
+
author: 관리자
|
| 5 |
+
tags: [API, 참조, 문서]
|
| 6 |
+
category: 문서
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
# API 참조 문서
|
| 10 |
+
|
| 11 |
+
이 문서는 AI 친화적인 포털의 API 엔드포인트를 설명합니다.
|
| 12 |
+
|
| 13 |
+
## 콘텐츠 API
|
| 14 |
+
|
| 15 |
+
### 모든 콘텐츠 조회
|
| 16 |
+
|
| 17 |
+
```http
|
| 18 |
+
GET /api/content
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
응답 예시:
|
| 22 |
+
```json
|
| 23 |
+
[
|
| 24 |
+
{
|
| 25 |
+
"id": "articles/getting-started",
|
| 26 |
+
"title": "AI 친화적인 포털 시작하기",
|
| 27 |
+
"date": "2024-03-21",
|
| 28 |
+
"author": "관리자",
|
| 29 |
+
"tags": ["시작하기", "가이드", "튜토리얼"],
|
| 30 |
+
"category": "가이드",
|
| 31 |
+
"content": "..."
|
| 32 |
+
}
|
| 33 |
+
]
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
### 특정 콘텐츠 조회
|
| 37 |
+
|
| 38 |
+
```http
|
| 39 |
+
GET /api/content?id=articles/getting-started
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
### 태그로 필터링
|
| 43 |
+
|
| 44 |
+
```http
|
| 45 |
+
GET /api/content?tag=시작하기
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
### 카테고리로 필터링
|
| 49 |
+
|
| 50 |
+
```http
|
| 51 |
+
GET /api/content?category=가이드
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
## 응답 형식
|
| 55 |
+
|
| 56 |
+
### 성공 응답
|
| 57 |
+
|
| 58 |
+
```json
|
| 59 |
+
{
|
| 60 |
+
"id": "string",
|
| 61 |
+
"title": "string",
|
| 62 |
+
"date": "string",
|
| 63 |
+
"author": "string",
|
| 64 |
+
"tags": ["string"],
|
| 65 |
+
"category": "string",
|
| 66 |
+
"content": "string"
|
| 67 |
+
}
|
| 68 |
+
```
|
| 69 |
+
|
| 70 |
+
### 에러 응답
|
| 71 |
+
|
| 72 |
+
```json
|
| 73 |
+
{
|
| 74 |
+
"error": "string"
|
| 75 |
+
}
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
## 상태 코드
|
| 79 |
+
|
| 80 |
+
- 200: 성공
|
| 81 |
+
- 404: 콘텐츠를 찾을 수 없음
|
| 82 |
+
- 500: 서버 에러
|
| 83 |
+
|
| 84 |
+
## 사용 예시
|
| 85 |
+
|
| 86 |
+
```javascript
|
| 87 |
+
// 모든 콘텐츠 조회
|
| 88 |
+
const response = await fetch('/api/content');
|
| 89 |
+
const data = await response.json();
|
| 90 |
+
|
| 91 |
+
// 특정 콘텐츠 조회
|
| 92 |
+
const response = await fetch('/api/content?id=articles/getting-started');
|
| 93 |
+
const data = await response.json();
|
| 94 |
+
|
| 95 |
+
// 태그로 필터링
|
| 96 |
+
const response = await fetch('/api/content?tag=시작하기');
|
| 97 |
+
const data = await response.json();
|
| 98 |
+
```
|
src/lib/git.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
'use client';
|
| 2 |
+
|
| 3 |
+
export interface CommitInfo {
|
| 4 |
+
hash: string;
|
| 5 |
+
author: string;
|
| 6 |
+
date: string;
|
| 7 |
+
message: string;
|
| 8 |
+
changes: {
|
| 9 |
+
added: string[];
|
| 10 |
+
modified: string[];
|
| 11 |
+
deleted: string[];
|
| 12 |
+
};
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
export async function getCommitHistory(): Promise<CommitInfo[]> {
|
| 16 |
+
try {
|
| 17 |
+
const response = await fetch('/api/git?action=history');
|
| 18 |
+
if (!response.ok) {
|
| 19 |
+
throw new Error('커밋 이력 조회 실패');
|
| 20 |
+
}
|
| 21 |
+
const data = await response.json();
|
| 22 |
+
return data.commits;
|
| 23 |
+
} catch (error) {
|
| 24 |
+
console.error('커밋 이력 조회 실패:', error);
|
| 25 |
+
throw error;
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
export async function rollbackToCommit(commitHash: string): Promise<void> {
|
| 30 |
+
try {
|
| 31 |
+
const response = await fetch('/api/git', {
|
| 32 |
+
method: 'POST',
|
| 33 |
+
headers: {
|
| 34 |
+
'Content-Type': 'application/json',
|
| 35 |
+
},
|
| 36 |
+
body: JSON.stringify({
|
| 37 |
+
action: 'rollback',
|
| 38 |
+
commitHash,
|
| 39 |
+
}),
|
| 40 |
+
});
|
| 41 |
+
|
| 42 |
+
if (!response.ok) {
|
| 43 |
+
const data = await response.json();
|
| 44 |
+
throw new Error(data.error || '롤백 실패');
|
| 45 |
+
}
|
| 46 |
+
} catch (error) {
|
| 47 |
+
console.error('롤백 실패:', error);
|
| 48 |
+
throw error;
|
| 49 |
+
}
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
export async function getFileDiff(
|
| 53 |
+
filePath: string,
|
| 54 |
+
commitHash1: string,
|
| 55 |
+
commitHash2: string
|
| 56 |
+
): Promise<string> {
|
| 57 |
+
try {
|
| 58 |
+
const response = await fetch(
|
| 59 |
+
`/api/git?action=diff&hash1=${commitHash1}&hash2=${commitHash2}&file=${encodeURIComponent(filePath)}`
|
| 60 |
+
);
|
| 61 |
+
|
| 62 |
+
if (!response.ok) {
|
| 63 |
+
const data = await response.json();
|
| 64 |
+
throw new Error(data.error || '파일 변경사항 비교 실패');
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
const data = await response.json();
|
| 68 |
+
return data.diff;
|
| 69 |
+
} catch (error) {
|
| 70 |
+
console.error('파일 변경사항 비교 실패:', error);
|
| 71 |
+
throw error;
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
export async function commitChanges(message: string): Promise<string> {
|
| 76 |
+
try {
|
| 77 |
+
const response = await fetch('/api/git', {
|
| 78 |
+
method: 'POST',
|
| 79 |
+
headers: {
|
| 80 |
+
'Content-Type': 'application/json',
|
| 81 |
+
},
|
| 82 |
+
body: JSON.stringify({
|
| 83 |
+
action: 'commit',
|
| 84 |
+
message,
|
| 85 |
+
}),
|
| 86 |
+
});
|
| 87 |
+
|
| 88 |
+
if (!response.ok) {
|
| 89 |
+
const data = await response.json();
|
| 90 |
+
throw new Error(data.error || '커밋 실패');
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
const data = await response.json();
|
| 94 |
+
return data.message;
|
| 95 |
+
} catch (error) {
|
| 96 |
+
console.error('변경사항 커밋 실패:', error);
|
| 97 |
+
throw error;
|
| 98 |
+
}
|
| 99 |
+
}
|
src/lib/markdown.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import fs from 'fs';
|
| 2 |
+
import path from 'path';
|
| 3 |
+
import matter from 'gray-matter';
|
| 4 |
+
import { remark } from 'remark';
|
| 5 |
+
import html from 'remark-html';
|
| 6 |
+
|
| 7 |
+
const contentDirectory = path.join(process.cwd(), 'src/content');
|
| 8 |
+
|
| 9 |
+
export interface PostMetadata {
|
| 10 |
+
title: string;
|
| 11 |
+
date: string;
|
| 12 |
+
author: string;
|
| 13 |
+
tags: string[];
|
| 14 |
+
category?: string;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
export interface Post extends PostMetadata {
|
| 18 |
+
id: string;
|
| 19 |
+
content: string;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
export async function getPostById(id: string): Promise<Post | null> {
|
| 23 |
+
try {
|
| 24 |
+
const fullPath = path.join(contentDirectory, `${id}.md`);
|
| 25 |
+
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
| 26 |
+
|
| 27 |
+
const { data, content } = matter(fileContents);
|
| 28 |
+
const processedContent = await remark()
|
| 29 |
+
.use(html)
|
| 30 |
+
.process(content);
|
| 31 |
+
|
| 32 |
+
return {
|
| 33 |
+
id,
|
| 34 |
+
content: processedContent.toString(),
|
| 35 |
+
title: data.title,
|
| 36 |
+
date: data.date,
|
| 37 |
+
author: data.author,
|
| 38 |
+
tags: data.tags || [],
|
| 39 |
+
category: data.category
|
| 40 |
+
};
|
| 41 |
+
} catch (error) {
|
| 42 |
+
console.error(`Error getting post ${id}:`, error);
|
| 43 |
+
return null;
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
export async function getAllPosts(): Promise<Post[]> {
|
| 48 |
+
const posts: Post[] = [];
|
| 49 |
+
|
| 50 |
+
try {
|
| 51 |
+
const directories = ['articles', 'docs'];
|
| 52 |
+
|
| 53 |
+
for (const dir of directories) {
|
| 54 |
+
const dirPath = path.join(contentDirectory, dir);
|
| 55 |
+
if (!fs.existsSync(dirPath)) continue;
|
| 56 |
+
|
| 57 |
+
const files = fs.readdirSync(dirPath);
|
| 58 |
+
|
| 59 |
+
for (const file of files) {
|
| 60 |
+
if (!file.endsWith('.md')) continue;
|
| 61 |
+
|
| 62 |
+
const id = `${dir}/${file.replace(/\.md$/, '')}`;
|
| 63 |
+
const post = await getPostById(id);
|
| 64 |
+
if (post) posts.push(post);
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
return posts.sort((a, b) => (new Date(b.date)).getTime() - (new Date(a.date)).getTime());
|
| 69 |
+
} catch (error) {
|
| 70 |
+
console.error('Error getting all posts:', error);
|
| 71 |
+
return [];
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
export async function getPostsByTag(tag: string): Promise<Post[]> {
|
| 76 |
+
const allPosts = await getAllPosts();
|
| 77 |
+
return allPosts.filter(post => post.tags.includes(tag));
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
export async function getPostsByCategory(category: string): Promise<Post[]> {
|
| 81 |
+
const allPosts = await getAllPosts();
|
| 82 |
+
return allPosts.filter(post => post.category === category);
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
export async function getAllTags(): Promise<string[]> {
|
| 86 |
+
const allPosts = await getAllPosts();
|
| 87 |
+
const tagSet = new Set<string>();
|
| 88 |
+
|
| 89 |
+
allPosts.forEach(post => {
|
| 90 |
+
post.tags.forEach(tag => tagSet.add(tag));
|
| 91 |
+
});
|
| 92 |
+
|
| 93 |
+
return Array.from(tagSet).sort();
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
export async function getAllCategories(): Promise<string[]> {
|
| 97 |
+
const allPosts = await getAllPosts();
|
| 98 |
+
const categorySet = new Set<string>();
|
| 99 |
+
|
| 100 |
+
allPosts.forEach(post => {
|
| 101 |
+
if (post.category) categorySet.add(post.category);
|
| 102 |
+
});
|
| 103 |
+
|
| 104 |
+
return Array.from(categorySet).sort();
|
| 105 |
+
}
|
src/types/jsonld.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export interface JsonLdContext {
|
| 2 |
+
'@context': string | Record<string, string>;
|
| 3 |
+
}
|
| 4 |
+
|
| 5 |
+
export interface BlogPostingJsonLd extends JsonLdContext {
|
| 6 |
+
'@type': 'BlogPosting';
|
| 7 |
+
'@id': string;
|
| 8 |
+
headline: string;
|
| 9 |
+
datePublished: string;
|
| 10 |
+
author: {
|
| 11 |
+
'@type': 'Person';
|
| 12 |
+
name: string;
|
| 13 |
+
};
|
| 14 |
+
keywords: string[];
|
| 15 |
+
articleSection?: string;
|
| 16 |
+
description?: string;
|
| 17 |
+
text: string;
|
| 18 |
+
url: string;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
export interface WebPageJsonLd extends JsonLdContext {
|
| 22 |
+
'@type': 'WebPage';
|
| 23 |
+
'@id': string;
|
| 24 |
+
name: string;
|
| 25 |
+
description?: string;
|
| 26 |
+
url: string;
|
| 27 |
+
isPartOf: {
|
| 28 |
+
'@type': 'WebSite';
|
| 29 |
+
'@id': string;
|
| 30 |
+
name: string;
|
| 31 |
+
url: string;
|
| 32 |
+
};
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
export interface BreadcrumbListJsonLd extends JsonLdContext {
|
| 36 |
+
'@type': 'BreadcrumbList';
|
| 37 |
+
itemListElement: {
|
| 38 |
+
'@type': 'ListItem';
|
| 39 |
+
position: number;
|
| 40 |
+
item: {
|
| 41 |
+
'@id': string;
|
| 42 |
+
name: string;
|
| 43 |
+
};
|
| 44 |
+
}[];
|
| 45 |
+
}
|
tailwind.config.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type { Config } from 'tailwindcss';
|
| 2 |
+
|
| 3 |
+
const config: Config = {
|
| 4 |
+
content: [
|
| 5 |
+
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
| 6 |
+
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
| 7 |
+
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
| 8 |
+
],
|
| 9 |
+
theme: {
|
| 10 |
+
extend: {
|
| 11 |
+
backgroundImage: {
|
| 12 |
+
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
| 13 |
+
'gradient-conic':
|
| 14 |
+
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
| 15 |
+
},
|
| 16 |
+
},
|
| 17 |
+
},
|
| 18 |
+
plugins: [
|
| 19 |
+
require('@tailwindcss/typography'),
|
| 20 |
+
],
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
export default config;
|