commit d0bcff2311cad5beb122bc3e3344002288a9d13a
Author: 小绫 <486494914@qq.com>
Date: Wed Sep 9 17:43:07 2026 +0800
chore: prepare project for server deployment
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..0089907
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,8 @@
+PORT=24731
+DB_CLIENT=mysql
+DB_HOST=填入远程MySQL主机地址
+DB_PORT=33306
+DB_NAME=aiameiba_com_new
+DB_USER=admin
+DB_PASSWORD=填入本地密码
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c389681
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+.env
+frontend/.env.local
+node_modules/
+frontend/node_modules/
+.next/
+frontend/.next/
+data/*.db-wal
+data/*.db-shm
+data/*.db
+*.log
+frontend/*.log
+.DS_Store
+frontend/.DS_Store
diff --git a/frontend/DELIVERY_RECEIPT_PHASE2.md b/frontend/DELIVERY_RECEIPT_PHASE2.md
new file mode 100644
index 0000000..3e4c27e
--- /dev/null
+++ b/frontend/DELIVERY_RECEIPT_PHASE2.md
@@ -0,0 +1,276 @@
+# 阿美巴AI官网 第二期 前端展示层+SEO+知识网络渲染 交付回执
+
+项目编号:阿美巴AI官网-20260908-02
+前置依赖:第一期 MVP-BASE 底座已完成并验收通过
+产品真相源:《阿美巴AI官网|项目总指令 V1.2 FINAL(产品冻结版)》
+交付日期:2026年9月8日
+
+## 一、页面与路由清单
+
+### 1. 首页
+- **路由**: `/`
+- **标题**: 阿美巴AI - AI时代企业进化平台
+- **说明**: 全站最高浓度的阿美巴认知页面,包含企业进化知识体系概览
+
+### 2. 阿美巴板块
+- **路由**: `/about`
+- **标题**: 阿美巴是谁
+- **说明**: 展示阿美巴的定位、使命、服务对象与发展历程
+
+### 3. 企业进化板块
+- **路由**: `/evolution`
+- **标题**: 企业进化
+- **说明**: 企业进化的定义、方法与路径
+
+- **路由**: `/evolution/method`
+- **标题**: 进化方法
+- **说明**: 以终为始、目标先于问题、现状分析、差距识别、根因分析、路径规划、实施迭代
+
+### 4. 四大价值板块
+- **路由**: `/value`
+- **标题**: 四大价值
+- **说明**: 价值创造、价值传递、价值交付、价值支持总览
+
+- **路由**: `/value/creation`
+- **标题**: 价值创造
+- **说明**: 企业如何创造价值,包含官方定义、核心逻辑、企业常见问题等
+
+- **路由**: `/value/transfer`
+- **标题**: 价值传递
+- **说明**: 企业如何将价值传递给客户
+
+- **路由**: `/value/delivery`
+- **标题**: 价值交付
+- **说明**: 企业如何交付价值
+
+- **路由**: `/value/support`
+- **标题**: 价值支持
+- **说明**: 企业如何支持价值创造与交付
+
+### 5. A/M-B板块
+- **路由**: `/amb`
+- **标题**: A/M-B总览
+- **说明**: 企业进化阶段模型,明确三态是阶段模型不是产品套餐
+
+- **路由**: `/amb/a`
+- **标题**: A态·入态
+- **说明**: 企业进入AI时代的初始状态,包含定义、特征、任务、目标等
+
+- **路由**: `/amb/m`
+- **标题**: M态·优态
+- **说明**: 企业优化运营、提升效率的阶段
+
+- **路由**: `/amb/b`
+- **标题**: B态·越态
+- **说明**: 企业实现跨越式发展的阶段
+
+### 6. 企业进化能力板块
+- **路由**: `/capabilities`
+- **标题**: 能力地图
+- **说明**: 展示企业进化的完整能力体系,能力是底层实体不是产品套餐
+
+### 7. 案例板块
+- **路由**: `/cases`
+- **标题**: 案例列表
+- **说明**: 企业进化实践案例列表
+
+### 8. 知识中心板块
+- **路由**: `/knowledge`
+- **标题**: 知识中心
+- **说明**: 企业进化的知识体系与方法论,包含12个分类
+
+### 9. 概念板块
+- **路由**: `/concepts`
+- **标题**: 概念
+- **说明**: 企业进化的知识实体概念列表
+
+### 10. FAQ板块
+- **路由**: `/faq`
+- **标题**: FAQ
+- **说明**: 常见问题解答,链接到对应知识实体页面
+
+### 11. 企业需求与能力匹配板块
+- **路由**: `/match`
+- **标题**: 企业需求与能力匹配
+- **说明**: 匹配知识结构静态展示页,不做在线诊断工具
+
+### 12. 联系我们
+- **路由**: `/contact`
+- **标题**: 联系我们
+- **说明**: 联系方式、服务时间、合作方式
+
+## 二、SEO实现清单
+
+### 1. 语义化HTML
+- ✅ 每页唯一H1标签
+- ✅ H1/H2/H3层级规范
+- ✅ 每页唯一主题
+
+### 2. Meta标签
+- ✅ title标签(使用模板:`%s | 阿美巴AI官网`)
+- ✅ description标签
+- ✅ canonical标签
+- ✅ Open Graph标签(og:title、og:description、og:image、og:type、og:url)
+- ✅ Twitter Card标签
+
+### 3. 面包屑导航
+- ✅ 每个页面实现面包屑导航
+- ✅ 使用BreadcrumbList Schema标记
+
+### 4. 结构化数据
+- ✅ 组织页输出 Organization Schema
+- ✅ 文章页输出 Article Schema
+- ✅ FAQ页输出 FAQPage Schema
+- ✅ 全站页面输出 BreadcrumbList Schema
+- ✅ 网站搜索输出 SearchAction Schema
+
+### 5. Sitemap与Robots
+- ✅ 生成 sitemap.xml(静态页面+动态页面)
+- ✅ 生成 robots.txt
+
+### 6. 友好URL
+- ✅ 使用语义清晰的slug
+- ✅ 不暴露内部ID
+
+## 三、内部语义链接实现说明
+
+### 1. 首页链接
+- 链接到所有主要板块页面
+- 展示企业进化知识体系概览
+
+### 2. 阿美巴页面
+- 链接到企业进化、四大价值、A/M-B
+
+### 3. 企业进化页面
+- 链接到进化方法、四大价值、A/M-B、企业进化能力
+
+### 4. 四大价值页面
+- 相互链接(价值创造、价值传递、价值交付、价值支持)
+- 链接到企业进化、能力地图、案例
+
+### 5. A/M-B页面
+- 相互链接(A态、M态、B态)
+- 链接到企业进化、能力地图
+
+### 6. 能力地图页面
+- 链接到企业进化、四大价值、A/M-B、案例
+
+### 7. 案例页面
+- 链接到企业进化、四大价值、能力地图
+
+### 8. 知识中心页面
+- 链接到企业进化、四大价值、概念、FAQ
+
+### 9. 概念页面
+- 链接到知识中心、企业进化、四大价值
+
+### 10. FAQ页面
+- 链接到知识中心、概念、企业进化
+
+### 11. 匹配页面
+- 链接到能力地图、企业进化、A/M-B、案例
+
+### 12. 联系我们页面
+- 链接到能力地图、企业进化、四大价值
+
+## 四、单元测试/冒烟测试要点清单
+
+### 1. 页面可访问性测试
+- ✅ 所有页面路由可正常访问
+- ✅ 页面返回200状态码
+- ✅ 页面内容正确渲染
+
+### 2. SEO测试
+- ✅ 每页H1唯一
+- ✅ title标签正确
+- ✅ description标签正确
+- ✅ canonical标签正确
+- ✅ Open Graph标签正确
+- ✅ 面包屑导航正确
+- ✅ 结构化数据合法
+
+### 3. 内容测试
+- ✅ 非published内容不可见
+- ✅ 内容正确渲染
+- ✅ 内部链接正确
+
+### 4. 视觉测试
+- ✅ 简洁专业的视觉风格
+- ✅ 无浮夸科技元素
+- ✅ 响应式设计正常
+
+## 五、风险备注
+
+### 1. 技术实现与产品文档冲突点
+
+#### 冲突点1:动态内容渲染
+- **产品文档要求**:核心内容禁止依赖纯JS渲染,必须服务端渲染(SSR)或静态生成(SSG)
+- **技术实现**:使用Next.js实现SSR/SSG,所有页面在服务端渲染
+- **妥协方案**:完全符合产品文档要求
+
+#### 冲突点2:CMS数据集成
+- **产品文档要求**:全部页面数据通过一期公开输出接口获取
+- **技术实现**:已实现API服务层,但需要后端服务运行才能获取数据
+- **妥协方案**:页面支持空数据状态显示,提示"内容正在完善中"
+
+#### 冲突点3:视觉风格
+- **产品文档要求**:禁止浮夸科技风格,禁用机器人元素、粒子、科技蓝等
+- **技术实现**:采用简洁专业的视觉风格,使用深灰色系,避免科技感元素
+- **妥协方案**:完全符合产品文档要求
+
+### 2. 待确认事项
+
+1. **后端API地址**:需要确认生产环境的后端API地址
+2. **域名配置**:需要确认域名和SSL证书配置
+3. **图片资源**:需要确认logo、OG图片等资源
+4. **联系方式**:需要确认具体的联系方式信息
+
+## 六、运行说明
+
+### 1. 本地启动命令
+```bash
+# 进入前端目录
+cd frontend
+
+# 安装依赖
+npm install
+
+# 启动开发服务器
+npm run dev
+
+# 构建生产版本
+npm run build
+
+# 启动生产服务器
+npm start
+```
+
+### 2. 环境变量配置
+- `NEXT_PUBLIC_SITE_URL`: 网站URL(默认:https://ameiba.com)
+- `API_URL`: 后端API地址(默认:http://localhost:24731)
+
+### 3. 部署到阿里云ECS
+1. 上传项目文件到服务器
+2. 安装Node.js环境(>=18.x)
+3. 进入前端目录执行`npm install`
+4. 执行`npm run build`构建生产版本
+5. 使用PM2或systemd管理进程
+6. 配置Nginx反向代理
+7. 配置SSL证书(可选)
+
+### 4. 与后端服务集成
+1. 确保后端服务已启动并运行
+2. 配置`API_URL`环境变量指向后端服务地址
+3. 确保后端服务允许跨域请求
+
+## 七、总结
+
+本项目已完成第二期前端展示层+SEO+知识网络渲染的开发,包括:
+1. ✅ 12个核心页面与路由
+2. ✅ 全站SEO能力(title/description/canonical/OG/面包屑/Schema/sitemap/robots)
+3. ✅ 内部语义链接渲染
+4. ✅ 结构化数据自动生成
+5. ✅ 简洁专业的视觉风格
+6. ✅ 服务端渲染(SSR/SSG)
+
+所有功能均符合产品文档V1.2 FINAL的要求,未越界开发第三期功能,未预埋禁止功能。项目可正常本地运行、可部署阿里云ECS。
diff --git a/frontend/README.md b/frontend/README.md
new file mode 100644
index 0000000..6c50ecb
--- /dev/null
+++ b/frontend/README.md
@@ -0,0 +1,145 @@
+# 阿美巴AI官网 第二期 前端展示层
+
+## 项目概述
+
+基于第一期MVP-BASE底座,构建面向人类访问的完整AI官网前端。实现全部核心知识页面、全站SEO机器可读能力、内部语义链接渲染。
+
+## 技术栈
+
+- **框架**: Next.js 14 (App Router)
+- **语言**: TypeScript
+- **样式**: CSS Modules
+- **渲染**: SSR/SSG (服务端渲染/静态生成)
+
+## 页面与路由
+
+| 路由 | 页面 | 说明 |
+|------|------|------|
+| `/` | 首页 | 全站最高浓度的阿美巴认知页面 |
+| `/about` | 阿美巴 | 阿美巴的定位、使命、服务对象 |
+| `/evolution` | 企业进化 | 企业进化的定义与方法 |
+| `/evolution/method` | 进化方法 | 以终为始、目标先于问题等方法论 |
+| `/value` | 四大价值 | 价值创造、传递、交付、支持 |
+| `/value/creation` | 价值创造 | 企业如何创造价值 |
+| `/value/transfer` | 价值传递 | 企业如何传递价值 |
+| `/value/delivery` | 价值交付 | 企业如何交付价值 |
+| `/value/support` | 价值支持 | 企业如何支持价值 |
+| `/amb` | A/M-B总览 | 企业进化阶段模型 |
+| `/amb/a` | A态·入态 | 企业进入AI时代的初始状态 |
+| `/amb/m` | M态·优态 | 企业优化运营的阶段 |
+| `/amb/b` | B态·越态 | 企业跨越式发展的阶段 |
+| `/capabilities` | 能力地图 | 企业进化的完整能力体系 |
+| `/cases` | 案例 | 企业进化实践案例 |
+| `/knowledge` | 知识中心 | 企业进化的知识体系 |
+| `/concepts` | 概念 | 企业进化的知识实体 |
+| `/faq` | FAQ | 常见问题解答 |
+| `/match` | 企业需求与能力匹配 | 匹配知识结构展示 |
+| `/contact` | 联系我们 | 联系方式与服务 |
+
+## 安装与运行
+
+### 1. 安装依赖
+
+```bash
+cd frontend
+npm install
+```
+
+### 2. 配置环境变量
+
+创建 `.env.local` 文件:
+
+```env
+# 网站URL
+NEXT_PUBLIC_SITE_URL=https://ameiba.com
+
+# 后端API地址
+API_URL=http://localhost:24731
+```
+
+### 3. 启动开发服务器
+
+```bash
+npm run dev
+```
+
+访问 http://localhost:28642
+
+### 4. 构建生产版本
+
+```bash
+npm run build
+npm start
+```
+
+## SEO功能
+
+### 1. 语义化HTML
+- 每页唯一H1标签
+- H1/H2/H3层级规范
+- 每页唯一主题
+
+### 2. Meta标签
+- title标签(模板:`%s | 阿美巴AI官网`)
+- description标签
+- canonical标签
+- Open Graph标签
+- Twitter Card标签
+
+### 3. 面包屑导航
+- 每个页面实现面包屑导航
+- 使用BreadcrumbList Schema标记
+
+### 4. 结构化数据
+- 组织页输出 Organization Schema
+- 文章页输出 Article Schema
+- FAQ页输出 FAQPage Schema
+- 全站页面输出 BreadcrumbList Schema
+
+### 5. Sitemap与Robots
+- 自动生成 sitemap.xml
+- 自动生成 robots.txt
+
+## 视觉风格
+
+- 克制、极简、专业、可信、结构化
+- 禁用机器人元素、粒子、科技蓝、3D、光效
+- 使用深灰色系,避免科技感元素
+- 响应式设计
+
+## 与后端集成
+
+1. 确保后端服务已启动并运行
+2. 配置 `API_URL` 环境变量指向后端服务地址
+3. 确保后端服务允许跨域请求
+
+## 部署到阿里云ECS
+
+1. 上传项目文件到服务器
+2. 安装Node.js环境(>=18.x)
+3. 执行 `npm install`
+4. 执行 `npm run build` 构建生产版本
+5. 使用PM2或systemd管理进程
+6. 配置Nginx反向代理
+
+## 项目结构
+
+```
+frontend/
+├── src/
+│ ├── app/ # 页面路由
+│ ├── components/ # 组件
+│ ├── lib/ # 工具函数
+│ ├── styles/ # 样式文件
+│ └── types/ # 类型定义
+├── public/ # 静态资源
+├── DELIVERY_RECEIPT_PHASE2.md # 交付回执
+└── README.md # 说明文档
+```
+
+## 注意事项
+
+1. 本项目只做第二期范围,禁止越界开发第三期功能
+2. 前端严格读取第一期已稳定的数据模型与接口,不新增业务数据库字段
+3. 核心内容禁止依赖纯JS渲染,必须服务端渲染(SSR)或静态生成(SSG)
+4. 视觉禁止浮夸科技风格,风格必须克制、极简、专业、可信、结构化
diff --git a/frontend/next-env.d.ts b/frontend/next-env.d.ts
new file mode 100644
index 0000000..4f11a03
--- /dev/null
+++ b/frontend/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/frontend/next.config.js b/frontend/next.config.js
new file mode 100644
index 0000000..5715404
--- /dev/null
+++ b/frontend/next.config.js
@@ -0,0 +1,13 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ images: {
+ domains: ['localhost'],
+ },
+ // 配置后端API地址
+ env: {
+ API_URL: process.env.API_URL || 'http://localhost:24731',
+ },
+}
+
+module.exports = nextConfig
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
new file mode 100644
index 0000000..dba9c37
--- /dev/null
+++ b/frontend/package-lock.json
@@ -0,0 +1,5048 @@
+{
+ "name": "ameiba-ai-website-frontend",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "ameiba-ai-website-frontend",
+ "version": "1.0.0",
+ "dependencies": {
+ "next": "14.0.4",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "^20.10.0",
+ "@types/react": "^18.2.39",
+ "@types/react-dom": "^18.2.17",
+ "eslint": "^8.54.0",
+ "eslint-config-next": "14.0.4",
+ "typescript": "^5.3.2"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz",
+ "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz",
+ "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.3"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
+ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4"
+ }
+ },
+ "node_modules/@next/env": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/env/-/env-14.0.4.tgz",
+ "integrity": "sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ==",
+ "license": "MIT"
+ },
+ "node_modules/@next/eslint-plugin-next": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz",
+ "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob": "7.1.7"
+ }
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.4.tgz",
+ "integrity": "sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.4.tgz",
+ "integrity": "sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.4.tgz",
+ "integrity": "sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.4.tgz",
+ "integrity": "sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.4.tgz",
+ "integrity": "sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.4.tgz",
+ "integrity": "sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.4.tgz",
+ "integrity": "sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-ia32-msvc": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.4.tgz",
+ "integrity": "sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.4.tgz",
+ "integrity": "sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nolyfill/is-core-module": {
+ "version": "1.0.39",
+ "resolved": "https://registry.npmmirror.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz",
+ "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.4.0"
+ }
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rushstack/eslint-patch": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmmirror.com/@rushstack/eslint-patch/-/eslint-patch-1.16.1.tgz",
+ "integrity": "sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.2.tgz",
+ "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmmirror.com/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+ "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.43",
+ "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.19.43.tgz",
+ "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.31",
+ "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.31.tgz",
+ "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.1.4.tgz",
+ "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.4.0.tgz",
+ "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@unrs/resolver-binding-android-arm-eabi": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz",
+ "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-android-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz",
+ "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz",
+ "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-x64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz",
+ "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-freebsd-x64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz",
+ "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz",
+ "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz",
+ "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz",
+ "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz",
+ "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-loong64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz",
+ "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-loong64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz",
+ "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz",
+ "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz",
+ "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz",
+ "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz",
+ "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz",
+ "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz",
+ "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-openharmony-arm64": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz",
+ "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz",
+ "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz",
+ "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz",
+ "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz",
+ "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/acorn": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.15.0.tgz",
+ "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-query": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.3.2.tgz",
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.9.tgz",
+ "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.0",
+ "es-object-atoms": "^1.1.1",
+ "get-intrinsic": "^1.3.0",
+ "is-string": "^1.1.1",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmmirror.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
+ "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-shim-unscopables": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ast-types-flow": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmmirror.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
+ "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axe-core": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmmirror.com/axe-core/-/axe-core-4.13.0.tgz",
+ "integrity": "sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axobject-query": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/busboy": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/busboy/-/busboy-1.6.0.tgz",
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
+ "dependencies": {
+ "streamsearch": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.9.tgz",
+ "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "get-intrinsic": "^1.3.0",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001810",
+ "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+ "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/damerau-levenshtein": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
+ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.2",
+ "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.24.2.tgz",
+ "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-abstract-get": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/es-abstract-get/-/es-abstract-get-1.0.0.tgz",
+ "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.2",
+ "is-callable": "^1.2.7",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz",
+ "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.2",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.1.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.3.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "iterator.prototype": "^1.1.5",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.3.4.tgz",
+ "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-abstract-get": "^1.0.0",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.1.0",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-next": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/eslint-config-next/-/eslint-config-next-14.0.4.tgz",
+ "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@next/eslint-plugin-next": "14.0.4",
+ "@rushstack/eslint-patch": "^1.3.3",
+ "@typescript-eslint/parser": "^5.4.2 || ^6.0.0",
+ "eslint-import-resolver-node": "^0.3.6",
+ "eslint-import-resolver-typescript": "^3.5.2",
+ "eslint-plugin-import": "^2.28.1",
+ "eslint-plugin-jsx-a11y": "^6.7.1",
+ "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
+ },
+ "peerDependencies": {
+ "eslint": "^7.23.0 || ^8.0.0",
+ "typescript": ">=3.3.1"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.10",
+ "resolved": "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz",
+ "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.16.1",
+ "resolve": "^2.0.0-next.6"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmmirror.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz",
+ "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@nolyfill/is-core-module": "1.0.39",
+ "debug": "^4.4.0",
+ "get-tsconfig": "^4.10.0",
+ "is-bun-module": "^2.0.0",
+ "stable-hash": "^0.0.5",
+ "tinyglobby": "^0.2.13",
+ "unrs-resolver": "^1.6.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-import-resolver-typescript"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*",
+ "eslint-plugin-import-x": "*"
+ },
+ "peerDependenciesMeta": {
+ "eslint-plugin-import": {
+ "optional": true
+ },
+ "eslint-plugin-import-x": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.14.0.tgz",
+ "integrity": "sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.32.0",
+ "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
+ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.9",
+ "array.prototype.findlastindex": "^1.2.6",
+ "array.prototype.flat": "^1.3.3",
+ "array.prototype.flatmap": "^1.3.3",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.1",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.16.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.1",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.9",
+ "tsconfig-paths": "^3.15.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmmirror.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz",
+ "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "aria-query": "^5.3.2",
+ "array-includes": "^3.1.8",
+ "array.prototype.flatmap": "^1.3.2",
+ "ast-types-flow": "^0.0.8",
+ "axe-core": "^4.10.0",
+ "axobject-query": "^4.1.0",
+ "damerau-levenshtein": "^1.0.8",
+ "emoji-regex": "^9.2.2",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^3.3.5",
+ "language-tags": "^1.0.9",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.includes": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.37.5",
+ "resolved": "https://registry.npmmirror.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
+ "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.3",
+ "array.prototype.tosorted": "^1.1.4",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.2.1",
+ "estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.9",
+ "object.fromentries": "^2.0.8",
+ "object.values": "^1.2.1",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.5",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.12",
+ "string.prototype.repeat": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "5.0.0-canary-7118f5dd7-20230705",
+ "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz",
+ "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.20.3.tgz",
+ "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.4.4.tgz",
+ "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.2.0.tgz",
+ "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2",
+ "hasown": "^2.0.4",
+ "is-callable": "^1.2.7",
+ "is-document.all": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.14.3",
+ "resolved": "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.14.3.tgz",
+ "integrity": "sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bun-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/is-bun-module/-/is-bun-module-2.0.0.tgz",
+ "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.7.1"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.2",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.2.tgz",
+ "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-document.all": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-document.all/-/is-document.all-1.0.0.tgz",
+ "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmmirror.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
+ "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.3.2.tgz",
+ "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmmirror.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/language-subtag-registry": {
+ "version": "0.3.23",
+ "resolved": "https://registry.npmmirror.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
+ "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/language-tags": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmmirror.com/language-tags/-/language-tags-1.0.9.tgz",
+ "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "language-subtag-registry": "^0.3.20"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.18",
+ "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/napi-postinstall": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmmirror.com/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
+ "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "napi-postinstall": "lib/cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/napi-postinstall"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/next": {
+ "version": "14.0.4",
+ "resolved": "https://registry.npmmirror.com/next/-/next-14.0.4.tgz",
+ "integrity": "sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "14.0.4",
+ "@swc/helpers": "0.5.2",
+ "busboy": "1.6.0",
+ "caniuse-lite": "^1.0.30001406",
+ "graceful-fs": "^4.2.11",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.1",
+ "watchpack": "2.4.0"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "14.0.4",
+ "@next/swc-darwin-x64": "14.0.4",
+ "@next/swc-linux-arm64-gnu": "14.0.4",
+ "@next/swc-linux-arm64-musl": "14.0.4",
+ "@next/swc-linux-x64-gnu": "14.0.4",
+ "@next/swc-linux-x64-musl": "14.0.4",
+ "@next/swc-win32-arm64-msvc": "14.0.4",
+ "@next/swc-win32-ia32-msvc": "14.0.4",
+ "@next/swc-win32-x64-msvc": "14.0.4"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "sass": "^1.3.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-exports-info": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmmirror.com/node-exports-info/-/node-exports-info-1.6.2.tgz",
+ "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array.prototype.flatmap": "^1.3.3",
+ "es-errors": "^1.3.0",
+ "object.entries": "^1.1.9",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/node-exports-info/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.9.tgz",
+ "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/own-keys": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/own-keys/-/own-keys-1.0.2.tgz",
+ "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmmirror.com/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "2.0.0-next.7",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-2.0.0-next.7.tgz",
+ "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.2",
+ "node-exports-info": "^1.6.0",
+ "object-keys": "^1.1.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.4.tgz",
+ "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "get-intrinsic": "^1.3.0",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stable-hash": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmmirror.com/stable-hash/-/stable-hash-0.0.5.tgz",
+ "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/streamsearch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/streamsearch/-/streamsearch-1.1.0.tgz",
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/string.prototype.includes": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
+ "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.1.0.tgz",
+ "integrity": "sha512-tHNHTxInrYLCga9O9YGxWA3G9/nnzQw8UGAyqGx3Ar1pSTTzIuM4woFSq4SowkXCjJIwq5sIiQvEfRI9tCH1qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.2",
+ "get-intrinsic": "^1.3.0",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.4",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.11",
+ "resolved": "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz",
+ "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.2",
+ "es-object-atoms": "^1.1.2",
+ "has-property-descriptors": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz",
+ "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/styled-jsx": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz",
+ "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
+ "license": "MIT",
+ "dependencies": {
+ "client-only": "0.0.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
+ "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.8.tgz",
+ "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.9",
+ "for-each": "^0.3.5",
+ "gopd": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "possible-typed-array-names": "^1.1.0",
+ "reflect.getprototypeof": "^1.0.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unrs-resolver": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/unrs-resolver/-/unrs-resolver-1.12.2.tgz",
+ "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "napi-postinstall": "^0.3.4"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unrs-resolver"
+ },
+ "optionalDependencies": {
+ "@unrs/resolver-binding-android-arm-eabi": "1.12.2",
+ "@unrs/resolver-binding-android-arm64": "1.12.2",
+ "@unrs/resolver-binding-darwin-arm64": "1.12.2",
+ "@unrs/resolver-binding-darwin-x64": "1.12.2",
+ "@unrs/resolver-binding-freebsd-x64": "1.12.2",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-loong64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.12.2",
+ "@unrs/resolver-binding-linux-x64-musl": "1.12.2",
+ "@unrs/resolver-binding-openharmony-arm64": "1.12.2",
+ "@unrs/resolver-binding-wasm32-wasi": "1.12.2",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.12.2"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "license": "MIT",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.22",
+ "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.22.tgz",
+ "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.9",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/frontend/package.json b/frontend/package.json
new file mode 100644
index 0000000..da05ea8
--- /dev/null
+++ b/frontend/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "ameiba-ai-website-frontend",
+ "version": "1.0.0",
+ "description": "阿美巴AI官网 第二期 前端展示层",
+ "scripts": {
+ "dev": "node node_modules/next/dist/bin/next dev -p 28642",
+ "build": "node node_modules/next/dist/bin/next build",
+ "start": "node node_modules/next/dist/bin/next start -p 28642",
+ "lint": "node node_modules/next/dist/bin/next lint"
+ },
+ "dependencies": {
+ "next": "14.0.4",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "^20.10.0",
+ "@types/react": "^18.2.39",
+ "@types/react-dom": "^18.2.17",
+ "eslint": "^8.54.0",
+ "eslint-config-next": "14.0.4",
+ "typescript": "^5.3.2"
+ }
+}
diff --git a/frontend/public/images/icp.png b/frontend/public/images/icp.png
new file mode 100644
index 0000000..9f76394
Binary files /dev/null and b/frontend/public/images/icp.png differ
diff --git a/frontend/public/images/logo.png b/frontend/public/images/logo.png
new file mode 100644
index 0000000..39332e0
Binary files /dev/null and b/frontend/public/images/logo.png differ
diff --git a/frontend/src/app/about/page.tsx b/frontend/src/app/about/page.tsx
new file mode 100644
index 0000000..c8fe339
--- /dev/null
+++ b/frontend/src/app/about/page.tsx
@@ -0,0 +1,90 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '阿美巴是谁',
+ description: '了解阿美巴AI - AI时代企业进化平台,我们的定位、使命、服务对象与发展历程',
+ canonical: '/about',
+ }),
+};
+
+export default async function AboutPage() {
+ const settings = await getSiteSettings();
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '阿美巴', url: '/about' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['about.title'] || '阿美巴是谁'}
+
+
+ {settings['about.positionTitle'] || '定位'}
+
+ {settings['about.positionText'] || settings['about.intro'] || '阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。'}
+
+
+
+
+ {settings['about.existTitle'] || '为什么存在'}
+
+ {(settings['about.existText'] || '在AI时代,企业面临着前所未有的挑战与机遇。传统的企业管理方法已无法适应快速变化的环境,企业需要一套系统化的进化方法,实现从传统模式向AI时代模式的转型。\n阿美巴的存在,就是为了帮助企业完成这一进化过程,实现可持续增长与发展。').split('\n')[0]}
+
+
+ {(settings['about.existText'] || '').split('\n')[1] || '阿美巴的存在,就是为了帮助企业完成这一进化过程,实现可持续增长与发展。'}
+
+
+
+
+ {settings['about.audienceTitle'] || '服务对象'}
+
+ {settings['about.audienceText'] || '我们服务的对象是那些希望在AI时代实现转型与增长的企业,无论企业当前处于哪个发展阶段,我们都能提供适合的进化路径与能力支持。'}
+
+
+
+
+ {settings['about.historyTitle'] || '发展历程'}
+
+ {settings['about.historyText'] || '待填充'}
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/admin/page.tsx b/frontend/src/app/admin/page.tsx
new file mode 100644
index 0000000..dad5e91
--- /dev/null
+++ b/frontend/src/app/admin/page.tsx
@@ -0,0 +1,160 @@
+'use client';
+
+import { FormEvent, useEffect, useState } from 'react';
+
+const API_URL = process.env.API_URL || 'http://localhost:24731';
+const contentTypes = [
+ { value: 'page', label: '页面' }, { value: 'article', label: '文章' }, { value: 'case', label: '案例' },
+ { value: 'faq', label: '常见问题' }, { value: 'capability', label: '企业能力' }, { value: 'service', label: '服务' },
+];
+const statusLabels: Record = { draft: '草稿', review: '审核中', published: '已发布', unpublished: '已下线', historical: '历史版本' };
+const detailFields: Record> = {
+ page: [{ key: 'slug', label: '页面地址' }, { key: 'summary', label: '页面摘要', multiline: true }, { key: 'seo_title', label: '搜索标题' }, { key: 'seo_description', label: '搜索简介', multiline: true }],
+ article: [{ key: 'category', label: '文章分类' }, { key: 'tags', label: '文章标签' }, { key: 'author', label: '作者' }],
+ case: [{ key: 'client_name', label: '客户名称' }, { key: 'industry', label: '所属行业' }, { key: 'challenge', label: '客户遇到的问题', multiline: true }, { key: 'solution', label: '解决方案', multiline: true }, { key: 'result', label: '实施结果', multiline: true }],
+ faq: [{ key: 'question', label: '问题' }, { key: 'answer', label: '回答', multiline: true }],
+ capability: [{ key: 'capability_type', label: '能力分类' }, { key: 'features', label: '能力说明', multiline: true }, { key: 'use_cases', label: '适用场景', multiline: true }],
+ service: [{ key: 'service_type', label: '服务类型' }, { key: 'pricing_model', label: '收费方式' }, { key: 'delivery_method', label: '交付方式' }],
+};
+const pageChoices = [
+ { value: 'home', label: '首页', description: '修改首页顶部展示的标题和介绍' },
+ { value: 'about', label: '阿美巴', description: '修改“阿美巴是谁”页面的标题和开场介绍' },
+ { value: 'evolution', label: '企业进化', description: '修改企业进化页面的标题和开场介绍' },
+ { value: 'value', label: '四大价值', description: '修改四大价值页面的标题和开场介绍' },
+ { value: 'amb', label: 'A/M-B', description: '修改A/M-B三态模型页面的标题和开场介绍' },
+ { value: 'capabilities', label: '能力地图', description: '修改能力地图页面的标题和开场介绍' },
+ { value: 'cases', label: '案例', description: '修改案例页面的标题和开场介绍' },
+ { value: 'knowledge', label: '知识中心', description: '修改知识中心页面的标题和开场介绍' },
+ { value: 'faq', label: 'FAQ', description: '修改常见问题页面的标题和开场介绍' },
+ { value: 'contact', label: '联系我们', description: '修改联系方式、服务时间和咨询服务' },
+ { value: 'site', label: '全站底部', description: '修改网站名称和页脚版权文字' },
+];
+const pageFields: Record> = {
+ home: [
+ { key: 'site.name', label: '网站名称', help: '显示在顶部左侧和浏览器页面中' },
+ { key: 'home.heroTitle', label: '首页主标题', help: '显示在首页深色大横幅中' },
+ { key: 'home.heroSubtitle', label: '首页副标题', help: '显示在首页主标题下方' },
+ { key: 'home.heroDescription', label: '首页介绍文字', help: '显示在首页副标题下方', multiline: true },
+ ],
+ about: [
+ { key: 'about.title', label: '页面标题', help: '显示在“阿美巴”页面最上方' },
+ { key: 'about.intro', label: '开场介绍', help: '显示在“定位”部分,用于介绍阿美巴', multiline: true },
+ { key: 'about.positionTitle', label: '定位标题', help: '定位区块的标题' },
+ { key: 'about.positionText', label: '定位正文', help: '定位区块下方的正文', multiline: true },
+ { key: 'about.existTitle', label: '为什么存在标题', help: '为什么存在区块的标题' },
+ { key: 'about.existText', label: '为什么存在正文', help: '每行填写一段,显示在该区块中', multiline: true },
+ { key: 'about.audienceTitle', label: '服务对象标题', help: '服务对象区块的标题' },
+ { key: 'about.audienceText', label: '服务对象正文', help: '服务对象区块下方的正文', multiline: true },
+ { key: 'about.historyTitle', label: '发展历程标题', help: '发展历程区块的标题' },
+ { key: 'about.historyText', label: '发展历程正文', help: '发展历程区块下方的文字', multiline: true },
+ ],
+ evolution: [
+ { key: 'evolution.title', label: '页面标题', help: '显示在“企业进化”页面最上方' },
+ { key: 'evolution.intro', label: '开场介绍', help: '显示在“什么是企业进化”部分', multiline: true },
+ { key: 'evolution.definitionTitle', label: '定义区块标题', help: '什么是企业进化区块的标题' },
+ { key: 'evolution.definitionMore', label: '定义补充说明', help: '定义区块的第二段文字', multiline: true },
+ { key: 'evolution.whyTitle', label: '为什么需要标题', help: '挑战说明区块的标题' },
+ { key: 'evolution.whyIntro', label: '挑战说明', help: '挑战列表上方的文字' },
+ { key: 'evolution.whyItems', label: '挑战项目', help: '每行填写一项,保存后显示为列表', multiline: true },
+ ],
+ value: [
+ { key: 'value.title', label: '页面标题', help: '显示在“四大价值”页面最上方' },
+ { key: 'value.intro', label: '开场介绍', help: '显示在价值体系概述部分', multiline: true },
+ { key: 'value.overviewTitle', label: '概述区块标题', help: '价值体系概述区块的标题' },
+ { key: 'value.valuesTitle', label: '价值卡片标题', help: '四张价值卡片上方的标题' },
+ { key: 'value.relationTitle', label: '关系区块标题', help: '价值体系关系区块的标题' },
+ { key: 'value.relationText', label: '关系说明', help: '价值体系关系区块的说明文字', multiline: true },
+ ],
+ amb: [
+ { key: 'amb.title', label: '页面标题', help: '显示在“A/M-B”页面最上方' },
+ { key: 'amb.intro', label: '开场介绍', help: '显示在模型介绍部分', multiline: true },
+ { key: 'amb.whatTitle', label: '“什么是A/M-B”标题', help: '模型说明区块的标题' },
+ { key: 'amb.whatNote', label: '模型重要说明', help: '模型说明区块中的重点文字', multiline: true },
+ { key: 'amb.whatPurpose', label: '模型作用说明', help: '模型说明区块中的最后一段', multiline: true },
+ { key: 'amb.statesTitle', label: '三种状态标题', help: '三种状态卡片上方的标题' },
+ { key: 'amb.stateA', label: 'A态卡片', help: '格式:卡片标题|卡片说明' },
+ { key: 'amb.stateM', label: 'M态卡片', help: '格式:卡片标题|卡片说明' },
+ { key: 'amb.stateB', label: 'B态卡片', help: '格式:卡片标题|卡片说明' },
+ { key: 'amb.recognitionTitle', label: '状态识别标题', help: '状态识别区块的标题' },
+ { key: 'amb.recognitionText', label: '状态识别说明', help: '每行一段,显示在状态识别区块', multiline: true },
+ ],
+ capabilities: [
+ { key: 'capabilities.title', label: '页面标题', help: '显示在能力地图页面最上方' },
+ { key: 'capabilities.intro', label: '开场介绍', help: '显示在能力概述部分', multiline: true },
+ ],
+ cases: [
+ { key: 'cases.title', label: '页面标题', help: '显示在案例页面最上方' },
+ { key: 'cases.intro', label: '开场介绍', help: '显示在案例概述部分', multiline: true },
+ ],
+ knowledge: [
+ { key: 'knowledge.title', label: '页面标题', help: '显示在知识中心页面最上方' },
+ { key: 'knowledge.intro', label: '开场介绍', help: '显示在知识体系部分', multiline: true },
+ ],
+ faq: [
+ { key: 'faq.title', label: '页面标题', help: '显示在FAQ页面最上方' },
+ { key: 'faq.intro', label: '开场介绍', help: '显示在FAQ概述部分', multiline: true },
+ ],
+ contact: [
+ { key: 'contact.title', label: '页面标题', help: '显示在“联系我们”页面最上方' },
+ { key: 'contact.contactTitle', label: '联系方式标题', help: '联系方式卡片区域上方的标题' },
+ { key: 'contact.email', label: '邮箱', help: '显示在联系方式的邮箱卡片中' },
+ { key: 'contact.phone', label: '电话', help: '显示在联系方式的电话卡片中' },
+ { key: 'contact.address', label: '地址', help: '显示在联系方式的地址卡片中' },
+ { key: 'contact.serviceHoursTitle', label: '服务时间标题', help: '服务时间区域的标题' },
+ { key: 'contact.serviceHours', label: '服务时间', help: '例如:周一至周五:9:00 - 18:00' },
+ { key: 'contact.consultationTitle', label: '咨询服务标题', help: '咨询服务区域的标题' },
+ { key: 'contact.consultationIntro', label: '咨询服务说明', help: '咨询服务列表上方的说明文字' },
+ { key: 'contact.consultationItems', label: '咨询服务项目', help: '每行填写一项,保存后会显示为列表', multiline: true },
+ { key: 'contact.cooperationTitle', label: '合作方式标题', help: '合作方式区域的标题' },
+ { key: 'contact.cooperationItems', label: '合作方式项目', help: '每行填写一项,保存后会显示为列表', multiline: true },
+ { key: 'contact.faqTitle', label: '常见问题标题', help: '常见问题区域的标题' },
+ { key: 'contact.faqText', label: '常见问题说明', help: '常见问题链接前的说明文字' },
+ { key: 'contact.relatedTitle', label: '相关知识标题', help: '页面底部相关知识区域的标题' },
+ ],
+ site: [
+ { key: 'site.name', label: '网站名称', help: '显示在顶部左侧' },
+ { key: 'site.footerCopyright', label: '页脚版权文字', help: '显示在所有页面最底部' },
+ { key: 'site.footerEmail', label: '页脚邮箱', help: '显示在所有页面页脚,可点击发送邮件' },
+ { key: 'site.footerPhone', label: '页脚电话', help: '显示在所有页面页脚,可点击拨打电话' },
+ { key: 'site.footerAddress', label: '页脚地址', help: '显示在所有页面页脚' },
+ { key: 'site.icp', label: 'ICP备案号', help: '显示在页脚,点击后跳转工信部备案查询网站' },
+ ],
+};
+
+type ContentItem = { content_id: string; title: string; body?: string; content_type: string; publish_status: string; [key: string]: any };
+type Setting = { setting_key: string; setting_value: string; setting_group: string };
+
+async function request(path: string, token: string, options: RequestInit = {}) {
+ const response = await fetch(`${API_URL}${path}`, { ...options, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, ...(options.headers || {}) } });
+ const data = response.status === 204 ? null : await response.json();
+ if (!response.ok) throw new Error(data?.error || '操作没有完成,请稍后重试');
+ return data;
+}
+function typeLabel(value: string) { return contentTypes.find(item => item.value === value)?.label || value; }
+function settingLabel(key: string) { return ({ 'home.heroTitle': '首页主标题', 'home.heroSubtitle': '首页副标题', 'home.heroDescription': '首页介绍文字', 'site.name': '网站名称', 'site.footerCopyright': '页脚版权文字' } as Record)[key] || key; }
+
+export default function AdminPage() {
+ const [token, setToken] = useState(''); const [username, setUsername] = useState('admin'); const [password, setPassword] = useState('');
+ const [error, setError] = useState(''); const [message, setMessage] = useState(''); const [activeTab, setActiveTab] = useState<'settings' | 'contents' | 'password'>('settings');
+ const [settings, setSettings] = useState([]); const [selectedPage, setSelectedPage] = useState('home'); const [type, setType] = useState('article'); const [contents, setContents] = useState([]);
+ const [editing, setEditing] = useState(null); const [details, setDetails] = useState>({}); const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState('');
+
+ useEffect(() => { const saved = window.localStorage.getItem('ameiba_admin_token'); if (saved) { setToken(saved); loadSettings(saved); } }, []);
+ async function loadSettings(authToken = token) { try { setSettings(await request('/api/admin/settings', authToken)); } catch (e: any) { setError(e.message); } }
+ async function loadContents(contentType = type, authToken = token) { try { setContents((await request(`/api/admin/contents/${contentType}?pageSize=100`, authToken)).list || []); } catch (e: any) { setError(e.message); } }
+ async function login(event: FormEvent) { event.preventDefault(); setError(''); try { const response = await fetch(`${API_URL}/api/admin/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); if (!response.ok) throw new Error(data.error || '用户名或密码错误'); window.localStorage.setItem('ameiba_admin_token', data.token); setToken(data.token); setPassword(''); await loadSettings(data.token); } catch (e: any) { setError(e.message); } }
+ async function saveSetting(setting: Setting) { setError(''); setMessage(''); try { await request(`/api/admin/settings/${encodeURIComponent(setting.setting_key)}`, token, { method: 'PUT', body: JSON.stringify({ value: setting.setting_value, group: setting.setting_group }) }); setMessage('已保存,刷新前台页面即可看到修改。'); } catch (e: any) { setError(e.message); } }
+ function beginCreate() { setError(''); setMessage(''); setDetails({}); setEditing({ content_id: '', title: '', body: '', content_type: type, publish_status: 'draft' }); }
+ function beginEdit(item: ContentItem) { setError(''); setMessage(''); const next: Record = {}; (detailFields[item.content_type] || []).forEach(field => { next[field.key] = item[field.key] == null ? '' : String(item[field.key]); }); setDetails(next); setEditing({ ...item }); }
+ async function saveContent(event: FormEvent) { event.preventDefault(); if (!editing) return; setError(''); setMessage(''); const data = { title: editing.title, body: editing.body || '', publish_status: editing.publish_status, ...details }; try { const path = editing.content_id ? `/api/admin/contents/${editing.content_type}/${editing.content_id}` : `/api/admin/contents/${type}`; await request(path, token, { method: editing.content_id ? 'PUT' : 'POST', body: JSON.stringify(data) }); setMessage('内容已保存。'); setEditing(null); await loadContents(type); } catch (e: any) { setError(e.message); } }
+ async function changePassword(event: FormEvent) { event.preventDefault(); setError(''); setMessage(''); try { await request('/api/admin/password', token, { method: 'PUT', body: JSON.stringify({ currentPassword, newPassword }) }); setMessage('密码已修改,请重新登录。'); logout(); } catch (e: any) { setError(e.message); } }
+ function logout() { window.localStorage.removeItem('ameiba_admin_token'); setToken(''); }
+
+ if (!token) return 阿美巴内容管理
管理后台
在这里修改网站文字、文章和知识内容。
;
+
+ return 阿美巴内容管理
站点管理
修改并保存后,前台对应位置会使用新内容。
{message &&
{message}
}{error &&
{error}
}
+ {activeTab === 'settings' &&
按页面修改文字
先选择前台页面,再修改该页面上实际看到的文字。每项旁边都写明了修改位置。
{pageChoices.find(page => page.value === selectedPage)?.description}
{(pageFields[selectedPage] || []).map(field => { const index = settings.findIndex(item => item.setting_key === field.key); const setting = index >= 0 ? settings[index] : { setting_key: field.key, setting_value: '', setting_group: selectedPage }; return
{field.label}{field.help}
{field.multiline ?
})}
}
+ {activeTab === 'contents' &&
文章与内容
选择内容类型后,可以新增、修改或删除内容。
{editing && }{contents.map(item =>
{item.title || '未命名内容'}{typeLabel(item.content_type)} · {statusLabels[item.publish_status] || item.publish_status}
)}
}
+ {activeTab === 'password' &&
}
+
;
+}
diff --git a/frontend/src/app/amb/a/page.tsx b/frontend/src/app/amb/a/page.tsx
new file mode 100644
index 0000000..422f5a3
--- /dev/null
+++ b/frontend/src/app/amb/a/page.tsx
@@ -0,0 +1,135 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: 'A态·入态',
+ description: '企业开始进入AI时代企业进化的一种状态,建立基础能力与AI应用体系',
+ canonical: '/amb/a',
+ }),
+};
+
+export default function AmbAPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: 'A/M-B', url: '/amb' },
+ { name: 'A态·入态', url: '/amb/a' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
A态·入态
+
+
+ 定义
+
+ A态·入态,是企业开始进入AI时代企业进化的一种状态。企业开始建立AI时代进化认知,
+ 明确需要解决的方向,并启动基础性的能力、组织和AI应用建设。
+
+
+
+
+ 企业特征
+
+ - 传统运营模式为主
+ - 数字化程度较低
+ - 缺乏系统化的管理方法
+ - 组织结构相对僵化
+
+
+
+
+ 常见状态
+
+ - 业务增长遇到瓶颈
+ - 运营效率有待提升
+ - 组织能力跟不上业务发展
+ - 缺乏清晰的发展战略
+
+
+
+
+ 核心任务
+
+ - 建立数字化基础设施
+ - 优化核心业务流程
+ - 提升组织能力
+ - 制定清晰的发展战略
+
+
+
+
+ 关键进化动作
+
+ 建立数字化基础设施、优化核心业务流程、提升组织能力、制定清晰的发展战略。
+
+
+
+
+ 典型障碍
+
+ - 缺乏数字化人才
+ - 组织变革阻力大
+ - 资源投入不足
+ - 缺乏系统化的方法论
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/amb/b/page.tsx b/frontend/src/app/amb/b/page.tsx
new file mode 100644
index 0000000..d539a27
--- /dev/null
+++ b/frontend/src/app/amb/b/page.tsx
@@ -0,0 +1,128 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: 'B态·越态',
+ description: '企业突破原有运行边界、形成新的企业运行能力的一种状态',
+ canonical: '/amb/b',
+ }),
+};
+
+export default function AmbBPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: 'A/M-B', url: '/amb' },
+ { name: 'B态·越态', url: '/amb/b' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
B态·越态
+
+
+ 定义
+
+ B态·越态,是企业突破原有运行边界、形成新的企业运行能力的一种状态。
+ 企业进一步通过组织重塑、系统重构、企业级AI等方式,形成新的经营与管理方式。
+
+
+
+
+ 企业特征
+
+ - 突破原有运行边界
+ - 形成新的运行能力
+ - 组织重塑与系统重构
+ - 企业级AI应用
+
+
+
+
+ 常见状态
+
+ - 业务模式创新
+ - 组织架构重塑
+ - 系统重构升级
+ - AI深度融合
+
+
+
+
+ 关键进化动作
+
+ - 组织重塑与变革
+ - 系统重构与升级
+ - 企业级AI部署
+ - 新业务模式探索
+
+
+
+
+ 典型障碍
+
+ - 组织变革阻力
+ - 系统重构复杂度
+ - AI技术应用难度
+ - 文化转型挑战
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/amb/m/page.tsx b/frontend/src/app/amb/m/page.tsx
new file mode 100644
index 0000000..96cf282
--- /dev/null
+++ b/frontend/src/app/amb/m/page.tsx
@@ -0,0 +1,135 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: 'M态·优态',
+ description: '企业进一步围绕现有经营与管理体系进行优化的一种状态',
+ canonical: '/amb/m',
+ }),
+};
+
+export default function AmbMPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: 'A/M-B', url: '/amb' },
+ { name: 'M态·优态', url: '/amb/m' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
M态·优态
+
+
+ 定义
+
+ M态·优态,是企业进一步围绕现有经营与管理体系进行优化的一种状态。
+ 企业重点围绕流程、组织、标准化、AI应用等持续优化,使企业形成更稳定、更可复制的运行能力。
+
+
+
+
+ 企业特征
+
+ - 数字化程度较高
+ - 运营效率持续优化
+ - 组织能力较强
+ - 具备系统化的管理方法
+
+
+
+
+ 常见状态
+
+ - 业务稳定增长
+ - 运营效率较高
+ - 组织能力匹配业务发展
+ - 具备一定的创新能力
+
+
+
+
+ 核心任务
+
+ - 持续优化运营效率
+ - 提升组织创新能力
+ - 拓展新的业务领域
+ - 建立竞争优势
+
+
+
+
+ 进化目标
+
+ 从M态进化到B态,实现跨越式发展。
+
+
+
+
+ 典型障碍
+
+ - 创新动力不足
+ - 组织惯性较大
+ - 资源分配不够灵活
+ - 缺乏突破性思维
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/amb/page.tsx b/frontend/src/app/amb/page.tsx
new file mode 100644
index 0000000..acf0c81
--- /dev/null
+++ b/frontend/src/app/amb/page.tsx
@@ -0,0 +1,112 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: 'A/M-B企业进化路径|AI时代企业三态状态模型',
+ description: 'A/M-B是阿美巴用于识别企业在AI时代进化状态的三态状态模型,包括A态·入态、M态·优态、B态·越态',
+ canonical: '/amb',
+ }),
+};
+
+export default async function AMBPage() {
+ const settings = await getSiteSettings();
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: 'A/M-B', url: '/amb' },
+ ];
+
+ const states = [
+ {
+ id: 'a',
+ title: 'A态·入态',
+ description: '企业开始进入AI时代企业进化的一种状态',
+ link: '/amb/a',
+ },
+ {
+ id: 'm',
+ title: 'M态·优态',
+ description: '企业进一步围绕现有经营与管理体系进行优化的一种状态',
+ link: '/amb/m',
+ },
+ {
+ id: 'b',
+ title: 'B态·越态',
+ description: '企业突破原有运行边界、形成新的企业运行能力的一种状态',
+ link: '/amb/b',
+ },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['amb.title'] || 'A/M-B三态模型:AI时代企业进化状态识别框架'}
+
+
+ {settings['amb.whatTitle'] || '什么是A/M-B'}
+
+ {settings['amb.intro'] || 'A/M-B是阿美巴用于识别企业在AI时代进化状态的三态状态模型,包括A态·入态、M态·优态、B态·越态。'}
+
+
+ {settings['amb.whatNote'] || 'A/M-B不是产品套餐,不是收费等级,不是强制线性路径,不是所有企业必须经历的三个固定阶段。'}
+
+
+ {settings['amb.whatPurpose'] || 'A/M-B的作用,是帮助企业识别自身所处状态,并进一步判断当前需要完成的关键进化动作。'}
+
+
+
+
+ {settings['amb.statesTitle'] || '三种状态'}
+
+ {states.map((state) => (
+
+
+
{state.id === 'a' ? (settings['amb.stateA'] || `A态·入态|${state.description}`).split('|').slice(1).join('|') : state.id === 'm' ? (settings['amb.stateM'] || `M态·优态|${state.description}`).split('|').slice(1).join('|') : (settings['amb.stateB'] || `B态·越态|${state.description}`).split('|').slice(1).join('|')}
+
+ ))}
+
+
+
+
+ {settings['amb.recognitionTitle'] || '状态识别'}
+ {(settings['amb.recognitionText'] || '企业可以根据自身情况处于不同状态,也不意味着所有企业必须从A到M再到B。\n企业需要根据自身发展阶段和实际情况,判断当前所处的状态,并确定需要完成的关键进化动作。').split('\n').map(text => {text}
)}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/capabilities/page.tsx b/frontend/src/app/capabilities/page.tsx
new file mode 100644
index 0000000..26df2c8
--- /dev/null
+++ b/frontend/src/app/capabilities/page.tsx
@@ -0,0 +1,117 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+const API_URL = process.env.API_URL || 'http://localhost:3000';
+
+async function getCapabilities() {
+ try {
+ const res = await fetch(`${API_URL}/api/contents/capability?pageSize=100`, {
+ cache: 'no-store',
+ });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return data.list || [];
+ } catch (error) {
+ return [];
+ }
+}
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '能力地图',
+ description: '企业进化的完整能力体系,包括战略顶层设计、经营增长、组织重塑等能力',
+ canonical: '/capabilities',
+ }),
+};
+
+export default async function CapabilitiesPage() {
+ const capabilities = await getCapabilities();
+ const settings = await getSiteSettings();
+
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '能力地图', url: '/capabilities' },
+ ];
+
+ // 按类别分组
+ const categorySet = new Set();
+ capabilities.forEach((c: any) => {
+ categorySet.add(String(c.capability_type || '其他'));
+ });
+ const categories = Array.from(categorySet);
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['capabilities.title'] || '企业进化能力地图'}
+
+
+ {settings['capabilities.overviewTitle'] || '能力概述'}
+
+ {settings['capabilities.intro'] || '能力是底层实体,不是产品套餐。阿美巴提供完整的企业进化能力体系,帮助企业在战略、经营、组织、技术、AI等多个维度实现进化。'}
+
+
+
+
+ {settings['capabilities.categoryTitle'] || '能力分类'}
+ {capabilities.length > 0 ? (
+ categories.map((category: string) => (
+
+
{category}
+
+ {capabilities
+ .filter((c: any) => String(c.capability_type || '其他') === category)
+ .map((capability: any) => (
+
+
{capability.title}
+
{capability.features || capability.body || ''}
+
+ ))}
+
+
+ ))
+ ) : (
+
+
暂无能力数据
+
能力内容正在完善中,请稍后再来查看。
+
+ )}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/cases/page.tsx b/frontend/src/app/cases/page.tsx
new file mode 100644
index 0000000..097716e
--- /dev/null
+++ b/frontend/src/app/cases/page.tsx
@@ -0,0 +1,104 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+const API_URL = process.env.API_URL || 'http://localhost:24731';
+interface CaseItem { id: string; title: string; slug: string; client_name: string; industry: string; summary: string; }
+
+async function getCases(): Promise {
+ try {
+ const res = await fetch(`${API_URL}/api/contents/case?pageSize=100`, { cache: 'no-store' });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return (data.list || []).map((item: any) => ({ ...item, id: item.id || item.content_id, summary: item.summary || item.body || '' }));
+ } catch { return []; }
+}
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '案例',
+ description: '阿美巴将通过企业进化案例,展示企业在真实经营环境中的进化过程',
+ canonical: '/cases',
+ }),
+};
+
+export default async function CasesPage() {
+ const settings = await getSiteSettings();
+ const cases = await getCases();
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '案例', url: '/cases' },
+ ];
+
+ // 案例列表 - 从CMS获取published状态的案例
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['cases.title'] || '企业进化案例'}
+
+
+ {settings['cases.overviewTitle'] || '案例概述'}
+
+ {settings['cases.intro'] || '阿美巴将通过企业进化案例,展示企业在真实经营环境中的目标、现状、障碍、根因、进化路径与实施过程。'}
+
+
+
+
+ {settings['cases.listTitle'] || '案例列表'}
+ {cases.length > 0 ? (
+
+ {cases.map((caseItem) => (
+
+
+
+ {caseItem.industry}
+ {caseItem.client_name}
+
+
{caseItem.summary}
+
+ ))}
+
+ ) : (
+
+ )}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/concepts/page.tsx b/frontend/src/app/concepts/page.tsx
new file mode 100644
index 0000000..4453c12
--- /dev/null
+++ b/frontend/src/app/concepts/page.tsx
@@ -0,0 +1,108 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '概念',
+ description: '企业进化的知识实体概念列表,展示实体定义与关联关系',
+ canonical: '/concepts',
+ }),
+};
+
+export default function ConceptsPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '概念', url: '/concepts' },
+ ];
+
+ // 概念列表 - 从CMS获取实体数据
+ interface ConceptItem {
+ id: string;
+ name: string;
+ slug: string;
+ definition: string;
+ description: string;
+ }
+
+ const concepts: ConceptItem[] = [
+ // 概念数据将从CMS接口获取
+ // 示例结构:
+ // {
+ // id: 'entity-001',
+ // name: '概念名称',
+ // slug: 'concept-slug',
+ // definition: '概念定义',
+ // description: '概念描述',
+ // }
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
概念
+
+
+ 概念概述
+
+ 概念是企业进化的知识实体,每个概念都有明确的定义和关联关系。
+ 通过概念可以理解企业进化的知识体系。
+
+
+
+
+ 概念列表
+ {concepts.length > 0 ? (
+
+ {concepts.map((concept) => (
+
+
+
{concept.definition}
+
{concept.description}
+
+ ))}
+
+ ) : (
+
+
暂无概念数据
+
概念内容正在完善中,请稍后再来查看。
+
+ )}
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/contact/page.tsx b/frontend/src/app/contact/page.tsx
new file mode 100644
index 0000000..859f8f1
--- /dev/null
+++ b/frontend/src/app/contact/page.tsx
@@ -0,0 +1,114 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '联系我们',
+ description: '联系阿美巴AI,了解企业进化服务',
+ canonical: '/contact',
+ }),
+};
+
+function list(value: string | undefined, fallback: string[]) {
+ return (value ? value.split('\n').map(item => item.trim()).filter(Boolean) : fallback);
+}
+
+export default async function ContactPage() {
+ const settings = await getSiteSettings();
+ const consultationItems = list(settings['contact.consultationItems'], ['企业进化诊断', '进化路径规划', '战略咨询', '组织变革咨询', 'AI部署咨询']);
+ const cooperationItems = list(settings['contact.cooperationItems'], ['顾问服务', '咨询服务', '企业陪跑', '定制化服务']);
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '联系我们', url: '/contact' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['contact.title'] || '联系我们'}
+
+
+ {settings['contact.contactTitle'] || '联系方式'}
+
+
+
邮箱
+
{settings['contact.email'] || 'contact@ameiba.com'}
+
+
+
电话
+
{settings['contact.phone'] || '待填充'}
+
+
+
地址
+
{settings['contact.address'] || '待填充'}
+
+
+
+
+
+ {settings['contact.serviceHoursTitle'] || '服务时间'}
+
+ {settings['contact.serviceHours'] || '周一至周五:9:00 - 18:00'}
+
+
+
+
+ {settings['contact.consultationTitle'] || '咨询服务'}
+
+ {settings['contact.consultationIntro'] || '我们提供以下咨询服务:'}
+
+
+ {consultationItems.map(item => - {item}
)}
+
+
+
+
+ {settings['contact.cooperationTitle'] || '合作方式'}
+
+ {cooperationItems.map(item => - {item}
)}
+
+
+
+
+ {settings['contact.faqTitle'] || '常见问题'}
+
+ {settings['contact.faqText'] || '如有其他问题,请查看'}常见问题或直接联系我们。
+
+
+
+
+ {settings['contact.relatedTitle'] || '相关知识'}
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/evolution/method/page.tsx b/frontend/src/app/evolution/method/page.tsx
new file mode 100644
index 0000000..7218a8f
--- /dev/null
+++ b/frontend/src/app/evolution/method/page.tsx
@@ -0,0 +1,129 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '进化方法',
+ description: '企业进化的方法论:以终为始、目标先于问题、现状分析、差距识别、根因分析、路径规划、实施迭代',
+ canonical: '/evolution/method',
+ }),
+};
+
+export default function EvolutionMethodPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '企业进化', url: '/evolution' },
+ { name: '进化方法', url: '/evolution/method' },
+ ];
+
+ const methods = [
+ {
+ id: 'goal-first',
+ title: '以终为始',
+ description: '先明确企业进化的终极目标,再反推实现路径',
+ },
+ {
+ id: 'goal-before-problem',
+ title: '目标先于问题',
+ description: '先设定目标,再分析现状与问题,避免被问题牵着走',
+ },
+ {
+ id: 'current-analysis',
+ title: '现状分析',
+ description: '全面评估企业当前状态,包括战略、组织、流程、能力等',
+ },
+ {
+ id: 'gap-identification',
+ title: '差距识别',
+ description: '对比目标与现状,识别关键差距与改进空间',
+ },
+ {
+ id: 'root-cause',
+ title: '根因分析',
+ description: '深入分析问题根源,找到制约企业发展的根本因素',
+ },
+ {
+ id: 'path-planning',
+ title: '路径规划',
+ description: '制定系统化的进化路径,明确阶段性目标与里程碑',
+ },
+ {
+ id: 'implementation',
+ title: '实施迭代',
+ description: '分阶段实施,持续迭代优化,确保进化效果',
+ },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
企业进化方法
+
+
+ 核心理念
+
+ 企业进化方法的核心是以终为始,目标先于问题。我们首先明确企业进化的终极目标,
+ 然后反推实现路径,确保每一步都朝着目标前进。
+
+
+
+
+ 方法论框架
+
+ {methods.map((method, index) => (
+
+
{index + 1}. {method.title}
+
{method.description}
+
+ ))}
+
+
+
+
+ 为什么目标先于问题
+
+ 传统的问题导向方法容易让企业陷入"救火"模式,被动应对各种问题。
+ 而目标导向的方法让企业主动设定方向,有计划地推进进化。
+
+
+ 只有先明确目标,才能判断哪些问题是真正需要解决的,
+ 哪些问题是次要的,从而集中资源解决关键问题。
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/evolution/page.tsx b/frontend/src/app/evolution/page.tsx
new file mode 100644
index 0000000..9686216
--- /dev/null
+++ b/frontend/src/app/evolution/page.tsx
@@ -0,0 +1,87 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '企业进化',
+ description: '企业进化是企业围绕长期发展目标持续调整、重构与升级的过程',
+ canonical: '/evolution',
+ }),
+};
+
+export default async function EvolutionPage() {
+ const settings = await getSiteSettings();
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '企业进化', url: '/evolution' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['evolution.title'] || '企业进化'}
+
+
+ {settings['evolution.definitionTitle'] || '什么是企业进化'}
+
+ {settings['evolution.intro'] || '企业进化,是企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力的过程。'}
+
+
+ {settings['evolution.definitionMore'] || '增长更多体现结果层变化。进化更强调底层能力、系统与企业状态的持续调整和升级。AI是时代变量和重要赋能工具,不是企业进化本身的终点。'}
+
+
+
+
+ {settings['evolution.whyTitle'] || '为什么需要企业进化'}
+
+ {settings['evolution.whyIntro'] || '在AI时代,企业面临着前所未有的挑战:'}
+
+
+ {(settings['evolution.whyItems'] || '技术快速迭代,传统业务模式面临冲击\n客户需求变化,个性化、智能化要求提高\n竞争环境加剧,需要更高效的运营模式\n人才结构变化,需要新的组织能力').split('\n').map(item => - {item}
)}
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/faq/page.tsx b/frontend/src/app/faq/page.tsx
new file mode 100644
index 0000000..610b3ae
--- /dev/null
+++ b/frontend/src/app/faq/page.tsx
@@ -0,0 +1,118 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema, generateFAQSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+const API_URL = process.env.API_URL || 'http://localhost:3000';
+
+async function getFAQs() {
+ try {
+ const res = await fetch(`${API_URL}/api/contents/faq?pageSize=100`, {
+ cache: 'no-store',
+ });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return data.list || [];
+ } catch (error) {
+ return [];
+ }
+}
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: 'FAQ',
+ description: '常见问题解答,链接到对应知识实体页面',
+ canonical: '/faq',
+ }),
+};
+
+export default async function FAQPage() {
+ const faqs = await getFAQs();
+ const settings = await getSiteSettings();
+
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: 'FAQ', url: '/faq' },
+ ];
+
+ // 生成FAQ Schema
+ const faqSchema = generateFAQSchema(
+ faqs.map((faq: any) => ({
+ question: faq.question,
+ answer: faq.answer,
+ }))
+ );
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['faq.title'] || '常见问题'}
+
+
+ {settings['faq.overviewTitle'] || 'FAQ概述'}
+
+ {settings['faq.intro'] || '以下是关于企业进化的常见问题解答。每个答案都链接到相关的知识实体页面,方便深入了解。'}
+
+
+
+
+ {settings['faq.listTitle'] || '问题列表'}
+ {faqs.length > 0 ? (
+
+ {faqs.map((faq: any) => (
+
+ ))}
+
+ ) : (
+
+
暂无FAQ数据
+
FAQ内容正在完善中,请稍后再来查看。
+
+ )}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/knowledge/page.tsx b/frontend/src/app/knowledge/page.tsx
new file mode 100644
index 0000000..1ec45f6
--- /dev/null
+++ b/frontend/src/app/knowledge/page.tsx
@@ -0,0 +1,135 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+const API_URL = process.env.API_URL || 'http://localhost:24731';
+interface ArticleItem { id: string; title: string; slug: string; category: string; summary: string; author: string; date: string; }
+
+async function getArticles(): Promise {
+ try {
+ const res = await fetch(`${API_URL}/api/contents/article?pageSize=100`, { cache: 'no-store' });
+ if (!res.ok) return [];
+ const data = await res.json();
+ return (data.list || []).map((item: any) => ({ ...item, id: item.id || item.content_id, summary: item.summary || item.body || '', date: item.date || item.created_at || '' }));
+ } catch { return []; }
+}
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '知识中心',
+ description: '企业进化的知识体系与方法论,包括企业进化、AI时代企业、企业经营等分类',
+ canonical: '/knowledge',
+ }),
+};
+
+export default async function KnowledgePage() {
+ const settings = await getSiteSettings();
+ const articles = await getArticles();
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '知识中心', url: '/knowledge' },
+ ];
+
+ // 知识分类
+ const categories = [
+ { id: 'evolution', name: '企业进化', count: 0 },
+ { id: 'ai-era', name: 'AI时代企业', count: 0 },
+ { id: 'management', name: '企业经营', count: 0 },
+ { id: 'organization', name: '组织重塑', count: 0 },
+ { id: 'values', name: '四大价值', count: 0 },
+ { id: 'ai-organization', name: 'AI组织', count: 0 },
+ { id: 'enterprise-management', name: '企业管理', count: 0 },
+ { id: 'methodology', name: '方法论', count: 0 },
+ { id: 'cases', name: '案例', count: 0 },
+ { id: 'observation', name: '企业观察', count: 0 },
+ { id: 'viewpoint', name: '阿美巴观点', count: 0 },
+ { id: 'faq', name: 'FAQ', count: 0 },
+ ];
+
+ // 文章列表 - 从CMS获取published状态的文章
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['knowledge.title'] || '知识中心'}
+
+
+ {settings['knowledge.systemTitle'] || '知识体系'}
+
+ {settings['knowledge.intro'] || '知识中心汇集了企业进化的知识体系与方法论,帮助企业理解和掌握AI时代的经营管理方法。'}
+
+
+
+
+ {settings['knowledge.categoryTitle'] || '知识分类'}
+
+ {categories.map((category) => (
+
+
{category.name}
+
{category.count} 篇文章
+
+ ))}
+
+
+
+
+ {settings['knowledge.articleTitle'] || '最新文章'}
+ {articles.length > 0 ? (
+
+ {articles.map((article) => (
+
+
+
+ {article.category}
+ {article.author}
+ {article.date}
+
+
{article.summary}
+
+ ))}
+
+ ) : (
+
+
暂无文章数据
+
文章内容正在完善中,请稍后再来查看。
+
+ )}
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
new file mode 100644
index 0000000..7e8ef09
--- /dev/null
+++ b/frontend/src/app/layout.tsx
@@ -0,0 +1,104 @@
+import type { Metadata } from 'next';
+import '@/styles/globals.css';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ title: {
+ default: '阿美巴AI官网 - AI时代企业进化平台',
+ template: '%s | 阿美巴AI官网',
+ },
+ description: '阿美巴AI - 专注AI时代企业进化,提供战略顶层设计、经营增长、组织重塑等企业进化能力与服务',
+ keywords: ['阿美巴', 'AI', '企业进化', '战略咨询', '组织重塑', '经营增长'],
+ openGraph: {
+ type: 'website',
+ locale: 'zh_CN',
+ url: 'https://ameiba.com',
+ siteName: '阿美巴AI官网',
+ images: [
+ {
+ url: '/og-default.jpg',
+ width: 1200,
+ height: 630,
+ alt: '阿美巴AI官网',
+ },
+ ],
+ },
+ twitter: {
+ card: 'summary_large_image',
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: {
+ index: true,
+ follow: true,
+ 'max-video-preview': -1,
+ 'max-image-preview': 'large',
+ 'max-snippet': -1,
+ },
+ },
+};
+
+export default async function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const settings = await getSiteSettings();
+ const siteName = settings['site.name'] || '阿美巴AI';
+ return (
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/app/match/page.tsx b/frontend/src/app/match/page.tsx
new file mode 100644
index 0000000..ab4bfa9
--- /dev/null
+++ b/frontend/src/app/match/page.tsx
@@ -0,0 +1,167 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '企业需求与能力匹配',
+ description: '基于企业特征匹配进化能力与服务,展示匹配知识结构',
+ canonical: '/match',
+ }),
+};
+
+export default function MatchPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '企业需求与能力匹配', url: '/match' },
+ ];
+
+ // 匹配逻辑结构
+ const matchStructure = [
+ {
+ id: 'company-type',
+ title: '企业类型',
+ description: '根据企业所属行业和规模进行分类。阿美巴重点关注中小企业、实体企业、制造型企业,其他类型企业可根据具体情况判断是否适配。',
+ options: ['制造业', '服务业', '科技企业', '传统企业', '初创企业'],
+ },
+ {
+ id: 'company-stage',
+ title: '企业阶段',
+ description: '根据企业发展阶段进行分类',
+ options: ['A态·入态', 'M态·优态', 'B态·越态'],
+ },
+ {
+ id: 'evolution-goal',
+ title: '进化目标',
+ description: '企业希望实现的进化目标',
+ options: ['数字化转型', '效率提升', '创新增长', '组织重塑'],
+ },
+ {
+ id: 'current-status',
+ title: '当前状态',
+ description: '企业当前的运营状态',
+ options: ['增长瓶颈', '效率低下', '创新不足', '组织僵化'],
+ },
+ {
+ id: 'key-obstacles',
+ title: '关键障碍',
+ description: '制约企业发展的关键因素',
+ options: ['人才短缺', '技术落后', '流程混乱', '文化阻力'],
+ },
+ {
+ id: 'company-needs',
+ title: '企业需求',
+ description: '企业当前的核心需求',
+ options: ['战略规划', '组织优化', '技术升级', '人才培养'],
+ },
+ {
+ id: 'ameiba-capability',
+ title: '阿美巴能力',
+ description: '阿美巴可以提供的能力支持',
+ options: ['战略顶层设计', '组织重塑', 'AI部署', '经营分析'],
+ },
+ {
+ id: 'adaptive-service',
+ title: '适配服务',
+ description: '根据需求匹配的具体服务',
+ options: ['顾问服务', '咨询服务', '企业陪跑', '定制化服务'],
+ },
+ {
+ id: 'case-evidence',
+ title: '案例佐证',
+ description: '相关的成功案例',
+ options: [],
+ },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
企业需求与能力匹配
+
+
+ 匹配概述
+
+ 本页面展示企业需求与阿美巴能力的匹配知识结构。
+ 这是信息结构与匹配逻辑说明,不是在线诊断工具。
+
+
+ 企业可以根据自身特征,了解如何匹配阿美巴的能力与服务。
+
+
+
+
+ 匹配逻辑
+
+ {matchStructure.map((item, index) => (
+
+
{index + 1}. {item.title}
+
{item.description}
+ {item.options.length > 0 && (
+
+ {item.options.map((option, optionIndex) => (
+ - {option}
+ ))}
+
+ )}
+
+ ))}
+
+
+
+
+ 使用说明
+
+ - 首先确定企业类型和阶段
+ - 明确进化目标和当前状态
+ - 识别关键障碍和企业需求
+ - 匹配阿美巴的能力和服务
+ - 参考相关案例佐证
+
+
+
+
+ 注意事项
+
+ - 本页面仅为知识结构说明
+ - 不做在线诊断、自动评分
+ - 不做AI问答、自动推荐
+ - 如需专业诊断,请联系我们
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
new file mode 100644
index 0000000..071e5ca
--- /dev/null
+++ b/frontend/src/app/page.tsx
@@ -0,0 +1,133 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateOrganizationSchema, generateWebSiteSearchAction } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '阿美巴AI - AI时代企业进化平台',
+ description: '阿美巴AI专注AI时代企业进化,提供战略顶层设计、经营增长、组织重塑等企业进化能力与服务,帮助企业实现从A态到M态再到B态的进化。',
+ canonical: '/',
+ }),
+};
+
+export default async function HomePage() {
+ const settings = await getSiteSettings();
+ // 首页认知浓度顺序:按产品总指令排列
+ const cognitiveSections = [
+ {
+ id: 'who-we-are',
+ title: '我们是谁',
+ description: '阿美巴(Ameiba)是AI时代企业进化平台',
+ link: '/about',
+ },
+ {
+ id: 'what-is-evolution',
+ title: '什么是企业进化',
+ description: '企业进化是企业围绕长期发展目标持续调整、重构与升级的过程',
+ link: '/evolution',
+ },
+ {
+ id: 'goal-before-problem',
+ title: '为什么目标先于问题',
+ description: '以终为始,先明确进化目标,再分析现状差距',
+ link: '/evolution/method',
+ },
+ {
+ id: 'evolution-method',
+ title: '企业进化方法',
+ description: '系统化的企业进化方法论与实施路径',
+ link: '/evolution/method',
+ },
+ {
+ id: 'four-values',
+ title: '四大价值',
+ description: '价值创造、价值传递、价值交付、价值支持',
+ link: '/value',
+ },
+ {
+ id: 'amb-path',
+ title: 'A/M-B三态状态模型',
+ description: 'AI时代企业进化状态识别框架',
+ link: '/amb',
+ },
+ {
+ id: 'capabilities',
+ title: '企业进化能力',
+ description: '支撑企业进化的完整能力体系',
+ link: '/capabilities',
+ },
+ {
+ id: 'cases',
+ title: '企业进化案例',
+ description: '企业在真实经营环境中的进化过程',
+ link: '/cases',
+ },
+ {
+ id: 'knowledge',
+ title: '知识中心',
+ description: '企业进化的知识体系与方法论',
+ link: '/knowledge',
+ },
+ {
+ id: 'match',
+ title: '企业需求与能力匹配',
+ description: '基于企业特征匹配进化能力与服务',
+ link: '/match',
+ },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 首页内容 - 服务端渲染 */}
+
+
+
{settings['home.heroTitle'] || '阿美巴(Ameiba)'}
+
{settings['home.heroSubtitle'] || 'AI时代企业进化平台'}
+
+ {settings['home.heroDescription'] || '我们帮助企业在AI时代实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。'}
+
+
+
+
+
+
+
企业进化知识体系
+
+ {cognitiveSections.map((section) => (
+
+
+
{section.description}
+
+ ))}
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/robots.ts b/frontend/src/app/robots.ts
new file mode 100644
index 0000000..0800961
--- /dev/null
+++ b/frontend/src/app/robots.ts
@@ -0,0 +1,16 @@
+import { MetadataRoute } from 'next';
+
+export default function robots(): MetadataRoute.Robots {
+ const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://ameiba.com';
+
+ return {
+ rules: [
+ {
+ userAgent: '*',
+ allow: '/',
+ disallow: ['/api/', '/admin/'],
+ },
+ ],
+ sitemap: `${baseUrl}/sitemap.xml`,
+ };
+}
\ No newline at end of file
diff --git a/frontend/src/app/sitemap.ts b/frontend/src/app/sitemap.ts
new file mode 100644
index 0000000..4ebe9ea
--- /dev/null
+++ b/frontend/src/app/sitemap.ts
@@ -0,0 +1,36 @@
+import { MetadataRoute } from 'next';
+
+const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://ameiba.com';
+
+export default function sitemap(): MetadataRoute.Sitemap {
+ // 静态页面
+ const staticPages = [
+ { url: BASE_URL, lastModified: new Date(), changeFrequency: 'weekly' as const, priority: 1.0 },
+ { url: `${BASE_URL}/about`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/evolution`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/evolution/method`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/value`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/value/creation`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/value/transfer`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/value/delivery`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/value/support`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/amb`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/amb/a`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/amb/m`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/amb/b`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/capabilities`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/cases`, lastModified: new Date(), changeFrequency: 'weekly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/knowledge`, lastModified: new Date(), changeFrequency: 'weekly' as const, priority: 0.8 },
+ { url: `${BASE_URL}/concepts`, lastModified: new Date(), changeFrequency: 'weekly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/faq`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/match`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.7 },
+ { url: `${BASE_URL}/contact`, lastModified: new Date(), changeFrequency: 'monthly' as const, priority: 0.6 },
+ ];
+
+ // 动态页面(从CMS获取)
+ // 这里需要在实际部署时从API获取数据
+ // 暂时返回静态页面
+ const dynamicPages: MetadataRoute.Sitemap = [];
+
+ return [...staticPages, ...dynamicPages];
+}
\ No newline at end of file
diff --git a/frontend/src/app/value/creation/page.tsx b/frontend/src/app/value/creation/page.tsx
new file mode 100644
index 0000000..c5ecd66
--- /dev/null
+++ b/frontend/src/app/value/creation/page.tsx
@@ -0,0 +1,112 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '价值创造',
+ description: '企业如何创造价值,包括产品创新、服务创新、商业模式创新等',
+ canonical: '/value/creation',
+ }),
+};
+
+export default function ValueCreationPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '四大价值', url: '/value' },
+ { name: '价值创造', url: '/value/creation' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
价值创造
+
+
+ 官方定义
+
+ 价值创造是企业通过创新和优化,为客户和自身创造新价值的过程。
+ 它包括产品创新、服务创新、商业模式创新等多个维度。
+
+
+
+
+ 核心逻辑
+
+ 价值创造的核心是发现并满足客户需求,通过创新提供更好的产品或服务,
+ 从而获得市场认可和商业回报。
+
+
+
+
+ 企业常见问题
+
+ - 如何发现新的价值创造机会?
+ - 如何平衡创新与风险?
+ - 如何建立持续创新的能力?
+
+
+
+
+ 与其他价值的关系
+
+ 价值创造是四大价值的基础。只有创造出有价值的产品或服务,
+ 才能进行价值传递、交付和支持。
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/value/delivery/page.tsx b/frontend/src/app/value/delivery/page.tsx
new file mode 100644
index 0000000..0da854f
--- /dev/null
+++ b/frontend/src/app/value/delivery/page.tsx
@@ -0,0 +1,110 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '价值交付',
+ description: '企业如何交付价值,包括生产、运营、服务等',
+ canonical: '/value/delivery',
+ }),
+};
+
+export default function ValueDeliveryPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '四大价值', url: '/value' },
+ { name: '价值交付', url: '/value/delivery' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
价值交付
+
+
+ 官方定义
+
+ 价值交付是企业将创造的价值实际提供给客户的过程。
+ 它包括生产制造、运营执行、客户服务等多个环节。
+
+
+
+
+ 核心逻辑
+
+ 价值交付的核心是确保客户能够顺利获得并使用企业提供的价值,
+ 从而实现客户满意度和企业收益。
+
+
+
+
+ 企业常见问题
+
+ - 如何提高交付效率?
+ - 如何保证交付质量?
+ - 如何优化客户体验?
+
+
+
+
+ 与其他价值的关系
+
+ 价值交付是价值创造和传递的最终实现。
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/value/page.tsx b/frontend/src/app/value/page.tsx
new file mode 100644
index 0000000..ec98c95
--- /dev/null
+++ b/frontend/src/app/value/page.tsx
@@ -0,0 +1,116 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+import { getSiteSettings } from '@/lib/settings';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '四大价值',
+ description: '企业进化的四大价值:价值创造、价值传递、价值交付、价值支持',
+ canonical: '/value',
+ }),
+};
+
+export default async function ValuePage() {
+ const settings = await getSiteSettings();
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '四大价值', url: '/value' },
+ ];
+
+ const values = [
+ {
+ id: 'creation',
+ title: '价值创造',
+ description: '企业如何创造价值,包括产品创新、服务创新、商业模式创新等',
+ link: '/value/creation',
+ },
+ {
+ id: 'transfer',
+ title: '价值传递',
+ description: '企业如何将价值传递给客户,包括营销、销售、渠道等',
+ link: '/value/transfer',
+ },
+ {
+ id: 'delivery',
+ title: '价值交付',
+ description: '企业如何交付价值,包括生产、运营、服务等',
+ link: '/value/delivery',
+ },
+ {
+ id: 'support',
+ title: '价值支持',
+ description: '企业如何支持价值创造与交付,包括组织、流程、IT等',
+ link: '/value/support',
+ },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
{settings['value.title'] || '四大价值'}
+
+
+ {settings['value.overviewTitle'] || '价值体系概述'}
+
+ {settings['value.intro'] || '企业进化的核心是价值体系的进化。四大价值构成了企业创造、传递、交付和支持价值的完整体系,是企业进化的基础框架。'}
+
+
+
+
+ {settings['value.valuesTitle'] || '四大价值'}
+
+ {values.map((value) => (
+
+
+
{value.description}
+
+ ))}
+
+
+
+
+ {settings['value.relationTitle'] || '价值体系的关系'}
+
+ {settings['value.relationText'] || '四大价值相互关联、相互支撑。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。'}
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/value/support/page.tsx b/frontend/src/app/value/support/page.tsx
new file mode 100644
index 0000000..4e80797
--- /dev/null
+++ b/frontend/src/app/value/support/page.tsx
@@ -0,0 +1,110 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '价值支持',
+ description: '企业如何支持价值创造与交付,包括组织、流程、IT等',
+ canonical: '/value/support',
+ }),
+};
+
+export default function ValueSupportPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '四大价值', url: '/value' },
+ { name: '价值支持', url: '/value/support' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
价值支持
+
+
+ 官方定义
+
+ 价值支持是企业为价值创造、传递和交付提供基础保障的过程。
+ 它包括组织架构、流程体系、IT系统、人力资源等多个方面。
+
+
+
+
+ 核心逻辑
+
+ 价值支持的核心是构建高效、灵活、可扩展的支撑体系,
+ 确保价值创造、传递和交付能够顺利进行。
+
+
+
+
+ 企业常见问题
+
+ - 如何构建高效的组织架构?
+ - 如何优化业务流程?
+ - 如何部署适合的IT系统?
+
+
+
+
+ 与其他价值的关系
+
+ 价值支持是其他三大价值的基础保障。
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/app/value/transfer/page.tsx b/frontend/src/app/value/transfer/page.tsx
new file mode 100644
index 0000000..610b022
--- /dev/null
+++ b/frontend/src/app/value/transfer/page.tsx
@@ -0,0 +1,110 @@
+import type { Metadata } from 'next';
+import { generateSEO, generateBreadcrumbSchema } from '@/lib/seo';
+
+export const metadata: Metadata = {
+ ...generateSEO({
+ title: '价值传递',
+ description: '企业如何将价值传递给客户,包括营销、销售、渠道等',
+ canonical: '/value/transfer',
+ }),
+};
+
+export default function ValueTransferPage() {
+ const breadcrumbs = [
+ { name: '首页', url: '/' },
+ { name: '四大价值', url: '/value' },
+ { name: '价值传递', url: '/value/transfer' },
+ ];
+
+ return (
+ <>
+ {/* 结构化数据 */}
+
+
+
+ {/* 面包屑导航 */}
+
+
+
价值传递
+
+
+ 官方定义
+
+ 价值传递是企业将创造的价值有效传递给目标客户的过程。
+ 它包括营销策略、销售渠道、品牌传播等多个环节。
+
+
+
+
+ 核心逻辑
+
+ 价值传递的核心是让客户了解、认识并接受企业创造的价值,
+ 从而产生购买意愿和行为。
+
+
+
+
+ 企业常见问题
+
+ - 如何精准定位目标客户?
+ - 如何有效传递价值主张?
+ - 如何建立高效的销售渠道?
+
+
+
+
+ 与其他价值的关系
+
+ 价值传递是连接价值创造与价值交付的桥梁。
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts
new file mode 100644
index 0000000..841f993
--- /dev/null
+++ b/frontend/src/lib/api.ts
@@ -0,0 +1,251 @@
+import { Entity, DirectedRelationship, Content, Page, Article, Case, FAQ, Capability, Service, PaginatedResponse } from '@/types';
+
+const API_BASE_URL = process.env.API_URL || 'http://localhost:3000';
+
+// 通用请求函数
+async function fetchApi(endpoint: string, options?: RequestInit): Promise {
+ const url = `${API_BASE_URL}${endpoint}`;
+ const response = await fetch(url, {
+ ...options,
+ headers: {
+ 'Content-Type': 'application/json',
+ ...options?.headers,
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
+ }
+
+ return response.json();
+}
+
+// 实体相关API
+export const entityApi = {
+ // 获取实体列表
+ getList: (params?: { page?: number; pageSize?: number; orderBy?: string }) => {
+ const searchParams = new URLSearchParams();
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ if (params?.orderBy) searchParams.set('orderBy', params.orderBy);
+ return fetchApi>(`/api/entities?${searchParams.toString()}`);
+ },
+
+ // 获取实体详情
+ getById: (id: string) => fetchApi(`/api/entities/${id}`),
+
+ // 公开接口:获取实体列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams();
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi(`/api/public/entities?${searchParams.toString()}`);
+ },
+
+ // 公开接口:获取实体详情
+ getPublicById: (id: string) => fetchApi(`/api/public/entities/${id}`),
+
+ // 公开接口:获取实体的关系
+ getPublicRelationships: (id: string) => fetchApi<{ source: DirectedRelationship[]; target: DirectedRelationship[] }>(`/api/public/entities/${id}/relationships`),
+
+ // 公开接口:获取实体的内容
+ getPublicContents: (id: string) => fetchApi(`/api/public/entities/${id}/contents`),
+};
+
+// 关系相关API
+export const relationshipApi = {
+ // 获取关系列表
+ getList: (params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams();
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi>(`/api/relationships?${searchParams.toString()}`);
+ },
+
+ // 获取关系详情
+ getById: (id: string) => fetchApi(`/api/relationships/${id}`),
+
+ // 获取实体的出向关系
+ getBySourceEntity: (entityId: string) => fetchApi(`/api/relationships/source/${entityId}`),
+
+ // 获取实体的入向关系
+ getByTargetEntity: (entityId: string) => fetchApi(`/api/relationships/target/${entityId}`),
+};
+
+// 内容相关API
+export const contentApi = {
+ // 获取内容列表
+ getList: (type: string, params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams();
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi>(`/api/contents/${type}?${searchParams.toString()}`);
+ },
+
+ // 获取内容详情
+ getById: (type: string, id: string) => fetchApi(`/api/contents/${type}/${id}`),
+
+ // 公开接口:获取内容列表
+ getPublicList: (type?: string, params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams();
+ if (type) searchParams.set('type', type);
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi(`/api/public/contents?${searchParams.toString()}`);
+ },
+
+ // 公开接口:获取内容详情
+ getPublicById: (id: string) => fetchApi(`/api/public/contents/${id}`),
+
+ // 公开接口:获取内容的实体关联
+ getPublicEntities: (id: string) => fetchApi(`/api/public/contents/${id}/entities`),
+};
+
+// 页面相关API
+export const pageApi = {
+ // 获取页面列表
+ getList: (params?: { page?: number; pageSize?: number }) => contentApi.getList('page', params),
+
+ // 获取页面详情
+ getById: (id: string) => contentApi.getById('page', id),
+
+ // 公开接口:获取页面列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => contentApi.getPublicList('page', params),
+
+ // 公开接口:获取页面详情
+ getPublicById: (id: string) => contentApi.getPublicById(id),
+};
+
+// 文章相关API
+export const articleApi = {
+ // 获取文章列表
+ getList: (params?: { page?: number; pageSize?: number }) => contentApi.getList('article', params),
+
+ // 获取文章详情
+ getById: (id: string) => contentApi.getById('article', id),
+
+ // 公开接口:获取文章列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => contentApi.getPublicList('article', params),
+
+ // 公开接口:获取文章详情
+ getPublicById: (id: string) => contentApi.getPublicById(id),
+};
+
+// 案例相关API
+export const caseApi = {
+ // 获取案例列表
+ getList: (params?: { page?: number; pageSize?: number }) => contentApi.getList('case', params),
+
+ // 获取案例详情
+ getById: (id: string) => contentApi.getById('case', id),
+
+ // 公开接口:获取案例列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => contentApi.getPublicList('case', params),
+
+ // 公开接口:获取案例详情
+ getPublicById: (id: string) => contentApi.getPublicById(id),
+};
+
+// FAQ相关API
+export const faqApi = {
+ // 获取FAQ列表
+ getList: (params?: { page?: number; pageSize?: number }) => contentApi.getList('faq', params),
+
+ // 获取FAQ详情
+ getById: (id: string) => contentApi.getById('faq', id),
+
+ // 公开接口:获取FAQ列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => contentApi.getPublicList('faq', params),
+
+ // 公开接口:获取FAQ详情
+ getPublicById: (id: string) => contentApi.getPublicById(id),
+};
+
+// 能力相关API
+export const capabilityApi = {
+ // 获取能力列表
+ getList: (params?: { page?: number; pageSize?: number }) => contentApi.getList('capability', params),
+
+ // 获取能力详情
+ getById: (id: string) => contentApi.getById('capability', id),
+
+ // 公开接口:获取能力列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => contentApi.getPublicList('capability', params),
+
+ // 公开接口:获取能力详情
+ getPublicById: (id: string) => contentApi.getPublicById(id),
+};
+
+// 服务相关API
+export const serviceApi = {
+ // 获取服务列表
+ getList: (params?: { page?: number; pageSize?: number }) => contentApi.getList('service', params),
+
+ // 获取服务详情
+ getById: (id: string) => contentApi.getById('service', id),
+
+ // 公开接口:获取服务列表
+ getPublicList: (params?: { page?: number; pageSize?: number }) => contentApi.getPublicList('service', params),
+
+ // 公开接口:获取服务详情
+ getPublicById: (id: string) => contentApi.getPublicById(id),
+};
+
+// 关联相关API
+export const joinApi = {
+ // 获取关联列表
+ getList: (params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams();
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi>(`/api/joins?${searchParams.toString()}`);
+ },
+
+ // 获取实体的所有关联
+ getByEntityId: (entityId: string) => fetchApi<{ join_id: string; entity_id: string; content_id: string; join_note?: string; created_at: string }[]>(`/api/joins/entity/${entityId}`),
+
+ // 获取内容的所有关联
+ getByContentId: (contentId: string) => fetchApi<{ join_id: string; entity_id: string; content_id: string; join_note?: string; created_at: string }[]>(`/api/joins/content/${contentId}`),
+};
+
+// 搜索相关API
+export const searchApi = {
+ // 搜索实体
+ entities: (keyword: string, params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams({ keyword });
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi(`/api/public/search/entities?${searchParams.toString()}`);
+ },
+
+ // 搜索内容
+ contents: (keyword: string, type?: string, params?: { page?: number; pageSize?: number }) => {
+ const searchParams = new URLSearchParams({ keyword });
+ if (type) searchParams.set('type', type);
+ if (params?.page) searchParams.set('page', params.page.toString());
+ if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString());
+ return fetchApi(`/api/public/search/contents?${searchParams.toString()}`);
+ },
+};
+
+// JSON-LD相关API
+export const jsonLdApi = {
+ // 获取实体的JSON-LD
+ getEntityJsonLd: (id: string) => fetchApi>(`/api/jsonld/entities/${id}`),
+
+ // 获取内容的JSON-LD
+ getContentJsonLd: (id: string) => fetchApi>(`/api/jsonld/contents/${id}`),
+
+ // 获取所有实体的JSON-LD列表
+ getAllEntitiesJsonLd: () => fetchApi[]>('/api/jsonld/entities'),
+
+ // 获取所有内容的JSON-LD列表
+ getAllContentsJsonLd: (type?: string) => {
+ const searchParams = new URLSearchParams();
+ if (type) searchParams.set('type', type);
+ return fetchApi[]>(`/api/jsonld/contents?${searchParams.toString()}`);
+ },
+
+ // 获取站点地图的JSON-LD
+ getSitemapJsonLd: () => fetchApi>('/api/jsonld/sitemap'),
+};
\ No newline at end of file
diff --git a/frontend/src/lib/seo.ts b/frontend/src/lib/seo.ts
new file mode 100644
index 0000000..fb212ba
--- /dev/null
+++ b/frontend/src/lib/seo.ts
@@ -0,0 +1,160 @@
+import { SEOData, Breadcrumb, JsonLdData } from '@/types';
+
+const SITE_NAME = '阿美巴AI官网';
+const SITE_DESCRIPTION = '阿美巴AI - AI时代企业进化平台';
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://ameiba.com';
+
+// 生成SEO数据
+export function generateSEO(data: SEOData): Record {
+ const title = data.title ? `${data.title} - ${SITE_NAME}` : SITE_NAME;
+ const description = data.description || SITE_DESCRIPTION;
+ const canonical = data.canonical ? `${SITE_URL}${data.canonical}` : SITE_URL;
+
+ return {
+ title,
+ description,
+ canonical,
+ 'og:title': data.ogTitle || title,
+ 'og:description': data.ogDescription || description,
+ 'og:image': data.ogImage || `${SITE_URL}/og-default.jpg`,
+ 'og:type': 'website',
+ 'og:url': canonical,
+ 'twitter:card': 'summary_large_image',
+ 'twitter:title': data.ogTitle || title,
+ 'twitter:description': data.ogDescription || description,
+ 'twitter:image': data.ogImage || `${SITE_URL}/og-default.jpg`,
+ };
+}
+
+// 生成面包屑Schema
+export function generateBreadcrumbSchema(breadcrumbs: Breadcrumb[]): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'BreadcrumbList',
+ itemListElement: breadcrumbs.map((item, index) => ({
+ '@type': 'ListItem',
+ position: index + 1,
+ name: item.name,
+ item: `${SITE_URL}${item.url}`,
+ })),
+ };
+}
+
+// 生成组织Schema
+export function generateOrganizationSchema(): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'Organization',
+ name: '阿美巴AI',
+ description: 'AI时代企业进化平台',
+ url: SITE_URL,
+ logo: `${SITE_URL}/logo.png`,
+ sameAs: [],
+ };
+}
+
+// 生成文章Schema
+export function generateArticleSchema(data: {
+ title: string;
+ description: string;
+ url: string;
+ image?: string;
+ author?: string;
+ datePublished?: string;
+ dateModified?: string;
+}): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'Article',
+ headline: data.title,
+ description: data.description,
+ image: data.image || `${SITE_URL}/og-default.jpg`,
+ url: `${SITE_URL}${data.url}`,
+ author: data.author ? {
+ '@type': 'Person',
+ name: data.author,
+ } : undefined,
+ publisher: {
+ '@type': 'Organization',
+ name: SITE_NAME,
+ logo: {
+ '@type': 'ImageObject',
+ url: `${SITE_URL}/logo.png`,
+ },
+ },
+ datePublished: data.datePublished,
+ dateModified: data.dateModified,
+ };
+}
+
+// 生成FAQ Schema
+export function generateFAQSchema(faqs: Array<{ question: string; answer: string }>): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: faqs.map(faq => ({
+ '@type': 'Question',
+ name: faq.question,
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: faq.answer,
+ },
+ })),
+ };
+}
+
+// 生成服务Schema
+export function generateServiceSchema(data: {
+ name: string;
+ description: string;
+ url: string;
+ provider?: string;
+}): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'Service',
+ name: data.name,
+ description: data.description,
+ url: `${SITE_URL}${data.url}`,
+ provider: data.provider ? {
+ '@type': 'Organization',
+ name: data.provider,
+ } : undefined,
+ };
+}
+
+// 生成案例Schema
+export function generateCaseSchema(data: {
+ title: string;
+ description: string;
+ url: string;
+ image?: string;
+}): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'Article',
+ headline: data.title,
+ description: data.description,
+ image: data.image || `${SITE_URL}/og-default.jpg`,
+ url: `${SITE_URL}${data.url}`,
+ articleSection: '案例',
+ };
+}
+
+// 生成网站搜索Schema
+export function generateWebSiteSearchAction(): JsonLdData {
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'WebSite',
+ name: SITE_NAME,
+ url: SITE_URL,
+ potentialAction: {
+ '@type': 'SearchAction',
+ target: {
+ '@type': 'EntryPoint',
+ urlTemplate: `${SITE_URL}/search?q={search_term_string}`,
+ },
+ 'query-input': 'required name=search_term_string',
+ },
+ };
+}
\ No newline at end of file
diff --git a/frontend/src/lib/settings.ts b/frontend/src/lib/settings.ts
new file mode 100644
index 0000000..e4ccdba
--- /dev/null
+++ b/frontend/src/lib/settings.ts
@@ -0,0 +1,13 @@
+const API_URL = process.env.API_URL || 'http://localhost:24731';
+
+export type SiteSettings = Record;
+
+export async function getSiteSettings(): Promise {
+ try {
+ const response = await fetch(`${API_URL}/api/public/settings`, { cache: 'no-store' });
+ if (!response.ok) return {};
+ return response.json();
+ } catch {
+ return {};
+ }
+}
diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css
new file mode 100644
index 0000000..06cd54f
--- /dev/null
+++ b/frontend/src/styles/globals.css
@@ -0,0 +1,1187 @@
+/* 全局样式 - 克制、极简、专业、可信、结构化 */
+:root {
+ /* 主色调 - 避免科技蓝,使用更专业的深灰色系 */
+ --color-primary: #1a1a1a;
+ --color-secondary: #4a4a4a;
+ --color-text: #333333;
+ --color-text-light: #666666;
+ --color-bg: #ffffff;
+ --color-bg-light: #f8f9fa;
+ --color-border: #e0e0e0;
+ --color-accent: #2c3e50;
+
+ /* 间距 */
+ --spacing-xs: 0.25rem;
+ --spacing-sm: 0.5rem;
+ --spacing-md: 1rem;
+ --spacing-lg: 1.5rem;
+ --spacing-xl: 2rem;
+ --spacing-2xl: 3rem;
+ --spacing-3xl: 4rem;
+
+ /* 字体 */
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ --font-serif: Georgia, "Times New Roman", Times, serif;
+
+ /* 字体大小 */
+ --text-xs: 0.75rem;
+ --text-sm: 0.875rem;
+ --text-base: 1rem;
+ --text-lg: 1.125rem;
+ --text-xl: 1.25rem;
+ --text-2xl: 1.5rem;
+ --text-3xl: 1.875rem;
+ --text-4xl: 2.25rem;
+
+ /* 行高 */
+ --leading-tight: 1.25;
+ --leading-normal: 1.5;
+ --leading-relaxed: 1.75;
+
+ /* 最大宽度 */
+ --max-width: 1200px;
+ --max-width-narrow: 800px;
+}
+
+/* 基础重置 */
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: var(--font-sans);
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+ color: var(--color-text);
+ background-color: var(--color-bg);
+}
+
+/* 排版 */
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 600;
+ line-height: var(--leading-tight);
+ color: var(--color-primary);
+}
+
+h1 {
+ font-size: var(--text-4xl);
+ margin-bottom: var(--spacing-lg);
+}
+
+h2 {
+ font-size: var(--text-3xl);
+ margin-bottom: var(--spacing-md);
+}
+
+h3 {
+ font-size: var(--text-2xl);
+ margin-bottom: var(--spacing-md);
+}
+
+h4 {
+ font-size: var(--text-xl);
+ margin-bottom: var(--spacing-sm);
+}
+
+p {
+ margin-bottom: var(--spacing-md);
+ line-height: var(--leading-relaxed);
+}
+
+a {
+ color: var(--color-accent);
+ text-decoration: none;
+ transition: color 0.2s ease;
+}
+
+a:hover {
+ color: var(--color-primary);
+ text-decoration: underline;
+}
+
+/* 容器 */
+.container {
+ max-width: var(--max-width);
+ margin: 0 auto;
+ padding: 0 var(--spacing-md);
+}
+
+.container-narrow {
+ max-width: var(--max-width-narrow);
+ margin: 0 auto;
+ padding: 0 var(--spacing-md);
+}
+
+/* 间距工具类 */
+.mb-xs { margin-bottom: var(--spacing-xs); }
+.mb-sm { margin-bottom: var(--spacing-sm); }
+.mb-md { margin-bottom: var(--spacing-md); }
+.mb-lg { margin-bottom: var(--spacing-lg); }
+.mb-xl { margin-bottom: var(--spacing-xl); }
+.mb-2xl { margin-bottom: var(--spacing-2xl); }
+.mb-3xl { margin-bottom: var(--spacing-3xl); }
+
+.mt-xs { margin-top: var(--spacing-xs); }
+.mt-sm { margin-top: var(--spacing-sm); }
+.mt-md { margin-top: var(--spacing-md); }
+.mt-lg { margin-top: var(--spacing-lg); }
+.mt-xl { margin-top: var(--spacing-xl); }
+.mt-2xl { margin-top: var(--spacing-2xl); }
+.mt-3xl { margin-top: var(--spacing-3xl); }
+
+/* 文本工具类 */
+.text-center { text-align: center; }
+.text-light { color: var(--color-text-light); }
+.text-small { font-size: var(--text-sm); }
+
+/* 列表 */
+ul, ol {
+ padding-left: var(--spacing-lg);
+ margin-bottom: var(--spacing-md);
+}
+
+li {
+ margin-bottom: var(--spacing-sm);
+}
+
+/* 卡片 */
+.card {
+ background: var(--color-bg);
+ border: 1px solid var(--color-border);
+ border-radius: 4px;
+ padding: var(--spacing-lg);
+ margin-bottom: var(--spacing-md);
+}
+
+.card:hover {
+ border-color: var(--color-secondary);
+}
+
+/* 按钮 */
+.btn {
+ display: inline-block;
+ padding: var(--spacing-sm) var(--spacing-lg);
+ font-size: var(--text-base);
+ font-weight: 500;
+ text-align: center;
+ text-decoration: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.btn-primary {
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+}
+
+.btn-primary:hover {
+ background-color: var(--color-secondary);
+ text-decoration: none;
+}
+
+.btn-outline {
+ background-color: transparent;
+ color: var(--color-primary);
+ border-color: var(--color-primary);
+}
+
+.btn-outline:hover {
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ text-decoration: none;
+}
+
+/* 标签 */
+.tag {
+ display: inline-block;
+ padding: var(--spacing-xs) var(--spacing-sm);
+ font-size: var(--text-xs);
+ font-weight: 500;
+ background-color: var(--color-bg-light);
+ color: var(--color-text-light);
+ border-radius: 2px;
+ margin-right: var(--spacing-xs);
+ margin-bottom: var(--spacing-xs);
+}
+
+/* 分隔线 */
+.divider {
+ height: 1px;
+ background-color: var(--color-border);
+ margin: var(--spacing-xl) 0;
+}
+
+/* 响应式 */
+@media (max-width: 768px) {
+ :root {
+ --text-4xl: 1.875rem;
+ --text-3xl: 1.5rem;
+ --text-2xl: 1.25rem;
+ }
+
+ .container {
+ padding: 0 var(--spacing-sm);
+ }
+}
+
+/* 页面结构与组件布局
+ * 页面使用原生 CSS,保持克制、专业、可信的 B2B 品牌表达。
+ */
+:root {
+ --color-ink: #17212b;
+ --color-ink-soft: #52606d;
+ --color-paper: #f7f8f6;
+ --color-surface: #ffffff;
+ --color-line: #d9dfdc;
+ --color-accent: #c45b37;
+ --color-accent-soft: #f3e4dd;
+ --shadow-soft: 0 18px 45px rgba(23, 33, 43, 0.08);
+ --radius: 12px;
+}
+
+body {
+ background: var(--color-paper);
+ color: var(--color-ink);
+}
+
+.site-header {
+ position: sticky;
+ top: 0;
+ z-index: 20;
+ background: rgba(247, 248, 246, 0.94);
+ border-bottom: 1px solid var(--color-line);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+}
+
+.main-nav {
+ min-height: 72px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 32px;
+}
+
+.logo {
+ flex: 0 0 auto;
+ color: var(--color-ink);
+ font-size: 1.15rem;
+ font-weight: 750;
+ letter-spacing: -0.04em;
+}
+
+.logo:hover {
+ color: var(--color-accent);
+ text-decoration: none;
+}
+
+.nav-links {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 22px;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.nav-links li {
+ margin: 0;
+}
+
+.nav-links a {
+ color: var(--color-ink-soft);
+ font-size: 0.88rem;
+ white-space: nowrap;
+}
+
+.nav-links a:hover {
+ color: var(--color-accent);
+ text-decoration: none;
+}
+
+.main-content {
+ min-height: calc(100vh - 145px);
+}
+
+.hero-section {
+ position: relative;
+ overflow: hidden;
+ padding: 112px 0 104px;
+ background: var(--color-ink);
+ color: #f7f8f6;
+}
+
+.hero-section::after {
+ content: "";
+ position: absolute;
+ right: 8%;
+ top: 22%;
+ width: 180px;
+ height: 180px;
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ border-radius: 50%;
+ box-shadow: 0 0 0 28px rgba(255, 255, 255, 0.04), 0 0 0 56px rgba(255, 255, 255, 0.025);
+}
+
+.hero-section .container {
+ position: relative;
+ z-index: 1;
+}
+
+.hero-section h1 {
+ max-width: 780px;
+ margin-bottom: 20px;
+ color: #ffffff;
+ font-size: clamp(3.2rem, 8vw, 7rem);
+ letter-spacing: -0.075em;
+ line-height: 0.98;
+}
+
+.hero-subtitle {
+ margin-bottom: 22px;
+ color: #f0c2b1;
+ font-size: clamp(1.25rem, 2.5vw, 2rem);
+ font-weight: 600;
+ letter-spacing: -0.035em;
+}
+
+.hero-description {
+ max-width: 680px;
+ margin-bottom: 0;
+ color: rgba(247, 248, 246, 0.72);
+ font-size: 1.1rem;
+}
+
+.cognitive-section,
+.content-section,
+.related-section,
+.contact-section {
+ padding: 72px 0;
+}
+
+.cognitive-section {
+ background: var(--color-paper);
+}
+
+.cognitive-section h2,
+.content-section h2,
+.related-section h2 {
+ margin-bottom: 28px;
+ letter-spacing: -0.05em;
+}
+
+.cognitive-grid,
+.value-grid,
+.amb-grid,
+.cases-grid,
+.concepts-grid,
+.category-grid,
+.capability-list,
+.method-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 18px;
+}
+
+.cognitive-card,
+.value-card,
+.amb-card,
+.case-card,
+.concept-card,
+.category-card,
+.capability-card,
+.method-card,
+.article-card {
+ min-height: 100%;
+ padding: 26px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ background: var(--color-surface);
+ box-shadow: 0 1px 0 rgba(23, 33, 43, 0.02);
+ transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
+}
+
+.cognitive-card:hover,
+.value-card:hover,
+.amb-card:hover,
+.case-card:hover,
+.concept-card:hover,
+.category-card:hover,
+.capability-card:hover,
+.method-card:hover,
+.article-card:hover {
+ transform: translateY(-3px);
+ border-color: rgba(196, 91, 55, 0.55);
+ box-shadow: var(--shadow-soft);
+}
+
+.cognitive-card h3,
+.value-card h3,
+.amb-card h3,
+.case-card h3,
+.concept-card h3,
+.category-card h3,
+.method-card h3 {
+ margin-bottom: 12px;
+ font-size: 1.35rem;
+ letter-spacing: -0.04em;
+}
+
+.cognitive-card h3 a,
+.value-card h3 a,
+.amb-card h3 a,
+.case-card h3 a,
+.concept-card h3 a {
+ color: var(--color-ink);
+}
+
+.cognitive-card h3 a:hover,
+.value-card h3 a:hover,
+.amb-card h3 a:hover,
+.case-card h3 a:hover,
+.concept-card h3 a:hover {
+ color: var(--color-accent);
+ text-decoration: none;
+}
+
+.cognitive-card p,
+.value-card p,
+.amb-card p,
+.case-card p,
+.concept-card p,
+.category-card p,
+.capability-card p,
+.method-card p,
+.article-card p {
+ color: var(--color-ink-soft);
+}
+
+.breadcrumb {
+ padding: 28px 0 10px;
+ color: var(--color-ink-soft);
+ font-size: 0.85rem;
+}
+
+.breadcrumb ol {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.breadcrumb li {
+ margin: 0;
+}
+
+.breadcrumb li + li::before {
+ content: "/";
+ margin-right: 8px;
+ color: #9aa5a0;
+}
+
+.breadcrumb a {
+ color: var(--color-ink-soft);
+}
+
+.breadcrumb a:hover {
+ color: var(--color-accent);
+}
+
+.content-section > p,
+.content-section > ul,
+.related-section > ul {
+ max-width: 760px;
+}
+
+.content-section + .content-section {
+ border-top: 1px solid var(--color-line);
+}
+
+.content-section h2::before,
+.related-section h2::before {
+ content: "";
+ display: inline-block;
+ width: 28px;
+ height: 3px;
+ margin: 0 12px 0 0;
+ vertical-align: middle;
+ background: var(--color-accent);
+}
+
+.content-section ul:not(.nav-links),
+.content-section ol {
+ display: grid;
+ gap: 10px;
+ padding-left: 0;
+ list-style: none;
+}
+
+.content-section ul:not(.nav-links) li,
+.content-section ol li {
+ position: relative;
+ margin: 0;
+ padding: 14px 18px 14px 42px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ background: var(--color-surface);
+ color: var(--color-ink-soft);
+}
+
+.content-section ul:not(.nav-links) li::before {
+ content: "";
+ position: absolute;
+ left: 18px;
+ top: 50%;
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background: var(--color-accent);
+ transform: translateY(-50%);
+}
+
+.concept-definition {
+ margin-bottom: 10px;
+ color: var(--color-ink) !important;
+ font-weight: 600;
+}
+
+.concept-description {
+ margin-bottom: 0;
+ color: var(--color-ink-soft) !important;
+}
+
+.related-section {
+ border-top: 1px solid var(--color-line);
+}
+
+.related-section ul {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px 24px;
+ padding-left: 0;
+ list-style: none;
+}
+
+.related-section li {
+ margin: 0;
+}
+
+.capability-category {
+ margin-bottom: 40px;
+}
+
+.capability-category > h3 {
+ margin-bottom: 16px;
+ color: var(--color-accent);
+ font-size: 1rem;
+ letter-spacing: 0.02em;
+}
+
+.capability-list {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.capability-card h4 {
+ margin-bottom: 10px;
+ font-size: 1.15rem;
+}
+
+.capability-card p,
+.case-meta,
+.article-meta {
+ margin-bottom: 0;
+ font-size: 0.92rem;
+}
+
+.faq-list,
+.articles-list {
+ display: grid;
+ gap: 12px;
+}
+
+.faq-item {
+ padding: 22px 24px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ background: var(--color-surface);
+}
+
+.faq-item h3 {
+ margin-bottom: 10px;
+ font-size: 1.15rem;
+}
+
+.faq-answer p {
+ margin: 0;
+ color: var(--color-ink-soft);
+}
+
+.empty-state {
+ padding: 32px;
+ border: 1px dashed #b7c0bb;
+ border-radius: var(--radius);
+ background: #fbfcfa;
+ color: var(--color-ink-soft);
+}
+
+.empty-state p:last-child {
+ margin-bottom: 0;
+}
+
+.contact-section {
+ background: var(--color-accent-soft);
+}
+
+.contact-section h2 {
+ margin-bottom: 12px;
+}
+
+.contact-info {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 18px;
+ margin-top: 28px;
+}
+
+.contact-item {
+ padding: 22px;
+ border: 1px solid rgba(196, 91, 55, 0.25);
+ border-radius: var(--radius);
+ background: rgba(255, 255, 255, 0.48);
+}
+
+.contact-item h3 {
+ margin-bottom: 8px;
+ font-size: 1rem;
+}
+
+.match-flow,
+.match-options {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 18px;
+ margin: 28px 0;
+}
+
+.match-step {
+ padding: 24px;
+ border-top: 3px solid var(--color-accent);
+ background: var(--color-surface);
+}
+
+.match-step h3 {
+ margin-bottom: 10px;
+ font-size: 1.15rem;
+}
+
+.site-footer {
+ border-top: 1px solid var(--color-line);
+ background: var(--color-ink);
+ color: rgba(247, 248, 246, 0.72);
+}
+
+.logo {
+ display: inline-flex;
+ align-items: center;
+ gap: 9px;
+}
+
+.brand-logo {
+ width: 30px;
+ height: 30px;
+ object-fit: contain;
+ border-radius: 6px;
+}
+
+.footer-content {
+ min-height: 164px;
+ padding: 30px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+}
+
+.footer-info p {
+ margin: 0;
+ font-size: 0.95rem;
+ color: rgba(247, 248, 246, 0.86);
+}
+
+.footer-contact {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px 18px;
+ margin-top: 13px;
+ color: rgba(247, 248, 246, 0.58);
+ font-size: 0.9rem;
+ line-height: 1.6;
+}
+
+.footer-contact a,
+.footer-contact span,
+.icp-link {
+ color: inherit;
+}
+
+.footer-contact a:hover,
+.icp-link:hover {
+ color: #ffffff;
+ text-decoration: none;
+}
+
+.icp-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin-top: 12px;
+ align-self: flex-end;
+ font-size: 0.9rem;
+}
+
+.icp-badge {
+ width: 20px;
+ height: 20px;
+ object-fit: contain;
+}
+
+.footer-links {
+ display: flex;
+ gap: 18px;
+}
+
+.footer-links a {
+ color: rgba(247, 248, 246, 0.72);
+ font-size: 0.9rem;
+}
+
+.footer-links a:hover {
+ color: #ffffff;
+ text-decoration: none;
+}
+
+@media (max-width: 900px) {
+ .main-nav {
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 8px;
+ padding: 16px 0;
+ }
+
+ .nav-links {
+ width: 100%;
+ justify-content: flex-start;
+ gap: 14px 18px;
+ overflow-x: auto;
+ }
+
+ .cognitive-grid,
+ .value-grid,
+ .amb-grid,
+ .cases-grid,
+ .concepts-grid,
+ .category-grid,
+ .method-grid,
+ .match-flow,
+ .match-options,
+ .contact-info {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+}
+
+@media (max-width: 600px) {
+ .hero-section {
+ padding: 76px 0 72px;
+ }
+
+ .hero-section::after {
+ right: -70px;
+ top: 38%;
+ width: 150px;
+ height: 150px;
+ }
+
+ .cognitive-section,
+ .content-section,
+ .related-section,
+ .contact-section {
+ padding: 52px 0;
+ }
+
+ .cognitive-grid,
+ .value-grid,
+ .amb-grid,
+ .cases-grid,
+ .concepts-grid,
+ .category-grid,
+ .capability-list,
+ .method-grid,
+ .match-flow,
+ .match-options,
+ .contact-info {
+ grid-template-columns: 1fr;
+ }
+
+ .cognitive-card,
+ .value-card,
+ .amb-card,
+ .case-card,
+ .concept-card,
+ .category-card,
+ .capability-card,
+ .method-card,
+ .article-card {
+ padding: 22px;
+ }
+
+ .footer-content {
+ align-items: flex-start;
+ flex-direction: column;
+ justify-content: center;
+ padding: 20px 0;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ html {
+ scroll-behavior: auto;
+ }
+
+ *,
+ *::before,
+ *::after {
+ transition-duration: 0.01ms !important;
+ }
+}
+
+/* 管理后台 */
+.admin-shell {
+ min-height: calc(100vh - 72px);
+ padding: 56px 20px;
+ background: #eef1ef;
+}
+
+.admin-login,
+.admin-panel {
+ width: min(1120px, 100%);
+ margin: 0 auto;
+ border: 1px solid var(--color-line);
+ border-radius: 16px;
+ background: #fff;
+ box-shadow: var(--shadow-soft);
+}
+
+.admin-login {
+ max-width: 460px;
+ padding: 42px;
+}
+
+.admin-panel {
+ overflow: hidden;
+}
+
+.admin-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 24px;
+ padding: 32px 36px;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.admin-header h1,
+.admin-login h1 {
+ margin-bottom: 8px;
+ letter-spacing: -0.06em;
+}
+
+.admin-kicker {
+ margin-bottom: 8px;
+ color: var(--color-accent);
+ font-size: 0.75rem;
+ font-weight: 800;
+ letter-spacing: 0.14em;
+}
+
+.admin-muted {
+ color: var(--color-ink-soft);
+ font-size: 0.9rem;
+}
+
+.admin-tabs {
+ display: flex;
+ gap: 4px;
+ padding: 0 36px;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.admin-tabs button {
+ padding: 16px 18px;
+ border: 0;
+ border-bottom: 3px solid transparent;
+ background: transparent;
+ color: var(--color-ink-soft);
+ cursor: pointer;
+ font: inherit;
+}
+
+.admin-tabs button.active,
+.admin-tabs button:hover {
+ border-bottom-color: var(--color-accent);
+ color: var(--color-ink);
+}
+
+.admin-section {
+ padding: 36px;
+}
+
+.admin-section h2 {
+ margin-bottom: 8px;
+ font-size: 1.5rem;
+}
+
+.admin-section-heading {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 24px;
+ margin-bottom: 28px;
+}
+
+.admin-form,
+.editor-form {
+ display: grid;
+ gap: 18px;
+ margin-top: 28px;
+}
+
+.admin-form.narrow {
+ max-width: 520px;
+}
+
+.admin-form label,
+.editor-form label {
+ display: grid;
+ gap: 8px;
+ color: var(--color-ink);
+ font-size: 0.9rem;
+ font-weight: 650;
+}
+
+.admin-form input,
+.editor-form input,
+.editor-form textarea,
+.editor-form select,
+.admin-actions select,
+.setting-row input,
+.setting-row textarea {
+ width: 100%;
+ border: 1px solid #c8d0cc;
+ border-radius: 8px;
+ padding: 12px 14px;
+ background: #fbfcfb;
+ color: var(--color-ink);
+ font: inherit;
+}
+
+.admin-form input:focus,
+.editor-form input:focus,
+.editor-form textarea:focus,
+.editor-form select:focus,
+.setting-row textarea:focus,
+.setting-row input:focus,
+.admin-actions select:focus {
+ outline: 3px solid rgba(196, 91, 55, 0.2);
+ border-color: var(--color-accent);
+}
+
+.admin-button,
+.admin-quiet-button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 42px;
+ border-radius: 8px;
+ padding: 10px 18px;
+ font: inherit;
+ font-weight: 700;
+ cursor: pointer;
+}
+
+.admin-button {
+ border: 1px solid var(--color-ink);
+ background: var(--color-ink);
+ color: #fff;
+}
+
+.admin-button:hover {
+ background: var(--color-accent);
+ border-color: var(--color-accent);
+}
+
+.admin-button.small {
+ min-width: 70px;
+ min-height: 38px;
+ padding: 8px 12px;
+ font-size: 0.85rem;
+}
+
+.admin-quiet-button {
+ border: 1px solid var(--color-line);
+ background: transparent;
+ color: var(--color-ink-soft);
+}
+
+.admin-quiet-button:hover {
+ border-color: var(--color-accent);
+ color: var(--color-accent);
+}
+
+.admin-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.settings-list,
+.content-table {
+ display: grid;
+ gap: 10px;
+}
+
+.setting-row,
+.content-row {
+ display: grid;
+ grid-template-columns: minmax(180px, 0.4fr) minmax(260px, 1fr) auto;
+ align-items: center;
+ gap: 16px;
+ padding: 16px;
+ border: 1px solid var(--color-line);
+ border-radius: 10px;
+ background: #fbfcfb;
+}
+
+.setting-row textarea {
+ resize: vertical;
+ min-height: 48px;
+}
+
+.page-picker {
+ min-width: 170px;
+ border: 1px solid var(--color-line);
+ border-radius: 8px;
+ padding: 11px 14px;
+ background: #fff;
+ color: var(--color-ink);
+ font: inherit;
+}
+
+.page-description {
+ margin: -8px 0 18px;
+ color: var(--color-accent);
+ font-size: 0.9rem;
+}
+
+.setting-row strong,
+.content-row strong {
+ display: block;
+ overflow-wrap: anywhere;
+}
+
+.setting-row span,
+.content-row span {
+ display: block;
+ margin-top: 5px;
+ color: var(--color-ink-soft);
+ font-size: 0.78rem;
+}
+
+.editor-form {
+ margin-bottom: 28px;
+ padding: 22px;
+ border: 1px solid var(--color-line);
+ border-radius: 10px;
+ background: #f7f9f7;
+}
+
+.editor-hint {
+ margin: 0 0 18px;
+ color: var(--color-ink-soft);
+ font-size: 0.9rem;
+}
+
+.admin-error,
+.admin-success {
+ margin: 18px 36px 0;
+ padding: 12px 14px;
+ border-radius: 8px;
+ font-size: 0.9rem;
+}
+
+.admin-error {
+ background: #fff0ed;
+ color: #a33e25;
+}
+
+.admin-success {
+ background: #eef8f0;
+ color: #2f7041;
+}
+
+.admin-login .admin-error {
+ margin: 0;
+}
+
+.admin-link {
+ color: rgba(247, 248, 246, 0.42);
+ font-size: 0.75rem;
+}
+
+.admin-link:hover {
+ color: rgba(247, 248, 246, 0.8);
+ text-decoration: none;
+}
+
+@media (max-width: 700px) {
+ .admin-shell {
+ padding: 24px 12px;
+ }
+
+ .admin-login,
+ .admin-section,
+ .admin-header {
+ padding: 24px;
+ }
+
+ .admin-tabs {
+ padding: 0 24px;
+ overflow-x: auto;
+ }
+
+ .admin-section-heading,
+ .admin-header {
+ align-items: stretch;
+ flex-direction: column;
+ }
+
+ .setting-row,
+ .content-row {
+ grid-template-columns: 1fr;
+ }
+
+ .setting-row .admin-button,
+ .content-row .admin-quiet-button {
+ width: 100%;
+ }
+}
diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts
new file mode 100644
index 0000000..bd2bcf0
--- /dev/null
+++ b/frontend/src/types/index.ts
@@ -0,0 +1,127 @@
+// 数据模型类型定义
+
+export interface Entity {
+ entity_id: string;
+ name: string;
+ definition?: string;
+ description?: string;
+ metadata?: Record;
+ created_at: string;
+ updated_at: string;
+}
+
+export interface DirectedRelationship {
+ rel_id: string;
+ source_entity_id: string;
+ relation_type: string;
+ target_entity_id: string;
+ rel_status: 'active' | 'inactive';
+ authority_level: number;
+ is_public: number;
+ effective_at?: string;
+ expire_at?: string;
+ created_at: string;
+ updated_at: string;
+}
+
+export interface Content {
+ content_id: string;
+ title: string;
+ body?: string;
+ content_type: 'page' | 'article' | 'case' | 'faq' | 'capability' | 'service';
+ publish_status: 'draft' | 'review' | 'published' | 'unpublished' | 'historical';
+ authority_level: number;
+ version_no: number;
+ version_note?: string;
+ metadata?: Record;
+ created_at: string;
+ updated_at: string;
+ archived_at?: string;
+}
+
+export interface Page extends Content {
+ content_type: 'page';
+ slug?: string;
+ template?: string;
+ seo_title?: string;
+ seo_description?: string;
+ seo_keywords?: string;
+}
+
+export interface Article extends Content {
+ content_type: 'article';
+ category?: string;
+ tags?: string;
+ cover_image?: string;
+ author?: string;
+}
+
+export interface Case extends Content {
+ content_type: 'case';
+ client_name?: string;
+ industry?: string;
+ challenge?: string;
+ solution?: string;
+ result?: string;
+}
+
+export interface FAQ extends Content {
+ content_type: 'faq';
+ question?: string;
+ answer?: string;
+ sort_order?: number;
+}
+
+export interface Capability extends Content {
+ content_type: 'capability';
+ capability_type?: string;
+ features?: string;
+ use_cases?: string;
+}
+
+export interface Service extends Content {
+ content_type: 'service';
+ service_type?: string;
+ pricing_model?: string;
+ delivery_method?: string;
+}
+
+export interface EntityContentJoin {
+ join_id: string;
+ entity_id: string;
+ content_id: string;
+ join_note?: string;
+ created_at: string;
+}
+
+// API响应类型
+export interface PaginatedResponse {
+ list: T[];
+ total: number;
+ page: number;
+ pageSize: number;
+ totalPages: number;
+}
+
+// SEO类型
+export interface SEOData {
+ title: string;
+ description: string;
+ canonical?: string;
+ ogTitle?: string;
+ ogDescription?: string;
+ ogImage?: string;
+}
+
+// 面包屑类型
+export interface Breadcrumb {
+ name: string;
+ url: string;
+}
+
+// 结构化数据类型
+export interface JsonLdData {
+ '@context': string;
+ '@type': string;
+ [key: string]: any;
+}
\ No newline at end of file
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
new file mode 100644
index 0000000..7f8d87f
--- /dev/null
+++ b/frontend/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..2424172
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,5766 @@
+{
+ "name": "ameiba-ai-website-mvp-base",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "ameiba-ai-website-mvp-base",
+ "version": "1.0.0",
+ "dependencies": {
+ "better-sqlite3": "^9.4.3",
+ "cors": "^2.8.5",
+ "dotenv": "^16.3.1",
+ "express": "^4.18.2",
+ "joi": "^17.11.0",
+ "sync-mysql": "^3.0.1",
+ "uuid": "^9.0.0"
+ },
+ "devDependencies": {
+ "jest": "^29.7.0",
+ "nodemon": "^3.0.2",
+ "supertest": "^6.3.3"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/core/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.8.tgz",
+ "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@babel/types": "^7.29.8",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.8"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz",
+ "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+ "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+ "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.8.tgz",
+ "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.8",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.8",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.8",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmmirror.com/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmmirror.com/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.6.tgz",
+ "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/console/-/console-29.7.0.tgz",
+ "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/core/-/core-29.7.0.tgz",
+ "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/reporters": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.7.0",
+ "jest-config": "^29.7.0",
+ "jest-haste-map": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-resolve-dependencies": "^29.7.0",
+ "jest-runner": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "jest-watcher": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/environment/-/environment-29.7.0.tgz",
+ "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/expect/-/expect-29.7.0.tgz",
+ "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^29.7.0",
+ "jest-snapshot": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
+ "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.6.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
+ "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/globals/-/globals-29.7.0.tgz",
+ "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/expect": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "jest-mock": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/reporters/-/reporters-29.7.0.tgz",
+ "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/@jest/source-map/-/source-map-29.6.3.tgz",
+ "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/test-result/-/test-result-29.7.0.tgz",
+ "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
+ "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "^29.7.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/@jest/transform/-/transform-29.7.0.tgz",
+ "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.2"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+ "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@noble/hashes": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmmirror.com/@noble/hashes/-/hashes-1.8.0.tgz",
+ "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.21.3 || >=16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@paralleldrive/cuid2": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz",
+ "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@noble/hashes": "^1.1.5"
+ }
+ },
+ "node_modules/@sideway/address": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz",
+ "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.12",
+ "resolved": "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.27.12.tgz",
+ "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
+ "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.9",
+ "resolved": "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
+ "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "26.5.0",
+ "resolved": "https://registry.npmmirror.com/@types/node/-/node-26.5.0.tgz",
+ "integrity": "sha512-dVSGpriSoCgz8WnDNTuSSuSv1PC/ALXihO4ulRZt7Md8k9mlbdin3lGOcDE8SnWOgf513ByWlXd7BK4azmyg/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~8.9.0"
+ }
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "license": "MIT"
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "license": "MIT"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/babel-jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/babel-jest/-/babel-jest-29.7.0.tgz",
+ "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/transform": "^29.7.0",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.6.3",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
+ "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
+ "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
+ "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+ "license": "MIT",
+ "dependencies": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/barrage": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/barrage/-/barrage-1.1.0.tgz",
+ "integrity": "sha512-lmhNsUZG+34gUrZl0SKOeYZ20o4Xni2wd52fzzrIsniQqoqfwa3otEP4Vceks+KwGACNsnQ1YSYtsaPWHrQ+3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "promise": "^6.0.0"
+ }
+ },
+ "node_modules/barrage/node_modules/asap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz",
+ "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA=="
+ },
+ "node_modules/barrage/node_modules/promise": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz",
+ "integrity": "sha512-O+uwGKreKNKkshzZv2P7N64lk6EP17iXBn0PbUnNQhk+Q0AHLstiTrjkx3v5YBd3cxUe7Sq6KyRhl/A0xUjk7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "asap": "~1.0.0"
+ }
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.21",
+ "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.21.tgz",
+ "integrity": "sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/better-sqlite3": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmmirror.com/better-sqlite3/-/better-sqlite3-9.6.0.tgz",
+ "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "bindings": "^1.5.0",
+ "prebuild-install": "^7.1.1"
+ }
+ },
+ "node_modules/bignumber.js": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+ "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.6",
+ "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.6.tgz",
+ "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "~1.2.0",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "on-finished": "~2.4.1",
+ "qs": "~6.15.1",
+ "raw-body": "~2.5.3",
+ "type-is": "~1.6.18",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.18",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.18.tgz",
+ "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.9",
+ "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.9.tgz",
+ "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.11.20",
+ "caniuse-lite": "^1.0.30001810",
+ "electron-to-chromium": "^1.5.420",
+ "node-releases": "^2.0.54",
+ "update-browserslist-db": "^1.3.2"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "license": "MIT"
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001810",
+ "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+ "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "license": "ISC"
+ },
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
+ "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmmirror.com/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz",
+ "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmmirror.com/component-emitter/-/component-emitter-1.3.1.tgz",
+ "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/concat-stream/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/concat-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/concat-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.7.tgz",
+ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
+ "license": "MIT"
+ },
+ "node_modules/cookiejar": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmmirror.com/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/core-js": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+ "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
+ "hasInstallScript": true,
+ "license": "MIT"
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.6.tgz",
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/create-jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/create-jest/-/create-jest-29.7.0.tgz",
+ "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-config": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "prompts": "^2.0.1"
+ },
+ "bin": {
+ "create-jest": "bin/create-jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/dedent": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmmirror.com/dedent/-/dedent-1.7.2.tgz",
+ "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dezalgo": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/dezalgo/-/dezalgo-1.0.4.tgz",
+ "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.422",
+ "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.422.tgz",
+ "integrity": "sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "license": "(MIT OR WTFPL)",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/expect": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/expect/-/expect-29.7.0.tgz",
+ "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/expect-utils": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.22.2",
+ "resolved": "https://registry.npmmirror.com/express/-/express-4.22.2.tgz",
+ "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "~1.20.5",
+ "content-disposition": "~0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "~0.7.1",
+ "cookie-signature": "~1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.3.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "~2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "~0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "~6.15.1",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "~0.19.0",
+ "serve-static": "~1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "~2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "license": "MIT"
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.3.2.tgz",
+ "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "~2.0.2",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.6.tgz",
+ "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.4",
+ "mime-types": "^2.1.35"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/formidable": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmmirror.com/formidable/-/formidable-2.1.5.tgz",
+ "integrity": "sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@paralleldrive/cuid2": "^2.2.2",
+ "dezalgo": "^1.0.4",
+ "once": "^1.4.0",
+ "qs": "^6.11.0"
+ },
+ "funding": {
+ "url": "https://ko-fi.com/tunnckoCore/commissions"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "license": "MIT"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-port": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
+ "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+ "license": "MIT"
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.2",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.2.tgz",
+ "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest/-/jest-29.7.0.tgz",
+ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.7.0"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
+ "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^5.0.0",
+ "jest-util": "^29.7.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-circus/-/jest-circus-29.7.0.tgz",
+ "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/expect": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^1.0.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.7.0",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.7.0",
+ "pure-rand": "^6.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-cli": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-cli/-/jest-cli-29.7.0.tgz",
+ "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "create-jest": "^29.7.0",
+ "exit": "^0.1.2",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-config/-/jest-config-29.7.0.tgz",
+ "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "babel-jest": "^29.7.0",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.7.0",
+ "jest-environment-node": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-runner": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-diff": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.7.0.tgz",
+ "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.6.3",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-docblock/-/jest-docblock-29.7.0.tgz",
+ "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-each/-/jest-each-29.7.0.tgz",
+ "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-environment-node": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
+ "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.6.3.tgz",
+ "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
+ "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
+ "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
+ "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.7.0.tgz",
+ "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.6.3",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-mock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-mock/-/jest-mock-29.7.0.tgz",
+ "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
+ "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-resolve/-/jest-resolve-29.7.0.tgz",
+ "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^2.0.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
+ "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-regex-util": "^29.6.3",
+ "jest-snapshot": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-runner/-/jest-runner-29.7.0.tgz",
+ "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/environment": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.7.0",
+ "jest-environment-node": "^29.7.0",
+ "jest-haste-map": "^29.7.0",
+ "jest-leak-detector": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-resolve": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-watcher": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-runtime/-/jest-runtime-29.7.0.tgz",
+ "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/globals": "^29.7.0",
+ "@jest/source-map": "^29.6.3",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
+ "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.7.0",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.7.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-29.7.0.tgz",
+ "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-validate/-/jest-validate-29.7.0.tgz",
+ "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-watcher": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-29.7.0.tgz",
+ "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.7.0",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/joi": {
+ "version": "17.13.7",
+ "resolved": "https://registry.npmmirror.com/joi/-/joi-17.13.7.tgz",
+ "integrity": "sha512-MF80Dm5Y2veNy8QWVx9Bj3ui4mo7+VPSPsR1M+oaHXV0Gx6zGX9a2F+OZG3Blby9tOlzU9Rs5FUimlEhbKtfnQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.3.0",
+ "@hapi/topo": "^5.1.0",
+ "@sideway/address": "^4.1.5",
+ "@sideway/formula": "^3.0.1",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "3.15.2",
+ "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.15.2.tgz",
+ "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/mysql": {
+ "version": "2.18.1",
+ "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
+ "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
+ "license": "MIT",
+ "dependencies": {
+ "bignumber.js": "9.0.0",
+ "readable-stream": "2.3.7",
+ "safe-buffer": "5.1.2",
+ "sqlstring": "2.3.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mysql/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/mysql/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/mysql/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+ "license": "MIT"
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-abi": {
+ "version": "3.96.0",
+ "resolved": "https://registry.npmmirror.com/node-abi/-/node-abi-3.96.0.tgz",
+ "integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==",
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-abi/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.54",
+ "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.54.tgz",
+ "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/nodemon": {
+ "version": "3.1.14",
+ "resolved": "https://registry.npmmirror.com/nodemon/-/nodemon-3.1.14.tgz",
+ "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^4",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^10.2.1",
+ "pstree.remy": "^1.1.8",
+ "semver": "^7.5.3",
+ "simple-update-notifier": "^2.0.0",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nodemon"
+ }
+ },
+ "node_modules/nodemon/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/nodemon/node_modules/brace-expansion": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-5.0.9.tgz",
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/nodemon/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nodemon/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/nodemon/node_modules/minimatch": {
+ "version": "10.2.6",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.8"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/nodemon/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nodemon/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/nodemon/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
+ "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/prebuild-install": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.2.tgz",
+ "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
+ "node_modules/promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "license": "MIT",
+ "dependencies": {
+ "asap": "~2.0.3"
+ }
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmmirror.com/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.4.tgz",
+ "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/pure-rand": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmmirror.com/pure-rand/-/pure-rand-6.1.0.tgz",
+ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/qs": {
+ "version": "6.15.3",
+ "resolved": "https://registry.npmmirror.com/qs/-/qs-6.15.3.tgz",
+ "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "es-define-property": "^1.0.1",
+ "side-channel": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.3.tgz",
+ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "license": "MIT"
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.12",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.12.tgz",
+ "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve.exports": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmmirror.com/resolve.exports/-/resolve.exports-2.0.3.tgz",
+ "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmmirror.com/send/-/send-0.19.2.tgz",
+ "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.1",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "~2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "~2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.16.3.tgz",
+ "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "~0.19.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/simple-update-notifier": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+ "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/simple-update-notifier/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/sqlstring": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
+ "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/superagent": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmmirror.com/superagent/-/superagent-8.1.2.tgz",
+ "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==",
+ "deprecated": "Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "component-emitter": "^1.3.0",
+ "cookiejar": "^2.1.4",
+ "debug": "^4.3.4",
+ "fast-safe-stringify": "^2.1.1",
+ "form-data": "^4.0.0",
+ "formidable": "^2.1.2",
+ "methods": "^1.1.2",
+ "mime": "2.6.0",
+ "qs": "^6.11.0",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">=6.4.0 <13 || >=14"
+ }
+ },
+ "node_modules/superagent/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/superagent/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/superagent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/superagent/node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/supertest": {
+ "version": "6.3.4",
+ "resolved": "https://registry.npmmirror.com/supertest/-/supertest-6.3.4.tgz",
+ "integrity": "sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==",
+ "deprecated": "Please upgrade to supertest v7.1.3+, see release notes at https://github.com/forwardemail/supertest/releases/tag/v7.1.3 - maintenance is supported by Forward Email @ https://forwardemail.net",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "methods": "^1.1.2",
+ "superagent": "^8.1.2"
+ },
+ "engines": {
+ "node": ">=6.4.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sync-mysql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sync-mysql/-/sync-mysql-3.0.1.tgz",
+ "integrity": "sha512-EKWJFuiPRtj1s6bjSaf4tzMFeq8x0JgKtgyIsTTkD20E8pkzInEFxj1B+efbYMjQUfN9MEY3HOsaSYUmSbsUKw==",
+ "license": "MIT",
+ "dependencies": {
+ "babel-runtime": "^6.18.0",
+ "concat-stream": "^1.6.0",
+ "sync-rpc": "^1.1.1",
+ "then-mysql": "^1.1.1"
+ }
+ },
+ "node_modules/sync-rpc": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.7.tgz",
+ "integrity": "sha512-YHciI7TUxL8EPqz/bg01sZfwuzQA0odao1wf1Ywdtw7j5vl30aQ6s+bLRTvgPPgzr94cg+WMm6Bxi/P7BJOxgw==",
+ "license": "MIT",
+ "dependencies": {
+ "get-port": "^3.1.0"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.5.tgz",
+ "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==",
+ "license": "MIT",
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/then-mysql": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/then-mysql/-/then-mysql-1.1.1.tgz",
+ "integrity": "sha512-QqWODY1xtWFo3XR4GllWFkXMTz+QirJKcggMETNPeGqPDcxUyApqDW5GgAUJEz4Dga3/WrXNmZY0bT+cAWjQ2g==",
+ "license": "MIT",
+ "dependencies": {
+ "barrage": "^1.1.0",
+ "mysql": "^2.10.0",
+ "promise": "^7.1.1"
+ }
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/touch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/touch/-/touch-3.1.1.tgz",
+ "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "license": "MIT"
+ },
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmmirror.com/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "8.9.0",
+ "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-8.9.0.tgz",
+ "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz",
+ "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yargs": {
+ "version": "17.7.3",
+ "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.3.tgz",
+ "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..7dc4ccf
--- /dev/null
+++ b/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "ameiba-ai-website-mvp-base",
+ "version": "1.0.0",
+ "description": "阿美巴AI官网 MVP-BASE 第一期底座开发",
+ "main": "src/index.js",
+ "scripts": {
+ "start": "node src/index.js",
+ "dev": "nodemon src/index.js",
+ "test": "jest",
+ "migrate": "node src/database/migrate.js",
+ "seed": "node src/database/seed.js"
+ },
+ "dependencies": {
+ "better-sqlite3": "^9.4.3",
+ "cors": "^2.8.5",
+ "dotenv": "^16.3.1",
+ "express": "^4.18.2",
+ "joi": "^17.11.0",
+ "sync-mysql": "^3.0.1",
+ "uuid": "^9.0.0"
+ },
+ "devDependencies": {
+ "jest": "^29.7.0",
+ "nodemon": "^3.0.2",
+ "supertest": "^6.3.3"
+ },
+ "allowScripts": {
+ "better-sqlite3@9.6.0": true
+ }
+}
diff --git a/public/images/icp.png b/public/images/icp.png
new file mode 100644
index 0000000..9f76394
Binary files /dev/null and b/public/images/icp.png differ
diff --git a/public/images/logo.png b/public/images/logo.png
new file mode 100644
index 0000000..39332e0
Binary files /dev/null and b/public/images/logo.png differ
diff --git a/src/config/database.js b/src/config/database.js
new file mode 100644
index 0000000..a04b941
--- /dev/null
+++ b/src/config/database.js
@@ -0,0 +1,86 @@
+require('dotenv').config();
+const SyncMySQL = require('sync-mysql');
+
+let db;
+
+const requiredConfig = ['DB_HOST', 'DB_PORT', 'DB_NAME', 'DB_USER', 'DB_PASSWORD'];
+
+class MySqlStatement {
+ constructor(connection, sql) {
+ this.connection = connection;
+ this.sql = sql;
+ }
+
+ all(...params) {
+ const result = this.connection.query(this.sql, params);
+ return Array.isArray(result) ? result : [];
+ }
+
+ get(...params) {
+ const rows = this.all(...params);
+ return rows[0];
+ }
+
+ run(...params) {
+ const result = this.connection.query(this.sql, params) || {};
+ return {
+ changes: result.affectedRows || 0,
+ lastInsertRowid: result.insertId || 0,
+ };
+ }
+}
+
+class MySqlDatabase {
+ constructor(config) {
+ this.connection = new SyncMySQL(config);
+ }
+
+ prepare(sql) {
+ return new MySqlStatement(this.connection, sql);
+ }
+
+ exec(sql) {
+ // 当前迁移脚本只包含独立的CREATE TABLE语句,可安全按分号拆分执行。
+ sql.split(';')
+ .map(statement => statement.trim())
+ .filter(Boolean)
+ .forEach(statement => this.connection.query(statement));
+ }
+
+ close() {
+ try {
+ this.connection.dispose();
+ } catch (error) {
+ // sync-mysql的RPC worker已提前退出时,关闭过程不应阻断服务退出。
+ console.warn('MySQL连接关闭提示:', error.message);
+ }
+ }
+}
+
+const getDb = () => {
+ if (!db) {
+ const missing = requiredConfig.filter(key => !process.env[key]);
+ if (missing.length > 0) {
+ throw new Error(`MySQL配置缺失: ${missing.join(', ')}`);
+ }
+
+ db = new MySqlDatabase({
+ host: process.env.DB_HOST,
+ port: Number(process.env.DB_PORT),
+ database: process.env.DB_NAME,
+ user: process.env.DB_USER,
+ password: process.env.DB_PASSWORD,
+ charset: 'utf8mb4',
+ });
+ }
+ return db;
+};
+
+const closeDb = () => {
+ if (db) {
+ db.close();
+ db = null;
+ }
+};
+
+module.exports = { getDb, closeDb };
diff --git a/src/database/migrate.js b/src/database/migrate.js
new file mode 100644
index 0000000..910f6a4
--- /dev/null
+++ b/src/database/migrate.js
@@ -0,0 +1,268 @@
+const { getDb, closeDb } = require('../config/database');
+
+const createTables = () => {
+ const db = getDb();
+
+ // Entity表 - 知识实体表(P1-01增加entity_type,P1-02增加status/public_flag)
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS entities (
+ entity_id VARCHAR(36) PRIMARY KEY,
+ entity_type VARCHAR(64) DEFAULT 'concept',
+ name TEXT NOT NULL,
+ definition TEXT,
+ description TEXT,
+ status VARCHAR(32) DEFAULT 'active',
+ public_flag BOOLEAN DEFAULT 1,
+ authority_level INTEGER DEFAULT 1,
+ metadata TEXT,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
+ )
+ `);
+
+ // DirectedRelationship表 - 有向实体关系表
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS directed_relationships (
+ rel_id VARCHAR(36) PRIMARY KEY,
+ source_entity_id VARCHAR(36) NOT NULL,
+ relation_type VARCHAR(255) NOT NULL,
+ target_entity_id VARCHAR(36) NOT NULL,
+ rel_status VARCHAR(32) DEFAULT 'active',
+ authority_level INTEGER DEFAULT 1,
+ is_public BOOLEAN DEFAULT 0,
+ effective_at DATETIME,
+ expire_at DATETIME,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (source_entity_id) REFERENCES entities(entity_id),
+ FOREIGN KEY (target_entity_id) REFERENCES entities(entity_id)
+ )
+ `);
+
+ // Content基础表 - 内容基础模型
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS contents (
+ content_id VARCHAR(36) PRIMARY KEY,
+ title TEXT NOT NULL,
+ body TEXT,
+ content_type VARCHAR(32) NOT NULL,
+ publish_status VARCHAR(32) DEFAULT 'draft',
+ authority_level INTEGER DEFAULT 1,
+ version_no INTEGER DEFAULT 1,
+ version_note TEXT,
+ metadata TEXT,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ archived_at DATETIME
+ )
+ `);
+
+ // Page表 - 页面扩展(P1-03增加summary)
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS pages (
+ page_id VARCHAR(36) PRIMARY KEY,
+ slug VARCHAR(255) UNIQUE,
+ template VARCHAR(255),
+ summary TEXT,
+ seo_title TEXT,
+ seo_description TEXT,
+ seo_keywords TEXT,
+ FOREIGN KEY (page_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // Article表 - 文章扩展(P1-04增加published_at)
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS articles (
+ article_id VARCHAR(36) PRIMARY KEY,
+ category VARCHAR(255),
+ tags TEXT,
+ cover_image VARCHAR(1024),
+ author VARCHAR(255),
+ published_at DATETIME,
+ FOREIGN KEY (article_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // Case表 - 案例扩展(P0-01扩展完整案例字段)
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS cases (
+ case_id VARCHAR(36) PRIMARY KEY,
+ client_name TEXT,
+ industry TEXT,
+ challenge TEXT,
+ solution TEXT,
+ result TEXT,
+ background TEXT,
+ enterprise_stage TEXT,
+ original_goal TEXT,
+ current_state TEXT,
+ surface_problem TEXT,
+ amb_judgment TEXT,
+ key_obstacle TEXT,
+ root_cause TEXT,
+ evolution_path TEXT,
+ implementation TEXT,
+ case_significance TEXT,
+ FOREIGN KEY (case_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // FAQ表 - 常见问题扩展
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS faqs (
+ faq_id VARCHAR(36) PRIMARY KEY,
+ question TEXT,
+ answer TEXT,
+ sort_order INTEGER DEFAULT 0,
+ FOREIGN KEY (faq_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // Capability表 - 能力扩展
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS capabilities (
+ capability_id VARCHAR(36) PRIMARY KEY,
+ capability_type TEXT,
+ features TEXT,
+ use_cases TEXT,
+ FOREIGN KEY (capability_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // Service表 - 服务扩展
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS services (
+ service_id VARCHAR(36) PRIMARY KEY,
+ service_type TEXT,
+ pricing_model TEXT,
+ delivery_method TEXT,
+ FOREIGN KEY (service_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // EntityContentJoin表 - 实体-内容多对多关联中间表
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS entity_content_joins (
+ join_id VARCHAR(36) PRIMARY KEY,
+ entity_id VARCHAR(36) NOT NULL,
+ content_id VARCHAR(36) NOT NULL,
+ join_note TEXT,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (entity_id) REFERENCES entities(entity_id),
+ FOREIGN KEY (content_id) REFERENCES contents(content_id)
+ )
+ `);
+
+ // 管理员账号表
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS admin_users (
+ user_id VARCHAR(36) PRIMARY KEY,
+ username VARCHAR(64) NOT NULL UNIQUE,
+ password_hash VARCHAR(255) NOT NULL,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
+ )
+ `);
+
+ // 前台可编辑站点配置
+ db.exec(`
+ CREATE TABLE IF NOT EXISTS site_settings (
+ setting_key VARCHAR(128) PRIMARY KEY,
+ setting_value TEXT,
+ setting_group VARCHAR(64) DEFAULT 'general',
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
+ )
+ `);
+
+ console.log('数据库表创建完成');
+};
+
+const migrate = () => {
+ try {
+ createTables();
+ seedAdminAndSettings();
+ console.log('数据库迁移完成');
+ } catch (error) {
+ console.error('数据库迁移失败:', error);
+ throw error;
+ }
+};
+
+const seedAdminAndSettings = () => {
+ const db = getDb();
+ const crypto = require('crypto');
+ const user = db.prepare('SELECT user_id FROM admin_users WHERE username = ?').get('admin');
+ if (!user) {
+ const salt = crypto.randomBytes(16).toString('hex');
+ const hash = crypto.scryptSync('已移除的历史密码', salt, 64).toString('hex');
+ db.prepare(`
+ INSERT INTO admin_users (user_id, username, password_hash)
+ VALUES (?, ?, ?)
+ `).run(require('uuid').v4(), 'admin', `${salt}:${hash}`);
+ console.log('默认管理员账号已创建: admin');
+ }
+
+ const defaults = {
+ 'site.name': ['阿美巴AI', 'general'],
+ 'site.footerCopyright': ['© 2026 阿美巴AI. All rights reserved.', 'general'],
+ 'site.footerEmail': ['ameiba0258@gmail.com', 'general'],
+ 'site.footerPhone': ['4009080258', 'general'],
+ 'site.footerAddress': ['四川省成都市双流区正兴街道湖畔路北段366号1栋3楼1号', 'general'],
+ 'site.icp': ['蜀ICP备2025143754号-7', 'general'],
+ 'home.heroTitle': ['阿美巴(Ameiba)', 'home'],
+ 'home.heroSubtitle': ['AI时代企业进化平台', 'home'],
+ 'home.heroDescription': ['我们帮助企业在AI时代实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。', 'home'],
+ 'contact.title': ['联系我们', 'contact'],
+ 'contact.contactTitle': ['联系方式', 'contact'],
+ 'contact.email': ['contact@ameiba.com', 'contact'],
+ 'contact.phone': ['待填充', 'contact'],
+ 'contact.address': ['待填充', 'contact'],
+ 'contact.serviceHoursTitle': ['服务时间', 'contact'],
+ 'contact.serviceHours': ['周一至周五:9:00 - 18:00', 'contact'],
+ 'contact.consultationTitle': ['咨询服务', 'contact'],
+ 'contact.consultationIntro': ['我们提供以下咨询服务:', 'contact'],
+ 'contact.consultationItems': ['企业进化诊断\n进化路径规划\n战略咨询\n组织变革咨询\nAI部署咨询', 'contact'],
+ 'contact.cooperationTitle': ['合作方式', 'contact'],
+ 'contact.cooperationItems': ['顾问服务\n咨询服务\n企业陪跑\n定制化服务', 'contact'],
+ 'contact.faqTitle': ['常见问题', 'contact'],
+ 'contact.faqText': ['如有其他问题,请查看', 'contact'],
+ 'contact.relatedTitle': ['相关知识', 'contact'],
+ };
+ const pageDefaults = {
+ about: ['阿美巴是谁', '阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化。'],
+ evolution: ['企业进化', '企业进化是企业围绕长期发展目标持续调整、重构与升级的过程。'],
+ value: ['四大价值', '价值创造、价值传递、价值交付、价值支持共同构成企业经营的价值体系。'],
+ amb: ['A/M-B三态模型:AI时代企业进化状态识别框架', 'A/M-B模型用于帮助企业识别自身所处的进化状态,并明确下一步行动。'],
+ capabilities: ['企业进化能力地图', '从战略、经营、组织到AI部署,构建企业持续进化所需要的能力地图。'],
+ cases: ['企业进化案例', '通过真实案例,展示企业在经营环境中的目标、障碍、进化路径与实施过程。'],
+ knowledge: ['知识中心', '集中展示企业进化相关的知识、方法和实践内容。'],
+ faq: ['常见问题', '以下是关于企业进化的常见问题解答。'],
+ };
+ Object.entries(pageDefaults).forEach(([page, [title, intro]]) => {
+ defaults[`${page}.title`] = [title, page];
+ defaults[`${page}.intro`] = [intro, page];
+ });
+ const extraDefaults = {
+ 'amb.whatTitle': ['什么是A/M-B', 'amb'], 'amb.whatNote': ['A/M-B不是产品套餐,不是收费等级,不是强制线性路径,不是所有企业必须经历的三个固定阶段。', 'amb'], 'amb.whatPurpose': ['A/M-B的作用,是帮助企业识别自身所处状态,并进一步判断当前需要完成的关键进化动作。', 'amb'], 'amb.statesTitle': ['三种状态', 'amb'], 'amb.stateA': ['A态·入态|企业开始进入AI时代企业进化的一种状态', 'amb'], 'amb.stateM': ['M态·优态|企业进一步围绕现有经营与管理体系进行优化的一种状态', 'amb'], 'amb.stateB': ['B态·越态|企业突破原有运行边界、形成新的企业运行能力的一种状态', 'amb'], 'amb.recognitionTitle': ['状态识别', 'amb'], 'amb.recognitionText': ['企业可以根据自身情况处于不同状态,也不意味着所有企业必须从A到M再到B。\n企业需要根据自身发展阶段和实际情况,判断当前所处的状态,并确定需要完成的关键进化动作。', 'amb'],
+ 'evolution.definitionTitle': ['什么是企业进化', 'evolution'], 'evolution.definitionMore': ['增长更多体现结果层变化。进化更强调底层能力、系统与企业状态的持续调整和升级。AI是时代变量和重要赋能工具,不是企业进化本身的终点。', 'evolution'], 'evolution.whyTitle': ['为什么需要企业进化', 'evolution'], 'evolution.whyIntro': ['在AI时代,企业面临着前所未有的挑战:', 'evolution'], 'evolution.whyItems': ['技术快速迭代,传统业务模式面临冲击\n客户需求变化,个性化、智能化要求提高\n竞争环境加剧,需要更高效的运营模式\n人才结构变化,需要新的组织能力', 'evolution'],
+ 'value.overviewTitle': ['价值体系概述', 'value'], 'value.valuesTitle': ['四大价值', 'value'], 'value.relationTitle': ['价值体系的关系', 'value'], 'value.relationText': ['四大价值相互关联、相互支撑。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。', 'value'],
+ 'about.positionTitle': ['定位', 'about'], 'about.positionText': ['阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。', 'about'], 'about.existTitle': ['为什么存在', 'about'], 'about.existText': ['在AI时代,企业面临着前所未有的挑战与机遇。传统的企业管理方法已无法适应快速变化的环境,企业需要一套系统化的进化方法,实现从传统模式向AI时代模式的转型。\n阿美巴的存在,就是为了帮助企业完成这一进化过程,实现可持续增长与发展。', 'about'], 'about.audienceTitle': ['服务对象', 'about'], 'about.audienceText': ['我们服务的对象是那些希望在AI时代实现转型与增长的企业,无论企业当前处于哪个发展阶段,我们都能提供适合的进化路径与能力支持。', 'about'], 'about.historyTitle': ['发展历程', 'about'], 'about.historyText': ['待填充', 'about'],
+ 'capabilities.overviewTitle': ['能力概述', 'capabilities'], 'capabilities.categoryTitle': ['能力分类', 'capabilities'], 'cases.overviewTitle': ['案例概述', 'cases'], 'cases.listTitle': ['案例列表', 'cases'], 'knowledge.systemTitle': ['知识体系', 'knowledge'], 'knowledge.categoryTitle': ['知识分类', 'knowledge'], 'knowledge.articleTitle': ['最新文章', 'knowledge'], 'faq.overviewTitle': ['FAQ概述', 'faq'], 'faq.listTitle': ['问题列表', 'faq'],
+ };
+ Object.entries(extraDefaults).forEach(([key, [value, group]]) => {
+ defaults[key] = [value, group];
+ });
+ Object.entries(defaults).forEach(([key, [value, group]]) => {
+ const existing = db.prepare('SELECT setting_key FROM site_settings WHERE setting_key = ?').get(key);
+ if (!existing) {
+ db.prepare('INSERT INTO site_settings (setting_key, setting_value, setting_group) VALUES (?, ?, ?)').run(key, value, group);
+ }
+ });
+};
+
+if (require.main === module) {
+ migrate();
+}
+
+module.exports = { migrate, createTables, seedAdminAndSettings };
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..39cd9b2
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,105 @@
+const express = require('express');
+const cors = require('cors');
+const path = require('path');
+require('dotenv').config();
+
+const { getDb, closeDb } = require('./config/database');
+const { migrate } = require('./database/migrate');
+
+// 路由导入
+const entityRoutes = require('./routes/entityRoutes');
+const relationshipRoutes = require('./routes/relationshipRoutes');
+const contentRoutes = require('./routes/contentRoutes');
+const entityContentJoinRoutes = require('./routes/entityContentJoinRoutes');
+const publicApiRoutes = require('./routes/publicApiRoutes');
+const jsonLdRoutes = require('./routes/jsonLdRoutes');
+const adminRoutes = require('./routes/adminRoutes');
+
+const app = express();
+const PORT = process.env.PORT || 24731;
+
+// 中间件
+app.use(cors({ origin: true, credentials: true }));
+app.use(express.json());
+app.use(express.urlencoded({ extended: true }));
+
+// 静态文件服务
+app.use('/static', express.static(path.join(__dirname, '../public')));
+
+// 路由
+app.use('/api/entities', entityRoutes);
+app.use('/api/relationships', relationshipRoutes);
+app.use('/api/contents', contentRoutes);
+app.use('/api/joins', entityContentJoinRoutes);
+app.use('/api/public', publicApiRoutes);
+app.use('/api/jsonld', jsonLdRoutes);
+app.use('/api/admin', adminRoutes);
+
+// 健康检查
+app.get('/health', (req, res) => {
+ res.json({ status: 'ok', timestamp: new Date().toISOString() });
+});
+
+// 首页
+app.get('/', (req, res) => {
+ res.json({
+ name: '阿美巴AI官网 MVP-BASE',
+ version: '1.0.0',
+ description: '第一期底座开发 - 知识模型、关系模型、内容模型、CMS治理内核',
+ endpoints: {
+ entities: '/api/entities',
+ relationships: '/api/relationships',
+ contents: '/api/contents',
+ joins: '/api/joins',
+ publicApi: '/api/public',
+ jsonLd: '/api/jsonld'
+ }
+ });
+});
+
+// 错误处理中间件
+app.use((err, req, res, next) => {
+ console.error('服务器错误:', err);
+ res.status(500).json({ error: '服务器内部错误' });
+});
+
+// 启动服务器
+const startServer = async () => {
+ try {
+ // 初始化数据库
+ console.log('正在初始化数据库...');
+ migrate();
+
+ // 启动服务器
+ app.listen(PORT, () => {
+ console.log(`服务器运行在 http://localhost:${PORT}`);
+ console.log('API文档:');
+ console.log(` 实体管理: http://localhost:${PORT}/api/entities`);
+ console.log(` 关系管理: http://localhost:${PORT}/api/relationships`);
+ console.log(` 内容管理: http://localhost:${PORT}/api/contents`);
+ console.log(` 关联管理: http://localhost:${PORT}/api/joins`);
+ console.log(` 公开API: http://localhost:${PORT}/api/public`);
+ console.log(` JSON-LD: http://localhost:${PORT}/api/jsonld`);
+ });
+ } catch (error) {
+ console.error('启动服务器失败:', error);
+ process.exit(1);
+ }
+};
+
+// 优雅关闭
+process.on('SIGINT', () => {
+ console.log('正在关闭服务器...');
+ closeDb();
+ process.exit(0);
+});
+
+process.on('SIGTERM', () => {
+ console.log('正在关闭服务器...');
+ closeDb();
+ process.exit(0);
+});
+
+startServer();
+
+module.exports = app;
diff --git a/src/models/Article.js b/src/models/Article.js
new file mode 100644
index 0000000..da17991
--- /dev/null
+++ b/src/models/Article.js
@@ -0,0 +1,153 @@
+const { getDb } = require('../config/database');
+const Content = require('./Content');
+
+class Article extends Content {
+ constructor(data = {}) {
+ super(data);
+ this.content_type = 'article';
+ this.article_id = data.article_id || this.content_id;
+ this.category = data.category || null;
+ this.tags = data.tags || null;
+ this.cover_image = data.cover_image || null;
+ this.author = data.author || null;
+ this.published_at = data.published_at || null;
+ }
+
+ static create(data) {
+ const db = getDb();
+
+ // 先创建Content记录
+ const contentData = {
+ ...data,
+ content_type: 'article'
+ };
+
+ const content = super.create(contentData);
+
+ // 再创建Article扩展记录
+ const stmt = db.prepare(`
+ INSERT INTO articles (article_id, category, tags, cover_image, author, published_at)
+ VALUES (?, ?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ data.category || null,
+ data.tags || null,
+ data.cover_image || null,
+ data.author || null,
+ data.published_at || null
+ );
+
+ return this.findById(content.content_id);
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, a.article_id, a.category, a.tags, a.cover_image, a.author, a.published_at
+ FROM contents c
+ LEFT JOIN articles a ON c.content_id = a.article_id
+ WHERE c.content_id = ?
+ `);
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ // 更新Content部分
+ const contentData = { ...data };
+ delete contentData.article_id;
+ delete contentData.category;
+ delete contentData.tags;
+ delete contentData.cover_image;
+ delete contentData.author;
+ delete contentData.published_at;
+
+ super.update(contentId, contentData);
+
+ // 更新Article扩展部分
+ const articleData = {};
+ if (data.category !== undefined) articleData.category = data.category;
+ if (data.tags !== undefined) articleData.tags = data.tags;
+ if (data.cover_image !== undefined) articleData.cover_image = data.cover_image;
+ if (data.author !== undefined) articleData.author = data.author;
+ if (data.published_at !== undefined) articleData.published_at = data.published_at;
+
+ if (Object.keys(articleData).length > 0) {
+ const setClause = Object.keys(articleData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(articleData);
+
+ const stmt = db.prepare(`UPDATE articles SET ${setClause} WHERE article_id = ?`);
+ stmt.run(...values, contentId);
+ }
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+
+ // 删除Article扩展记录
+ const stmt1 = db.prepare('DELETE FROM articles WHERE article_id = ?');
+ stmt1.run(contentId);
+
+ // 删除Content记录
+ return super.delete(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = `
+ SELECT c.*, a.article_id, a.category, a.tags, a.cover_image, a.author, a.published_at
+ FROM contents c
+ LEFT JOIN articles a ON c.content_id = a.article_id
+ WHERE c.content_type = 'article'
+ `;
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => {
+ if (key === 'category' || key === 'tags' || key === 'cover_image' || key === 'author' || key === 'published_at') {
+ return `a.${key} = ?`;
+ }
+ return `c.${key} = ?`;
+ });
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = Article;
\ No newline at end of file
diff --git a/src/models/Capability.js b/src/models/Capability.js
new file mode 100644
index 0000000..5cb55c9
--- /dev/null
+++ b/src/models/Capability.js
@@ -0,0 +1,145 @@
+const { getDb } = require('../config/database');
+const Content = require('./Content');
+
+class Capability extends Content {
+ constructor(data = {}) {
+ super(data);
+ this.content_type = 'capability';
+ this.capability_id = data.capability_id || this.content_id;
+ this.capability_type = data.capability_type || null;
+ this.features = data.features || null;
+ this.use_cases = data.use_cases || null;
+ }
+
+ static create(data) {
+ const db = getDb();
+
+ // 先创建Content记录
+ const contentData = {
+ ...data,
+ content_type: 'capability'
+ };
+
+ const content = super.create(contentData);
+
+ // 再创建Capability扩展记录
+ const stmt = db.prepare(`
+ INSERT INTO capabilities (capability_id, capability_type, features, use_cases)
+ VALUES (?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ data.capability_type || null,
+ data.features || null,
+ data.use_cases || null
+ );
+
+ return this.findById(content.content_id);
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, cap.capability_id, cap.capability_type, cap.features, cap.use_cases
+ FROM contents c
+ LEFT JOIN capabilities cap ON c.content_id = cap.capability_id
+ WHERE c.content_id = ?
+ `);
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ // 更新Content部分
+ const contentData = { ...data };
+ delete contentData.capability_id;
+ delete contentData.capability_type;
+ delete contentData.features;
+ delete contentData.use_cases;
+
+ super.update(contentId, contentData);
+
+ // 更新Capability扩展部分
+ const capabilityData = {};
+ if (data.capability_type !== undefined) capabilityData.capability_type = data.capability_type;
+ if (data.features !== undefined) capabilityData.features = data.features;
+ if (data.use_cases !== undefined) capabilityData.use_cases = data.use_cases;
+
+ if (Object.keys(capabilityData).length > 0) {
+ const setClause = Object.keys(capabilityData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(capabilityData);
+
+ const stmt = db.prepare(`UPDATE capabilities SET ${setClause} WHERE capability_id = ?`);
+ stmt.run(...values, contentId);
+ }
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+
+ // 删除Capability扩展记录
+ const stmt1 = db.prepare('DELETE FROM capabilities WHERE capability_id = ?');
+ stmt1.run(contentId);
+
+ // 删除Content记录
+ return super.delete(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = `
+ SELECT c.*, cap.capability_id, cap.capability_type, cap.features, cap.use_cases
+ FROM contents c
+ LEFT JOIN capabilities cap ON c.content_id = cap.capability_id
+ WHERE c.content_type = 'capability'
+ `;
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => {
+ if (key === 'capability_type' || key === 'features' || key === 'use_cases') {
+ return `cap.${key} = ?`;
+ }
+ return `c.${key} = ?`;
+ });
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = Capability;
\ No newline at end of file
diff --git a/src/models/Case.js b/src/models/Case.js
new file mode 100644
index 0000000..b786b81
--- /dev/null
+++ b/src/models/Case.js
@@ -0,0 +1,207 @@
+const { getDb } = require('../config/database');
+const Content = require('./Content');
+
+class Case extends Content {
+ constructor(data = {}) {
+ super(data);
+ this.content_type = 'case';
+ this.case_id = data.case_id || this.content_id;
+ this.client_name = data.client_name || null;
+ this.industry = data.industry || null;
+ this.challenge = data.challenge || null;
+ this.solution = data.solution || null;
+ this.result = data.result || null;
+ // P0-01扩展字段
+ this.background = data.background || null;
+ this.enterprise_stage = data.enterprise_stage || null;
+ this.original_goal = data.original_goal || null;
+ this.current_state = data.current_state || null;
+ this.surface_problem = data.surface_problem || null;
+ this.amb_judgment = data.amb_judgment || null;
+ this.key_obstacle = data.key_obstacle || null;
+ this.root_cause = data.root_cause || null;
+ this.evolution_path = data.evolution_path || null;
+ this.implementation = data.implementation || null;
+ this.case_significance = data.case_significance || null;
+ }
+
+ static create(data) {
+ const db = getDb();
+
+ // 先创建Content记录
+ const contentData = {
+ ...data,
+ content_type: 'case'
+ };
+
+ const content = super.create(contentData);
+
+ // 再创建Case扩展记录(P0-01扩展完整案例字段)
+ const stmt = db.prepare(`
+ INSERT INTO cases (case_id, client_name, industry, challenge, solution, result,
+ background, enterprise_stage, original_goal, current_state, surface_problem,
+ amb_judgment, key_obstacle, root_cause, evolution_path, implementation, case_significance)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ data.client_name || null,
+ data.industry || null,
+ data.challenge || null,
+ data.solution || null,
+ data.result || null,
+ data.background || null,
+ data.enterprise_stage || null,
+ data.original_goal || null,
+ data.current_state || null,
+ data.surface_problem || null,
+ data.amb_judgment || null,
+ data.key_obstacle || null,
+ data.root_cause || null,
+ data.evolution_path || null,
+ data.implementation || null,
+ data.case_significance || null
+ );
+
+ return this.findById(content.content_id);
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, cs.case_id, cs.client_name, cs.industry, cs.challenge, cs.solution, cs.result,
+ cs.background, cs.enterprise_stage, cs.original_goal, cs.current_state, cs.surface_problem,
+ cs.amb_judgment, cs.key_obstacle, cs.root_cause, cs.evolution_path, cs.implementation, cs.case_significance
+ FROM contents c
+ LEFT JOIN cases cs ON c.content_id = cs.case_id
+ WHERE c.content_id = ?
+ `);
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ // 更新Content部分
+ const contentData = { ...data };
+ delete contentData.case_id;
+ delete contentData.client_name;
+ delete contentData.industry;
+ delete contentData.challenge;
+ delete contentData.solution;
+ delete contentData.result;
+ delete contentData.background;
+ delete contentData.enterprise_stage;
+ delete contentData.original_goal;
+ delete contentData.current_state;
+ delete contentData.surface_problem;
+ delete contentData.amb_judgment;
+ delete contentData.key_obstacle;
+ delete contentData.root_cause;
+ delete contentData.evolution_path;
+ delete contentData.implementation;
+ delete contentData.case_significance;
+
+ super.update(contentId, contentData);
+
+ // 更新Case扩展部分(P0-01扩展完整案例字段)
+ const caseData = {};
+ if (data.client_name !== undefined) caseData.client_name = data.client_name;
+ if (data.industry !== undefined) caseData.industry = data.industry;
+ if (data.challenge !== undefined) caseData.challenge = data.challenge;
+ if (data.solution !== undefined) caseData.solution = data.solution;
+ if (data.result !== undefined) caseData.result = data.result;
+ if (data.background !== undefined) caseData.background = data.background;
+ if (data.enterprise_stage !== undefined) caseData.enterprise_stage = data.enterprise_stage;
+ if (data.original_goal !== undefined) caseData.original_goal = data.original_goal;
+ if (data.current_state !== undefined) caseData.current_state = data.current_state;
+ if (data.surface_problem !== undefined) caseData.surface_problem = data.surface_problem;
+ if (data.amb_judgment !== undefined) caseData.amb_judgment = data.amb_judgment;
+ if (data.key_obstacle !== undefined) caseData.key_obstacle = data.key_obstacle;
+ if (data.root_cause !== undefined) caseData.root_cause = data.root_cause;
+ if (data.evolution_path !== undefined) caseData.evolution_path = data.evolution_path;
+ if (data.implementation !== undefined) caseData.implementation = data.implementation;
+ if (data.case_significance !== undefined) caseData.case_significance = data.case_significance;
+
+ if (Object.keys(caseData).length > 0) {
+ const setClause = Object.keys(caseData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(caseData);
+
+ const stmt = db.prepare(`UPDATE cases SET ${setClause} WHERE case_id = ?`);
+ stmt.run(...values, contentId);
+ }
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+
+ // 删除Case扩展记录
+ const stmt1 = db.prepare('DELETE FROM cases WHERE case_id = ?');
+ stmt1.run(contentId);
+
+ // 删除Content记录
+ return super.delete(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = `
+ SELECT c.*, cs.case_id, cs.client_name, cs.industry, cs.challenge, cs.solution, cs.result,
+ cs.background, cs.enterprise_stage, cs.original_goal, cs.current_state, cs.surface_problem,
+ cs.amb_judgment, cs.key_obstacle, cs.root_cause, cs.evolution_path, cs.implementation, cs.case_significance
+ FROM contents c
+ LEFT JOIN cases cs ON c.content_id = cs.case_id
+ WHERE c.content_type = 'case'
+ `;
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => {
+ if (key === 'client_name' || key === 'industry' || key === 'challenge' || key === 'solution' || key === 'result' ||
+ key === 'background' || key === 'enterprise_stage' || key === 'original_goal' || key === 'current_state' ||
+ key === 'surface_problem' || key === 'amb_judgment' || key === 'key_obstacle' || key === 'root_cause' ||
+ key === 'evolution_path' || key === 'implementation' || key === 'case_significance') {
+ return `cs.${key} = ?`;
+ }
+ return `c.${key} = ?`;
+ });
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = Case;
\ No newline at end of file
diff --git a/src/models/Content.js b/src/models/Content.js
new file mode 100644
index 0000000..e1d2444
--- /dev/null
+++ b/src/models/Content.js
@@ -0,0 +1,229 @@
+const { getDb } = require('../config/database');
+const { v4: uuidv4 } = require('uuid');
+
+class Content {
+ constructor(data = {}) {
+ this.content_id = data.content_id || uuidv4();
+ this.title = data.title;
+ this.body = data.body || null;
+ this.content_type = data.content_type;
+ this.publish_status = data.publish_status || 'draft';
+ this.authority_level = data.authority_level || 1;
+ this.version_no = data.version_no || 1;
+ this.version_note = data.version_note || null;
+ this.metadata = data.metadata ? JSON.stringify(data.metadata) : null;
+ this.created_at = data.created_at || new Date().toISOString();
+ this.updated_at = data.updated_at || new Date().toISOString();
+ this.archived_at = data.archived_at || null;
+ }
+
+ static create(data) {
+ const db = getDb();
+ const content = new Content(data);
+
+ const stmt = db.prepare(`
+ INSERT INTO contents (
+ content_id, title, body, content_type, publish_status,
+ authority_level, version_no, version_note, metadata,
+ created_at, updated_at, archived_at
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ content.title,
+ content.body,
+ content.content_type,
+ content.publish_status,
+ content.authority_level,
+ content.version_no,
+ content.version_note,
+ content.metadata,
+ content.created_at,
+ content.updated_at,
+ content.archived_at
+ );
+
+ return content;
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM contents WHERE content_id = ?');
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static findByType(contentType, options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM contents WHERE content_type = ?';
+ const params = [contentType];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+
+ static findPublished(options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM contents WHERE publish_status = ?';
+ const params = ['published'];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ const updateData = { ...data };
+ delete updateData.content_id;
+ delete updateData.created_at;
+
+ updateData.updated_at = new Date().toISOString();
+
+ if (updateData.metadata) {
+ updateData.metadata = JSON.stringify(updateData.metadata);
+ }
+
+ const setClause = Object.keys(updateData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(updateData);
+
+ const stmt = db.prepare(`UPDATE contents SET ${setClause} WHERE content_id = ?`);
+ stmt.run(...values, contentId);
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+ const stmt = db.prepare('DELETE FROM contents WHERE content_id = ?');
+ return stmt.run(contentId);
+ }
+
+ static count() {
+ const db = getDb();
+ const stmt = db.prepare('SELECT COUNT(*) as count FROM contents');
+ const row = stmt.get();
+ return row.count;
+ }
+
+ // 内容状态流转
+ static transitionStatus(contentId, newStatus) {
+ const validTransitions = {
+ 'draft': ['review'],
+ 'review': ['draft', 'published'],
+ 'published': ['unpublished'],
+ 'unpublished': ['historical', 'published'],
+ 'historical': []
+ };
+
+ const content = this.findById(contentId);
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+
+ const allowedTransitions = validTransitions[content.publish_status];
+ if (!allowedTransitions.includes(newStatus)) {
+ throw new Error(`不允许从 ${content.publish_status} 转换到 ${newStatus}`);
+ }
+
+ const updateData = {
+ publish_status: newStatus,
+ updated_at: new Date().toISOString()
+ };
+
+ // 如果转换到historical,记录归档时间
+ if (newStatus === 'historical') {
+ updateData.archived_at = new Date().toISOString();
+ }
+
+ // 如果转换到published,增加版本号
+ if (newStatus === 'published') {
+ updateData.version_no = content.version_no + 1;
+ }
+
+ return this.update(contentId, updateData);
+ }
+
+ // 创建历史版本
+ static createHistoricalVersion(contentId) {
+ const content = this.findById(contentId);
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+
+ // 创建新版本
+ const newData = {
+ ...content,
+ content_id: uuidv4(),
+ version_no: content.version_no + 1,
+ publish_status: 'historical',
+ archived_at: new Date().toISOString(),
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString()
+ };
+
+ return this.create(newData);
+ }
+}
+
+module.exports = Content;
\ No newline at end of file
diff --git a/src/models/DirectedRelationship.js b/src/models/DirectedRelationship.js
new file mode 100644
index 0000000..4a4a444
--- /dev/null
+++ b/src/models/DirectedRelationship.js
@@ -0,0 +1,145 @@
+const { getDb } = require('../config/database');
+const { v4: uuidv4 } = require('uuid');
+
+class DirectedRelationship {
+ constructor(data = {}) {
+ this.rel_id = data.rel_id || uuidv4();
+ this.source_entity_id = data.source_entity_id;
+ this.relation_type = data.relation_type;
+ this.target_entity_id = data.target_entity_id;
+ this.rel_status = data.rel_status || 'active';
+ this.authority_level = data.authority_level || 1;
+ this.is_public = data.is_public || 0;
+ this.effective_at = data.effective_at || null;
+ this.expire_at = data.expire_at || null;
+ this.created_at = data.created_at || new Date().toISOString();
+ this.updated_at = data.updated_at || new Date().toISOString();
+ }
+
+ static create(data) {
+ const db = getDb();
+ const relationship = new DirectedRelationship(data);
+
+ const stmt = db.prepare(`
+ INSERT INTO directed_relationships (
+ rel_id, source_entity_id, relation_type, target_entity_id,
+ rel_status, authority_level, is_public, effective_at, expire_at,
+ created_at, updated_at
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ relationship.rel_id,
+ relationship.source_entity_id,
+ relationship.relation_type,
+ relationship.target_entity_id,
+ relationship.rel_status,
+ relationship.authority_level,
+ relationship.is_public,
+ relationship.effective_at,
+ relationship.expire_at,
+ relationship.created_at,
+ relationship.updated_at
+ );
+
+ return relationship;
+ }
+
+ static findById(relId) {
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM directed_relationships WHERE rel_id = ?');
+ return stmt.get(relId);
+ }
+
+ static findBySourceEntity(sourceEntityId, options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM directed_relationships WHERE source_entity_id = ?';
+ const params = [sourceEntityId];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ const stmt = db.prepare(query);
+ return stmt.all(...params);
+ }
+
+ static findByTargetEntity(targetEntityId, options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM directed_relationships WHERE target_entity_id = ?';
+ const params = [targetEntityId];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ const stmt = db.prepare(query);
+ return stmt.all(...params);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM directed_relationships';
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` WHERE ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ return stmt.all(...params);
+ }
+
+ static update(relId, data) {
+ const db = getDb();
+
+ const updateData = { ...data };
+ delete updateData.rel_id;
+ delete updateData.created_at;
+
+ updateData.updated_at = new Date().toISOString();
+
+ const setClause = Object.keys(updateData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(updateData);
+
+ const stmt = db.prepare(`UPDATE directed_relationships SET ${setClause} WHERE rel_id = ?`);
+ stmt.run(...values, relId);
+
+ return this.findById(relId);
+ }
+
+ static delete(relId) {
+ const db = getDb();
+ const stmt = db.prepare('DELETE FROM directed_relationships WHERE rel_id = ?');
+ return stmt.run(relId);
+ }
+
+ static count() {
+ const db = getDb();
+ const stmt = db.prepare('SELECT COUNT(*) as count FROM directed_relationships');
+ const row = stmt.get();
+ return row.count;
+ }
+}
+
+module.exports = DirectedRelationship;
\ No newline at end of file
diff --git a/src/models/Entity.js b/src/models/Entity.js
new file mode 100644
index 0000000..b3d0e30
--- /dev/null
+++ b/src/models/Entity.js
@@ -0,0 +1,134 @@
+const { getDb } = require('../config/database');
+const { v4: uuidv4 } = require('uuid');
+
+class Entity {
+ constructor(data = {}) {
+ this.entity_id = data.entity_id || uuidv4();
+ this.entity_type = data.entity_type || 'concept';
+ this.name = data.name;
+ this.definition = data.definition || null;
+ this.description = data.description || null;
+ this.status = data.status || 'active';
+ this.public_flag = data.public_flag !== undefined ? data.public_flag : 1;
+ this.authority_level = data.authority_level || 1;
+ this.metadata = data.metadata ? JSON.stringify(data.metadata) : null;
+ this.created_at = data.created_at || new Date().toISOString();
+ this.updated_at = data.updated_at || new Date().toISOString();
+ }
+
+ static create(data) {
+ const db = getDb();
+ const entity = new Entity(data);
+
+ const stmt = db.prepare(`
+ INSERT INTO entities (entity_id, entity_type, name, definition, description, status, public_flag, authority_level, metadata, created_at, updated_at)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ entity.entity_id,
+ entity.entity_type,
+ entity.name,
+ entity.definition,
+ entity.description,
+ entity.status,
+ entity.public_flag,
+ entity.authority_level,
+ entity.metadata,
+ entity.created_at,
+ entity.updated_at
+ );
+
+ return entity;
+ }
+
+ static findById(entityId) {
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM entities WHERE entity_id = ?');
+ const row = stmt.get(entityId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM entities';
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` WHERE ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+
+ static update(entityId, data) {
+ const db = getDb();
+
+ // 禁止修改entity_id
+ if (data.entity_id && data.entity_id !== entityId) {
+ throw new Error('不能修改entity_id');
+ }
+
+ const updateData = { ...data };
+ delete updateData.entity_id;
+ delete updateData.created_at;
+
+ updateData.updated_at = new Date().toISOString();
+
+ if (updateData.metadata) {
+ updateData.metadata = JSON.stringify(updateData.metadata);
+ }
+
+ const setClause = Object.keys(updateData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(updateData);
+
+ const stmt = db.prepare(`UPDATE entities SET ${setClause} WHERE entity_id = ?`);
+ stmt.run(...values, entityId);
+
+ return this.findById(entityId);
+ }
+
+ static delete(entityId) {
+ const db = getDb();
+ const stmt = db.prepare('DELETE FROM entities WHERE entity_id = ?');
+ return stmt.run(entityId);
+ }
+
+ static count() {
+ const db = getDb();
+ const stmt = db.prepare('SELECT COUNT(*) as count FROM entities');
+ const row = stmt.get();
+ return row.count;
+ }
+}
+
+module.exports = Entity;
\ No newline at end of file
diff --git a/src/models/EntityContentJoin.js b/src/models/EntityContentJoin.js
new file mode 100644
index 0000000..e6d0bc3
--- /dev/null
+++ b/src/models/EntityContentJoin.js
@@ -0,0 +1,116 @@
+const { getDb } = require('../config/database');
+const { v4: uuidv4 } = require('uuid');
+
+class EntityContentJoin {
+ constructor(data = {}) {
+ this.join_id = data.join_id || uuidv4();
+ this.entity_id = data.entity_id;
+ this.content_id = data.content_id;
+ this.join_note = data.join_note || null;
+ this.created_at = data.created_at || new Date().toISOString();
+ }
+
+ static create(data) {
+ const db = getDb();
+ const join = new EntityContentJoin(data);
+
+ const stmt = db.prepare(`
+ INSERT INTO entity_content_joins (join_id, entity_id, content_id, join_note, created_at)
+ VALUES (?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ join.join_id,
+ join.entity_id,
+ join.content_id,
+ join.join_note,
+ join.created_at
+ );
+
+ return join;
+ }
+
+ static findById(joinId) {
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM entity_content_joins WHERE join_id = ?');
+ return stmt.get(joinId);
+ }
+
+ static findByEntityId(entityId) {
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM entity_content_joins WHERE entity_id = ?');
+ return stmt.all(entityId);
+ }
+
+ static findByContentId(contentId) {
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM entity_content_joins WHERE content_id = ?');
+ return stmt.all(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = 'SELECT * FROM entity_content_joins';
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` WHERE ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ return stmt.all(...params);
+ }
+
+ static update(joinId, data) {
+ const db = getDb();
+
+ const updateData = { ...data };
+ delete updateData.join_id;
+ delete updateData.created_at;
+
+ const setClause = Object.keys(updateData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(updateData);
+
+ const stmt = db.prepare(`UPDATE entity_content_joins SET ${setClause} WHERE join_id = ?`);
+ stmt.run(...values, joinId);
+
+ return this.findById(joinId);
+ }
+
+ static delete(joinId) {
+ const db = getDb();
+ const stmt = db.prepare('DELETE FROM entity_content_joins WHERE join_id = ?');
+ return stmt.run(joinId);
+ }
+
+ static deleteByEntityAndContent(entityId, contentId) {
+ const db = getDb();
+ const stmt = db.prepare('DELETE FROM entity_content_joins WHERE entity_id = ? AND content_id = ?');
+ return stmt.run(entityId, contentId);
+ }
+
+ static count() {
+ const db = getDb();
+ const stmt = db.prepare('SELECT COUNT(*) as count FROM entity_content_joins');
+ const row = stmt.get();
+ return row.count;
+ }
+}
+
+module.exports = EntityContentJoin;
\ No newline at end of file
diff --git a/src/models/FAQ.js b/src/models/FAQ.js
new file mode 100644
index 0000000..6872212
--- /dev/null
+++ b/src/models/FAQ.js
@@ -0,0 +1,145 @@
+const { getDb } = require('../config/database');
+const Content = require('./Content');
+
+class FAQ extends Content {
+ constructor(data = {}) {
+ super(data);
+ this.content_type = 'faq';
+ this.faq_id = data.faq_id || this.content_id;
+ this.question = data.question || null;
+ this.answer = data.answer || null;
+ this.sort_order = data.sort_order || 0;
+ }
+
+ static create(data) {
+ const db = getDb();
+
+ // 先创建Content记录
+ const contentData = {
+ ...data,
+ content_type: 'faq'
+ };
+
+ const content = super.create(contentData);
+
+ // 再创建FAQ扩展记录
+ const stmt = db.prepare(`
+ INSERT INTO faqs (faq_id, question, answer, sort_order)
+ VALUES (?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ data.question || null,
+ data.answer || null,
+ data.sort_order || 0
+ );
+
+ return this.findById(content.content_id);
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, f.faq_id, f.question, f.answer, f.sort_order
+ FROM contents c
+ LEFT JOIN faqs f ON c.content_id = f.faq_id
+ WHERE c.content_id = ?
+ `);
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ // 更新Content部分
+ const contentData = { ...data };
+ delete contentData.faq_id;
+ delete contentData.question;
+ delete contentData.answer;
+ delete contentData.sort_order;
+
+ super.update(contentId, contentData);
+
+ // 更新FAQ扩展部分
+ const faqData = {};
+ if (data.question !== undefined) faqData.question = data.question;
+ if (data.answer !== undefined) faqData.answer = data.answer;
+ if (data.sort_order !== undefined) faqData.sort_order = data.sort_order;
+
+ if (Object.keys(faqData).length > 0) {
+ const setClause = Object.keys(faqData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(faqData);
+
+ const stmt = db.prepare(`UPDATE faqs SET ${setClause} WHERE faq_id = ?`);
+ stmt.run(...values, contentId);
+ }
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+
+ // 删除FAQ扩展记录
+ const stmt1 = db.prepare('DELETE FROM faqs WHERE faq_id = ?');
+ stmt1.run(contentId);
+
+ // 删除Content记录
+ return super.delete(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = `
+ SELECT c.*, f.faq_id, f.question, f.answer, f.sort_order
+ FROM contents c
+ LEFT JOIN faqs f ON c.content_id = f.faq_id
+ WHERE c.content_type = 'faq'
+ `;
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => {
+ if (key === 'question' || key === 'answer' || key === 'sort_order') {
+ return `f.${key} = ?`;
+ }
+ return `c.${key} = ?`;
+ });
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = FAQ;
\ No newline at end of file
diff --git a/src/models/Page.js b/src/models/Page.js
new file mode 100644
index 0000000..8550aaf
--- /dev/null
+++ b/src/models/Page.js
@@ -0,0 +1,174 @@
+const { getDb } = require('../config/database');
+const Content = require('./Content');
+
+class Page extends Content {
+ constructor(data = {}) {
+ super(data);
+ this.content_type = 'page';
+ this.page_id = data.page_id || this.content_id;
+ this.slug = data.slug || null;
+ this.template = data.template || null;
+ this.summary = data.summary || null;
+ this.seo_title = data.seo_title || null;
+ this.seo_description = data.seo_description || null;
+ this.seo_keywords = data.seo_keywords || null;
+ }
+
+ static create(data) {
+ const db = getDb();
+
+ // 先创建Content记录
+ const contentData = {
+ ...data,
+ content_type: 'page'
+ };
+
+ const content = super.create(contentData);
+
+ // 再创建Page扩展记录
+ const stmt = db.prepare(`
+ INSERT INTO pages (page_id, slug, template, summary, seo_title, seo_description, seo_keywords)
+ VALUES (?, ?, ?, ?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ data.slug || null,
+ data.template || null,
+ data.summary || null,
+ data.seo_title || null,
+ data.seo_description || null,
+ data.seo_keywords || null
+ );
+
+ return this.findById(content.content_id);
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, p.page_id, p.slug, p.template, p.summary, p.seo_title, p.seo_description, p.seo_keywords
+ FROM contents c
+ LEFT JOIN pages p ON c.content_id = p.page_id
+ WHERE c.content_id = ?
+ `);
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static findBySlug(slug) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, p.page_id, p.slug, p.template, p.summary, p.seo_title, p.seo_description, p.seo_keywords
+ FROM contents c
+ LEFT JOIN pages p ON c.content_id = p.page_id
+ WHERE p.slug = ?
+ `);
+ const row = stmt.get(slug);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ // 更新Content部分
+ const contentData = { ...data };
+ delete contentData.page_id;
+ delete contentData.slug;
+ delete contentData.template;
+ delete contentData.summary;
+ delete contentData.seo_title;
+ delete contentData.seo_description;
+ delete contentData.seo_keywords;
+
+ super.update(contentId, contentData);
+
+ // 更新Page扩展部分
+ const pageData = {};
+ if (data.slug !== undefined) pageData.slug = data.slug;
+ if (data.template !== undefined) pageData.template = data.template;
+ if (data.summary !== undefined) pageData.summary = data.summary;
+ if (data.seo_title !== undefined) pageData.seo_title = data.seo_title;
+ if (data.seo_description !== undefined) pageData.seo_description = data.seo_description;
+ if (data.seo_keywords !== undefined) pageData.seo_keywords = data.seo_keywords;
+
+ if (Object.keys(pageData).length > 0) {
+ const setClause = Object.keys(pageData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(pageData);
+
+ const stmt = db.prepare(`UPDATE pages SET ${setClause} WHERE page_id = ?`);
+ stmt.run(...values, contentId);
+ }
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+
+ // 删除Page扩展记录
+ const stmt1 = db.prepare('DELETE FROM pages WHERE page_id = ?');
+ stmt1.run(contentId);
+
+ // 删除Content记录
+ return super.delete(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = `
+ SELECT c.*, p.page_id, p.slug, p.template, p.summary, p.seo_title, p.seo_description, p.seo_keywords
+ FROM contents c
+ LEFT JOIN pages p ON c.content_id = p.page_id
+ WHERE c.content_type = 'page'
+ `;
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => {
+ if (key === 'slug' || key === 'template' || key === 'summary' || key === 'seo_title' || key === 'seo_description' || key === 'seo_keywords') {
+ return `p.${key} = ?`;
+ }
+ return `c.${key} = ?`;
+ });
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = Page;
\ No newline at end of file
diff --git a/src/models/Service.js b/src/models/Service.js
new file mode 100644
index 0000000..152edbf
--- /dev/null
+++ b/src/models/Service.js
@@ -0,0 +1,145 @@
+const { getDb } = require('../config/database');
+const Content = require('./Content');
+
+class Service extends Content {
+ constructor(data = {}) {
+ super(data);
+ this.content_type = 'service';
+ this.service_id = data.service_id || this.content_id;
+ this.service_type = data.service_type || null;
+ this.pricing_model = data.pricing_model || null;
+ this.delivery_method = data.delivery_method || null;
+ }
+
+ static create(data) {
+ const db = getDb();
+
+ // 先创建Content记录
+ const contentData = {
+ ...data,
+ content_type: 'service'
+ };
+
+ const content = super.create(contentData);
+
+ // 再创建Service扩展记录
+ const stmt = db.prepare(`
+ INSERT INTO services (service_id, service_type, pricing_model, delivery_method)
+ VALUES (?, ?, ?, ?)
+ `);
+
+ stmt.run(
+ content.content_id,
+ data.service_type || null,
+ data.pricing_model || null,
+ data.delivery_method || null
+ );
+
+ return this.findById(content.content_id);
+ }
+
+ static findById(contentId) {
+ const db = getDb();
+ const stmt = db.prepare(`
+ SELECT c.*, s.service_id, s.service_type, s.pricing_model, s.delivery_method
+ FROM contents c
+ LEFT JOIN services s ON c.content_id = s.service_id
+ WHERE c.content_id = ?
+ `);
+ const row = stmt.get(contentId);
+
+ if (row && row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+
+ return row;
+ }
+
+ static update(contentId, data) {
+ const db = getDb();
+
+ // 更新Content部分
+ const contentData = { ...data };
+ delete contentData.service_id;
+ delete contentData.service_type;
+ delete contentData.pricing_model;
+ delete contentData.delivery_method;
+
+ super.update(contentId, contentData);
+
+ // 更新Service扩展部分
+ const serviceData = {};
+ if (data.service_type !== undefined) serviceData.service_type = data.service_type;
+ if (data.pricing_model !== undefined) serviceData.pricing_model = data.pricing_model;
+ if (data.delivery_method !== undefined) serviceData.delivery_method = data.delivery_method;
+
+ if (Object.keys(serviceData).length > 0) {
+ const setClause = Object.keys(serviceData).map(key => `${key} = ?`).join(', ');
+ const values = Object.values(serviceData);
+
+ const stmt = db.prepare(`UPDATE services SET ${setClause} WHERE service_id = ?`);
+ stmt.run(...values, contentId);
+ }
+
+ return this.findById(contentId);
+ }
+
+ static delete(contentId) {
+ const db = getDb();
+
+ // 删除Service扩展记录
+ const stmt1 = db.prepare('DELETE FROM services WHERE service_id = ?');
+ stmt1.run(contentId);
+
+ // 删除Content记录
+ return super.delete(contentId);
+ }
+
+ static findAll(options = {}) {
+ const db = getDb();
+ let query = `
+ SELECT c.*, s.service_id, s.service_type, s.pricing_model, s.delivery_method
+ FROM contents c
+ LEFT JOIN services s ON c.content_id = s.service_id
+ WHERE c.content_type = 'service'
+ `;
+ const params = [];
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => {
+ if (key === 'service_type' || key === 'pricing_model' || key === 'delivery_method') {
+ return `s.${key} = ?`;
+ }
+ return `c.${key} = ?`;
+ });
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = Service;
\ No newline at end of file
diff --git a/src/routes/adminRoutes.js b/src/routes/adminRoutes.js
new file mode 100644
index 0000000..8cd5501
--- /dev/null
+++ b/src/routes/adminRoutes.js
@@ -0,0 +1,98 @@
+const express = require('express');
+const router = express.Router();
+const { v4: uuidv4 } = require('uuid');
+const AdminAuthService = require('../services/AdminAuthService');
+const ContentService = require('../services/ContentService');
+const { getDb } = require('../config/database');
+
+const auth = (req, res, next) => {
+ const header = req.headers.authorization || '';
+ const token = header.startsWith('Bearer ') ? header.slice(7) : null;
+ const session = AdminAuthService.verify(token);
+ if (!session) return res.status(401).json({ error: '请先登录管理后台' });
+ req.admin = session;
+ req.adminToken = token;
+ next();
+};
+
+router.post('/login', (req, res) => {
+ try {
+ const { username, password } = req.body;
+ res.json(AdminAuthService.login(username, password));
+ } catch (error) {
+ res.status(401).json({ error: error.message });
+ }
+});
+
+router.use(auth);
+
+router.get('/me', (req, res) => res.json({ username: req.admin.username }));
+
+router.post('/logout', (req, res) => {
+ AdminAuthService.logout(req.adminToken);
+ res.json({ success: true });
+});
+
+router.put('/password', (req, res) => {
+ try {
+ const { currentPassword, newPassword } = req.body;
+ res.json(AdminAuthService.changePassword(req.admin.username, currentPassword, newPassword));
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+router.get('/settings', (req, res) => {
+ const rows = getDb().prepare('SELECT * FROM site_settings ORDER BY setting_group, setting_key').all();
+ res.json(rows);
+});
+
+router.put('/settings/:key', (req, res) => {
+ const key = req.params.key;
+ const value = req.body.value === undefined ? '' : String(req.body.value);
+ const group = req.body.group || 'general';
+ const db = getDb();
+ const existing = db.prepare('SELECT setting_key FROM site_settings WHERE setting_key = ?').get(key);
+ if (existing) {
+ db.prepare('UPDATE site_settings SET setting_value = ?, setting_group = ?, updated_at = CURRENT_TIMESTAMP WHERE setting_key = ?').run(value, group, key);
+ } else {
+ db.prepare('INSERT INTO site_settings (setting_key, setting_value, setting_group) VALUES (?, ?, ?)').run(key, value, group);
+ }
+ res.json({ setting_key: key, setting_value: value, setting_group: group });
+});
+
+router.get('/contents/:type', (req, res) => {
+ try {
+ const { page = 1, pageSize = 50 } = req.query;
+ res.json(ContentService.paginate(req.params.type, Number(page), Number(pageSize)));
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+router.post('/contents/:type', (req, res) => {
+ try {
+ res.status(201).json(ContentService.create(req.body, req.params.type));
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+router.put('/contents/:type/:id', (req, res) => {
+ try {
+ res.json(ContentService.update(req.params.id, req.body, req.params.type));
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+router.delete('/contents/:type/:id', (req, res) => {
+ try {
+ ContentService.delete(req.params.id);
+ res.status(204).send();
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+module.exports = router;
diff --git a/src/routes/contentRoutes.js b/src/routes/contentRoutes.js
new file mode 100644
index 0000000..07a405f
--- /dev/null
+++ b/src/routes/contentRoutes.js
@@ -0,0 +1,91 @@
+const express = require('express');
+const router = express.Router();
+const ContentService = require('../services/ContentService');
+
+// 获取内容列表(根据类型)
+router.get('/:type', async (req, res) => {
+ try {
+ const { page = 1, pageSize = 10, orderBy } = req.query;
+ const result = ContentService.paginate(req.params.type, parseInt(page), parseInt(pageSize), { orderBy });
+ res.json(result);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取已发布的内容列表(根据类型)
+router.get('/:type/published', async (req, res) => {
+ try {
+ const { page = 1, pageSize = 10, orderBy } = req.query;
+ const result = ContentService.paginate(req.params.type, parseInt(page), parseInt(pageSize), {
+ orderBy,
+ where: { publish_status: 'published' }
+ });
+ res.json(result);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取内容详情
+router.get('/:type/:id', async (req, res) => {
+ try {
+ const content = ContentService.getById(req.params.id, req.params.type);
+ res.json(content);
+ } catch (error) {
+ res.status(404).json({ error: error.message });
+ }
+});
+
+// 创建内容
+router.post('/:type', async (req, res) => {
+ try {
+ const content = ContentService.create(req.body, req.params.type);
+ res.status(201).json(content);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 更新内容
+router.put('/:type/:id', async (req, res) => {
+ try {
+ const content = ContentService.update(req.params.id, req.body, req.params.type);
+ res.json(content);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 删除内容
+router.delete('/:type/:id', async (req, res) => {
+ try {
+ ContentService.delete(req.params.id);
+ res.status(204).send();
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 内容状态流转
+router.put('/:type/:id/transition', async (req, res) => {
+ try {
+ const { status } = req.body;
+ const content = ContentService.transitionStatus(req.params.id, status);
+ res.json(content);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 创建历史版本
+router.post('/:type/:id/history', async (req, res) => {
+ try {
+ const content = ContentService.createHistoricalVersion(req.params.id);
+ res.status(201).json(content);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/src/routes/entityContentJoinRoutes.js b/src/routes/entityContentJoinRoutes.js
new file mode 100644
index 0000000..87e2160
--- /dev/null
+++ b/src/routes/entityContentJoinRoutes.js
@@ -0,0 +1,86 @@
+const express = require('express');
+const router = express.Router();
+const EntityContentJoinService = require('../services/EntityContentJoinService');
+
+// 获取关联列表
+router.get('/', async (req, res) => {
+ try {
+ const { page = 1, pageSize = 10, orderBy } = req.query;
+ const result = EntityContentJoinService.paginate(parseInt(page), parseInt(pageSize), { orderBy });
+ res.json(result);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取关联详情
+router.get('/:id', async (req, res) => {
+ try {
+ const join = EntityContentJoinService.getById(req.params.id);
+ res.json(join);
+ } catch (error) {
+ res.status(404).json({ error: error.message });
+ }
+});
+
+// 获取实体的所有关联
+router.get('/entity/:entityId', async (req, res) => {
+ try {
+ const joins = EntityContentJoinService.getByEntityId(req.params.entityId);
+ res.json(joins);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取内容的所有关联
+router.get('/content/:contentId', async (req, res) => {
+ try {
+ const joins = EntityContentJoinService.getByContentId(req.params.contentId);
+ res.json(joins);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 创建关联
+router.post('/', async (req, res) => {
+ try {
+ const join = EntityContentJoinService.create(req.body);
+ res.status(201).json(join);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 更新关联
+router.put('/:id', async (req, res) => {
+ try {
+ const join = EntityContentJoinService.update(req.params.id, req.body);
+ res.json(join);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 删除关联
+router.delete('/:id', async (req, res) => {
+ try {
+ EntityContentJoinService.delete(req.params.id);
+ res.status(204).send();
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 删除实体与内容的关联
+router.delete('/entity/:entityId/content/:contentId', async (req, res) => {
+ try {
+ EntityContentJoinService.deleteByEntityAndContent(req.params.entityId, req.params.contentId);
+ res.status(204).send();
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/src/routes/entityRoutes.js b/src/routes/entityRoutes.js
new file mode 100644
index 0000000..3c01da4
--- /dev/null
+++ b/src/routes/entityRoutes.js
@@ -0,0 +1,56 @@
+const express = require('express');
+const router = express.Router();
+const EntityService = require('../services/EntityService');
+
+// 获取实体列表
+router.get('/', async (req, res) => {
+ try {
+ const { page = 1, pageSize = 10, orderBy } = req.query;
+ const result = EntityService.paginate(parseInt(page), parseInt(pageSize), { orderBy });
+ res.json(result);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取实体详情
+router.get('/:id', async (req, res) => {
+ try {
+ const entity = EntityService.getById(req.params.id);
+ res.json(entity);
+ } catch (error) {
+ res.status(404).json({ error: error.message });
+ }
+});
+
+// 创建实体
+router.post('/', async (req, res) => {
+ try {
+ const entity = EntityService.create(req.body);
+ res.status(201).json(entity);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 更新实体
+router.put('/:id', async (req, res) => {
+ try {
+ const entity = EntityService.update(req.params.id, req.body);
+ res.json(entity);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 删除实体
+router.delete('/:id', async (req, res) => {
+ try {
+ EntityService.delete(req.params.id);
+ res.status(204).send();
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/src/routes/jsonLdRoutes.js b/src/routes/jsonLdRoutes.js
new file mode 100644
index 0000000..b904f93
--- /dev/null
+++ b/src/routes/jsonLdRoutes.js
@@ -0,0 +1,56 @@
+const express = require('express');
+const router = express.Router();
+const JsonLdService = require('../services/JsonLdService');
+
+// 获取实体的JSON-LD
+router.get('/entities/:id', async (req, res) => {
+ try {
+ const jsonLd = JsonLdService.generateEntityJsonLd(req.params.id);
+ res.json(jsonLd);
+ } catch (error) {
+ res.status(404).json({ error: error.message });
+ }
+});
+
+// 获取内容的JSON-LD
+router.get('/contents/:id', async (req, res) => {
+ try {
+ const jsonLd = JsonLdService.generateContentJsonLd(req.params.id);
+ res.json(jsonLd);
+ } catch (error) {
+ res.status(404).json({ error: error.message });
+ }
+});
+
+// 获取所有实体的JSON-LD列表
+router.get('/entities', async (req, res) => {
+ try {
+ const jsonLdList = JsonLdService.generateAllEntitiesJsonLd();
+ res.json(jsonLdList);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取所有内容的JSON-LD列表
+router.get('/contents', async (req, res) => {
+ try {
+ const { type } = req.query;
+ const jsonLdList = JsonLdService.generateAllContentsJsonLd(type);
+ res.json(jsonLdList);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取站点地图的JSON-LD
+router.get('/sitemap', async (req, res) => {
+ try {
+ const jsonLd = JsonLdService.generateSitemapJsonLd();
+ res.json(jsonLd);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/src/routes/publicApiRoutes.js b/src/routes/publicApiRoutes.js
new file mode 100644
index 0000000..30f2ef6
--- /dev/null
+++ b/src/routes/publicApiRoutes.js
@@ -0,0 +1,149 @@
+const express = require('express');
+const router = express.Router();
+const PublicApiService = require('../services/PublicApiService');
+const { getDb } = require('../config/database');
+
+// 获取前台展示配置(只读)
+router.get('/settings', async (req, res) => {
+ try {
+ const rows = getDb().prepare('SELECT setting_key, setting_value FROM site_settings').all();
+ res.json(Object.fromEntries(rows.map(row => [row.setting_key, row.setting_value])));
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取已发布的实体列表
+router.get('/entities', async (req, res) => {
+ try {
+ const { page = 1, pageSize = 10, orderBy } = req.query;
+ const offset = (parseInt(page) - 1) * parseInt(pageSize);
+ const entities = PublicApiService.getPublishedEntities({
+ orderBy,
+ limit: parseInt(pageSize),
+ offset
+ });
+ res.json(entities);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取已发布的实体详情
+router.get('/entities/:id', async (req, res) => {
+ try {
+ const entity = PublicApiService.getPublishedEntityById(req.params.id);
+ if (!entity) {
+ return res.status(404).json({ error: '实体不存在' });
+ }
+ res.json(entity);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取实体的已发布关系
+router.get('/entities/:id/relationships', async (req, res) => {
+ try {
+ const sourceRelationships = PublicApiService.getPublishedRelationshipsBySource(req.params.id);
+ const targetRelationships = PublicApiService.getPublishedRelationshipsByTarget(req.params.id);
+
+ res.json({
+ source: sourceRelationships,
+ target: targetRelationships
+ });
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取实体的已发布内容
+router.get('/entities/:id/contents', async (req, res) => {
+ try {
+ const contents = PublicApiService.getEntityPublishedContents(req.params.id);
+ res.json(contents);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取已发布的内容列表
+router.get('/contents', async (req, res) => {
+ try {
+ const { type, page = 1, pageSize = 10, orderBy } = req.query;
+ const offset = (parseInt(page) - 1) * parseInt(pageSize);
+ const contents = PublicApiService.getPublishedContents(type, {
+ orderBy,
+ limit: parseInt(pageSize),
+ offset
+ });
+ res.json(contents);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取已发布的内容详情
+router.get('/contents/:id', async (req, res) => {
+ try {
+ const content = PublicApiService.getPublishedContentById(req.params.id);
+ if (!content) {
+ return res.status(404).json({ error: '内容不存在或未发布' });
+ }
+ res.json(content);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取内容的实体关联
+router.get('/contents/:id/entities', async (req, res) => {
+ try {
+ const entities = PublicApiService.getContentEntities(req.params.id);
+ res.json(entities);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 搜索实体
+router.get('/search/entities', async (req, res) => {
+ try {
+ const { keyword, page = 1, pageSize = 10, orderBy } = req.query;
+ if (!keyword) {
+ return res.status(400).json({ error: '搜索关键词不能为空' });
+ }
+
+ const offset = (parseInt(page) - 1) * parseInt(pageSize);
+ const entities = PublicApiService.searchEntities(keyword, {
+ orderBy,
+ limit: parseInt(pageSize),
+ offset
+ });
+ res.json(entities);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 搜索内容
+router.get('/search/contents', async (req, res) => {
+ try {
+ const { keyword, type, page = 1, pageSize = 10, orderBy } = req.query;
+ if (!keyword) {
+ return res.status(400).json({ error: '搜索关键词不能为空' });
+ }
+
+ const offset = (parseInt(page) - 1) * parseInt(pageSize);
+ const contents = PublicApiService.searchContents(keyword, type, {
+ orderBy,
+ limit: parseInt(pageSize),
+ offset
+ });
+ res.json(contents);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+module.exports = router;
diff --git a/src/routes/relationshipRoutes.js b/src/routes/relationshipRoutes.js
new file mode 100644
index 0000000..563d00c
--- /dev/null
+++ b/src/routes/relationshipRoutes.js
@@ -0,0 +1,76 @@
+const express = require('express');
+const router = express.Router();
+const DirectedRelationshipService = require('../services/DirectedRelationshipService');
+
+// 获取关系列表
+router.get('/', async (req, res) => {
+ try {
+ const { page = 1, pageSize = 10, orderBy } = req.query;
+ const result = DirectedRelationshipService.paginate(parseInt(page), parseInt(pageSize), { orderBy });
+ res.json(result);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取关系详情
+router.get('/:id', async (req, res) => {
+ try {
+ const relationship = DirectedRelationshipService.getById(req.params.id);
+ res.json(relationship);
+ } catch (error) {
+ res.status(404).json({ error: error.message });
+ }
+});
+
+// 获取实体的出向关系
+router.get('/source/:entityId', async (req, res) => {
+ try {
+ const relationships = DirectedRelationshipService.getBySourceEntity(req.params.entityId);
+ res.json(relationships);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 获取实体的入向关系
+router.get('/target/:entityId', async (req, res) => {
+ try {
+ const relationships = DirectedRelationshipService.getByTargetEntity(req.params.entityId);
+ res.json(relationships);
+ } catch (error) {
+ res.status(500).json({ error: error.message });
+ }
+});
+
+// 创建关系
+router.post('/', async (req, res) => {
+ try {
+ const relationship = DirectedRelationshipService.create(req.body);
+ res.status(201).json(relationship);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 更新关系
+router.put('/:id', async (req, res) => {
+ try {
+ const relationship = DirectedRelationshipService.update(req.params.id, req.body);
+ res.json(relationship);
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+// 删除关系
+router.delete('/:id', async (req, res) => {
+ try {
+ DirectedRelationshipService.delete(req.params.id);
+ res.status(204).send();
+ } catch (error) {
+ res.status(400).json({ error: error.message });
+ }
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/src/services/AdminAuthService.js b/src/services/AdminAuthService.js
new file mode 100644
index 0000000..3e9fdc0
--- /dev/null
+++ b/src/services/AdminAuthService.js
@@ -0,0 +1,57 @@
+const crypto = require('crypto');
+const { v4: uuidv4 } = require('uuid');
+const { getDb } = require('../config/database');
+
+const sessions = new Map();
+
+const hashPassword = (password, salt = crypto.randomBytes(16).toString('hex')) => {
+ const hash = crypto.scryptSync(password, salt, 64).toString('hex');
+ return `${salt}:${hash}`;
+};
+
+const verifyPassword = (password, stored) => {
+ const [salt, expected] = String(stored || '').split(':');
+ if (!salt || !expected) return false;
+ const actual = crypto.scryptSync(password, salt, 64).toString('hex');
+ return crypto.timingSafeEqual(Buffer.from(actual, 'hex'), Buffer.from(expected, 'hex'));
+};
+
+class AdminAuthService {
+ static login(username, password) {
+ const user = getDb().prepare('SELECT * FROM admin_users WHERE username = ?').get(username);
+ if (!user || !verifyPassword(password, user.password_hash)) {
+ throw new Error('用户名或密码错误');
+ }
+ const token = crypto.randomBytes(32).toString('hex');
+ sessions.set(token, { userId: user.user_id, username: user.username, expiresAt: Date.now() + 8 * 60 * 60 * 1000 });
+ return { token, username: user.username, expiresIn: 8 * 60 * 60 };
+ }
+
+ static verify(token) {
+ const session = sessions.get(token);
+ if (!session || session.expiresAt < Date.now()) {
+ if (token) sessions.delete(token);
+ return null;
+ }
+ return session;
+ }
+
+ static changePassword(username, currentPassword, newPassword) {
+ if (!newPassword || newPassword.length < 8) throw new Error('新密码至少需要8位');
+ const db = getDb();
+ const user = db.prepare('SELECT * FROM admin_users WHERE username = ?').get(username);
+ if (!user || !verifyPassword(currentPassword, user.password_hash)) throw new Error('当前密码错误');
+ db.prepare('UPDATE admin_users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE username = ?')
+ .run(hashPassword(newPassword), username);
+ for (const [token, session] of sessions.entries()) {
+ if (session.username === username) sessions.delete(token);
+ }
+ return { success: true };
+ }
+
+ static logout(token) {
+ sessions.delete(token);
+ }
+}
+
+module.exports = AdminAuthService;
diff --git a/src/services/ContentService.js b/src/services/ContentService.js
new file mode 100644
index 0000000..671a580
--- /dev/null
+++ b/src/services/ContentService.js
@@ -0,0 +1,220 @@
+const Content = require('../models/Content');
+const Page = require('../models/Page');
+const Article = require('../models/Article');
+const Case = require('../models/Case');
+const FAQ = require('../models/FAQ');
+const Capability = require('../models/Capability');
+const Service = require('../models/Service');
+const { getDb } = require('../config/database');
+const Joi = require('joi');
+
+class ContentService {
+ // 根据内容类型获取对应的模型
+ static getModelByType(contentType) {
+ const models = {
+ 'page': Page,
+ 'article': Article,
+ 'case': Case,
+ 'faq': FAQ,
+ 'capability': Capability,
+ 'service': Service
+ };
+
+ return models[contentType] || Content;
+ }
+
+ // 验证内容数据
+ static validateContent(data, contentType, isUpdate = false) {
+ const baseSchema = {
+ title: isUpdate ? Joi.string().min(1).max(255) : Joi.string().min(1).max(255).required(),
+ body: Joi.string().allow(null, ''),
+ publish_status: Joi.string().valid('draft', 'review', 'published', 'unpublished', 'historical'),
+ authority_level: Joi.number().integer().min(1).max(7),
+ version_no: Joi.number().integer().min(1),
+ version_note: Joi.string().allow(null, ''),
+ metadata: Joi.object()
+ };
+
+ // 根据内容类型添加特定字段验证
+ let specificSchema = {};
+
+ switch (contentType) {
+ case 'page':
+ specificSchema = {
+ slug: Joi.string().pattern(/^\/$|^[a-z0-9]+(?:-[a-z0-9]+)*$/),
+ summary: Joi.string().allow(null, ''),
+ template: Joi.string().allow(null, ''),
+ seo_title: Joi.string().allow(null, '').max(255),
+ seo_description: Joi.string().allow(null, '').max(500),
+ seo_keywords: Joi.string().allow(null, '')
+ };
+ break;
+ case 'article':
+ specificSchema = {
+ category: Joi.string().allow(null, ''),
+ tags: Joi.string().allow(null, ''),
+ cover_image: Joi.string().uri().allow(null, ''),
+ author: Joi.string().allow(null, '')
+ };
+ break;
+ case 'case':
+ specificSchema = {
+ client_name: Joi.string().allow(null, ''),
+ industry: Joi.string().allow(null, ''),
+ challenge: Joi.string().allow(null, ''),
+ solution: Joi.string().allow(null, ''),
+ result: Joi.string().allow(null, '')
+ };
+ break;
+ case 'faq':
+ specificSchema = {
+ question: Joi.string().allow(null, ''),
+ answer: Joi.string().allow(null, ''),
+ sort_order: Joi.number().integer().min(0)
+ };
+ break;
+ case 'capability':
+ specificSchema = {
+ capability_type: Joi.string().allow(null, ''),
+ features: Joi.string().allow(null, ''),
+ use_cases: Joi.string().allow(null, '')
+ };
+ break;
+ case 'service':
+ specificSchema = {
+ service_type: Joi.string().allow(null, ''),
+ pricing_model: Joi.string().allow(null, ''),
+ delivery_method: Joi.string().allow(null, '')
+ };
+ break;
+ }
+
+ const schema = Joi.object({ ...baseSchema, ...specificSchema });
+ return schema.validate(data, { abortEarly: false });
+ }
+
+ // 创建内容
+ static create(data, contentType) {
+ if (!contentType) {
+ throw new Error('内容类型不能为空');
+ }
+
+ const { error, value } = this.validateContent(data, contentType);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ const Model = this.getModelByType(contentType);
+ return Model.create({ ...value, content_type: contentType });
+ }
+
+ // 获取内容详情
+ static getById(contentId, contentType = null) {
+ let content;
+
+ if (contentType) {
+ const Model = this.getModelByType(contentType);
+ content = Model.findById(contentId);
+ } else {
+ content = Content.findById(contentId);
+ }
+
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+
+ return content;
+ }
+
+ // 获取内容列表
+ static getList(contentType, options = {}) {
+ const Model = this.getModelByType(contentType);
+ return Model.findAll(options);
+ }
+
+ // 获取已发布的内容
+ static getPublished(contentType, options = {}) {
+ const Model = this.getModelByType(contentType);
+ return Model.findAll({
+ ...options,
+ where: {
+ ...options.where,
+ publish_status: 'published'
+ }
+ });
+ }
+
+ // 更新内容
+ static update(contentId, data, contentType = null) {
+ // 检查内容是否存在
+ const existingContent = Content.findById(contentId);
+ if (!existingContent) {
+ throw new Error('内容不存在');
+ }
+
+ // 如果指定了内容类型,检查是否匹配
+ if (contentType && existingContent.content_type !== contentType) {
+ throw new Error('内容类型不匹配');
+ }
+
+ const { error, value } = this.validateContent(data, existingContent.content_type, true);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ const Model = this.getModelByType(existingContent.content_type);
+ return Model.update(contentId, value);
+ }
+
+ // 删除内容
+ static delete(contentId) {
+ const content = Content.findById(contentId);
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+
+ const Model = this.getModelByType(content.content_type);
+ return Model.delete(contentId);
+ }
+
+ // 内容状态流转
+ static transitionStatus(contentId, newStatus) {
+ return Content.transitionStatus(contentId, newStatus);
+ }
+
+ // 创建历史版本
+ static createHistoricalVersion(contentId) {
+ return Content.createHistoricalVersion(contentId);
+ }
+
+ // 获取内容总数
+ static count(contentType = null) {
+ if (contentType) {
+ const row = getDb().prepare('SELECT COUNT(*) AS count FROM contents WHERE content_type = ?').get(contentType);
+ return Number(row?.count || 0);
+ }
+ return Content.count();
+ }
+
+ // 分页查询
+ static paginate(contentType, page = 1, pageSize = 10, options = {}) {
+ const offset = (page - 1) * pageSize;
+ const Model = this.getModelByType(contentType);
+ const list = Model.findAll({
+ ...options,
+ limit: pageSize,
+ offset
+ });
+ const total = this.count(contentType);
+
+ return {
+ list,
+ total,
+ page,
+ pageSize,
+ totalPages: Math.ceil(total / pageSize)
+ };
+ }
+}
+
+module.exports = ContentService;
diff --git a/src/services/DirectedRelationshipService.js b/src/services/DirectedRelationshipService.js
new file mode 100644
index 0000000..eb915c2
--- /dev/null
+++ b/src/services/DirectedRelationshipService.js
@@ -0,0 +1,146 @@
+const DirectedRelationship = require('../models/DirectedRelationship');
+const Entity = require('../models/Entity');
+const Joi = require('joi');
+
+class DirectedRelationshipService {
+ // 验证关系数据
+ static validateRelationship(data, isUpdate = false) {
+ const schema = Joi.object({
+ source_entity_id: isUpdate ? Joi.string().uuid() : Joi.string().uuid().required(),
+ relation_type: isUpdate ? Joi.string().min(1).max(100) : Joi.string().min(1).max(100).required(),
+ target_entity_id: isUpdate ? Joi.string().uuid() : Joi.string().uuid().required(),
+ rel_status: Joi.string().valid('active', 'inactive'),
+ authority_level: Joi.number().integer().min(1).max(7),
+ is_public: Joi.number().integer().valid(0, 1),
+ effective_at: Joi.date().iso(),
+ expire_at: Joi.date().iso().greater(Joi.ref('effective_at'))
+ });
+
+ return schema.validate(data, { abortEarly: false });
+ }
+
+ // 创建关系
+ static create(data) {
+ const { error, value } = this.validateRelationship(data);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ // 检查源实体是否存在
+ const sourceEntity = Entity.findById(value.source_entity_id);
+ if (!sourceEntity) {
+ throw new Error('源实体不存在');
+ }
+
+ // 检查目标实体是否存在
+ const targetEntity = Entity.findById(value.target_entity_id);
+ if (!targetEntity) {
+ throw new Error('目标实体不存在');
+ }
+
+ // 检查是否试图创建自引用关系
+ if (value.source_entity_id === value.target_entity_id) {
+ throw new Error('不能创建自引用关系');
+ }
+
+ return DirectedRelationship.create(value);
+ }
+
+ // 获取关系详情
+ static getById(relId) {
+ const relationship = DirectedRelationship.findById(relId);
+ if (!relationship) {
+ throw new Error('关系不存在');
+ }
+ return relationship;
+ }
+
+ // 获取关系列表
+ static getList(options = {}) {
+ return DirectedRelationship.findAll(options);
+ }
+
+ // 获取实体的出向关系
+ static getBySourceEntity(sourceEntityId, options = {}) {
+ return DirectedRelationship.findBySourceEntity(sourceEntityId, options);
+ }
+
+ // 获取实体的入向关系(反向查询)
+ static getByTargetEntity(targetEntityId, options = {}) {
+ return DirectedRelationship.findByTargetEntity(targetEntityId, options);
+ }
+
+ // 更新关系
+ static update(relId, data) {
+ // 检查关系是否存在
+ const existingRelationship = DirectedRelationship.findById(relId);
+ if (!existingRelationship) {
+ throw new Error('关系不存在');
+ }
+
+ // 如果要修改源实体或目标实体,检查新实体是否存在
+ if (data.source_entity_id && data.source_entity_id !== existingRelationship.source_entity_id) {
+ const sourceEntity = Entity.findById(data.source_entity_id);
+ if (!sourceEntity) {
+ throw new Error('源实体不存在');
+ }
+ }
+
+ if (data.target_entity_id && data.target_entity_id !== existingRelationship.target_entity_id) {
+ const targetEntity = Entity.findById(data.target_entity_id);
+ if (!targetEntity) {
+ throw new Error('目标实体不存在');
+ }
+ }
+
+ // 检查是否试图创建自引用关系
+ const sourceEntityId = data.source_entity_id || existingRelationship.source_entity_id;
+ const targetEntityId = data.target_entity_id || existingRelationship.target_entity_id;
+ if (sourceEntityId === targetEntityId) {
+ throw new Error('不能创建自引用关系');
+ }
+
+ const { error, value } = this.validateRelationship(data, true);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ return DirectedRelationship.update(relId, value);
+ }
+
+ // 删除关系
+ static delete(relId) {
+ const relationship = DirectedRelationship.findById(relId);
+ if (!relationship) {
+ throw new Error('关系不存在');
+ }
+
+ return DirectedRelationship.delete(relId);
+ }
+
+ // 获取关系总数
+ static count() {
+ return DirectedRelationship.count();
+ }
+
+ // 分页查询
+ static paginate(page = 1, pageSize = 10, options = {}) {
+ const offset = (page - 1) * pageSize;
+ const list = DirectedRelationship.findAll({
+ ...options,
+ limit: pageSize,
+ offset
+ });
+ const total = this.count();
+
+ return {
+ list,
+ total,
+ page,
+ pageSize,
+ totalPages: Math.ceil(total / pageSize)
+ };
+ }
+}
+
+module.exports = DirectedRelationshipService;
\ No newline at end of file
diff --git a/src/services/EntityContentJoinService.js b/src/services/EntityContentJoinService.js
new file mode 100644
index 0000000..d856563
--- /dev/null
+++ b/src/services/EntityContentJoinService.js
@@ -0,0 +1,142 @@
+const EntityContentJoin = require('../models/EntityContentJoin');
+const Entity = require('../models/Entity');
+const Content = require('../models/Content');
+const Joi = require('joi');
+
+class EntityContentJoinService {
+ // 验证关联数据
+ static validateJoin(data, isUpdate = false) {
+ const schema = Joi.object({
+ entity_id: isUpdate ? Joi.string().uuid() : Joi.string().uuid().required(),
+ content_id: isUpdate ? Joi.string().uuid() : Joi.string().uuid().required(),
+ join_note: Joi.string().allow(null, '')
+ });
+
+ return schema.validate(data, { abortEarly: false });
+ }
+
+ // 创建关联
+ static create(data) {
+ const { error, value } = this.validateJoin(data);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ // 检查实体是否存在
+ const entity = Entity.findById(value.entity_id);
+ if (!entity) {
+ throw new Error('实体不存在');
+ }
+
+ // 检查内容是否存在
+ const content = Content.findById(value.content_id);
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+
+ // 检查是否已存在相同的关联
+ const existingJoins = EntityContentJoin.findByEntityId(value.entity_id);
+ const duplicateJoin = existingJoins.find(join => join.content_id === value.content_id);
+ if (duplicateJoin) {
+ throw new Error('该实体与内容的关联已存在');
+ }
+
+ return EntityContentJoin.create(value);
+ }
+
+ // 获取关联详情
+ static getById(joinId) {
+ const join = EntityContentJoin.findById(joinId);
+ if (!join) {
+ throw new Error('关联不存在');
+ }
+ return join;
+ }
+
+ // 获取实体的所有关联
+ static getByEntityId(entityId) {
+ return EntityContentJoin.findByEntityId(entityId);
+ }
+
+ // 获取内容的所有关联
+ static getByContentId(contentId) {
+ return EntityContentJoin.findByContentId(contentId);
+ }
+
+ // 获取所有关联
+ static getList(options = {}) {
+ return EntityContentJoin.findAll(options);
+ }
+
+ // 更新关联
+ static update(joinId, data) {
+ // 检查关联是否存在
+ const existingJoin = EntityContentJoin.findById(joinId);
+ if (!existingJoin) {
+ throw new Error('关联不存在');
+ }
+
+ // 如果要修改实体或内容,检查新实体或内容是否存在
+ if (data.entity_id && data.entity_id !== existingJoin.entity_id) {
+ const entity = Entity.findById(data.entity_id);
+ if (!entity) {
+ throw new Error('实体不存在');
+ }
+ }
+
+ if (data.content_id && data.content_id !== existingJoin.content_id) {
+ const content = Content.findById(data.content_id);
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+ }
+
+ const { error, value } = this.validateJoin(data, true);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ return EntityContentJoin.update(joinId, value);
+ }
+
+ // 删除关联
+ static delete(joinId) {
+ const join = EntityContentJoin.findById(joinId);
+ if (!join) {
+ throw new Error('关联不存在');
+ }
+
+ return EntityContentJoin.delete(joinId);
+ }
+
+ // 删除实体与内容的关联
+ static deleteByEntityAndContent(entityId, contentId) {
+ return EntityContentJoin.deleteByEntityAndContent(entityId, contentId);
+ }
+
+ // 获取关联总数
+ static count() {
+ return EntityContentJoin.count();
+ }
+
+ // 分页查询
+ static paginate(page = 1, pageSize = 10, options = {}) {
+ const offset = (page - 1) * pageSize;
+ const list = EntityContentJoin.findAll({
+ ...options,
+ limit: pageSize,
+ offset
+ });
+ const total = this.count();
+
+ return {
+ list,
+ total,
+ page,
+ pageSize,
+ totalPages: Math.ceil(total / pageSize)
+ };
+ }
+}
+
+module.exports = EntityContentJoinService;
\ No newline at end of file
diff --git a/src/services/EntityService.js b/src/services/EntityService.js
new file mode 100644
index 0000000..b789ec4
--- /dev/null
+++ b/src/services/EntityService.js
@@ -0,0 +1,97 @@
+const Entity = require('../models/Entity');
+const Joi = require('joi');
+
+class EntityService {
+ // 验证实体数据
+ static validateEntity(data, isUpdate = false) {
+ const schema = Joi.object({
+ name: isUpdate ? Joi.string().min(1).max(255) : Joi.string().min(1).max(255).required(),
+ definition: Joi.string().allow(null, ''),
+ description: Joi.string().allow(null, ''),
+ metadata: Joi.object()
+ });
+
+ return schema.validate(data, { abortEarly: false });
+ }
+
+ // 创建实体
+ static create(data) {
+ const { error, value } = this.validateEntity(data);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ return Entity.create(value);
+ }
+
+ // 获取实体详情
+ static getById(entityId) {
+ const entity = Entity.findById(entityId);
+ if (!entity) {
+ throw new Error('实体不存在');
+ }
+ return entity;
+ }
+
+ // 获取实体列表
+ static getList(options = {}) {
+ return Entity.findAll(options);
+ }
+
+ // 更新实体
+ static update(entityId, data) {
+ // 检查实体是否存在
+ const existingEntity = Entity.findById(entityId);
+ if (!existingEntity) {
+ throw new Error('实体不存在');
+ }
+
+ // 禁止修改entity_id
+ if (data.entity_id && data.entity_id !== entityId) {
+ throw new Error('不能修改entity_id');
+ }
+
+ const { error, value } = this.validateEntity(data, true);
+ if (error) {
+ throw new Error(`验证失败: ${error.details.map(d => d.message).join(', ')}`);
+ }
+
+ return Entity.update(entityId, value);
+ }
+
+ // 删除实体
+ static delete(entityId) {
+ const entity = Entity.findById(entityId);
+ if (!entity) {
+ throw new Error('实体不存在');
+ }
+
+ return Entity.delete(entityId);
+ }
+
+ // 获取实体总数
+ static count() {
+ return Entity.count();
+ }
+
+ // 分页查询
+ static paginate(page = 1, pageSize = 10, options = {}) {
+ const offset = (page - 1) * pageSize;
+ const list = Entity.findAll({
+ ...options,
+ limit: pageSize,
+ offset
+ });
+ const total = this.count();
+
+ return {
+ list,
+ total,
+ page,
+ pageSize,
+ totalPages: Math.ceil(total / pageSize)
+ };
+ }
+}
+
+module.exports = EntityService;
\ No newline at end of file
diff --git a/src/services/JsonLdService.js b/src/services/JsonLdService.js
new file mode 100644
index 0000000..d50feba
--- /dev/null
+++ b/src/services/JsonLdService.js
@@ -0,0 +1,214 @@
+const Entity = require('../models/Entity');
+const DirectedRelationship = require('../models/DirectedRelationship');
+const Content = require('../models/Content');
+const EntityContentJoin = require('../models/EntityContentJoin');
+
+class JsonLdService {
+ // 生成实体的JSON-LD结构化数据
+ static generateEntityJsonLd(entityId) {
+ const entity = Entity.findById(entityId);
+ if (!entity) {
+ throw new Error('实体不存在');
+ }
+
+ // 获取实体的关系
+ const sourceRelationships = DirectedRelationship.findBySourceEntity(entityId, {
+ where: { rel_status: 'active', is_public: 1 }
+ });
+
+ const targetRelationships = DirectedRelationship.findByTargetEntity(entityId, {
+ where: { rel_status: 'active', is_public: 1 }
+ });
+
+ // 获取实体的内容
+ const contentJoins = EntityContentJoin.findByEntityId(entityId);
+ const contentIds = contentJoins.map(join => join.content_id);
+ let contents = [];
+
+ if (contentIds.length > 0) {
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const placeholders = contentIds.map(() => '?').join(',');
+ const stmt = db.prepare(`SELECT * FROM contents WHERE content_id IN (${placeholders}) AND publish_status = 'published'`);
+ contents = stmt.all(...contentIds);
+ }
+
+ // 构建JSON-LD结构
+ const jsonLd = {
+ '@context': 'https://schema.org',
+ '@type': 'Thing',
+ '@id': `entity:${entity.entity_id}`,
+ 'name': entity.name,
+ 'description': entity.description || entity.definition || '',
+ 'identifier': entity.entity_id
+ };
+
+ // 添加元数据
+ if (entity.metadata) {
+ const metadata = typeof entity.metadata === 'string' ? JSON.parse(entity.metadata) : entity.metadata;
+ Object.assign(jsonLd, metadata);
+ }
+
+ // 添加关系
+ if (sourceRelationships.length > 0) {
+ jsonLd['relatedTo'] = sourceRelationships.map(rel => ({
+ '@type': 'Relationship',
+ 'relationshipType': rel.relation_type,
+ 'target': {
+ '@type': 'Thing',
+ '@id': `entity:${rel.target_entity_id}`,
+ 'identifier': rel.target_entity_id
+ }
+ }));
+ }
+
+ // 添加内容
+ if (contents.length > 0) {
+ jsonLd['associatedMedia'] = contents.map(content => ({
+ '@type': 'CreativeWork',
+ '@id': `content:${content.content_id}`,
+ 'name': content.title,
+ 'description': content.body ? content.body.substring(0, 200) : '',
+ 'identifier': content.content_id
+ }));
+ }
+
+ return jsonLd;
+ }
+
+ // 生成内容的JSON-LD结构化数据
+ static generateContentJsonLd(contentId) {
+ const content = Content.findById(contentId);
+ if (!content) {
+ throw new Error('内容不存在');
+ }
+
+ // 获取内容的实体关联
+ const contentJoins = EntityContentJoin.findByContentId(contentId);
+ const entityIds = contentJoins.map(join => join.entity_id);
+ let entities = [];
+
+ if (entityIds.length > 0) {
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const placeholders = entityIds.map(() => '?').join(',');
+ const stmt = db.prepare(`SELECT * FROM entities WHERE entity_id IN (${placeholders})`);
+ entities = stmt.all(...entityIds);
+ }
+
+ // 根据内容类型构建不同的JSON-LD结构
+ let jsonLd = {
+ '@context': 'https://schema.org',
+ '@id': `content:${content.content_id}`,
+ 'name': content.title,
+ 'description': content.body ? content.body.substring(0, 200) : '',
+ 'identifier': content.content_id
+ };
+
+ switch (content.content_type) {
+ case 'page':
+ jsonLd['@type'] = 'WebPage';
+ break;
+ case 'article':
+ jsonLd['@type'] = 'Article';
+ break;
+ case 'case':
+ jsonLd['@type'] = 'CaseStudy';
+ break;
+ case 'faq':
+ jsonLd['@type'] = 'FAQPage';
+ break;
+ case 'capability':
+ jsonLd['@type'] = 'Service';
+ break;
+ case 'service':
+ jsonLd['@type'] = 'Service';
+ break;
+ default:
+ jsonLd['@type'] = 'CreativeWork';
+ }
+
+ // 添加元数据
+ if (content.metadata) {
+ const metadata = typeof content.metadata === 'string' ? JSON.parse(content.metadata) : content.metadata;
+ Object.assign(jsonLd, metadata);
+ }
+
+ // 添加实体关联
+ if (entities.length > 0) {
+ jsonLd['about'] = entities.map(entity => ({
+ '@type': 'Thing',
+ '@id': `entity:${entity.entity_id}`,
+ 'name': entity.name,
+ 'identifier': entity.entity_id
+ }));
+ }
+
+ // 特定内容类型的字段
+ if (content.content_type === 'article') {
+ jsonLd['articleBody'] = content.body;
+ if (content.author) {
+ jsonLd['author'] = {
+ '@type': 'Person',
+ 'name': content.author
+ };
+ }
+ }
+
+ if (content.content_type === 'faq') {
+ jsonLd['mainEntity'] = {
+ '@type': 'Question',
+ 'name': content.question,
+ 'acceptedAnswer': {
+ '@type': 'Answer',
+ 'text': content.answer
+ }
+ };
+ }
+
+ return jsonLd;
+ }
+
+ // 生成所有已发布实体的JSON-LD列表
+ static generateAllEntitiesJsonLd() {
+ const entities = Entity.findAll();
+ return entities.map(entity => this.generateEntityJsonLd(entity.entity_id));
+ }
+
+ // 生成所有已发布内容的JSON-LD列表
+ static generateAllContentsJsonLd(contentType = null) {
+ let contents;
+ if (contentType) {
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM contents WHERE publish_status = ? AND content_type = ?');
+ contents = stmt.all('published', contentType);
+ } else {
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const stmt = db.prepare('SELECT * FROM contents WHERE publish_status = ?');
+ contents = stmt.all('published');
+ }
+
+ return contents.map(content => this.generateContentJsonLd(content.content_id));
+ }
+
+ // 生成站点地图的JSON-LD
+ static generateSitemapJsonLd() {
+ const entities = this.generateAllEntitiesJsonLd();
+ const contents = this.generateAllContentsJsonLd();
+
+ return {
+ '@context': 'https://schema.org',
+ '@type': 'WebSite',
+ 'name': '阿美巴AI官网',
+ 'description': '阿美巴AI官网 - 知识底座与CMS内核',
+ 'hasPart': [
+ ...entities,
+ ...contents
+ ]
+ };
+ }
+}
+
+module.exports = JsonLdService;
\ No newline at end of file
diff --git a/src/services/PublicApiService.js b/src/services/PublicApiService.js
new file mode 100644
index 0000000..7ba8115
--- /dev/null
+++ b/src/services/PublicApiService.js
@@ -0,0 +1,210 @@
+const Entity = require('../models/Entity');
+const DirectedRelationship = require('../models/DirectedRelationship');
+const Content = require('../models/Content');
+const EntityContentJoin = require('../models/EntityContentJoin');
+
+class PublicApiService {
+ // 获取已发布的实体
+ static getPublishedEntities(options = {}) {
+ return Entity.findAll({
+ ...options,
+ where: {
+ ...options.where
+ }
+ });
+ }
+
+ // 获取已发布的实体详情
+ static getPublishedEntityById(entityId) {
+ return Entity.findById(entityId);
+ }
+
+ // 获取已发布的关系
+ static getPublishedRelationships(options = {}) {
+ return DirectedRelationship.findAll({
+ ...options,
+ where: {
+ ...options.where,
+ rel_status: 'active',
+ is_public: 1
+ }
+ });
+ }
+
+ // 获取实体的已发布出向关系
+ static getPublishedRelationshipsBySource(entityId) {
+ return DirectedRelationship.findBySourceEntity(entityId, {
+ where: {
+ rel_status: 'active',
+ is_public: 1
+ }
+ });
+ }
+
+ // 获取实体的已发布入向关系
+ static getPublishedRelationshipsByTarget(entityId) {
+ return DirectedRelationship.findByTargetEntity(entityId, {
+ where: {
+ rel_status: 'active',
+ is_public: 1
+ }
+ });
+ }
+
+ // 获取已发布的内容
+ static getPublishedContents(contentType, options = {}) {
+ let query = 'SELECT * FROM contents WHERE publish_status = ?';
+ const params = ['published'];
+
+ if (contentType) {
+ query += ' AND content_type = ?';
+ params.push(contentType);
+ }
+
+ if (options.where) {
+ const conditions = Object.keys(options.where).map(key => `${key} = ?`);
+ query += ` AND ${conditions.join(' AND ')}`;
+ params.push(...Object.values(options.where));
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+
+ // 获取已发布的内容详情
+ static getPublishedContentById(contentId) {
+ const content = Content.findById(contentId);
+ if (content && content.publish_status === 'published') {
+ return content;
+ }
+ return null;
+ }
+
+ // 获取实体的内容关联(已发布的内容)
+ static getEntityPublishedContents(entityId) {
+ const joins = EntityContentJoin.findByEntityId(entityId);
+ const contentIds = joins.map(join => join.content_id);
+
+ if (contentIds.length === 0) {
+ return [];
+ }
+
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const placeholders = contentIds.map(() => '?').join(',');
+ const stmt = db.prepare(`SELECT * FROM contents WHERE content_id IN (${placeholders}) AND publish_status = 'published'`);
+ return stmt.all(...contentIds);
+ }
+
+ // 获取内容的实体关联
+ static getContentEntities(contentId) {
+ const joins = EntityContentJoin.findByContentId(contentId);
+ const entityIds = joins.map(join => join.entity_id);
+
+ if (entityIds.length === 0) {
+ return [];
+ }
+
+ const { getDb } = require('../config/database');
+ const db = getDb();
+ const placeholders = entityIds.map(() => '?').join(',');
+ const stmt = db.prepare(`SELECT * FROM entities WHERE entity_id IN (${placeholders})`);
+ return stmt.all(...entityIds);
+ }
+
+ // 搜索实体
+ static searchEntities(keyword, options = {}) {
+ const { getDb } = require('../config/database');
+ const db = getDb();
+
+ let query = 'SELECT * FROM entities WHERE (name LIKE ? OR definition LIKE ? OR description LIKE ?)';
+ const params = [`%${keyword}%`, `%${keyword}%`, `%${keyword}%`];
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+
+ // 搜索内容
+ static searchContents(keyword, contentType = null, options = {}) {
+ const { getDb } = require('../config/database');
+ const db = getDb();
+
+ let query = 'SELECT * FROM contents WHERE publish_status = ? AND (title LIKE ? OR body LIKE ?)';
+ const params = ['published', `%${keyword}%`, `%${keyword}%`];
+
+ if (contentType) {
+ query += ' AND content_type = ?';
+ params.push(contentType);
+ }
+
+ if (options.orderBy) {
+ query += ` ORDER BY ${options.orderBy}`;
+ }
+
+ if (options.limit) {
+ query += ` LIMIT ?`;
+ params.push(options.limit);
+ }
+
+ if (options.offset) {
+ query += ` OFFSET ?`;
+ params.push(options.offset);
+ }
+
+ const stmt = db.prepare(query);
+ const rows = stmt.all(...params);
+
+ return rows.map(row => {
+ if (row.metadata) {
+ row.metadata = JSON.parse(row.metadata);
+ }
+ return row;
+ });
+ }
+}
+
+module.exports = PublicApiService;
\ No newline at end of file
diff --git a/tests/Content.test.js b/tests/Content.test.js
new file mode 100644
index 0000000..3c2abd1
--- /dev/null
+++ b/tests/Content.test.js
@@ -0,0 +1,95 @@
+const Content = require('../src/models/Content');
+const Page = require('../src/models/Page');
+const { getDb, closeDb } = require('../src/config/database');
+const { migrate } = require('../src/database/migrate');
+
+beforeAll(() => {
+ migrate();
+});
+
+afterAll(() => {
+ closeDb();
+});
+
+describe('Content Model', () => {
+ let contentId;
+
+ test('应该创建内容', () => {
+ const content = Content.create({
+ title: '测试内容',
+ body: '这是测试内容的主体',
+ content_type: 'page',
+ publish_status: 'draft'
+ });
+
+ expect(content).toBeDefined();
+ expect(content.content_id).toBeDefined();
+ expect(content.title).toBe('测试内容');
+ expect(content.body).toBe('这是测试内容的主体');
+ expect(content.content_type).toBe('page');
+ expect(content.publish_status).toBe('draft');
+
+ contentId = content.content_id;
+ });
+
+ test('应该根据ID查找内容', () => {
+ const content = Content.findById(contentId);
+ expect(content).toBeDefined();
+ expect(content.content_id).toBe(contentId);
+ expect(content.title).toBe('测试内容');
+ });
+
+ test('应该更新内容', () => {
+ const updatedContent = Content.update(contentId, {
+ title: '更新后的内容',
+ body: '更新后的主体'
+ });
+
+ expect(updatedContent.title).toBe('更新后的内容');
+ expect(updatedContent.body).toBe('更新后的主体');
+ });
+
+ test('应该进行状态流转', () => {
+ // draft -> review
+ const reviewContent = Content.transitionStatus(contentId, 'review');
+ expect(reviewContent.publish_status).toBe('review');
+
+ // review -> published
+ const publishedContent = Content.transitionStatus(contentId, 'published');
+ expect(publishedContent.publish_status).toBe('published');
+ expect(publishedContent.version_no).toBe(2);
+
+ // published -> unpublished
+ const unpublishedContent = Content.transitionStatus(contentId, 'unpublished');
+ expect(unpublishedContent.publish_status).toBe('unpublished');
+
+ // unpublished -> historical
+ const historicalContent = Content.transitionStatus(contentId, 'historical');
+ expect(historicalContent.publish_status).toBe('historical');
+ expect(historicalContent.archived_at).toBeDefined();
+ });
+
+ test('应该创建历史版本', () => {
+ // 先创建一个新的内容
+ const newContent = Content.create({
+ title: '历史版本测试',
+ body: '这是历史版本测试的主体',
+ content_type: 'article',
+ publish_status: 'draft'
+ });
+
+ // 创建历史版本
+ const historicalVersion = Content.createHistoricalVersion(newContent.content_id);
+ expect(historicalVersion).toBeDefined();
+ expect(historicalVersion.version_no).toBe(newContent.version_no + 1);
+ expect(historicalVersion.publish_status).toBe('historical');
+ });
+
+ test('应该删除内容', () => {
+ const result = Content.delete(contentId);
+ expect(result.changes).toBe(1);
+
+ const content = Content.findById(contentId);
+ expect(content).toBeUndefined();
+ });
+});
\ No newline at end of file
diff --git a/tests/DirectedRelationship.test.js b/tests/DirectedRelationship.test.js
new file mode 100644
index 0000000..53ada97
--- /dev/null
+++ b/tests/DirectedRelationship.test.js
@@ -0,0 +1,104 @@
+const Entity = require('../src/models/Entity');
+const DirectedRelationship = require('../src/models/DirectedRelationship');
+const { getDb, closeDb } = require('../src/config/database');
+const { migrate } = require('../src/database/migrate');
+
+beforeAll(() => {
+ migrate();
+});
+
+afterAll(() => {
+ closeDb();
+});
+
+describe('DirectedRelationship Model', () => {
+ let entity1Id, entity2Id, relId;
+
+ beforeAll(() => {
+ // 创建测试实体
+ const entity1 = Entity.create({
+ name: '实体1',
+ definition: '第一个测试实体'
+ });
+ entity1Id = entity1.entity_id;
+
+ const entity2 = Entity.create({
+ name: '实体2',
+ definition: '第二个测试实体'
+ });
+ entity2Id = entity2.entity_id;
+ });
+
+ test('应该创建关系', () => {
+ const relationship = DirectedRelationship.create({
+ source_entity_id: entity1Id,
+ relation_type: '包含',
+ target_entity_id: entity2Id,
+ rel_status: 'active',
+ authority_level: 3,
+ is_public: 1
+ });
+
+ expect(relationship).toBeDefined();
+ expect(relationship.rel_id).toBeDefined();
+ expect(relationship.source_entity_id).toBe(entity1Id);
+ expect(relationship.relation_type).toBe('包含');
+ expect(relationship.target_entity_id).toBe(entity2Id);
+ expect(relationship.rel_status).toBe('active');
+ expect(relationship.authority_level).toBe(3);
+ expect(relationship.is_public).toBe(1);
+
+ relId = relationship.rel_id;
+ });
+
+ test('应该根据ID查找关系', () => {
+ const relationship = DirectedRelationship.findById(relId);
+ expect(relationship).toBeDefined();
+ expect(relationship.rel_id).toBe(relId);
+ expect(relationship.source_entity_id).toBe(entity1Id);
+ });
+
+ test('应该根据源实体查找关系', () => {
+ const relationships = DirectedRelationship.findBySourceEntity(entity1Id);
+ expect(Array.isArray(relationships)).toBe(true);
+ expect(relationships.length).toBeGreaterThan(0);
+ expect(relationships[0].source_entity_id).toBe(entity1Id);
+ });
+
+ test('应该根据目标实体查找关系', () => {
+ const relationships = DirectedRelationship.findByTargetEntity(entity2Id);
+ expect(Array.isArray(relationships)).toBe(true);
+ expect(relationships.length).toBeGreaterThan(0);
+ expect(relationships[0].target_entity_id).toBe(entity2Id);
+ });
+
+ test('应该更新关系', () => {
+ const updatedRelationship = DirectedRelationship.update(relId, {
+ relation_type: '定位为',
+ authority_level: 5
+ });
+
+ expect(updatedRelationship.relation_type).toBe('定位为');
+ expect(updatedRelationship.authority_level).toBe(5);
+ });
+
+ test('应该获取所有关系', () => {
+ const relationships = DirectedRelationship.findAll();
+ expect(Array.isArray(relationships)).toBe(true);
+ expect(relationships.length).toBeGreaterThan(0);
+ });
+
+ test('应该删除关系', () => {
+ const result = DirectedRelationship.delete(relId);
+ expect(result.changes).toBe(1);
+
+ const relationship = DirectedRelationship.findById(relId);
+ expect(relationship).toBeUndefined();
+ });
+
+ afterAll(() => {
+ // 清理测试实体
+ Entity.delete(entity1Id);
+ Entity.delete(entity2Id);
+ });
+});
\ No newline at end of file
diff --git a/tests/Entity.test.js b/tests/Entity.test.js
new file mode 100644
index 0000000..b40fdde
--- /dev/null
+++ b/tests/Entity.test.js
@@ -0,0 +1,62 @@
+const Entity = require('../src/models/Entity');
+const { getDb, closeDb } = require('../src/config/database');
+const { migrate } = require('../src/database/migrate');
+
+beforeAll(() => {
+ migrate();
+});
+
+afterAll(() => {
+ closeDb();
+});
+
+describe('Entity Model', () => {
+ let entityId;
+
+ test('应该创建实体', () => {
+ const entity = Entity.create({
+ name: '测试实体',
+ definition: '这是一个测试实体',
+ description: '测试实体的描述'
+ });
+
+ expect(entity).toBeDefined();
+ expect(entity.entity_id).toBeDefined();
+ expect(entity.name).toBe('测试实体');
+ expect(entity.definition).toBe('这是一个测试实体');
+ expect(entity.description).toBe('测试实体的描述');
+
+ entityId = entity.entity_id;
+ });
+
+ test('应该根据ID查找实体', () => {
+ const entity = Entity.findById(entityId);
+ expect(entity).toBeDefined();
+ expect(entity.entity_id).toBe(entityId);
+ expect(entity.name).toBe('测试实体');
+ });
+
+ test('应该更新实体', () => {
+ const updatedEntity = Entity.update(entityId, {
+ name: '更新后的实体',
+ description: '更新后的描述'
+ });
+
+ expect(updatedEntity.name).toBe('更新后的实体');
+ expect(updatedEntity.description).toBe('更新后的描述');
+ });
+
+ test('应该获取所有实体', () => {
+ const entities = Entity.findAll();
+ expect(Array.isArray(entities)).toBe(true);
+ expect(entities.length).toBeGreaterThan(0);
+ });
+
+ test('应该删除实体', () => {
+ const result = Entity.delete(entityId);
+ expect(result.changes).toBe(1);
+
+ const entity = Entity.findById(entityId);
+ expect(entity).toBeUndefined();
+ });
+});
\ No newline at end of file
diff --git a/tests/EntityContentJoin.test.js b/tests/EntityContentJoin.test.js
new file mode 100644
index 0000000..3cc59a3
--- /dev/null
+++ b/tests/EntityContentJoin.test.js
@@ -0,0 +1,116 @@
+const Entity = require('../src/models/Entity');
+const Content = require('../src/models/Content');
+const EntityContentJoin = require('../src/models/EntityContentJoin');
+const { getDb, closeDb } = require('../src/config/database');
+const { migrate } = require('../src/database/migrate');
+
+beforeAll(() => {
+ migrate();
+});
+
+afterAll(() => {
+ closeDb();
+});
+
+describe('EntityContentJoin Model', () => {
+ let entity1Id, content1Id, joinId;
+
+ beforeAll(() => {
+ // 创建测试实体
+ const entity1 = Entity.create({
+ name: '测试实体',
+ definition: '用于测试关联的实体'
+ });
+ entity1Id = entity1.entity_id;
+
+ // 创建测试内容
+ const content1 = Content.create({
+ title: '测试内容',
+ body: '用于测试关联的内容',
+ content_type: 'article',
+ publish_status: 'draft'
+ });
+ content1Id = content1.content_id;
+ });
+
+ test('应该创建关联', () => {
+ const join = EntityContentJoin.create({
+ entity_id: entity1Id,
+ content_id: content1Id,
+ join_note: '测试关联备注'
+ });
+
+ expect(join).toBeDefined();
+ expect(join.join_id).toBeDefined();
+ expect(join.entity_id).toBe(entity1Id);
+ expect(join.content_id).toBe(content1Id);
+ expect(join.join_note).toBe('测试关联备注');
+
+ joinId = join.join_id;
+ });
+
+ test('应该根据ID查找关联', () => {
+ const join = EntityContentJoin.findById(joinId);
+ expect(join).toBeDefined();
+ expect(join.join_id).toBe(joinId);
+ expect(join.entity_id).toBe(entity1Id);
+ });
+
+ test('应该根据实体ID查找关联', () => {
+ const joins = EntityContentJoin.findByEntityId(entity1Id);
+ expect(Array.isArray(joins)).toBe(true);
+ expect(joins.length).toBeGreaterThan(0);
+ expect(joins[0].entity_id).toBe(entity1Id);
+ });
+
+ test('应该根据内容ID查找关联', () => {
+ const joins = EntityContentJoin.findByContentId(content1Id);
+ expect(Array.isArray(joins)).toBe(true);
+ expect(joins.length).toBeGreaterThan(0);
+ expect(joins[0].content_id).toBe(content1Id);
+ });
+
+ test('应该更新关联', () => {
+ const updatedJoin = EntityContentJoin.update(joinId, {
+ join_note: '更新后的关联备注'
+ });
+
+ expect(updatedJoin.join_note).toBe('更新后的关联备注');
+ });
+
+ test('应该获取所有关联', () => {
+ const joins = EntityContentJoin.findAll();
+ expect(Array.isArray(joins)).toBe(true);
+ expect(joins.length).toBeGreaterThan(0);
+ });
+
+ test('应该删除关联', () => {
+ const result = EntityContentJoin.delete(joinId);
+ expect(result.changes).toBe(1);
+
+ const join = EntityContentJoin.findById(joinId);
+ expect(join).toBeUndefined();
+ });
+
+ test('应该根据实体和内容删除关联', () => {
+ // 重新创建关联
+ const newJoin = EntityContentJoin.create({
+ entity_id: entity1Id,
+ content_id: content1Id
+ });
+
+ // 删除关联
+ const result = EntityContentJoin.deleteByEntityAndContent(entity1Id, content1Id);
+ expect(result.changes).toBe(1);
+
+ // 验证删除
+ const join = EntityContentJoin.findById(newJoin.join_id);
+ expect(join).toBeUndefined();
+ });
+
+ afterAll(() => {
+ // 清理测试数据
+ Entity.delete(entity1Id);
+ Content.delete(content1Id);
+ });
+});
\ No newline at end of file
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..2fc70ca
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,211 @@
+# 阿美巴AI官网 第三期 测试脚本运行说明
+
+## 概述
+
+本目录包含第三期AI认知验证闭环的所有测试脚本,用于验证整套站点是否满足产品核心目标:AI可以发现、理解、验证阿美巴知识网络。
+
+## 目录结构
+
+```
+tests/
+├── ai_cognitive_testset.md # AI认知测试集文档
+├── crawler/ # 爬虫校验脚本
+│ └── crawler.js
+├── content_filter/ # 内容边界校验脚本
+│ ├── content_filter.js
+│ └── ten_questions.js
+├── project_audit.js # V1.0全项目盘点脚本
+├── reports/ # 测试报告输出目录
+└── README.md # 本说明文档
+```
+
+## 前置条件
+
+### 1. 环境要求
+- Node.js >= 14.x
+- npm >= 6.x
+
+### 2. 服务要求
+- 后端服务运行中(默认端口3000)
+- 前端服务运行中(默认端口3000)
+
+### 3. 启动服务
+
+```bash
+# 启动后端服务
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+npm run dev
+
+# 启动前端服务(新终端)
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版/frontend
+npm run dev
+```
+
+## 测试脚本运行
+
+### 1. 模拟抓取校验脚本
+
+**功能**: 自动遍历全站sitemap.xml,抓取全部公开页面,校验页面质量
+
+**运行命令**:
+```bash
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+node tests/crawler/crawler.js
+```
+
+**校验内容**:
+- HTTP状态码(404/500异常页面告警)
+- H1标签唯一性
+- H2/H3标题层级规范
+- JSON-LD结构化数据语法合法性
+- 内部语义链接可访问性
+
+**输出报告**:
+- `tests/reports/crawler_report.json` - JSON格式报告
+- `tests/reports/crawler_report.md` - 可读格式报告
+
+### 2. 内容边界隔离校验脚本
+
+**功能**: 自动校验draft/review/unpublished/historical状态内容是否在公开页面不可见
+
+**运行命令**:
+```bash
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+node tests/content_filter/content_filter.js
+```
+
+**校验内容**:
+- draft状态内容在公开页面不可见
+- review状态内容在公开页面不可见
+- unpublished状态内容在公开页面不可见
+- historical状态内容在公开页面不可见
+- 仅published状态内容对外暴露
+- 历史版本数据仅存在后台CMS
+
+**输出报告**:
+- `tests/reports/content_filter_report.json` - JSON格式报告
+- `tests/reports/content_filter_report.md` - 可读格式报告
+
+### 3. 十问认知基线校验模块
+
+**功能**: 读取站点公开页面内容,提取核心文本、实体定义、实体关系,和产品文档《十问》标准答案做文本比对校验
+
+**运行命令**:
+```bash
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+node tests/content_filter/ten_questions.js
+```
+
+**校验内容**:
+- 阿美巴是谁?
+- 什么是企业进化?
+- 为什么目标先于问题?
+- 四大价值是什么?
+- A/M-B是什么?
+- 企业进化需要哪些能力?
+- 如何判断企业处于哪个阶段?
+- 阿美巴提供什么服务?
+- 如何开始企业进化?
+- 企业进化的价值是什么?
+
+**输出报告**:
+- `tests/reports/ten_questions_report.json` - JSON格式报告
+- `tests/reports/ten_questions_report.md` - 可读格式报告
+
+### 4. V1.0全项目盘点脚本
+
+**功能**: 自动扫描全项目代码库,生成盘点报告
+
+**运行命令**:
+```bash
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+node tests/project_audit.js
+```
+
+**校验内容**:
+- V1.0必须实现清单(50项)
+- V1.0明确不做清单(10项)
+- 代码预埋排查
+
+**输出报告**:
+- `tests/reports/project_audit_report.json` - JSON格式报告
+- `tests/reports/project_audit_report.md` - 可读格式报告
+
+## 环境变量配置
+
+可以通过环境变量自定义配置:
+
+```bash
+# 设置后端服务地址
+export BASE_URL=http://localhost:3000
+
+# 运行脚本
+node tests/crawler/crawler.js
+```
+
+## 测试报告说明
+
+### 报告格式
+
+所有脚本都会生成两种格式的报告:
+1. **JSON报告**: 机器可读格式,便于自动化处理
+2. **MD报告**: 人类可读格式,便于查看和分享
+
+### 报告内容
+
+- **摘要**: 总数、通过数、失败数、通过率
+- **失败详情**: 失败项的具体信息
+- **建议修复方案**: 针对失败项的修复建议
+
+## 常见问题
+
+### Q1: 脚本运行报错 "Cannot find module"
+
+**解决方案**: 安装依赖
+```bash
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+npm install
+```
+
+### Q2: 脚本运行报错 "请求超时"
+
+**解决方案**: 确保后端服务已启动
+```bash
+cd /Users/mac/Documents/GrowthMini/测试/AI官网升级版
+npm run dev
+```
+
+### Q3: 报告中显示大量失败项
+
+**可能原因**:
+1. 服务未启动
+2. 端口配置错误
+3. 网络连接问题
+
+**解决方案**:
+1. 确保服务已启动
+2. 检查端口配置
+3. 检查网络连接
+
+### Q4: 如何自定义测试页面列表
+
+**解决方案**: 修改脚本中的页面列表
+```javascript
+// 在crawler.js中修改
+const pages = [
+ '/',
+ '/about',
+ // 添加更多页面
+];
+```
+
+## 注意事项
+
+1. **测试环境**: 建议在测试环境运行,避免影响生产环境
+2. **数据准备**: 确保CMS中已录入测试数据
+3. **服务状态**: 确保后端和前端服务正常运行
+4. **报告归档**: 定期归档测试报告,便于追溯
+
+## 联系方式
+
+如有问题,请联系开发团队。
\ No newline at end of file
diff --git a/tests/ai_cognitive_testset.md b/tests/ai_cognitive_testset.md
new file mode 100644
index 0000000..186353b
--- /dev/null
+++ b/tests/ai_cognitive_testset.md
@@ -0,0 +1,575 @@
+# AI认知测试集
+
+项目编号:阿美巴AI官网-20260908-03
+产品真相源:《阿美巴AI官网|项目总指令 V1.2 FINAL(产品冻结版)》
+用途:验证AI是否能正确发现、理解、验证阿美巴知识网络
+
+## 一、测试集概述
+
+### 1.1 测试目标
+- 验证AI是否能正确识别阿美巴核心实体
+- 验证AI是否能正确读取实体定义和实体关系
+- 验证AI输出是否对齐产品文档《十问》标准答案
+- 验证内容边界隔离是否有效
+
+### 1.2 测试范围
+- 实体认知用例:检验AI对核心实体的理解
+- 十问认知用例:检验AI对标准问答的掌握
+- 内容边界用例:检验非published内容的隔离性
+
+### 1.3 测试方法
+- 静态文本比对
+- 结构化数据验证
+- 内容可访问性检查
+
+---
+
+## 二、实体认知用例
+
+### 2.1 阿美巴实体
+
+#### 测试用例:TC-ENTITY-001
+- **测试目标**:AI是否能正确识别"阿美巴"实体
+- **测试方法**:搜索"阿美巴"关键词,验证是否返回正确定义
+- **预期标准答案**:阿美巴(Ameiba)是AI时代企业进化平台
+- **校验要点**:
+ 1. 搜索结果包含"阿美巴"实体
+ 2. 实体定义包含"AI时代企业进化平台"
+ 3. 实体描述包含定位、使命等信息
+- **失败判定**:
+ - 搜索无结果
+ - 定义错误或不完整
+ - 与产品文档定义不符
+
+#### 测试用例:TC-ENTITY-002
+- **测试目标**:AI是否能正确识别阿美巴的服务对象
+- **测试方法**:访问/about页面,验证服务对象描述
+- **预期标准答案**:服务对象是希望在AI时代实现转型与增长的企业
+- **校验要点**:
+ 1. 页面包含服务对象描述
+ 2. 描述与产品文档一致
+- **失败判定**:
+ - 页面无服务对象描述
+ - 描述与产品文档不符
+
+---
+
+### 2.2 企业进化实体
+
+#### 测试用例:TC-ENTITY-003
+- **测试目标**:AI是否能正确识别"企业进化"实体
+- **测试方法**:访问/evolution页面,验证企业进化定义
+- **预期标准答案**:企业进化是企业在AI时代实现持续增长与转型的系统化方法
+- **校验要点**:
+ 1. 页面包含企业进化定义
+ 2. 定义包含"系统化方法"
+ 3. 定义与产品文档一致
+- **失败判定**:
+ - 页面无定义
+ - 定义错误或不完整
+ - 与产品文档定义不符
+
+#### 测试用例:TC-ENTITY-004
+- **测试目标**:AI是否能正确识别企业进化的核心理念
+- **测试方法**:访问/evolution/method页面,验证方法论
+- **预期标准答案**:以终为始、目标先于问题、现状分析、差距识别、根因分析、路径规划、实施迭代
+- **校验要点**:
+ 1. 页面包含完整的方法论
+ 2. 包含所有7个核心步骤
+ 3. 与产品文档一致
+- **失败判定**:
+ - 缺少核心步骤
+ - 步骤顺序错误
+ - 与产品文档不符
+
+---
+
+### 2.3 目标先于问题实体
+
+#### 测试用例:TC-ENTITY-005
+- **测试目标**:AI是否能正确理解"目标先于问题"的理念
+- **测试方法**:搜索"目标先于问题",验证理解深度
+- **预期标准答案**:先设定目标,再分析现状与问题,避免被问题牵着走
+- **校验要点**:
+ 1. 搜索结果包含"目标先于问题"
+ 2. 解释说明"先设定目标"
+ 3. 说明"避免被问题牵着走"
+- **失败判定**:
+ - 搜索无结果
+ - 解释错误或不完整
+ - 与产品文档理念不符
+
+---
+
+### 2.4 四大价值实体
+
+#### 测试用例:TC-ENTITY-006
+- **测试目标**:AI是否能正确识别四大价值
+- **测试方法**:访问/value页面,验证四大价值内容
+- **预期标准答案**:价值创造、价值传递、价值交付、价值支持
+- **校验要点**:
+ 1. 页面包含四大价值
+ 2. 包含所有4个价值
+ 3. 与产品文档一致
+- **失败判定**:
+ - 缺少价值项
+ - 价值名称错误
+ - 与产品文档不符
+
+#### 测试用例:TC-ENTITY-007
+- **测试目标**:AI是否能正确理解价值创造的定义
+- **测试方法**:访问/value/creation页面,验证价值创造定义
+- **预期标准答案**:企业通过创新和优化,为客户和自身创造新价值的过程
+- **校验要点**:
+ 1. 页面包含价值创造定义
+ 2. 定义包含"创新和优化"
+ 3. 定义与产品文档一致
+- **失败判定**:
+ - 页面无定义
+ - 定义错误或不完整
+ - 与产品文档定义不符
+
+---
+
+### 2.5 A/M-B三态实体
+
+#### 测试用例:TC-ENTITY-008
+- **测试目标**:AI是否能正确识别A/M-B三态
+- **测试方法**:访问/amb页面,验证三态内容
+- **预期标准答案**:A态·入态、M态·优态、B态·越态
+- **校验要点**:
+ 1. 页面包含三态
+ 2. 包含所有3个状态
+ 3. 与产品文档一致
+- **失败判定**:
+ - 缺少状态
+ - 状态名称错误
+ - 与产品文档不符
+
+#### 测试用例:TC-ENTITY-009
+- **测试目标**:AI是否能正确理解A态的定义
+- **测试方法**:访问/amb/a页面,验证A态定义
+- **预期标准答案**:企业进入AI时代的初始状态,需要建立基础能力,完成数字化转型
+- **校验要点**:
+ 1. 页面包含A态定义
+ 2. 定义包含"初始状态"
+ 3. 定义与产品文档一致
+- **失败判定**:
+ - 页面无定义
+ - 定义错误或不完整
+ - 与产品文档定义不符
+
+#### 测试用例:TC-ENTITY-010
+- **测试目标**:AI是否能正确理解M态的定义
+- **测试方法**:访问/amb/m页面,验证M态定义
+- **预期标准答案**:企业优化运营、提升效率、实现稳健增长的阶段
+- **校验要点**:
+ 1. 页面包含M态定义
+ 2. 定义包含"优化运营"
+ 3. 定义与产品文档一致
+- **失败判定**:
+ - 页面无定义
+ - 定义错误或不完整
+ - 与产品文档定义不符
+
+#### 测试用例:TC-ENTITY-011
+- **测试目标**:AI是否能正确理解B态的定义
+- **测试方法**:访问/amb/b页面,验证B态定义
+- **预期标准答案**:企业实现跨越式发展、成为行业领导者的阶段
+- **校验要点**:
+ 1. 页面包含B态定义
+ 2. 定义包含"跨越式发展"
+ 3. 定义与产品文档一致
+- **失败判定**:
+ - 页面无定义
+ - 定义错误或不完整
+ - 与产品文档定义不符
+
+---
+
+### 2.6 企业进化能力实体
+
+#### 测试用例:TC-ENTITY-012
+- **测试目标**:AI是否能正确识别企业进化能力
+- **测试方法**:访问/capabilities页面,验证能力列表
+- **预期标准答案**:战略顶层设计、经营增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用部署、进化诊断、进化规划、顾问服务、咨询服务、企业陪跑、定制化服务
+- **校验要点**:
+ 1. 页面包含能力列表
+ 2. 包含所有能力项
+ 3. 与产品文档一致
+- **失败判定**:
+ - 缺少能力项
+ - 能力名称错误
+ - 与产品文档不符
+
+---
+
+## 三、十问认知用例
+
+### 3.1 十问标准答案基线
+
+> 说明:以下为产品文档《十问》标准答案,用于校验AI读取网站后输出内容是否对齐官方口径
+
+#### 问题1:阿美巴是谁?
+- **标准答案**:阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。
+- **校验要点**:
+ 1. 包含"AI时代企业进化平台"
+ 2. 包含"系统化进化"
+ 3. 包含服务内容描述
+- **失败判定**:
+ - 缺少核心定义
+ - 定义错误或不完整
+ - 与标准答案偏差超过20%
+
+#### 问题2:什么是企业进化?
+- **标准答案**:企业进化是企业在AI时代实现持续增长与转型的系统化方法。它不是简单的产品升级或技术更新,而是从战略、组织、流程、能力等全方位的系统性变革。
+- **校验要点**:
+ 1. 包含"系统化方法"
+ 2. 包含"全方位的系统性变革"
+ 3. 区分与产品升级的不同
+- **失败判定**:
+ - 缺少核心定义
+ - 定义错误或不完整
+ - 与标准答案偏差超过20%
+
+#### 问题3:为什么目标先于问题?
+- **标准答案**:传统的问题导向方法容易让企业陷入"救火"模式,被动应对各种问题。而目标导向的方法让企业主动设定方向,有计划地推进进化。只有先明确目标,才能判断哪些问题是真正需要解决的,哪些问题是次要的,从而集中资源解决关键问题。
+- **校验要点**:
+ 1. 包含"目标导向"
+ 2. 包含"主动设定方向"
+ 3. 说明与问题导向的区别
+- **失败判定**:
+ - 缺少核心理念
+ - 理念错误或不完整
+ - 与标准答案偏差超过20%
+
+#### 问题4:四大价值是什么?
+- **标准答案**:四大价值包括价值创造、价值传递、价值交付、价值支持。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。
+- **校验要点**:
+ 1. 包含四大价值名称
+ 2. 包含各价值的角色定位
+ 3. 说明四者关系
+- **失败判定**:
+ - 缺少价值项
+ - 价值名称错误
+ - 与标准答案偏差超过20%
+
+#### 问题5:A/M-B是什么?
+- **标准答案**:A/M-B是企业进化阶段模型,描述了企业在AI时代进化的三个阶段。A态·入态是企业进入AI时代的初始状态,需要建立基础能力;M态·优态是企业优化运营、提升效率的阶段;B态·越态是企业实现跨越式发展、成为行业领导者的阶段。这是企业进化的阶段模型,不是产品套餐。
+- **校验要点**:
+ 1. 包含"阶段模型"
+ 2. 包含三态定义
+ 3. 明确"不是产品套餐"
+- **失败判定**:
+ - 缺少阶段模型定义
+ - 三态定义错误
+ - 与标准答案偏差超过20%
+
+#### 问题6:企业进化需要哪些能力?
+- **标准答案**:企业进化需要完整的能力体系,包括战略顶层设计、经营增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用部署等。这些能力是底层实体,不是产品套餐。
+- **校验要点**:
+ 1. 包含核心能力列表
+ 2. 明确"底层实体"
+ 3. 明确"不是产品套餐"
+- **失败判定**:
+ - 缺少能力列表
+ - 能力名称错误
+ - 与标准答案偏差超过20%
+
+#### 问题7:如何判断企业处于哪个阶段?
+- **标准答案**:企业可以根据自身特征判断所处阶段:A态企业通常数字化程度较低,缺乏系统化管理方法;M态企业数字化程度较高,运营效率持续优化;B态企业处于行业领先地位,具备强大创新能力。判断依据包括数字化程度、运营效率、组织能力、创新能力等维度。
+- **校验要点**:
+ 1. 包含各阶段特征
+ 2. 包含判断维度
+ 3. 与产品文档一致
+- **失败判定**:
+ - 缺少阶段特征
+ - 特征描述错误
+ - 与标准答案偏差超过20%
+
+#### 问题8:阿美巴提供什么服务?
+- **标准答案**:阿美巴提供顾问服务、咨询服务、企业陪跑、定制化服务等。服务内容包括企业进化诊断、进化路径规划、战略咨询、组织变革咨询、AI部署咨询等。具体服务根据企业需求和阶段匹配。
+- **校验要点**:
+ 1. 包含服务类型
+ 2. 包含服务内容
+ 3. 说明匹配逻辑
+- **失败判定**:
+ - 缺少服务类型
+ - 服务内容错误
+ - 与标准答案偏差超过20%
+
+#### 问题9:如何开始企业进化?
+- **标准答案**:企业进化从明确目标开始。首先确定企业进化的终极目标,然后分析现状与目标的差距,识别关键障碍,制定进化路径,分阶段实施,持续迭代优化。阿美巴可以提供专业诊断和规划服务,帮助企业制定适合的进化方案。
+- **校验要点**:
+ 1. 包含"明确目标"
+ 2. 包含实施步骤
+ 3. 说明阿美巴的作用
+- **失败判定**:
+ - 缺少核心步骤
+ - 步骤描述错误
+ - 与标准答案偏差超过20%
+
+#### 问题10:企业进化的价值是什么?
+- **标准答案**:企业进化的价值在于帮助企业在AI时代实现可持续增长与发展。通过系统化的进化方法,企业可以提升运营效率、增强创新能力、优化组织结构、提高市场竞争力,最终实现从传统模式向AI时代模式的转型。
+- **校验要点**:
+ 1. 包含"可持续增长与发展"
+ 2. 包含具体价值点
+ 3. 说明转型目标
+- **失败判定**:
+ - 缺少核心价值
+ - 价值描述错误
+ - 与标准答案偏差超过20%
+
+---
+
+### 3.2 十问测试用例
+
+#### 测试用例:TC-TEN-001
+- **测试目标**:AI是否能正确回答"阿美巴是谁?"
+- **测试方法**:访问/about页面,提取核心定义
+- **预期标准答案**:见问题1标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-002
+- **测试目标**:AI是否能正确回答"什么是企业进化?"
+- **测试方法**:访问/evolution页面,提取核心定义
+- **预期标准答案**:见问题2标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-003
+- **测试目标**:AI是否能正确回答"为什么目标先于问题?"
+- **测试方法**:访问/evolution/method页面,提取核心理念
+- **预期标准答案**:见问题3标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-004
+- **测试目标**:AI是否能正确回答"四大价值是什么?"
+- **测试方法**:访问/value页面,提取核心内容
+- **预期标准答案**:见问题4标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-005
+- **测试目标**:AI是否能正确回答"A/M-B是什么?"
+- **测试方法**:访问/amb页面,提取核心定义
+- **预期标准答案**:见问题5标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-006
+- **测试目标**:AI是否能正确回答"企业进化需要哪些能力?"
+- **测试方法**:访问/capabilities页面,提取能力列表
+- **预期标准答案**:见问题6标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-007
+- **测试目标**:AI是否能正确回答"如何判断企业处于哪个阶段?"
+- **测试方法**:访问/amb页面,提取阶段特征
+- **预期标准答案**:见问题7标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-008
+- **测试目标**:AI是否能正确回答"阿美巴提供什么服务?"
+- **测试方法**:访问/capabilities和/contact页面,提取服务内容
+- **预期标准答案**:见问题8标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-009
+- **测试目标**:AI是否能正确回答"如何开始企业进化?"
+- **测试方法**:访问/evolution/method页面,提取实施步骤
+- **预期标准答案**:见问题9标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+#### 测试用例:TC-TEN-010
+- **测试目标**:AI是否能正确回答"企业进化的价值是什么?"
+- **测试方法**:访问首页和/value页面,提取核心价值
+- **预期标准答案**:见问题10标准答案
+- **校验要点**:
+ 1. 页面包含标准答案核心内容
+ 2. 内容与标准答案偏差不超过20%
+- **失败判定**:
+ - 页面无相关内容
+ - 内容与标准答案偏差超过20%
+
+---
+
+## 四、内容边界隔离用例
+
+### 4.1 状态隔离测试
+
+#### 测试用例:TC-BOUNDARY-001
+- **测试目标**:draft状态内容是否在公开页面不可见
+- **测试方法**:检查所有公开页面,验证不包含draft状态内容
+- **预期结果**:所有公开页面不包含draft状态内容
+- **校验要点**:
+ 1. 页面不显示draft内容
+ 2. 接口不返回draft内容
+ 3. sitemap不包含draft内容
+- **失败判定**:
+ - 任何公开页面显示draft内容
+ - 接口返回draft内容
+ - sitemap包含draft内容
+
+#### 测试用例:TC-BOUNDARY-002
+- **测试目标**:review状态内容是否在公开页面不可见
+- **测试方法**:检查所有公开页面,验证不包含review状态内容
+- **预期结果**:所有公开页面不包含review状态内容
+- **校验要点**:
+ 1. 页面不显示review内容
+ 2. 接口不返回review内容
+ 3. sitemap不包含review内容
+- **失败判定**:
+ - 任何公开页面显示review内容
+ - 接口返回review内容
+ - sitemap包含review内容
+
+#### 测试用例:TC-BOUNDARY-003
+- **测试目标**:unpublished状态内容是否在公开页面不可见
+- **测试方法**:检查所有公开页面,验证不包含unpublished状态内容
+- **预期结果**:所有公开页面不包含unpublished状态内容
+- **校验要点**:
+ 1. 页面不显示unpublished内容
+ 2. 接口不返回unpublished内容
+ 3. sitemap不包含unpublished内容
+- **失败判定**:
+ - 任何公开页面显示unpublished内容
+ - 接口返回unpublished内容
+ - sitemap包含unpublished内容
+
+#### 测试用例:TC-BOUNDARY-004
+- **测试目标**:historical状态内容是否在公开页面不可见
+- **测试方法**:检查所有公开页面,验证不包含historical状态内容
+- **预期结果**:所有公开页面不包含historical状态内容
+- **校验要点**:
+ 1. 页面不显示historical内容
+ 2. 接口不返回historical内容
+ 3. sitemap不包含historical内容
+- **失败判定**:
+ - 任何公开页面显示historical内容
+ - 接口返回historical内容
+ - sitemap包含historical内容
+
+### 4.2 可见性测试
+
+#### 测试用例:TC-BOUNDARY-005
+- **测试目标**:仅published状态内容是否对外暴露
+- **测试方法**:检查所有公开页面,验证仅包含published状态内容
+- **预期结果**:所有公开页面仅包含published状态内容
+- **校验要点**:
+ 1. 页面仅显示published内容
+ 2. 接口仅返回published内容
+ 3. sitemap仅包含published内容
+- **失败判定**:
+ - 任何公开页面显示非published内容
+ - 接口返回非published内容
+ - sitemap包含非published内容
+
+### 4.3 历史版本隔离测试
+
+#### 测试用例:TC-BOUNDARY-006
+- **测试目标**:历史版本数据是否仅存在后台CMS
+- **测试方法**:检查前端和公开接口,验证不包含历史版本数据
+- **预期结果**:前端和公开接口不包含历史版本数据
+- **校验要点**:
+ 1. 前端页面不显示历史版本
+ 2. 公开接口不返回历史版本
+ 3. 历史版本仅在后台CMS可见
+- **失败判定**:
+ - 前端页面显示历史版本
+ - 公开接口返回历史版本
+ - 历史版本在前端或公开接口可见
+
+---
+
+## 五、测试执行说明
+
+### 5.1 执行环境
+- Node.js >= 14.x
+- npm >= 6.x
+- 后端服务运行中(端口3000)
+- 前端服务运行中(端口3000)
+
+### 5.2 执行步骤
+1. 启动后端服务:`npm run dev`
+2. 启动前端服务:`cd frontend && npm run dev`
+3. 执行测试脚本:
+ - 模拟抓取校验:`node tests/crawler/crawler.js`
+ - 内容边界校验:`node tests/content_filter/content_filter.js`
+ - 十问基线校验:`node tests/content_filter/ten_questions.js`
+4. 查看测试报告
+
+### 5.3 结果判定
+- **通过**:所有测试用例通过
+- **警告**:部分测试用例失败,但不影响核心功能
+- **失败**:核心测试用例失败,需要修复
+
+### 5.4 报告格式
+测试报告包含:
+- 测试用例总数
+- 通过用例数
+- 失败用例数
+- 警告用例数
+- 失败用例详情
+- 建议修复方案
+
+---
+
+## 六、测试集维护
+
+### 6.1 版本管理
+- 测试集版本:V1.0
+- 创建日期:2026-09-08
+- 维护人员:开发团队
+
+### 6.2 更新规则
+- 当产品文档更新时,同步更新测试集
+- 当新增功能时,补充相应测试用例
+- 当发现缺陷时,添加回归测试用例
+
+### 6.3 归档规则
+- 每次测试完成后,归档测试报告
+- 保留历史测试报告,便于追溯
+- 定期清理过期测试数据
\ No newline at end of file
diff --git a/tests/content_filter/content_filter.js b/tests/content_filter/content_filter.js
new file mode 100644
index 0000000..8685a9a
--- /dev/null
+++ b/tests/content_filter/content_filter.js
@@ -0,0 +1,515 @@
+/**
+ * 内容边界隔离校验脚本
+ * 自动校验draft/review/unpublished/historical状态内容是否在公开页面不可见
+ */
+
+const https = require('https');
+const http = require('http');
+const { JSDOM } = require('jsdom');
+const fs = require('fs');
+const path = require('path');
+
+// 配置
+const CONFIG = {
+ baseUrl: process.env.BASE_URL || 'http://localhost:3000',
+ timeout: 10000,
+ outputDir: path.join(__dirname, '../reports'),
+};
+
+// 测试结果
+const results = {
+ totalChecks: 0,
+ passedChecks: 0,
+ failedChecks: 0,
+ errors: [],
+ details: [],
+};
+
+/**
+ * 获取页面内容
+ */
+function fetchPage(url) {
+ return new Promise((resolve, reject) => {
+ const protocol = url.startsWith('https') ? https : http;
+ const timeout = CONFIG.timeout;
+
+ const req = protocol.get(url, { timeout }, (res) => {
+ let data = '';
+
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+
+ res.on('end', () => {
+ resolve({
+ status: res.statusCode,
+ headers: res.headers,
+ body: data,
+ url: url,
+ });
+ });
+ });
+
+ req.on('error', (err) => {
+ reject(err);
+ });
+
+ req.on('timeout', () => {
+ req.destroy();
+ reject(new Error('请求超时'));
+ });
+ });
+}
+
+/**
+ * 获取API响应
+ */
+function fetchApi(url) {
+ return new Promise((resolve, reject) => {
+ const protocol = url.startsWith('https') ? https : http;
+ const timeout = CONFIG.timeout;
+
+ const req = protocol.get(url, { timeout }, (res) => {
+ let data = '';
+
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+
+ res.on('end', () => {
+ try {
+ const jsonData = JSON.parse(data);
+ resolve({
+ status: res.statusCode,
+ headers: res.headers,
+ data: jsonData,
+ url: url,
+ });
+ } catch (error) {
+ resolve({
+ status: res.statusCode,
+ headers: res.headers,
+ data: null,
+ raw: data,
+ url: url,
+ });
+ }
+ });
+ });
+
+ req.on('error', (err) => {
+ reject(err);
+ });
+
+ req.on('timeout', () => {
+ req.destroy();
+ reject(new Error('请求超时'));
+ });
+ });
+}
+
+/**
+ * 检查页面是否包含非published状态内容
+ */
+function checkPageContent(html, url) {
+ const dom = new JSDOM(html);
+ const body = dom.window.document.body.textContent.toLowerCase();
+
+ // 非published状态的关键词
+ const nonPublishedKeywords = [
+ 'draft',
+ 'review',
+ 'unpublished',
+ 'historical',
+ '草稿',
+ '审核中',
+ '已下线',
+ '历史版本',
+ ];
+
+ const foundKeywords = [];
+
+ nonPublishedKeywords.forEach((keyword) => {
+ if (body.includes(keyword)) {
+ foundKeywords.push(keyword);
+ }
+ });
+
+ return {
+ valid: foundKeywords.length === 0,
+ message: foundKeywords.length === 0
+ ? '页面不包含非published状态内容'
+ : `页面包含非published状态关键词: ${foundKeywords.join(', ')}`,
+ foundKeywords: foundKeywords,
+ };
+}
+
+/**
+ * 检查API是否返回非published状态内容
+ */
+function checkApiContent(data, url) {
+ const issues = [];
+
+ // 检查返回的数据
+ function checkItem(item) {
+ if (item && item.publish_status && item.publish_status !== 'published') {
+ issues.push({
+ id: item.content_id || item.entity_id,
+ title: item.title || item.name,
+ status: item.publish_status,
+ });
+ }
+ }
+
+ // 递归检查数据
+ if (Array.isArray(data)) {
+ data.forEach(checkItem);
+ } else if (data && typeof data === 'object') {
+ if (data.list && Array.isArray(data.list)) {
+ data.list.forEach(checkItem);
+ } else {
+ checkItem(data);
+ }
+ }
+
+ return {
+ valid: issues.length === 0,
+ message: issues.length === 0
+ ? 'API不返回非published状态内容'
+ : `API返回${issues.length}条非published状态内容`,
+ issues: issues,
+ };
+}
+
+/**
+ * 检查sitemap是否包含非published状态内容
+ */
+function checkSitemap(html) {
+ const dom = new JSDOM(html);
+ const urls = dom.window.document.querySelectorAll('url');
+
+ const issues = [];
+
+ urls.forEach((url) => {
+ const loc = url.querySelector('loc');
+ if (loc) {
+ const urlStr = loc.textContent.toLowerCase();
+ // 检查URL是否包含非published状态标识
+ if (urlStr.includes('draft') || urlStr.includes('review') ||
+ urlStr.includes('unpublished') || urlStr.includes('historical')) {
+ issues.push(urlStr);
+ }
+ }
+ });
+
+ return {
+ valid: issues.length === 0,
+ message: issues.length === 0
+ ? 'sitemap不包含非published状态内容'
+ : `sitemap包含${issues.length}条非published状态URL`,
+ issues: issues,
+ };
+}
+
+/**
+ * 校验公开页面
+ */
+async function validatePublicPages() {
+ const pages = [
+ '/',
+ '/about',
+ '/evolution',
+ '/evolution/method',
+ '/value',
+ '/value/creation',
+ '/value/transfer',
+ '/value/delivery',
+ '/value/support',
+ '/amb',
+ '/amb/a',
+ '/amb/m',
+ '/amb/b',
+ '/capabilities',
+ '/cases',
+ '/knowledge',
+ '/concepts',
+ '/faq',
+ '/match',
+ '/contact',
+ ];
+
+ const pageResults = [];
+
+ for (const pagePath of pages) {
+ const url = `${CONFIG.baseUrl}${pagePath}`;
+ console.log(`校验页面: ${url}`);
+
+ try {
+ const response = await fetchPage(url);
+ const checkResult = checkPageContent(response.body, url);
+
+ pageResults.push({
+ url: url,
+ status: response.status,
+ check: checkResult,
+ });
+
+ results.totalChecks++;
+ if (checkResult.valid) {
+ results.passedChecks++;
+ console.log(` ✓ ${checkResult.message}`);
+ } else {
+ results.failedChecks++;
+ results.errors.push({
+ url: url,
+ error: checkResult.message,
+ keywords: checkResult.foundKeywords,
+ });
+ console.log(` ✗ ${checkResult.message}`);
+ }
+ } catch (error) {
+ results.totalChecks++;
+ results.failedChecks++;
+ results.errors.push({
+ url: url,
+ error: `页面访问失败: ${error.message}`,
+ });
+ console.log(` ✗ 页面访问失败: ${error.message}`);
+ }
+ }
+
+ return pageResults;
+}
+
+/**
+ * 校验公开API
+ */
+async function validatePublicApis() {
+ const apis = [
+ '/api/public/entities',
+ '/api/public/contents',
+ '/api/public/contents?type=page',
+ '/api/public/contents?type=article',
+ '/api/public/contents?type=case',
+ '/api/public/contents?type=faq',
+ '/api/public/contents?type=capability',
+ '/api/public/contents?type=service',
+ ];
+
+ const apiResults = [];
+
+ for (const apiPath of apis) {
+ const url = `${CONFIG.baseUrl}${apiPath}`;
+ console.log(`校验API: ${url}`);
+
+ try {
+ const response = await fetchApi(url);
+ const checkResult = checkApiContent(response.data, url);
+
+ apiResults.push({
+ url: url,
+ status: response.status,
+ check: checkResult,
+ });
+
+ results.totalChecks++;
+ if (checkResult.valid) {
+ results.passedChecks++;
+ console.log(` ✓ ${checkResult.message}`);
+ } else {
+ results.failedChecks++;
+ results.errors.push({
+ url: url,
+ error: checkResult.message,
+ issues: checkResult.issues,
+ });
+ console.log(` ✗ ${checkResult.message}`);
+ }
+ } catch (error) {
+ results.totalChecks++;
+ results.failedChecks++;
+ results.errors.push({
+ url: url,
+ error: `API访问失败: ${error.message}`,
+ });
+ console.log(` ✗ API访问失败: ${error.message}`);
+ }
+ }
+
+ return apiResults;
+}
+
+/**
+ * 校验sitemap
+ */
+async function validateSitemap() {
+ const url = `${CONFIG.baseUrl}/sitemap.xml`;
+ console.log(`校验sitemap: ${url}`);
+
+ try {
+ const response = await fetchPage(url);
+ const checkResult = checkSitemap(response.body);
+
+ results.totalChecks++;
+ if (checkResult.valid) {
+ results.passedChecks++;
+ console.log(` ✓ ${checkResult.message}`);
+ } else {
+ results.failedChecks++;
+ results.errors.push({
+ url: url,
+ error: checkResult.message,
+ issues: checkResult.issues,
+ });
+ console.log(` ✗ ${checkResult.message}`);
+ }
+
+ return {
+ url: url,
+ status: response.status,
+ check: checkResult,
+ };
+ } catch (error) {
+ results.totalChecks++;
+ results.failedChecks++;
+ results.errors.push({
+ url: url,
+ error: `sitemap访问失败: ${error.message}`,
+ });
+ console.log(` ✗ sitemap访问失败: ${error.message}`);
+
+ return {
+ url: url,
+ status: 'error',
+ check: {
+ valid: false,
+ message: `sitemap访问失败: ${error.message}`,
+ },
+ };
+ }
+}
+
+/**
+ * 生成测试报告
+ */
+function generateReport() {
+ // 创建报告目录
+ if (!fs.existsSync(CONFIG.outputDir)) {
+ fs.mkdirSync(CONFIG.outputDir, { recursive: true });
+ }
+
+ const reportPath = path.join(CONFIG.outputDir, 'content_filter_report.json');
+ const reportContent = {
+ summary: {
+ totalTime: new Date().toISOString(),
+ baseUrl: CONFIG.baseUrl,
+ totalChecks: results.totalChecks,
+ passedChecks: results.passedChecks,
+ failedChecks: results.failedChecks,
+ passRate: ((results.passedChecks / results.totalChecks) * 100).toFixed(2) + '%',
+ },
+ errors: results.errors,
+ details: results.details,
+ };
+
+ fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
+
+ // 生成可读报告
+ const readableReportPath = path.join(CONFIG.outputDir, 'content_filter_report.md');
+ let readableReport = `# 内容边界隔离校验报告
+
+生成时间: ${new Date().toISOString()}
+
+## 摘要
+
+- 总检查项: ${results.totalChecks}
+- 通过检查: ${results.passedChecks}
+- 失败检查: ${results.failedChecks}
+- 通过率: ${((results.passedChecks / results.totalChecks) * 100).toFixed(2)}%
+
+## 失败详情
+
+`;
+
+ if (results.errors.length === 0) {
+ readableReport += '无失败项\n\n';
+ } else {
+ results.errors.forEach((error, index) => {
+ readableReport += `${index + 1}. ${error.url}\n - ${error.error}\n\n`;
+ if (error.keywords) {
+ readableReport += ` - 发现关键词: ${error.keywords.join(', ')}\n\n`;
+ }
+ if (error.issues) {
+ readableReport += ` - 问题项: ${JSON.stringify(error.issues)}\n\n`;
+ }
+ });
+ }
+
+ readableReport += `## 校验规则
+
+1. draft/review/unpublished/historical状态内容绝对不会出现在公开页面、接口、sitemap内
+2. 仅published状态实体、内容对外暴露
+3. 历史版本数据仅存在后台CMS,前端/公开接口不可访问
+
+## 结论
+
+`;
+
+ if (results.failedChecks === 0) {
+ readableReport += '✅ 所有内容边界隔离检查通过\n';
+ } else {
+ readableReport += `❌ 存在${results.failedChecks}项内容边界隔离问题,需要修复\n`;
+ }
+
+ fs.writeFileSync(readableReportPath, readableReport);
+
+ console.log(`报告已生成:`);
+ console.log(` - JSON报告: ${reportPath}`);
+ console.log(` - 可读报告: ${readableReportPath}`);
+}
+
+/**
+ * 主函数
+ */
+async function main() {
+ console.log('开始内容边界隔离校验...');
+ console.log(`目标URL: ${CONFIG.baseUrl}`);
+
+ // 校验公开页面
+ console.log('\n=== 校验公开页面 ===');
+ const pageResults = await validatePublicPages();
+ results.details.push(...pageResults);
+
+ // 校验公开API
+ console.log('\n=== 校验公开API ===');
+ const apiResults = await validatePublicApis();
+ results.details.push(...apiResults);
+
+ // 校验sitemap
+ console.log('\n=== 校验sitemap ===');
+ const sitemapResult = await validateSitemap();
+ results.details.push(sitemapResult);
+
+ // 生成报告
+ console.log('\n正在生成报告...');
+ generateReport();
+
+ console.log('\n校验完成!');
+ console.log(`通过率: ${((results.passedChecks / results.totalChecks) * 100).toFixed(2)}%`);
+
+ // 返回结果
+ return results;
+}
+
+// 如果直接运行此脚本
+if (require.main === module) {
+ main().catch(console.error);
+}
+
+module.exports = {
+ main,
+ validatePublicPages,
+ validatePublicApis,
+ validateSitemap,
+ CONFIG,
+};
\ No newline at end of file
diff --git a/tests/content_filter/ten_questions.js b/tests/content_filter/ten_questions.js
new file mode 100644
index 0000000..2254b91
--- /dev/null
+++ b/tests/content_filter/ten_questions.js
@@ -0,0 +1,507 @@
+/**
+ * 十问认知基线静态校验模块
+ * 读取站点公开页面内容,提取核心文本、实体定义、实体关系
+ * 和产品文档《十问》标准答案做文本比对校验,输出差异报告
+ */
+
+const https = require('https');
+const http = require('http');
+const { JSDOM } = require('jsdom');
+const fs = require('fs');
+const path = require('path');
+
+// 配置
+const CONFIG = {
+ baseUrl: process.env.BASE_URL || 'http://localhost:3000',
+ timeout: 10000,
+ outputDir: path.join(__dirname, '../reports'),
+ similarityThreshold: 0.8, // 相似度阈值(80%)
+};
+
+// 十问标准答案基线
+const TEN_QUESTIONS = [
+ {
+ id: 'Q1',
+ question: '阿美巴是谁?',
+ standardAnswer: '阿美巴(Ameiba)是AI时代企业进化平台,专注于帮助企业实现系统化进化,从战略顶层设计到组织重塑,从经营增长到AI部署,提供完整的企业进化能力与服务。',
+ keywords: ['阿美巴', 'AI时代', '企业进化平台', '系统化进化'],
+ relatedPages: ['/about'],
+ },
+ {
+ id: 'Q2',
+ question: '什么是企业进化?',
+ standardAnswer: '企业进化是企业在AI时代实现持续增长与转型的系统化方法。它不是简单的产品升级或技术更新,而是从战略、组织、流程、能力等全方位的系统性变革。',
+ keywords: ['企业进化', '系统化方法', '全方位', '系统性变革'],
+ relatedPages: ['/evolution'],
+ },
+ {
+ id: 'Q3',
+ question: '为什么目标先于问题?',
+ standardAnswer: '传统的问题导向方法容易让企业陷入"救火"模式,被动应对各种问题。而目标导向的方法让企业主动设定方向,有计划地推进进化。只有先明确目标,才能判断哪些问题是真正需要解决的,哪些问题是次要的,从而集中资源解决关键问题。',
+ keywords: ['目标先于问题', '目标导向', '主动设定方向', '避免被动'],
+ relatedPages: ['/evolution/method'],
+ },
+ {
+ id: 'Q4',
+ question: '四大价值是什么?',
+ standardAnswer: '四大价值包括价值创造、价值传递、价值交付、价值支持。价值创造是基础,价值传递是桥梁,价值交付是结果,价值支持是保障。企业需要在这四个维度上协调发展,才能实现持续增长。',
+ keywords: ['四大价值', '价值创造', '价值传递', '价值交付', '价值支持'],
+ relatedPages: ['/value'],
+ },
+ {
+ id: 'Q5',
+ question: 'A/M-B是什么?',
+ standardAnswer: 'A/M-B是企业进化阶段模型,描述了企业在AI时代进化的三个阶段。A态·入态是企业进入AI时代的初始状态,需要建立基础能力;M态·优态是企业优化运营、提升效率的阶段;B态·越态是企业实现跨越式发展、成为行业领导者的阶段。这是企业进化的阶段模型,不是产品套餐。',
+ keywords: ['A/M-B', '阶段模型', 'A态', 'M态', 'B态', '不是产品套餐'],
+ relatedPages: ['/amb'],
+ },
+ {
+ id: 'Q6',
+ question: '企业进化需要哪些能力?',
+ standardAnswer: '企业进化需要完整的能力体系,包括战略顶层设计、经营增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用部署等。这些能力是底层实体,不是产品套餐。',
+ keywords: ['能力体系', '战略顶层设计', '底层实体', '不是产品套餐'],
+ relatedPages: ['/capabilities'],
+ },
+ {
+ id: 'Q7',
+ question: '如何判断企业处于哪个阶段?',
+ standardAnswer: '企业可以根据自身特征判断所处阶段:A态企业通常数字化程度较低,缺乏系统化管理方法;M态企业数字化程度较高,运营效率持续优化;B态企业处于行业领先地位,具备强大创新能力。判断依据包括数字化程度、运营效率、组织能力、创新能力等维度。',
+ keywords: ['判断阶段', '数字化程度', '运营效率', '组织能力', '创新能力'],
+ relatedPages: ['/amb'],
+ },
+ {
+ id: 'Q8',
+ question: '阿美巴提供什么服务?',
+ standardAnswer: '阿美巴提供顾问服务、咨询服务、企业陪跑、定制化服务等。服务内容包括企业进化诊断、进化路径规划、战略咨询、组织变革咨询、AI部署咨询等。具体服务根据企业需求和阶段匹配。',
+ keywords: ['顾问服务', '咨询服务', '企业陪跑', '定制化服务'],
+ relatedPages: ['/capabilities', '/contact'],
+ },
+ {
+ id: 'Q9',
+ question: '如何开始企业进化?',
+ standardAnswer: '企业进化从明确目标开始。首先确定企业进化的终极目标,然后分析现状与目标的差距,识别关键障碍,制定进化路径,分阶段实施,持续迭代优化。阿美巴可以提供专业诊断和规划服务,帮助企业制定适合的进化方案。',
+ keywords: ['明确目标', '分析差距', '识别障碍', '制定路径', '分阶段实施'],
+ relatedPages: ['/evolution/method'],
+ },
+ {
+ id: 'Q10',
+ question: '企业进化的价值是什么?',
+ standardAnswer: '企业进化的价值在于帮助企业在AI时代实现可持续增长与发展。通过系统化的进化方法,企业可以提升运营效率、增强创新能力、优化组织结构、提高市场竞争力,最终实现从传统模式向AI时代模式的转型。',
+ keywords: ['可持续增长', '提升效率', '增强创新', '优化结构', '提高竞争力'],
+ relatedPages: ['/', '/value'],
+ },
+];
+
+/**
+ * 获取页面内容
+ */
+function fetchPage(url) {
+ return new Promise((resolve, reject) => {
+ const protocol = url.startsWith('https') ? https : http;
+ const timeout = CONFIG.timeout;
+
+ const req = protocol.get(url, { timeout }, (res) => {
+ let data = '';
+
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+
+ res.on('end', () => {
+ resolve({
+ status: res.statusCode,
+ headers: res.headers,
+ body: data,
+ url: url,
+ });
+ });
+ });
+
+ req.on('error', (err) => {
+ reject(err);
+ });
+
+ req.on('timeout', () => {
+ req.destroy();
+ reject(new Error('请求超时'));
+ });
+ });
+}
+
+/**
+ * 提取页面文本内容
+ */
+function extractTextContent(html) {
+ const dom = new JSDOM(html);
+ const body = dom.window.document.body;
+
+ // 移除脚本和样式
+ const scripts = body.querySelectorAll('script, style');
+ scripts.forEach((script) => script.remove());
+
+ // 获取文本内容
+ let text = body.textContent || '';
+
+ // 清理文本
+ text = text
+ .replace(/\s+/g, ' ') // 合并空白字符
+ .replace(/\n+/g, '\n') // 合并换行符
+ .trim();
+
+ return text;
+}
+
+/**
+ * 提取页面结构化内容
+ */
+function extractStructuredContent(html) {
+ const dom = new JSDOM(html);
+ const document = dom.window.document;
+
+ // 提取标题
+ const h1 = document.querySelector('h1');
+ const h2s = document.querySelectorAll('h2');
+ const h3s = document.querySelectorAll('h3');
+
+ // 提取段落
+ const paragraphs = document.querySelectorAll('p');
+
+ // 提取列表
+ const lists = document.querySelectorAll('ul, ol');
+
+ // 提取JSON-LD
+ const jsonLdScripts = document.querySelectorAll('script[type="application/ld+json"]');
+ const jsonLdData = [];
+ jsonLdScripts.forEach((script) => {
+ try {
+ const data = JSON.parse(script.textContent);
+ jsonLdData.push(data);
+ } catch (error) {
+ // 忽略解析错误
+ }
+ });
+
+ return {
+ title: h1 ? h1.textContent.trim() : '',
+ h2s: Array.from(h2s).map((h2) => h2.textContent.trim()),
+ h3s: Array.from(h3s).map((h3) => h3.textContent.trim()),
+ paragraphs: Array.from(paragraphs).map((p) => p.textContent.trim()),
+ lists: Array.from(lists).map((list) => {
+ const items = list.querySelectorAll('li');
+ return Array.from(items).map((item) => item.textContent.trim());
+ }),
+ jsonLd: jsonLdData,
+ };
+}
+
+/**
+ * 计算文本相似度(简单的关键词匹配)
+ */
+function calculateSimilarity(text1, text2, keywords) {
+ const text1Lower = text1.toLowerCase();
+ const text2Lower = text2.toLowerCase();
+
+ let matchedKeywords = 0;
+ let totalKeywords = keywords.length;
+
+ keywords.forEach((keyword) => {
+ const keywordLower = keyword.toLowerCase();
+ if (text1Lower.includes(keywordLower) && text2Lower.includes(keywordLower)) {
+ matchedKeywords++;
+ }
+ });
+
+ return totalKeywords > 0 ? matchedKeywords / totalKeywords : 0;
+}
+
+/**
+ * 检查关键词是否存在
+ */
+function checkKeywords(text, keywords) {
+ const textLower = text.toLowerCase();
+ const foundKeywords = [];
+ const missingKeywords = [];
+
+ keywords.forEach((keyword) => {
+ const keywordLower = keyword.toLowerCase();
+ if (textLower.includes(keywordLower)) {
+ foundKeywords.push(keyword);
+ } else {
+ missingKeywords.push(keyword);
+ }
+ });
+
+ return {
+ found: foundKeywords,
+ missing: missingKeywords,
+ coverage: keywords.length > 0 ? foundKeywords.length / keywords.length : 0,
+ };
+}
+
+/**
+ * 校验单个问题
+ */
+async function validateQuestion(question) {
+ console.log(`\n校验问题: ${question.question}`);
+
+ const results = {
+ question: question,
+ pageResults: [],
+ overallStatus: 'passed',
+ missingKeywords: [],
+ similarityScore: 0,
+ };
+
+ for (const pagePath of question.relatedPages) {
+ const url = `${CONFIG.baseUrl}${pagePath}`;
+ console.log(` 访问页面: ${url}`);
+
+ try {
+ const response = await fetchPage(url);
+
+ if (response.status !== 200) {
+ results.pageResults.push({
+ url: url,
+ status: 'failed',
+ error: `HTTP状态码: ${response.status}`,
+ });
+ results.overallStatus = 'failed';
+ continue;
+ }
+
+ // 提取内容
+ const textContent = extractTextContent(response.body);
+ const structuredContent = extractStructuredContent(response.body);
+
+ // 检查关键词
+ const keywordCheck = checkKeywords(textContent, question.keywords);
+
+ // 计算相似度
+ const similarity = calculateSimilarity(
+ textContent,
+ question.standardAnswer,
+ question.keywords
+ );
+
+ // 判断是否通过
+ const passed = keywordCheck.coverage >= CONFIG.similarityThreshold;
+
+ results.pageResults.push({
+ url: url,
+ status: passed ? 'passed' : 'warning',
+ keywordCoverage: keywordCheck.coverage,
+ foundKeywords: keywordCheck.found,
+ missingKeywords: keywordCheck.missing,
+ similarity: similarity,
+ contentPreview: textContent.substring(0, 200) + '...',
+ });
+
+ if (!passed) {
+ results.overallStatus = 'warning';
+ results.missingKeywords.push(...keywordCheck.missing);
+ }
+
+ results.similarityScore = Math.max(results.similarityScore, similarity);
+
+ console.log(` 关键词覆盖: ${(keywordCheck.coverage * 100).toFixed(2)}%`);
+ console.log(` 相似度: ${(similarity * 100).toFixed(2)}%`);
+ console.log(` 状态: ${passed ? '✓ 通过' : '⚠ 警告'}`);
+
+ } catch (error) {
+ results.pageResults.push({
+ url: url,
+ status: 'failed',
+ error: `页面访问失败: ${error.message}`,
+ });
+ results.overallStatus = 'failed';
+ console.log(` ✗ 页面访问失败: ${error.message}`);
+ }
+ }
+
+ // 去重missingKeywords
+ results.missingKeywords = [...new Set(results.missingKeywords)];
+
+ return results;
+}
+
+/**
+ * 生成测试报告
+ */
+function generateReport(allResults) {
+ // 创建报告目录
+ if (!fs.existsSync(CONFIG.outputDir)) {
+ fs.mkdirSync(CONFIG.outputDir, { recursive: true });
+ }
+
+ const reportPath = path.join(CONFIG.outputDir, 'ten_questions_report.json');
+
+ // 统计
+ const summary = {
+ totalTime: new Date().toISOString(),
+ totalQuestions: allResults.length,
+ passedQuestions: allResults.filter((r) => r.overallStatus === 'passed').length,
+ warningQuestions: allResults.filter((r) => r.overallStatus === 'warning').length,
+ failedQuestions: allResults.filter((r) => r.overallStatus === 'failed').length,
+ averageSimilarity: 0,
+ };
+
+ // 计算平均相似度
+ const totalSimilarity = allResults.reduce((sum, r) => sum + r.similarityScore, 0);
+ summary.averageSimilarity = allResults.length > 0
+ ? (totalSimilarity / allResults.length * 100).toFixed(2) + '%'
+ : '0%';
+
+ const reportContent = {
+ summary: summary,
+ questions: allResults.map((r) => ({
+ id: r.question.id,
+ question: r.question.question,
+ status: r.overallStatus,
+ similarity: r.similarityScore,
+ missingKeywords: r.missingKeywords,
+ pageResults: r.pageResults,
+ })),
+ };
+
+ fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
+
+ // 生成可读报告
+ const readableReportPath = path.join(CONFIG.outputDir, 'ten_questions_report.md');
+ let readableReport = `# 十问认知基线校验报告
+
+生成时间: ${new Date().toISOString()}
+
+## 摘要
+
+- 总问题数: ${summary.totalQuestions}
+- 通过问题: ${summary.passedQuestions}
+- 警告问题: ${summary.warningQuestions}
+- 失败问题: ${summary.failedQuestions}
+- 平均相似度: ${summary.averageSimilarity}
+
+## 详细结果
+
+`;
+
+ allResults.forEach((result) => {
+ const statusIcon = result.overallStatus === 'passed' ? '✅' :
+ result.overallStatus === 'warning' ? '⚠️' : '❌';
+
+ readableReport += `### ${statusIcon} ${result.question.id}: ${result.question.question}
+
+**标准答案**: ${result.question.standardAnswer}
+
+**校验结果**:
+- 状态: ${result.overallStatus}
+- 相似度: ${(result.similarityScore * 100).toFixed(2)}%
+`;
+
+ if (result.missingKeywords.length > 0) {
+ readableReport += `- 缺失关键词: ${result.missingKeywords.join(', ')}
+`;
+ }
+
+ readableReport += `
+**页面详情**:
+`;
+
+ result.pageResults.forEach((pageResult) => {
+ readableReport += `- ${pageResult.url}
+ - 状态: ${pageResult.status}
+`;
+ if (pageResult.error) {
+ readableReport += ` - 错误: ${pageResult.error}
+`;
+ }
+ if (pageResult.keywordCoverage !== undefined) {
+ readableReport += ` - 关键词覆盖: ${(pageResult.keywordCoverage * 100).toFixed(2)}%
+`;
+ }
+ if (pageResult.foundKeywords) {
+ readableReport += ` - 找到关键词: ${pageResult.foundKeywords.join(', ')}
+`;
+ }
+ if (pageResult.missingKeywords && pageResult.missingKeywords.length > 0) {
+ readableReport += ` - 缺失关键词: ${pageResult.missingKeywords.join(', ')}
+`;
+ }
+ });
+
+ readableReport += '\n';
+ });
+
+ readableReport += `## 结论
+
+`;
+
+ if (summary.failedQuestions === 0 && summary.warningQuestions === 0) {
+ readableReport += '✅ 所有问题都通过校验,网站内容与产品文档《十问》标准答案高度一致\n';
+ } else if (summary.failedQuestions === 0) {
+ readableReport += `⚠️ ${summary.warningQuestions}个问题有警告,需要人工复核\n`;
+ } else {
+ readableReport += `❌ ${summary.failedQuestions}个问题失败,需要修复\n`;
+ }
+
+ readableReport += `
+## 建议
+
+1. 对于警告项,建议人工复核页面内容,确保与标准答案一致
+2. 对于缺失关键词,建议在CMS后台编辑相关页面,补充关键词内容
+3. 定期执行此校验,确保内容一致性
+
+## 注意事项
+
+- 本报告仅输出差异清单,不自动修正页面内容
+- 内容修改需要人工进入CMS后台编辑
+- 相似度计算基于关键词匹配,仅供参考
+`;
+
+ fs.writeFileSync(readableReportPath, readableReport);
+
+ console.log(`报告已生成:`);
+ console.log(` - JSON报告: ${reportPath}`);
+ console.log(` - 可读报告: ${readableReportPath}`);
+}
+
+/**
+ * 主函数
+ */
+async function main() {
+ console.log('开始十问认知基线校验...');
+ console.log(`目标URL: ${CONFIG.baseUrl}`);
+
+ const allResults = [];
+
+ // 逐个校验问题
+ for (const question of TEN_QUESTIONS) {
+ const result = await validateQuestion(question);
+ allResults.push(result);
+ }
+
+ // 生成报告
+ console.log('\n正在生成报告...');
+ generateReport(allResults);
+
+ // 统计结果
+ const passed = allResults.filter((r) => r.overallStatus === 'passed').length;
+ const warning = allResults.filter((r) => r.overallStatus === 'warning').length;
+ const failed = allResults.filter((r) => r.overallStatus === 'failed').length;
+
+ console.log('\n校验完成!');
+ console.log(`通过: ${passed}, 警告: ${warning}, 失败: ${failed}`);
+
+ // 返回结果
+ return allResults;
+}
+
+// 如果直接运行此脚本
+if (require.main === module) {
+ main().catch(console.error);
+}
+
+module.exports = {
+ main,
+ validateQuestion,
+ TEN_QUESTIONS,
+ CONFIG,
+};
\ No newline at end of file
diff --git a/tests/crawler/crawler.js b/tests/crawler/crawler.js
new file mode 100644
index 0000000..641bac6
--- /dev/null
+++ b/tests/crawler/crawler.js
@@ -0,0 +1,507 @@
+/**
+ * 模拟抓取校验脚本
+ * 自动遍历全站sitemap.xml,抓取全部公开页面,校验页面质量
+ */
+
+const https = require('https');
+const http = require('http');
+const { JSDOM } = require('jsdom');
+const fs = require('fs');
+const path = require('path');
+
+// 配置
+const CONFIG = {
+ baseUrl: process.env.BASE_URL || 'http://localhost:3000',
+ timeout: 10000,
+ outputDir: path.join(__dirname, '../reports'),
+};
+
+// 测试结果
+const results = {
+ totalPages: 0,
+ passedPages: 0,
+ failedPages: 0,
+ warnings: 0,
+ errors: [],
+ warningsList: [],
+ details: [],
+};
+
+/**
+ * 获取页面内容
+ */
+function fetchPage(url) {
+ return new Promise((resolve, reject) => {
+ const protocol = url.startsWith('https') ? https : http;
+ const timeout = CONFIG.timeout;
+
+ const req = protocol.get(url, { timeout }, (res) => {
+ let data = '';
+
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+
+ res.on('end', () => {
+ resolve({
+ status: res.statusCode,
+ headers: res.headers,
+ body: data,
+ url: url,
+ });
+ });
+ });
+
+ req.on('error', (err) => {
+ reject(err);
+ });
+
+ req.on('timeout', () => {
+ req.destroy();
+ reject(new Error('请求超时'));
+ });
+ });
+}
+
+/**
+ * 解析sitemap.xml
+ */
+async function parseSitemap() {
+ try {
+ const response = await fetchPage(`${CONFIG.baseUrl}/sitemap.xml`);
+ const dom = new JSDOM(response.body);
+ const urls = dom.window.document.querySelectorAll('url');
+
+ const sitemapUrls = [];
+ urls.forEach((url) => {
+ const loc = url.querySelector('loc');
+ if (loc) {
+ sitemapUrls.push(loc.textContent);
+ }
+ });
+
+ return sitemapUrls;
+ } catch (error) {
+ console.error('解析sitemap失败:', error.message);
+ return [];
+ }
+}
+
+/**
+ * 校验H1唯一性
+ */
+function validateH1(html, url) {
+ const dom = new JSDOM(html);
+ const h1Elements = dom.window.document.querySelectorAll('h1');
+
+ if (h1Elements.length === 0) {
+ return {
+ valid: false,
+ message: '缺少H1标签',
+ };
+ }
+
+ if (h1Elements.length > 1) {
+ return {
+ valid: false,
+ message: `存在${h1Elements.length}个H1标签,应唯一`,
+ };
+ }
+
+ return {
+ valid: true,
+ message: 'H1标签唯一',
+ content: h1Elements[0].textContent.trim(),
+ };
+}
+
+/**
+ * 校验标题层级
+ */
+function validateHeadings(html, url) {
+ const dom = new JSDOM(html);
+ const headings = dom.window.document.querySelectorAll('h1, h2, h3, h4, h5, h6');
+
+ const headingLevels = [];
+ headings.forEach((h) => {
+ const level = parseInt(h.tagName.substring(1));
+ headingLevels.push(level);
+ });
+
+ // 检查层级是否连续
+ let previousLevel = 0;
+ let isValid = true;
+ let errorMessage = '';
+
+ for (let i = 0; i < headingLevels.length; i++) {
+ const currentLevel = headingLevels[i];
+
+ // H1应该在最前面
+ if (i === 0 && currentLevel !== 1) {
+ isValid = false;
+ errorMessage = '第一个标题应该是H1';
+ break;
+ }
+
+ // 检查层级跳跃
+ if (currentLevel > previousLevel + 1 && previousLevel !== 0) {
+ isValid = false;
+ errorMessage = `标题层级跳跃:从H${previousLevel}到H${currentLevel}`;
+ break;
+ }
+
+ previousLevel = currentLevel;
+ }
+
+ return {
+ valid: isValid,
+ message: errorMessage || '标题层级规范',
+ headings: headingLevels,
+ };
+}
+
+/**
+ * 校验JSON-LD结构化数据
+ */
+function validateJsonLd(html, url) {
+ const dom = new JSDOM(html);
+ const scripts = dom.window.document.querySelectorAll('script[type="application/ld+json"]');
+
+ const jsonLdData = [];
+ let isValid = true;
+ let errorMessage = '';
+
+ scripts.forEach((script) => {
+ try {
+ const data = JSON.parse(script.textContent);
+ jsonLdData.push(data);
+
+ // 基本结构校验
+ if (!data['@context']) {
+ isValid = false;
+ errorMessage = 'JSON-LD缺少@context';
+ }
+ if (!data['@type']) {
+ isValid = false;
+ errorMessage = 'JSON-LD缺少@type';
+ }
+ } catch (error) {
+ isValid = false;
+ errorMessage = `JSON-LD语法错误: ${error.message}`;
+ }
+ });
+
+ return {
+ valid: isValid,
+ message: errorMessage || 'JSON-LD结构化数据合法',
+ count: jsonLdData.length,
+ data: jsonLdData,
+ };
+}
+
+/**
+ * 校验内部链接
+ */
+function validateInternalLinks(html, baseUrl) {
+ const dom = new JSDOM(html);
+ const links = dom.window.document.querySelectorAll('a[href]');
+
+ const internalLinks = [];
+ const brokenLinks = [];
+
+ links.forEach((link) => {
+ const href = link.getAttribute('href');
+
+ // 跳过外部链接和锚点
+ if (href.startsWith('http') || href.startsWith('#') || href.startsWith('mailto:')) {
+ return;
+ }
+
+ // 构建完整URL
+ let fullUrl;
+ if (href.startsWith('/')) {
+ fullUrl = `${CONFIG.baseUrl}${href}`;
+ } else {
+ fullUrl = `${CONFIG.baseUrl}/${href}`;
+ }
+
+ internalLinks.push({
+ text: link.textContent.trim(),
+ href: href,
+ fullUrl: fullUrl,
+ });
+ });
+
+ return {
+ valid: true,
+ message: `发现${internalLinks.length}个内部链接`,
+ links: internalLinks,
+ brokenLinks: brokenLinks,
+ };
+}
+
+/**
+ * 校验单个页面
+ */
+async function validatePage(url) {
+ const pageResult = {
+ url: url,
+ status: 'passed',
+ checks: [],
+ errors: [],
+ warnings: [],
+ };
+
+ try {
+ // 获取页面
+ const response = await fetchPage(url);
+
+ // 校验HTTP状态码
+ if (response.status !== 200) {
+ pageResult.status = 'failed';
+ pageResult.errors.push(`HTTP状态码异常: ${response.status}`);
+ results.errors.push({
+ url: url,
+ error: `HTTP状态码异常: ${response.status}`,
+ });
+ }
+
+ pageResult.checks.push({
+ name: 'HTTP状态码',
+ status: response.status === 200 ? 'passed' : 'failed',
+ message: `状态码: ${response.status}`,
+ });
+
+ // 校验H1唯一性
+ const h1Result = validateH1(response.body, url);
+ pageResult.checks.push({
+ name: 'H1唯一性',
+ status: h1Result.valid ? 'passed' : 'failed',
+ message: h1Result.message,
+ content: h1Result.content,
+ });
+
+ if (!h1Result.valid) {
+ pageResult.status = 'failed';
+ pageResult.errors.push(h1Result.message);
+ results.errors.push({
+ url: url,
+ error: h1Result.message,
+ });
+ }
+
+ // 校验标题层级
+ const headingsResult = validateHeadings(response.body, url);
+ pageResult.checks.push({
+ name: '标题层级',
+ status: headingsResult.valid ? 'passed' : 'failed',
+ message: headingsResult.message,
+ });
+
+ if (!headingsResult.valid) {
+ pageResult.status = 'failed';
+ pageResult.errors.push(headingsResult.message);
+ results.errors.push({
+ url: url,
+ error: headingsResult.message,
+ });
+ }
+
+ // 校验JSON-LD
+ const jsonLdResult = validateJsonLd(response.body, url);
+ pageResult.checks.push({
+ name: 'JSON-LD结构化数据',
+ status: jsonLdResult.valid ? 'passed' : 'failed',
+ message: jsonLdResult.message,
+ count: jsonLdResult.count,
+ });
+
+ if (!jsonLdResult.valid) {
+ pageResult.status = 'failed';
+ pageResult.errors.push(jsonLdResult.message);
+ results.errors.push({
+ url: url,
+ error: jsonLdResult.message,
+ });
+ }
+
+ // 校验内部链接
+ const linksResult = validateInternalLinks(response.body, url);
+ pageResult.checks.push({
+ name: '内部链接',
+ status: linksResult.valid ? 'passed' : 'failed',
+ message: linksResult.message,
+ linkCount: linksResult.links.length,
+ });
+
+ } catch (error) {
+ pageResult.status = 'failed';
+ pageResult.errors.push(`页面抓取失败: ${error.message}`);
+ results.errors.push({
+ url: url,
+ error: `页面抓取失败: ${error.message}`,
+ });
+ }
+
+ return pageResult;
+}
+
+/**
+ * 生成测试报告
+ */
+function generateReport() {
+ // 创建报告目录
+ if (!fs.existsSync(CONFIG.outputDir)) {
+ fs.mkdirSync(CONFIG.outputDir, { recursive: true });
+ }
+
+ const reportPath = path.join(CONFIG.outputDir, 'crawler_report.json');
+ const reportContent = {
+ summary: {
+ totalTime: new Date().toISOString(),
+ baseUrl: CONFIG.baseUrl,
+ totalPages: results.totalPages,
+ passedPages: results.passedPages,
+ failedPages: results.failedPages,
+ warnings: results.warnings,
+ passRate: ((results.passedPages / results.totalPages) * 100).toFixed(2) + '%',
+ },
+ errors: results.errors,
+ warnings: results.warningsList,
+ details: results.details,
+ };
+
+ fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
+
+ // 生成可读报告
+ const readableReportPath = path.join(CONFIG.outputDir, 'crawler_report.md');
+ let readableReport = `# 爬虫校验报告
+
+生成时间: ${new Date().toISOString()}
+
+## 摘要
+
+- 总页面数: ${results.totalPages}
+- 通过页面: ${results.passedPages}
+- 失败页面: ${results.failedPages}
+- 警告: ${results.warnings}
+- 通过率: ${((results.passedPages / results.totalPages) * 100).toFixed(2)}%
+
+## 失败详情
+
+`;
+
+ if (results.errors.length === 0) {
+ readableReport += '无失败项\n\n';
+ } else {
+ results.errors.forEach((error, index) => {
+ readableReport += `${index + 1}. ${error.url}\n - ${error.error}\n\n`;
+ });
+ }
+
+ readableReport += `## 页面详情
+
+`;
+
+ results.details.forEach((detail) => {
+ readableReport += `### ${detail.url}
+
+状态: ${detail.status}
+
+`;
+ detail.checks.forEach((check) => {
+ readableReport += `- ${check.name}: ${check.status} - ${check.message}\n`;
+ });
+ readableReport += '\n';
+ });
+
+ fs.writeFileSync(readableReportPath, readableReport);
+
+ console.log(`报告已生成:`);
+ console.log(` - JSON报告: ${reportPath}`);
+ console.log(` - 可读报告: ${readableReportPath}`);
+}
+
+/**
+ * 主函数
+ */
+async function main() {
+ console.log('开始爬虫校验...');
+ console.log(`目标URL: ${CONFIG.baseUrl}`);
+
+ // 获取sitemap
+ console.log('正在解析sitemap...');
+ const sitemapUrls = await parseSitemap();
+
+ if (sitemapUrls.length === 0) {
+ console.log('未找到sitemap,使用默认页面列表');
+ // 默认页面列表
+ sitemapUrls.push(
+ `${CONFIG.baseUrl}/`,
+ `${CONFIG.baseUrl}/about`,
+ `${CONFIG.baseUrl}/evolution`,
+ `${CONFIG.baseUrl}/evolution/method`,
+ `${CONFIG.baseUrl}/value`,
+ `${CONFIG.baseUrl}/value/creation`,
+ `${CONFIG.baseUrl}/value/transfer`,
+ `${CONFIG.baseUrl}/value/delivery`,
+ `${CONFIG.baseUrl}/value/support`,
+ `${CONFIG.baseUrl}/amb`,
+ `${CONFIG.baseUrl}/amb/a`,
+ `${CONFIG.baseUrl}/amb/m`,
+ `${CONFIG.baseUrl}/amb/b`,
+ `${CONFIG.baseUrl}/capabilities`,
+ `${CONFIG.baseUrl}/cases`,
+ `${CONFIG.baseUrl}/knowledge`,
+ `${CONFIG.baseUrl}/concepts`,
+ `${CONFIG.baseUrl}/faq`,
+ `${CONFIG.baseUrl}/match`,
+ `${CONFIG.baseUrl}/contact`
+ );
+ }
+
+ console.log(`共发现${sitemapUrls.length}个页面`);
+
+ // 逐个校验页面
+ for (let i = 0; i < sitemapUrls.length; i++) {
+ const url = sitemapUrls[i];
+ console.log(`[${i + 1}/${sitemapUrls.length}] 正在校验: ${url}`);
+
+ const pageResult = await validatePage(url);
+ results.details.push(pageResult);
+ results.totalPages++;
+
+ if (pageResult.status === 'passed') {
+ results.passedPages++;
+ console.log(` ✓ 通过`);
+ } else {
+ results.failedPages++;
+ console.log(` ✗ 失败`);
+ pageResult.errors.forEach((error) => {
+ console.log(` - ${error}`);
+ });
+ }
+ }
+
+ // 生成报告
+ console.log('\n正在生成报告...');
+ generateReport();
+
+ console.log('\n校验完成!');
+ console.log(`通过率: ${((results.passedPages / results.totalPages) * 100).toFixed(2)}%`);
+
+ // 返回结果
+ return results;
+}
+
+// 如果直接运行此脚本
+if (require.main === module) {
+ main().catch(console.error);
+}
+
+module.exports = {
+ main,
+ validatePage,
+ parseSitemap,
+ CONFIG,
+};
\ No newline at end of file
diff --git a/tests/model_verification.js b/tests/model_verification.js
new file mode 100644
index 0000000..f7dfa0f
--- /dev/null
+++ b/tests/model_verification.js
@@ -0,0 +1,548 @@
+/**
+ * 数据模型验证脚本
+ * 验证P0系统微调后的数据模型一致性
+ */
+
+const { getDb, closeDb } = require('../src/config/database');
+const { migrate } = require('../src/database/migrate');
+const Entity = require('../src/models/Entity');
+const Content = require('../src/models/Content');
+const Page = require('../src/models/Page');
+const Article = require('../src/models/Article');
+const Case = require('../src/models/Case');
+const FAQ = require('../src/models/FAQ');
+const Capability = require('../src/models/Capability');
+const Service = require('../src/models/Service');
+const DirectedRelationship = require('../src/models/DirectedRelationship');
+const EntityContentJoin = require('../src/models/EntityContentJoin');
+
+// 测试结果
+const results = {
+ entity: { passed: 0, failed: 0, details: [] },
+ page: { passed: 0, failed: 0, details: [] },
+ article: { passed: 0, failed: 0, details: [] },
+ case: { passed: 0, failed: 0, details: [] },
+ faq: { passed: 0, failed: 0, details: [] },
+ capability: { passed: 0, failed: 0, details: [] },
+ service: { passed: 0, failed: 0, details: [] },
+ relation: { passed: 0, failed: 0, details: [] },
+ join: { passed: 0, failed: 0, details: [] },
+ lifecycle: { passed: 0, failed: 0, details: [] },
+ authority: { passed: 0, failed: 0, details: [] },
+};
+
+/**
+ * 验证Entity模型
+ */
+function verifyEntity() {
+ console.log('\n=== 验证Entity模型 ===');
+
+ // 测试创建Entity
+ try {
+ const entity = Entity.create({
+ entity_type: 'concept',
+ name: '测试实体',
+ definition: '测试定义',
+ description: '测试描述',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ });
+
+ if (entity.entity_id && entity.entity_type === 'concept' && entity.status === 'active' && entity.public_flag === 1) {
+ results.entity.passed++;
+ results.entity.details.push('Entity创建成功,新字段正确');
+ } else {
+ results.entity.failed++;
+ results.entity.details.push('Entity创建失败:新字段不正确');
+ }
+
+ // 测试读取Entity
+ const foundEntity = Entity.findById(entity.entity_id);
+ if (foundEntity && foundEntity.entity_type === 'concept' && foundEntity.status === 'active') {
+ results.entity.passed++;
+ results.entity.details.push('Entity读取成功,新字段正确');
+ } else {
+ results.entity.failed++;
+ results.entity.details.push('Entity读取失败:新字段不正确');
+ }
+
+ // 测试更新Entity
+ const updatedEntity = Entity.update(entity.entity_id, {
+ entity_type: 'method',
+ status: 'inactive',
+ public_flag: 0,
+ });
+
+ if (updatedEntity.entity_type === 'method' && updatedEntity.status === 'inactive' && updatedEntity.public_flag === 0) {
+ results.entity.passed++;
+ results.entity.details.push('Entity更新成功,新字段正确');
+ } else {
+ results.entity.failed++;
+ results.entity.details.push('Entity更新失败:新字段不正确');
+ }
+
+ // 清理测试数据
+ Entity.delete(entity.entity_id);
+
+ } catch (error) {
+ results.entity.failed++;
+ results.entity.details.push(`Entity测试失败: ${error.message}`);
+ }
+
+ console.log(`Entity: ${results.entity.passed} passed, ${results.entity.failed} failed`);
+}
+
+/**
+ * 验证Page模型
+ */
+function verifyPage() {
+ console.log('\n=== 验证Page模型 ===');
+
+ try {
+ // 测试创建Page
+ const page = Page.create({
+ title: '测试页面',
+ body: '测试内容',
+ slug: 'test-page',
+ summary: '测试摘要',
+ seo_title: '测试SEO标题',
+ seo_description: '测试SEO描述',
+ });
+
+ if (page.page_id && page.summary === '测试摘要') {
+ results.page.passed++;
+ results.page.details.push('Page创建成功,summary字段正确');
+ } else {
+ results.page.failed++;
+ results.page.details.push('Page创建失败:summary字段不正确');
+ }
+
+ // 测试读取Page
+ const foundPage = Page.findById(page.page_id);
+ if (foundPage && foundPage.summary === '测试摘要') {
+ results.page.passed++;
+ results.page.details.push('Page读取成功,summary字段正确');
+ } else {
+ results.page.failed++;
+ results.page.details.push('Page读取失败:summary字段不正确');
+ }
+
+ // 清理测试数据
+ Content.delete(page.page_id);
+
+ } catch (error) {
+ results.page.failed++;
+ results.page.details.push(`Page测试失败: ${error.message}`);
+ }
+
+ console.log(`Page: ${results.page.passed} passed, ${results.page.failed} failed`);
+}
+
+/**
+ * 验证Article模型
+ */
+function verifyArticle() {
+ console.log('\n=== 验证Article模型 ===');
+
+ try {
+ // 测试创建Article
+ const article = Article.create({
+ title: '测试文章',
+ body: '测试内容',
+ category: '测试分类',
+ author: '测试作者',
+ published_at: '2026-09-08T00:00:00.000Z',
+ });
+
+ if (article.article_id && article.published_at === '2026-09-08T00:00:00.000Z') {
+ results.article.passed++;
+ results.article.details.push('Article创建成功,published_at字段正确');
+ } else {
+ results.article.failed++;
+ results.article.details.push('Article创建失败:published_at字段不正确');
+ }
+
+ // 测试读取Article
+ const foundArticle = Article.findById(article.article_id);
+ if (foundArticle && foundArticle.published_at === '2026-09-08T00:00:00.000Z') {
+ results.article.passed++;
+ results.article.details.push('Article读取成功,published_at字段正确');
+ } else {
+ results.article.failed++;
+ results.article.details.push('Article读取失败:published_at字段不正确');
+ }
+
+ // 清理测试数据
+ Content.delete(article.article_id);
+
+ } catch (error) {
+ results.article.failed++;
+ results.article.details.push(`Article测试失败: ${error.message}`);
+ }
+
+ console.log(`Article: ${results.article.passed} passed, ${results.article.failed} failed`);
+}
+
+/**
+ * 验证Case模型(P0-01扩展字段)
+ */
+function verifyCase() {
+ console.log('\n=== 验证Case模型(P0-01扩展字段)===');
+
+ try {
+ // 测试创建Case
+ const caseData = Case.create({
+ title: '测试案例',
+ body: '测试内容',
+ client_name: '测试客户',
+ industry: '测试行业',
+ background: '测试企业背景',
+ enterprise_stage: 'A态',
+ original_goal: '测试原始目标',
+ current_state: '测试当前状态',
+ surface_problem: '测试表面问题',
+ amb_judgment: '测试阿美巴判断',
+ key_obstacle: '测试关键障碍',
+ root_cause: '测试根因',
+ evolution_path: '测试进化路径',
+ implementation: '测试实施过程',
+ result: '测试结果',
+ case_significance: '测试案例意义',
+ });
+
+ // 验证所有新字段
+ const expectedValues = {
+ background: '测试企业背景',
+ enterprise_stage: 'A态',
+ original_goal: '测试原始目标',
+ current_state: '测试当前状态',
+ surface_problem: '测试表面问题',
+ amb_judgment: '测试阿美巴判断',
+ key_obstacle: '测试关键障碍',
+ root_cause: '测试根因',
+ evolution_path: '测试进化路径',
+ implementation: '测试实施过程',
+ case_significance: '测试案例意义',
+ };
+
+ let allFieldsCorrect = true;
+ for (const [field, expected] of Object.entries(expectedValues)) {
+ if (caseData[field] !== expected) {
+ allFieldsCorrect = false;
+ console.log(`字段 ${field} 不正确: 期望 "${expected}", 实际 "${caseData[field]}"`);
+ break;
+ }
+ }
+
+ if (caseData.case_id && allFieldsCorrect) {
+ results.case.passed++;
+ results.case.details.push('Case创建成功,所有P0-01扩展字段正确');
+ } else {
+ results.case.failed++;
+ results.case.details.push('Case创建失败:P0-01扩展字段不正确');
+ }
+
+ // 测试读取Case
+ const foundCase = Case.findById(caseData.case_id);
+ if (foundCase && foundCase.background === '测试企业背景' && foundCase.case_significance === '测试案例意义') {
+ results.case.passed++;
+ results.case.details.push('Case读取成功,所有P0-01扩展字段正确');
+ } else {
+ results.case.failed++;
+ results.case.details.push('Case读取失败:P0-01扩展字段不正确');
+ }
+
+ // 清理测试数据
+ Content.delete(caseData.case_id);
+
+ } catch (error) {
+ results.case.failed++;
+ results.case.details.push(`Case测试失败: ${error.message}`);
+ }
+
+ console.log(`Case: ${results.case.passed} passed, ${results.case.failed} failed`);
+}
+
+/**
+ * 验证Entity-Content多对多关系
+ */
+function verifyEntityContentJoin() {
+ console.log('\n=== 验证Entity-Content多对多关系 ===');
+
+ try {
+ // 创建测试Entity
+ const entity1 = Entity.create({
+ entity_type: 'concept',
+ name: '测试实体1',
+ });
+
+ const entity2 = Entity.create({
+ entity_type: 'concept',
+ name: '测试实体2',
+ });
+
+ // 创建测试Content
+ const content = Content.create({
+ title: '测试内容',
+ body: '测试内容',
+ content_type: 'article',
+ });
+
+ // 创建关联:一个Content关联多个Entity
+ const join1 = EntityContentJoin.create({
+ entity_id: entity1.entity_id,
+ content_id: content.content_id,
+ });
+
+ const join2 = EntityContentJoin.create({
+ entity_id: entity2.entity_id,
+ content_id: content.content_id,
+ });
+
+ // 验证一个Content关联多个Entity
+ const contentJoins = EntityContentJoin.findByContentId(content.content_id);
+ if (contentJoins.length === 2) {
+ results.join.passed++;
+ results.join.details.push('一个Content关联多个Entity成功');
+ } else {
+ results.join.failed++;
+ results.join.details.push('一个Content关联多个Entity失败');
+ }
+
+ // 创建另一个Content
+ const content2 = Content.create({
+ title: '测试内容2',
+ body: '测试内容2',
+ content_type: 'article',
+ });
+
+ // 创建关联:一个Entity关联多个Content
+ const join3 = EntityContentJoin.create({
+ entity_id: entity1.entity_id,
+ content_id: content2.content_id,
+ });
+
+ // 验证一个Entity关联多个Content
+ const entityJoins = EntityContentJoin.findByEntityId(entity1.entity_id);
+ if (entityJoins.length === 2) {
+ results.join.passed++;
+ results.join.details.push('一个Entity关联多个Content成功');
+ } else {
+ results.join.failed++;
+ results.join.details.push('一个Entity关联多个Content失败');
+ }
+
+ // 清理测试数据
+ EntityContentJoin.delete(join1.join_id);
+ EntityContentJoin.delete(join2.join_id);
+ EntityContentJoin.delete(join3.join_id);
+ Entity.delete(entity1.entity_id);
+ Entity.delete(entity2.entity_id);
+ Content.delete(content.content_id);
+ Content.delete(content2.content_id);
+
+ } catch (error) {
+ results.join.failed++;
+ results.join.details.push(`Entity-Content多对多测试失败: ${error.message}`);
+ }
+
+ console.log(`Entity-Content多对多: ${results.join.passed} passed, ${results.join.failed} failed`);
+}
+
+/**
+ * 验证内容生命周期
+ */
+function verifyContentLifecycle() {
+ console.log('\n=== 验证内容生命周期 ===');
+
+ try {
+ // 创建测试Content
+ const content = Content.create({
+ title: '测试内容',
+ body: '测试内容',
+ content_type: 'article',
+ publish_status: 'draft',
+ });
+
+ // 测试draft -> review
+ const reviewContent = Content.transitionStatus(content.content_id, 'review');
+ if (reviewContent.publish_status === 'review') {
+ results.lifecycle.passed++;
+ results.lifecycle.details.push('draft -> review 转换成功');
+ } else {
+ results.lifecycle.failed++;
+ results.lifecycle.details.push('draft -> review 转换失败');
+ }
+
+ // 测试review -> published
+ const publishedContent = Content.transitionStatus(content.content_id, 'published');
+ if (publishedContent.publish_status === 'published' && publishedContent.version_no === 2) {
+ results.lifecycle.passed++;
+ results.lifecycle.details.push('review -> published 转换成功,版本号递增');
+ } else {
+ results.lifecycle.failed++;
+ results.lifecycle.details.push('review -> published 转换失败');
+ }
+
+ // 测试published -> unpublished
+ const unpublishedContent = Content.transitionStatus(content.content_id, 'unpublished');
+ if (unpublishedContent.publish_status === 'unpublished') {
+ results.lifecycle.passed++;
+ results.lifecycle.details.push('published -> unpublished 转换成功');
+ } else {
+ results.lifecycle.failed++;
+ results.lifecycle.details.push('published -> unpublished 转换失败');
+ }
+
+ // 测试unpublished -> historical
+ const historicalContent = Content.transitionStatus(content.content_id, 'historical');
+ if (historicalContent.publish_status === 'historical' && historicalContent.archived_at) {
+ results.lifecycle.passed++;
+ results.lifecycle.details.push('unpublished -> historical 转换成功,记录归档时间');
+ } else {
+ results.lifecycle.failed++;
+ results.lifecycle.details.push('unpublished -> historical 转换失败');
+ }
+
+ // 清理测试数据
+ Content.delete(content.content_id);
+
+ } catch (error) {
+ results.lifecycle.failed++;
+ results.lifecycle.details.push(`内容生命周期测试失败: ${error.message}`);
+ }
+
+ console.log(`内容生命周期: ${results.lifecycle.passed} passed, ${results.lifecycle.failed} failed`);
+}
+
+/**
+ * 验证Authority权威等级
+ */
+function verifyAuthority() {
+ console.log('\n=== 验证Authority权威等级 ===');
+
+ try {
+ // 测试Entity的authority_level
+ const entity = Entity.create({
+ entity_type: 'concept',
+ name: '测试实体',
+ authority_level: 3,
+ });
+
+ if (entity.authority_level === 3) {
+ results.authority.passed++;
+ results.authority.details.push('Entity authority_level设置成功');
+ } else {
+ results.authority.failed++;
+ results.authority.details.push('Entity authority_level设置失败');
+ }
+
+ // 测试Relation的authority_level
+ const entity2 = Entity.create({
+ entity_type: 'concept',
+ name: '测试实体2',
+ });
+
+ const relation = DirectedRelationship.create({
+ source_entity_id: entity.entity_id,
+ relation_type: '测试关系',
+ target_entity_id: entity2.entity_id,
+ authority_level: 4,
+ });
+
+ if (relation.authority_level === 4) {
+ results.authority.passed++;
+ results.authority.details.push('Relation authority_level设置成功');
+ } else {
+ results.authority.failed++;
+ results.authority.details.push('Relation authority_level设置失败');
+ }
+
+ // 测试Content的authority_level
+ const content = Content.create({
+ title: '测试内容',
+ body: '测试内容',
+ content_type: 'article',
+ authority_level: 5,
+ });
+
+ if (content.authority_level === 5) {
+ results.authority.passed++;
+ results.authority.details.push('Content authority_level设置成功');
+ } else {
+ results.authority.failed++;
+ results.authority.details.push('Content authority_level设置失败');
+ }
+
+ // 清理测试数据
+ Entity.delete(entity.entity_id);
+ Entity.delete(entity2.entity_id);
+ DirectedRelationship.delete(relation.rel_id);
+ Content.delete(content.content_id);
+
+ } catch (error) {
+ results.authority.failed++;
+ results.authority.details.push(`Authority测试失败: ${error.message}`);
+ }
+
+ console.log(`Authority: ${results.authority.passed} passed, ${results.authority.failed} failed`);
+}
+
+/**
+ * 主函数
+ */
+function main() {
+ console.log('开始数据模型验证...');
+
+ // 初始化数据库
+ migrate();
+
+ // 执行验证
+ verifyEntity();
+ verifyPage();
+ verifyArticle();
+ verifyCase();
+ verifyEntityContentJoin();
+ verifyContentLifecycle();
+ verifyAuthority();
+
+ // 统计结果
+ let totalPassed = 0;
+ let totalFailed = 0;
+
+ for (const key in results) {
+ totalPassed += results[key].passed;
+ totalFailed += results[key].failed;
+ }
+
+ console.log('\n=== 验证结果汇总 ===');
+ console.log(`总测试: ${totalPassed + totalFailed}`);
+ console.log(`通过: ${totalPassed}`);
+ console.log(`失败: ${totalFailed}`);
+ console.log(`通过率: ${((totalPassed / (totalPassed + totalFailed)) * 100).toFixed(2)}%`);
+
+ // 输出详细结果
+ console.log('\n=== 详细结果 ===');
+ for (const key in results) {
+ console.log(`\n${key}:`);
+ results[key].details.forEach(detail => {
+ console.log(` - ${detail}`);
+ });
+ }
+
+ // 关闭数据库
+ closeDb();
+
+ return results;
+}
+
+// 如果直接运行此脚本
+if (require.main === module) {
+ main();
+}
+
+module.exports = {
+ main,
+ results,
+};
\ No newline at end of file
diff --git a/tests/p0_content_write.js b/tests/p0_content_write.js
new file mode 100644
index 0000000..3447a91
--- /dev/null
+++ b/tests/p0_content_write.js
@@ -0,0 +1,605 @@
+/**
+ * P0正式内容工程写入脚本
+ * 将冻结内容准确写入系统
+ */
+
+const { getDb, closeDb } = require('../src/config/database');
+const { migrate } = require('../src/database/migrate');
+const Entity = require('../src/models/Entity');
+const Content = require('../src/models/Content');
+const Page = require('../src/models/Page');
+const Article = require('../src/models/Article');
+const Case = require('../src/models/Case');
+const FAQ = require('../src/models/FAQ');
+const Capability = require('../src/models/Capability');
+const Service = require('../src/models/Service');
+const DirectedRelationship = require('../src/models/DirectedRelationship');
+const EntityContentJoin = require('../src/models/EntityContentJoin');
+
+// P0核心Entity定义
+const P0_ENTITIES = [
+ {
+ entity_id: 'E-AMEBA-MAIN',
+ entity_type: 'organization',
+ name: '阿美巴',
+ definition: '阿美巴以企业进化为核心、AI为时代背景和赋能工具的企业咨询与进化服务机构,聚焦长期系统性升级。',
+ description: '阿美巴|AI时代企业进化平台。各项能力升级最终应服务于企业整体进化目标。服务对象主要为国内中小企业,重点关注实体企业、制造型企业。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 1,
+ },
+ {
+ entity_id: 'E-EVOLUTION',
+ entity_type: 'concept',
+ name: '企业进化',
+ definition: '企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力的过程。',
+ description: '增长更多体现结果层变化。进化更强调底层能力、系统与企业状态的持续调整和升级。AI是时代变量和重要赋能工具,不是企业进化本身的终点。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ },
+ {
+ entity_id: 'E-GOAL',
+ entity_type: 'concept',
+ name: '企业进化目标',
+ definition: '企业进化目标是企业开展进化工作的一个重要起点和核心参照。',
+ description: '企业进化目标主要关注:中长期发展方向、企业价值定位、希望形成的企业状态、企业未来需要具备的能力。目标可以根据企业发展阶段和外部环境动态调整。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ },
+ {
+ entity_id: 'E-ENDSTART',
+ entity_type: 'method',
+ name: '以终为始',
+ definition: '以目标状态为参照,再反向分析企业当前状态及差距。',
+ description: '先明确希望到哪里,再分析现在在哪里,最后确定中间需要完成什么。"以终为始"是阿美巴企业进化工作的基本指导原则之一。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 3,
+ },
+ {
+ entity_id: 'E-PRIORITY',
+ entity_type: 'method',
+ name: '目标先于问题',
+ definition: '问题的重要性与优先级,需要结合企业整体进化目标判断。',
+ description: '不是所有问题都需要立即解决。如果某个问题与企业当前核心进化目标关联较弱,可以暂缓、简化或降低优先级。表面问题也可能只是更深层能力或系统问题的表现。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 3,
+ },
+ {
+ entity_id: 'E-METHOD',
+ entity_type: 'method',
+ name: '企业进化方法',
+ definition: '阿美巴目前使用的是企业进化工作逻辑和结构化分析方式,不对外宣称为某个已经正式命名、行业标准化的独立方法论体系。',
+ description: '包含两组互补逻辑:第一组企业进化主链:企业进化目标→当前状态→差距识别→关键障碍→根因→进化路径→实施→反馈→持续迭代。第二组顾问工作动作:观察→诊断→根因分析→方案。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 3,
+ },
+ {
+ entity_id: 'E-VALUE',
+ entity_type: 'concept',
+ name: '四大价值',
+ definition: '四大价值是阿美巴用于观察和分析企业价值运行状态的重要坐标。',
+ description: '四大价值包括:价值创造、价值传递、价值交付、价值支持。四大价值可用于辅助分析企业经营状态与进化方向。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ },
+ {
+ entity_id: 'E-AMB',
+ entity_type: 'stage',
+ name: 'A/M/B三态状态模型',
+ definition: 'A/M/B是企业AI时代进化状态模型,不是强制线性路径。',
+ description: 'A态·入态:企业AI时代进化的一种状态,代表企业开始建立AI时代进化认知、开展基础升级动作,并搭建初步的AI应用与体系建设基础。M态·优态:企业进一步围绕流程、组织、标准化和AI应用等进行优化,形成更稳定的AI时代能力基础。B态·越态:企业进一步突破原有边界,通过组织重塑、系统重构以及企业级AI等方式形成新的企业运行能力。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ },
+ {
+ entity_id: 'E-CAPABILITY',
+ entity_type: 'capability',
+ name: '企业进化能力',
+ definition: '能力体系可对应企业不同阶段、不同类型的进化需求。',
+ description: '20项官方能力:战略与顶层设计、经营与增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用与部署、企业进化诊断、企业进化规划、顾问服务、咨询服务、企业陪跑、定制化服务。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 1,
+ },
+ {
+ entity_id: 'E-AI-RELATION',
+ entity_type: 'concept',
+ name: 'AI与企业进化关系',
+ definition: 'AI是AI时代企业进化的重要时代变量和赋能工具。企业进化是核心目的。',
+ description: 'AI逐步进入企业的:组织、流程、知识、管理、经营。企业进化→目标,AI→重要赋能工具。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ },
+ {
+ entity_id: 'E-MATCH',
+ entity_type: 'method',
+ name: '企业需求与能力匹配',
+ definition: 'V1.0只建立静态匹配逻辑,不建立智能诊断、自动评分、聊天机器人等复杂功能。',
+ description: '官方匹配链:企业类型→企业阶段→企业进化目标→当前现状→核心障碍→企业需求→阿美巴能力→适配服务→案例佐证。四个企业判断维度:企业需求强度、企业合作意愿、企业支付能力、企业落地能力。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 3,
+ },
+ {
+ entity_id: 'E-CASE',
+ entity_type: 'concept',
+ name: '企业进化案例',
+ definition: '案例标准结构:企业背景→企业阶段→原始目标→企业现状→表面问题→阿美巴判断→关键障碍→根因→进化路径→实施过程→结果→案例意义。',
+ description: 'P0阶段不得虚构案例。如果当前没有真实案例资料,保持空缺、待填充或系统允许的占位状态。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 3,
+ },
+ {
+ entity_id: 'E-FAQ',
+ entity_type: 'concept',
+ name: 'AI认知FAQ',
+ definition: 'AI认知标准化FAQ,覆盖阿美巴核心知识问答。',
+ description: '必须完整写入20个FAQ,覆盖阿美巴是谁、企业进化、四大价值、A/M/B、能力体系等核心知识。',
+ status: 'active',
+ public_flag: 1,
+ authority_level: 2,
+ },
+];
+
+// 20个FAQ定义
+const P0_FAQS = [
+ {
+ question: '阿美巴是谁?',
+ answer: '阿美巴(Ameiba)是AI时代企业进化平台,以企业进化为核心、AI为时代背景和赋能工具的企业咨询与进化服务机构,聚焦长期系统性升级。服务对象主要为国内中小企业,重点关注实体企业、制造型企业。',
+ authority_level: 2,
+ },
+ {
+ question: '阿美巴做什么?',
+ answer: '阿美巴为企业提供进化咨询与服务能力,帮助企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力。',
+ authority_level: 2,
+ },
+ {
+ question: '阿美巴是不是AI公司?',
+ answer: '阿美巴不是单纯的AI公司。AI是AI时代企业进化的重要时代变量和赋能工具,企业进化才是核心目的。阿美巴以企业进化为核心,AI为赋能工具。',
+ authority_level: 2,
+ },
+ {
+ question: '阿美巴是不是培训公司?',
+ answer: '阿美巴不是单纯的培训公司。阿美巴为企业提供进化咨询与服务能力,包括顾问服务、咨询服务、企业陪跑、定制化服务等,帮助企业实现系统性进化。',
+ authority_level: 2,
+ },
+ {
+ question: '阿美巴与传统管理咨询有什么区别?',
+ answer: '阿美巴以企业进化为核心,AI为时代背景和赋能工具,聚焦长期系统性升级。传统管理咨询更侧重于解决当前问题,阿美巴更强调底层能力、系统与企业状态的持续调整和升级。',
+ authority_level: 3,
+ },
+ {
+ question: '什么是企业进化?',
+ answer: '企业进化是企业围绕长期发展目标,在战略、经营、商业模式、组织、价值、AI适应以及底层管理能力等方面持续调整、重构与升级,从而形成长期发展能力的过程。增长更多体现结果层变化,进化更强调底层能力、系统与企业状态的持续调整和升级。',
+ authority_level: 2,
+ },
+ {
+ question: '企业进化与增长有什么区别?',
+ answer: '增长更多体现结果层变化,进化更强调底层能力、系统与企业状态的持续调整和升级。企业进化是围绕长期发展目标的系统性升级过程。',
+ authority_level: 3,
+ },
+ {
+ question: '为什么目标先于问题?',
+ answer: '问题的重要性与优先级,需要结合企业整体进化目标判断。不是所有问题都需要立即解决。如果某个问题与企业当前核心进化目标关联较弱,可以暂缓、简化或降低优先级。目标先于问题,不是否定问题,而是重新确定问题的优先级和解决方向。',
+ authority_level: 3,
+ },
+ {
+ question: '什么是以终为始?',
+ answer: '以终为始是以目标状态为参照,再反向分析企业当前状态及差距。先明确希望到哪里,再分析现在在哪里,最后确定中间需要完成什么。"以终为始"是阿美巴企业进化工作的基本指导原则之一。',
+ authority_level: 3,
+ },
+ {
+ question: '什么是四大价值?',
+ answer: '四大价值包括:价值创造、价值传递、价值交付、价值支持。四大价值是阿美巴用于观察和分析企业价值运行状态的重要坐标,可用于辅助分析企业经营状态与进化方向。',
+ authority_level: 2,
+ },
+ {
+ question: 'A/M/B是什么?',
+ answer: 'A/M/B是企业AI时代进化状态模型,不是强制线性路径。企业可以根据自身情况处于不同状态,也不意味着所有企业必须从A到M再到B。这是企业AI时代进化状态识别框架。',
+ authority_level: 2,
+ },
+ {
+ question: 'A态是什么?',
+ answer: 'A态·入态是企业AI时代进化的一种状态,代表企业开始建立AI时代进化认知、开展基础升级动作,并搭建初步的AI应用与体系建设基础。',
+ authority_level: 2,
+ },
+ {
+ question: 'M态是什么?',
+ answer: 'M态·优态是企业进一步围绕流程、组织、标准化和AI应用等进行优化,形成更稳定的AI时代能力基础的状态。',
+ authority_level: 2,
+ },
+ {
+ question: 'B态是什么?',
+ answer: 'B态·越态是企业进一步突破原有边界,通过组织重塑、系统重构以及企业级AI等方式形成新的企业运行能力的状态。',
+ authority_level: 2,
+ },
+ {
+ question: '阿美巴有哪些企业进化能力?',
+ answer: '阿美巴提供20项企业进化能力:战略与顶层设计、经营与增长、商业模式、组织重塑、企业治理、独立核算、经营分析、价值评价、薪酬激励、IT部署、AI组织、企业AI系统、企业知识系统、AI应用与部署、企业进化诊断、企业进化规划、顾问服务、咨询服务、企业陪跑、定制化服务。',
+ authority_level: 1,
+ },
+ {
+ question: '什么样的企业适合阿美巴?',
+ answer: '阿美巴服务对象主要为国内中小企业,重点关注实体企业、制造型企业。企业可以根据自身情况判断是否适合,通过企业类型、企业阶段、企业进化目标、当前现状、核心障碍、企业需求等维度进行匹配。',
+ authority_level: 3,
+ },
+ {
+ question: '阿美巴提供哪些服务?',
+ answer: '阿美巴提供顾问服务、咨询服务、企业陪跑、定制化服务等。服务内容包括企业进化诊断、进化路径规划、战略咨询、组织变革咨询、AI部署咨询等。具体服务根据企业需求和阶段匹配。',
+ authority_level: 3,
+ },
+ {
+ question: '阿美巴如何判断企业是否适合?',
+ answer: '阿美巴通过企业需求与能力匹配逻辑进行判断:企业类型→企业阶段→企业进化目标→当前现状→核心障碍→企业需求→阿美巴能力→适配服务→案例佐证。同时考虑四个企业判断维度:企业需求强度、企业合作意愿、企业支付能力、企业落地能力。',
+ authority_level: 3,
+ },
+ {
+ question: '阿美巴是否提供咨询与企业陪跑?',
+ answer: '是的,阿美巴提供咨询服务和企业陪跑服务。咨询服务包括战略咨询、组织变革咨询、AI部署咨询等。企业陪跑是阿美巴提供的长期伴随式服务,帮助企业持续进行进化迭代。',
+ authority_level: 3,
+ },
+ {
+ question: '如何进一步联系阿美巴?',
+ answer: '您可以通过阿美巴官网联系我们页面获取联系方式,或通过官方邮箱、电话等渠道与阿美巴取得联系。阿美巴将根据您的企业情况提供相应的咨询与服务。',
+ authority_level: 3,
+ },
+];
+
+// 20项官方Capability定义
+const P0_CAPABILITIES = [
+ { name: '战略与顶层设计', capability_type: '战略', features: '企业战略规划与顶层设计能力', use_cases: '帮助企业明确长期发展方向和战略定位' },
+ { name: '经营与增长', capability_type: '经营', features: '企业经营增长与市场拓展能力', use_cases: '帮助企业实现经营增长和市场份额提升' },
+ { name: '商业模式', capability_type: '战略', features: '商业模式设计与创新能力', use_cases: '帮助企业设计和优化商业模式' },
+ { name: '组织重塑', capability_type: '组织', features: '组织架构优化与变革能力', use_cases: '帮助企业进行组织架构调整和变革' },
+ { name: '企业治理', capability_type: '组织', features: '企业治理体系与能力', help: '帮助企业建立现代企业治理体系' },
+ { name: '独立核算', capability_type: '经营', features: '独立核算体系与能力', use_cases: '帮助企业建立独立核算体系' },
+ { name: '经营分析', capability_type: '经营', features: '经营数据分析与决策支持能力', use_cases: '帮助企业进行经营数据分析和决策支持' },
+ { name: '价值评价', capability_type: '组织', features: '价值评价体系与能力', use_cases: '帮助企业建立价值评价体系' },
+ { name: '薪酬激励', capability_type: '组织', features: '薪酬激励体系设计能力', use_cases: '帮助企业设计薪酬激励体系' },
+ { name: 'IT部署', capability_type: '技术', features: 'IT系统规划与部署能力', use_cases: '帮助企业进行IT系统规划和部署' },
+ { name: 'AI组织', capability_type: 'AI', features: 'AI组织建设与管理能力', use_cases: '帮助企业建设AI组织能力' },
+ { name: '企业AI系统', capability_type: 'AI', features: '企业AI系统规划与实施能力', use_cases: '帮助企业规划和实施AI系统' },
+ { name: '企业知识系统', capability_type: 'AI', features: '企业知识管理系统能力', use_cases: '帮助企业建设知识管理系统' },
+ { name: 'AI应用与部署', capability_type: 'AI', features: 'AI应用场景规划与部署能力', use_cases: '帮助企业规划和部署AI应用场景' },
+ { name: '企业进化诊断', capability_type: '服务', features: '企业进化状态诊断能力', use_cases: '帮助企业诊断当前进化状态' },
+ { name: '企业进化规划', capability_type: '服务', features: '企业进化路径规划能力', use_cases: '帮助企业规划进化路径' },
+ { name: '顾问服务', capability_type: '服务', features: '专业顾问咨询服务', use_cases: '为企业提供专业顾问咨询' },
+ { name: '咨询服务', capability_type: '服务', features: '管理咨询服务', use_cases: '为企业提供管理咨询' },
+ { name: '企业陪跑', capability_type: '服务', features: '企业进化全程陪伴服务', use_cases: '为企业提供长期伴随式服务' },
+ { name: '定制化服务', capability_type: '服务', features: '定制化解决方案服务', use_cases: '为企业提供定制化解决方案' },
+];
+
+// 17条Directed Relations
+const P0_RELATIONS = [
+ { source: 'E-AMEBA-MAIN', type: '拥有核心认知', target: 'E-EVOLUTION' },
+ { source: 'E-AMEBA-MAIN', type: '具备赋能能力', target: 'E-CAPABILITY' },
+ { source: 'E-AMEBA-MAIN', type: '适配判断依据', target: 'E-MATCH' },
+ { source: 'E-EVOLUTION', type: '依赖目标基准', target: 'E-GOAL' },
+ { source: 'E-EVOLUTION', type: '遵循优化原则', target: 'E-ENDSTART' },
+ { source: 'E-EVOLUTION', type: '遵循判断准则', target: 'E-PRIORITY' },
+ { source: 'E-EVOLUTION', type: '依托迭代逻辑', target: 'E-METHOD' },
+ { source: 'E-EVOLUTION', type: '依托价值分析框架', target: 'E-VALUE' },
+ { source: 'E-EVOLUTION', type: '包含阶段特征', target: 'E-AMB' },
+ { source: 'E-EVOLUTION', type: '结合时代赋能工具', target: 'E-AI-RELATION' },
+ { source: 'E-GOAL', type: '指导问题优先级', target: 'E-PRIORITY' },
+ { source: 'E-GOAL', type: '指导迭代路径', target: 'E-METHOD' },
+ { source: 'E-PRIORITY', type: '落地指导依据', target: 'E-METHOD' },
+ { source: 'E-AMB', type: '适配能力升级', target: 'E-CAPABILITY' },
+ { source: 'E-MATCH', type: '匹配参考依据', target: 'E-CAPABILITY' },
+ { source: 'E-MATCH', type: '匹配阶段依据', target: 'E-AMB' },
+ { source: 'E-MATCH', type: '佐证参考', target: 'E-CASE' },
+];
+
+// 页面定义
+const P0_PAGES = [
+ { slug: '/', title: '阿美巴AI官网', h1: '阿美巴|AI时代企业进化平台', summary: '阿美巴以企业进化为核心、AI为时代背景和赋能工具的企业咨询与进化服务机构', entity_id: 'E-AMEBA-MAIN' },
+ { slug: '/about', title: '阿美巴是谁', h1: '阿美巴是谁', summary: '了解阿美巴AI - AI时代企业进化平台', entity_id: 'E-AMEBA-MAIN' },
+ { slug: '/evolution', title: '企业进化', h1: '企业进化', summary: '了解企业进化的定义、方法与路径', entity_id: 'E-EVOLUTION' },
+ { slug: '/evolution/method', title: '进化方法', h1: '企业进化方法', summary: '以终为始、目标先于问题、现状分析、差距识别、根因分析、路径规划、实施迭代', entity_id: 'E-METHOD' },
+ { slug: '/value', title: '四大价值', h1: '四大价值', summary: '价值创造、价值传递、价值交付、价值支持', entity_id: 'E-VALUE' },
+ { slug: '/value/creation', title: '价值创造', h1: '价值创造', summary: '企业如何创造价值', entity_id: 'E-VALUE' },
+ { slug: '/value/transfer', title: '价值传递', h1: '价值传递', summary: '企业如何将价值传递给客户', entity_id: 'E-VALUE' },
+ { slug: '/value/delivery', title: '价值交付', h1: '价值交付', summary: '企业如何交付价值', entity_id: 'E-VALUE' },
+ { slug: '/value/support', title: '价值支持', h1: '价值支持', summary: '企业如何支持价值创造与交付', entity_id: 'E-VALUE' },
+ { slug: '/amb', title: 'A/M/B企业进化路径', h1: 'A/M/B三态模型:AI时代企业进化状态识别框架', summary: 'A/M/B是企业AI时代进化状态模型,不是强制线性路径', entity_id: 'E-AMB' },
+ { slug: '/amb/a', title: 'A态·入态', h1: 'A态·入态', summary: '企业AI时代进化的一种状态', entity_id: 'E-AMB' },
+ { slug: '/amb/m', title: 'M态·优态', h1: 'M态·优态', summary: '企业进一步优化的状态', entity_id: 'E-AMB' },
+ { slug: '/amb/b', title: 'B态·越态', h1: 'B态·越态', summary: '企业突破边界的状态', entity_id: 'E-AMB' },
+ { slug: '/capabilities', title: '能力地图', h1: '企业进化能力地图', summary: '企业进化的完整能力体系', entity_id: 'E-CAPABILITY' },
+ { slug: '/cases', title: '案例', h1: '企业进化案例', summary: '企业进化实践案例', entity_id: 'E-CASE' },
+ { slug: '/knowledge', title: '知识中心', h1: '知识中心', summary: '企业进化的知识体系与方法论', entity_id: 'E-EVOLUTION' },
+ { slug: '/concepts', title: '概念', h1: '概念', summary: '企业进化的知识实体概念列表', entity_id: 'E-EVOLUTION' },
+ { slug: '/faq', title: 'FAQ', h1: '常见问题', summary: '常见问题解答', entity_id: 'E-FAQ' },
+ { slug: '/match', title: '企业需求与能力匹配', h1: '企业需求与能力匹配', summary: '基于企业特征匹配进化能力与服务', entity_id: 'E-MATCH' },
+ { slug: '/contact', title: '联系我们', h1: '联系我们', summary: '联系阿美巴AI', entity_id: 'E-AMEBA-MAIN' },
+];
+
+/**
+ * 写入P0核心Entity
+ */
+function writeP0Entities() {
+ console.log('\n=== 写入P0核心Entity ===');
+
+ let count = 0;
+ for (const entity of P0_ENTITIES) {
+ try {
+ // 检查是否已存在
+ const existing = Entity.findById(entity.entity_id);
+ if (existing) {
+ console.log(`Entity ${entity.entity_id} 已存在,跳过`);
+ continue;
+ }
+
+ Entity.create(entity);
+ count++;
+ console.log(`✓ 写入Entity: ${entity.entity_id} - ${entity.name}`);
+ } catch (error) {
+ console.error(`✗ 写入Entity失败: ${entity.entity_id} - ${error.message}`);
+ }
+ }
+
+ console.log(`共写入 ${count} 个Entity`);
+ return count;
+}
+
+/**
+ * 写入20个FAQ
+ */
+function writeP0FAQs() {
+ console.log('\n=== 写入20个FAQ ===');
+
+ let count = 0;
+ for (let i = 0; i < P0_FAQS.length; i++) {
+ try {
+ const faq = P0_FAQS[i];
+ const faqData = Content.create({
+ title: faq.question,
+ body: faq.answer,
+ content_type: 'faq',
+ publish_status: 'draft',
+ authority_level: faq.authority_level,
+ });
+
+ // 创建FAQ扩展记录
+ const db = getDb();
+ const stmt = db.prepare(`
+ INSERT INTO faqs (faq_id, question, answer, sort_order)
+ VALUES (?, ?, ?, ?)
+ `);
+ stmt.run(faqData.content_id, faq.question, faq.answer, i + 1);
+
+ // 关联到FAQ Entity
+ EntityContentJoin.create({
+ entity_id: 'E-FAQ',
+ content_id: faqData.content_id,
+ });
+
+ count++;
+ console.log(`✓ 写入FAQ ${i + 1}: ${faq.question.substring(0, 30)}...`);
+ } catch (error) {
+ console.error(`✗ 写入FAQ失败: ${error.message}`);
+ }
+ }
+
+ console.log(`共写入 ${count} 个FAQ`);
+ return count;
+}
+
+/**
+ * 写入20项官方Capability
+ */
+function writeP0Capabilities() {
+ console.log('\n=== 写入20项官方Capability ===');
+
+ let count = 0;
+ for (let i = 0; i < P0_CAPABILITIES.length; i++) {
+ try {
+ const cap = P0_CAPABILITIES[i];
+ const capData = Content.create({
+ title: cap.name,
+ body: cap.features,
+ content_type: 'capability',
+ publish_status: 'draft',
+ authority_level: 1,
+ });
+
+ // 创建Capability扩展记录
+ const db = getDb();
+ const stmt = db.prepare(`
+ INSERT INTO capabilities (capability_id, capability_type, features, use_cases)
+ VALUES (?, ?, ?, ?)
+ `);
+ stmt.run(capData.content_id, cap.capability_type, cap.features, cap.use_cases);
+
+ // 关联到Capability Entity
+ EntityContentJoin.create({
+ entity_id: 'E-CAPABILITY',
+ content_id: capData.content_id,
+ });
+
+ count++;
+ console.log(`✓ 写入Capability ${i + 1}: ${cap.name}`);
+ } catch (error) {
+ console.error(`✗ 写入Capability失败: ${error.message}`);
+ }
+ }
+
+ console.log(`共写入 ${count} 个Capability`);
+ return count;
+}
+
+/**
+ * 写入17条Directed Relations
+ */
+function writeP0Relations() {
+ console.log('\n=== 写入17条Directed Relations ===');
+
+ let count = 0;
+ for (const rel of P0_RELATIONS) {
+ try {
+ DirectedRelationship.create({
+ source_entity_id: rel.source,
+ relation_type: rel.type,
+ target_entity_id: rel.target,
+ rel_status: 'active',
+ authority_level: 2,
+ is_public: 1,
+ });
+
+ count++;
+ console.log(`✓ 写入Relation: ${rel.source} → ${rel.type} → ${rel.target}`);
+ } catch (error) {
+ console.error(`✗ 写入Relation失败: ${error.message}`);
+ }
+ }
+
+ console.log(`共写入 ${count} 条Relation`);
+ return count;
+}
+
+/**
+ * 写入P0页面
+ */
+function writeP0Pages() {
+ console.log('\n=== 写入P0页面 ===');
+
+ let count = 0;
+ for (const page of P0_PAGES) {
+ try {
+ const pageData = Page.create({
+ title: page.title,
+ body: page.h1,
+ slug: page.slug,
+ summary: page.summary,
+ seo_title: page.title,
+ seo_description: page.summary,
+ content_type: 'page',
+ publish_status: 'draft',
+ authority_level: 2,
+ });
+
+ // 关联到对应Entity
+ if (page.entity_id) {
+ EntityContentJoin.create({
+ entity_id: page.entity_id,
+ content_id: pageData.content_id,
+ });
+ }
+
+ count++;
+ console.log(`✓ 写入Page: ${page.slug} - ${page.title}`);
+ } catch (error) {
+ console.error(`✗ 写入Page失败: ${page.slug} - ${error.message}`);
+ }
+ }
+
+ console.log(`共写入 ${count} 个Page`);
+ return count;
+}
+
+/**
+ * 验证写入结果
+ */
+function verifyWriteResults() {
+ console.log('\n=== 验证写入结果 ===');
+
+ const entityCount = Entity.count();
+ const contentCount = Content.count();
+ const relationCount = DirectedRelationship.count();
+ const joinCount = EntityContentJoin.count();
+
+ console.log(`Entity数量: ${entityCount}`);
+ console.log(`Content数量: ${contentCount}`);
+ console.log(`Relation数量: ${relationCount}`);
+ console.log(`Entity-Content关联数量: ${joinCount}`);
+
+ // 验证13个P0 Entity
+ const p0EntityIds = P0_ENTITIES.map(e => e.entity_id);
+ let p0EntityCount = 0;
+ for (const id of p0EntityIds) {
+ const entity = Entity.findById(id);
+ if (entity) p0EntityCount++;
+ }
+ console.log(`P0 Entity存在数量: ${p0EntityCount}/13`);
+
+ // 验证FAQ数量
+ const faqContents = Content.findByType('faq');
+ console.log(`FAQ数量: ${faqContents.length}/20`);
+
+ // 验证Capability数量
+ const capContents = Content.findByType('capability');
+ console.log(`Capability数量: ${capContents.length}/20`);
+
+ // 验证Relation数量
+ console.log(`Relation数量: ${relationCount}/17`);
+
+ // 验证所有内容状态为draft
+ const { getDb } = require('../src/config/database');
+ const db = getDb();
+ const allContentsStmt = db.prepare('SELECT * FROM contents');
+ const allContents = allContentsStmt.all();
+ const draftCount = allContents.filter(c => c.publish_status === 'draft').length;
+ console.log(`draft状态内容数量: ${draftCount}/${allContents.length}`);
+
+ return {
+ entityCount,
+ contentCount,
+ relationCount,
+ joinCount,
+ p0EntityCount,
+ faqCount: faqContents.length,
+ capCount: capContents.length,
+ draftCount,
+ totalContents: allContents.length,
+ };
+}
+
+/**
+ * 主函数
+ */
+function main() {
+ console.log('开始P0正式内容工程写入...');
+
+ // 初始化数据库
+ migrate();
+
+ // 执行写入
+ writeP0Entities();
+ writeP0FAQs();
+ writeP0Capabilities();
+ writeP0Relations();
+ writeP0Pages();
+
+ // 验证结果
+ const results = verifyWriteResults();
+
+ console.log('\n=== P0内容写入完成 ===');
+
+ // 关闭数据库
+ closeDb();
+
+ return results;
+}
+
+// 如果直接运行此脚本
+if (require.main === module) {
+ main();
+}
+
+module.exports = {
+ main,
+ P0_ENTITIES,
+ P0_FAQS,
+ P0_CAPABILITIES,
+ P0_RELATIONS,
+ P0_PAGES,
+};
\ No newline at end of file
diff --git a/tests/project_audit.js b/tests/project_audit.js
new file mode 100644
index 0000000..61f608b
--- /dev/null
+++ b/tests/project_audit.js
@@ -0,0 +1,789 @@
+/**
+ * V1.0全项目盘点脚本
+ * 自动扫描全项目代码库,生成盘点报告
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+// 配置
+const CONFIG = {
+ projectRoot: path.join(__dirname, '../..'),
+ outputDir: path.join(__dirname, 'reports'),
+};
+
+// V1.0必须实现清单
+const V10_MUST_HAVE = [
+ {
+ id: 'MH-001',
+ name: 'Entity【知识实体表】',
+ description: '包含entity_id、name、definition、description、metadata等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS entities',
+ },
+ {
+ id: 'MH-002',
+ name: 'DirectedRelationship【有向实体关系表】',
+ description: '包含rel_id、source_entity_id、relation_type、target_entity_id等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS directed_relationships',
+ },
+ {
+ id: 'MH-003',
+ name: 'Content【内容基础表】',
+ description: '包含content_id、title、body、content_type、publish_status等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS contents',
+ },
+ {
+ id: 'MH-004',
+ name: 'Page【页面扩展表】',
+ description: '包含page_id、slug、template、seo_title等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS pages',
+ },
+ {
+ id: 'MH-005',
+ name: 'Article【文章扩展表】',
+ description: '包含article_id、category、tags、cover_image、author等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS articles',
+ },
+ {
+ id: 'MH-006',
+ name: 'Case【案例扩展表】',
+ description: '包含case_id、client_name、industry、challenge、solution、result等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS cases',
+ },
+ {
+ id: 'MH-007',
+ name: 'FAQ【常见问题扩展表】',
+ description: '包含faq_id、question、answer、sort_order等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS faqs',
+ },
+ {
+ id: 'MH-008',
+ name: 'Capability【能力扩展表】',
+ description: '包含capability_id、capability_type、features、use_cases等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS capabilities',
+ },
+ {
+ id: 'MH-009',
+ name: 'Service【服务扩展表】',
+ description: '包含service_id、service_type、pricing_model、delivery_method等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS services',
+ },
+ {
+ id: 'MH-010',
+ name: 'EntityContentJoin【实体-内容关联表】',
+ description: '包含join_id、entity_id、content_id、join_note等字段',
+ checkType: 'database',
+ checkPattern: 'CREATE TABLE IF NOT EXISTS entity_content_joins',
+ },
+ {
+ id: 'MH-011',
+ name: 'Entity管理CRUD',
+ description: '新增、编辑、停用实体,entity_id生成后不可修改',
+ checkType: 'api',
+ checkPattern: '/api/entities',
+ },
+ {
+ id: 'MH-012',
+ name: 'DirectedRelationship管理CRUD',
+ description: '新增、编辑、停用关系,禁止自动生成反向数据库记录',
+ checkType: 'api',
+ checkPattern: '/api/relationships',
+ },
+ {
+ id: 'MH-013',
+ name: '内容管理CRUD',
+ description: 'Page/Article/Case/FAQ/Capability/Service全部CRUD',
+ checkType: 'api',
+ checkPattern: '/api/contents',
+ },
+ {
+ id: 'MH-014',
+ name: '内容生命周期流转',
+ description: 'draft ↔ review → published → unpublished → historical',
+ checkType: 'api',
+ checkPattern: '/transition',
+ },
+ {
+ id: 'MH-015',
+ name: '权威等级L1-L7',
+ description: '可编辑存储',
+ checkType: 'database',
+ checkPattern: 'authority_level',
+ },
+ {
+ id: 'MH-016',
+ name: '版本留存',
+ description: '进入historical状态保留历史版本,不物理删除',
+ checkType: 'api',
+ checkPattern: '/history',
+ },
+ {
+ id: 'MH-017',
+ name: '公开输出接口',
+ description: '对外数据接口只返回status=published的内容',
+ checkType: 'api',
+ checkPattern: '/api/public',
+ },
+ {
+ id: 'MH-018',
+ name: 'JSON-LD结构化数据生成',
+ description: '系统自动生成JSON-LD结构化数据',
+ checkType: 'api',
+ checkPattern: '/api/jsonld',
+ },
+ {
+ id: 'MH-019',
+ name: '首页',
+ description: '路由: /,展示阿美巴认知体系',
+ checkType: 'frontend',
+ checkPattern: 'src/app/page.tsx',
+ },
+ {
+ id: 'MH-020',
+ name: '阿美巴页面',
+ description: '路由: /about,展示阿美巴定位、使命',
+ checkType: 'frontend',
+ checkPattern: 'src/app/about/page.tsx',
+ },
+ {
+ id: 'MH-021',
+ name: '企业进化页面',
+ description: '路由: /evolution,展示企业进化定义',
+ checkType: 'frontend',
+ checkPattern: 'src/app/evolution/page.tsx',
+ },
+ {
+ id: 'MH-022',
+ name: '进化方法页面',
+ description: '路由: /evolution/method,展示方法论',
+ checkType: 'frontend',
+ checkPattern: 'src/app/evolution/method/page.tsx',
+ },
+ {
+ id: 'MH-023',
+ name: '四大价值页面',
+ description: '路由: /value,展示四大价值',
+ checkType: 'frontend',
+ checkPattern: 'src/app/value/page.tsx',
+ },
+ {
+ id: 'MH-024',
+ name: '价值创造页面',
+ description: '路由: /value/creation,展示价值创造',
+ checkType: 'frontend',
+ checkPattern: 'src/app/value/creation/page.tsx',
+ },
+ {
+ id: 'MH-025',
+ name: '价值传递页面',
+ description: '路由: /value/transfer,展示价值传递',
+ checkType: 'frontend',
+ checkPattern: 'src/app/value/transfer/page.tsx',
+ },
+ {
+ id: 'MH-026',
+ name: '价值交付页面',
+ description: '路由: /value/delivery,展示价值交付',
+ checkType: 'frontend',
+ checkPattern: 'src/app/value/delivery/page.tsx',
+ },
+ {
+ id: 'MH-027',
+ name: '价值支持页面',
+ description: '路由: /value/support,展示价值支持',
+ checkType: 'frontend',
+ checkPattern: 'src/app/value/support/page.tsx',
+ },
+ {
+ id: 'MH-028',
+ name: 'A/M-B总览页面',
+ description: '路由: /amb,展示三态模型',
+ checkType: 'frontend',
+ checkPattern: 'src/app/amb/page.tsx',
+ },
+ {
+ id: 'MH-029',
+ name: 'A态页面',
+ description: '路由: /amb/a,展示A态定义',
+ checkType: 'frontend',
+ checkPattern: 'src/app/amb/a/page.tsx',
+ },
+ {
+ id: 'MH-030',
+ name: 'M态页面',
+ description: '路由: /amb/m,展示M态定义',
+ checkType: 'frontend',
+ checkPattern: 'src/app/amb/m/page.tsx',
+ },
+ {
+ id: 'MH-031',
+ name: 'B态页面',
+ description: '路由: /amb/b,展示B态定义',
+ checkType: 'frontend',
+ checkPattern: 'src/app/amb/b/page.tsx',
+ },
+ {
+ id: 'MH-032',
+ name: '能力地图页面',
+ description: '路由: /capabilities,展示能力体系',
+ checkType: 'frontend',
+ checkPattern: 'src/app/capabilities/page.tsx',
+ },
+ {
+ id: 'MH-033',
+ name: '案例页面',
+ description: '路由: /cases,展示案例列表',
+ checkType: 'frontend',
+ checkPattern: 'src/app/cases/page.tsx',
+ },
+ {
+ id: 'MH-034',
+ name: '知识中心页面',
+ description: '路由: /knowledge,展示知识体系',
+ checkType: 'frontend',
+ checkPattern: 'src/app/knowledge/page.tsx',
+ },
+ {
+ id: 'MH-035',
+ name: '概念页面',
+ description: '路由: /concepts,展示概念列表',
+ checkType: 'frontend',
+ checkPattern: 'src/app/concepts/page.tsx',
+ },
+ {
+ id: 'MH-036',
+ name: 'FAQ页面',
+ description: '路由: /faq,展示常见问题',
+ checkType: 'frontend',
+ checkPattern: 'src/app/faq/page.tsx',
+ },
+ {
+ id: 'MH-037',
+ name: '企业需求与能力匹配页面',
+ description: '路由: /match,展示匹配结构',
+ checkType: 'frontend',
+ checkPattern: 'src/app/match/page.tsx',
+ },
+ {
+ id: 'MH-038',
+ name: '联系我们页面',
+ description: '路由: /contact,展示联系方式',
+ checkType: 'frontend',
+ checkPattern: 'src/app/contact/page.tsx',
+ },
+ {
+ id: 'MH-039',
+ name: 'sitemap.xml生成',
+ description: '自动生成sitemap.xml',
+ checkType: 'frontend',
+ checkPattern: 'src/app/sitemap.ts',
+ },
+ {
+ id: 'MH-040',
+ name: 'robots.txt生成',
+ description: '自动生成robots.txt',
+ checkType: 'frontend',
+ checkPattern: 'src/app/robots.ts',
+ },
+ {
+ id: 'MH-041',
+ name: 'SEO元数据',
+ description: 'title/description/canonical/Open Graph/Twitter Card',
+ checkType: 'frontend',
+ checkPattern: 'generateSEO',
+ },
+ {
+ id: 'MH-042',
+ name: '面包屑导航',
+ description: 'BreadcrumbList Schema',
+ checkType: 'frontend',
+ checkPattern: 'generateBreadcrumbSchema',
+ },
+ {
+ id: 'MH-043',
+ name: '结构化数据',
+ description: 'Organization/Article/FAQPage/Service Schema',
+ checkType: 'frontend',
+ checkPattern: 'JsonLd',
+ },
+ {
+ id: 'MH-044',
+ name: '单元测试',
+ description: 'Entity/Content/DirectedRelationship/EntityContentJoin模型测试',
+ checkType: 'test',
+ checkPattern: '.test.js',
+ },
+ {
+ id: 'MH-045',
+ name: 'AI认知测试集',
+ description: '实体认知用例、十问认知用例',
+ checkType: 'test',
+ checkPattern: 'ai_cognitive_testset.md',
+ },
+ {
+ id: 'MH-046',
+ name: '模拟抓取校验脚本',
+ description: '遍历sitemap、校验页面质量',
+ checkType: 'test',
+ checkPattern: 'crawler.js',
+ },
+ {
+ id: 'MH-047',
+ name: '内容边界隔离校验脚本',
+ description: '校验非published内容不可见',
+ checkType: 'test',
+ checkPattern: 'content_filter.js',
+ },
+ {
+ id: 'MH-048',
+ name: '十问认知基线校验模块',
+ description: '校验网站内容与标准答案一致性',
+ checkType: 'test',
+ checkPattern: 'ten_questions.js',
+ },
+ {
+ id: 'MH-049',
+ name: 'V1.0全项目盘点脚本',
+ description: '扫描代码、核查禁止项',
+ checkType: 'test',
+ checkPattern: 'project_audit.js',
+ },
+ {
+ id: 'MH-050',
+ name: '交付回执文档',
+ description: '数据表清单、关键接口清单、单元测试要点',
+ checkType: 'document',
+ checkPattern: 'DELIVERY_RECEIPT.md',
+ },
+];
+
+// V1.0明确不做清单
+const V10_DONT_DO = [
+ {
+ id: 'DD-001',
+ name: 'AI聊天机器人',
+ description: '不得开发AI聊天机器人功能',
+ checkPattern: ['chatbot', 'chat-bot', 'ai-chat', '聊天机器人'],
+ },
+ {
+ id: 'DD-002',
+ name: '在线诊断',
+ description: '不得开发在线诊断功能',
+ checkPattern: ['diagnosis', 'diagnostic', '在线诊断', '诊断工具'],
+ },
+ {
+ id: 'DD-003',
+ name: '自动评分',
+ description: '不得开发自动评分功能',
+ checkPattern: ['auto-score', '自动评分', '评分系统'],
+ },
+ {
+ id: 'DD-004',
+ name: 'AIO对接',
+ description: '不得预埋AIO对接接口',
+ checkPattern: ['aio', 'AIO', '企客通'],
+ },
+ {
+ id: 'DD-005',
+ name: 'CRM对接',
+ description: '不得预埋CRM对接接口',
+ checkPattern: ['crm', 'CRM', '客户关系管理'],
+ },
+ {
+ id: 'DD-006',
+ name: '商城功能',
+ description: '不得开发商城功能',
+ checkPattern: ['shop', '商城', '电商', 'payment', '支付'],
+ },
+ {
+ id: 'DD-007',
+ name: '自动获客',
+ description: '不得开发自动获客功能',
+ checkPattern: ['lead-generation', '自动获客', '获客系统'],
+ },
+ {
+ id: 'DD-008',
+ name: '第三方大模型API',
+ description: '不得对接第三方大模型API',
+ checkPattern: ['openai', 'gpt', 'claude', 'gemini', '大模型API'],
+ },
+ {
+ id: 'DD-009',
+ name: 'AI Agent能力',
+ description: '不得开发AI Agent能力',
+ checkPattern: ['agent', 'AI Agent', '智能代理'],
+ },
+ {
+ id: 'DD-010',
+ name: '浮夸科技视觉',
+ description: '不得使用机器人、粒子、科技蓝、3D、光效等元素',
+ checkPattern: ['particle', 'robot', '3d', 'glow', '科技蓝'],
+ },
+];
+
+/**
+ * 扫描文件内容
+ */
+function scanFileContent(filePath, patterns) {
+ const results = [];
+
+ try {
+ const content = fs.readFileSync(filePath, 'utf8');
+ const lines = content.split('\n');
+
+ patterns.forEach((pattern) => {
+ const regex = new RegExp(pattern, 'gi');
+ lines.forEach((line, index) => {
+ if (regex.test(line)) {
+ results.push({
+ file: filePath,
+ line: index + 1,
+ content: line.trim(),
+ pattern: pattern,
+ });
+ }
+ });
+ });
+ } catch (error) {
+ // 忽略读取错误
+ }
+
+ return results;
+}
+
+/**
+ * 扫描目录
+ */
+function scanDirectory(dir, patterns) {
+ const results = [];
+
+ try {
+ const items = fs.readdirSync(dir);
+
+ items.forEach((item) => {
+ const fullPath = path.join(dir, item);
+ const stat = fs.statSync(fullPath);
+
+ if (stat.isDirectory()) {
+ // 跳过node_modules和.next目录
+ if (item === 'node_modules' || item === '.next' || item === 'data') {
+ return;
+ }
+ results.push(...scanDirectory(fullPath, patterns));
+ } else if (stat.isFile()) {
+ // 只扫描代码文件
+ const ext = path.extname(item);
+ if (['.js', '.ts', '.tsx', '.jsx', '.json', '.md'].includes(ext)) {
+ results.push(...scanFileContent(fullPath, patterns));
+ }
+ }
+ });
+ } catch (error) {
+ // 忽略读取错误
+ }
+
+ return results;
+}
+
+/**
+ * 检查文件是否存在
+ */
+function checkFileExists(filePath) {
+ return fs.existsSync(filePath);
+}
+
+/**
+ * 检查目录是否存在
+ */
+function checkDirectoryExists(dirPath) {
+ return fs.existsSync(dirPath);
+}
+
+/**
+ * 盘点V1.0必须实现项
+ */
+function auditMustHave() {
+ console.log('\n=== 盘点V1.0必须实现项 ===');
+
+ const results = [];
+
+ V10_MUST_HAVE.forEach((item) => {
+ let found = false;
+ let details = '';
+
+ switch (item.checkType) {
+ case 'database':
+ // 检查数据库迁移文件
+ const migrateFile = path.join(CONFIG.projectRoot, 'src/database/migrate.js');
+ if (checkFileExists(migrateFile)) {
+ const scanResults = scanFileContent(migrateFile, [item.checkPattern]);
+ found = scanResults.length > 0;
+ details = found ? `在migrate.js中找到` : '未在migrate.js中找到';
+ } else {
+ details = 'migrate.js文件不存在';
+ }
+ break;
+
+ case 'api':
+ // 检查API路由文件
+ const routesDir = path.join(CONFIG.projectRoot, 'src/routes');
+ if (checkDirectoryExists(routesDir)) {
+ const scanResults = scanDirectory(routesDir, [item.checkPattern]);
+ found = scanResults.length > 0;
+ details = found ? `在路由文件中找到` : '未在路由文件中找到';
+ } else {
+ details = 'routes目录不存在';
+ }
+ break;
+
+ case 'frontend':
+ // 检查前端文件
+ const frontendDir = path.join(CONFIG.projectRoot, 'frontend');
+ if (checkDirectoryExists(frontendDir)) {
+ const scanResults = scanDirectory(frontendDir, [item.checkPattern]);
+ found = scanResults.length > 0;
+ details = found ? `在前端文件中找到` : '未在前端文件中找到';
+ } else {
+ details = 'frontend目录不存在';
+ }
+ break;
+
+ case 'test':
+ // 检查测试文件
+ const testsDir = path.join(CONFIG.projectRoot, 'tests');
+ if (checkDirectoryExists(testsDir)) {
+ const scanResults = scanDirectory(testsDir, [item.checkPattern]);
+ found = scanResults.length > 0;
+ details = found ? `在测试文件中找到` : '未在测试文件中找到';
+ } else {
+ details = 'tests目录不存在';
+ }
+ break;
+
+ case 'document':
+ // 检查文档
+ const docPath = path.join(CONFIG.projectRoot, item.checkPattern);
+ found = checkFileExists(docPath);
+ details = found ? '文档存在' : '文档不存在';
+ break;
+ }
+
+ results.push({
+ ...item,
+ status: found ? 'completed' : 'missing',
+ details: details,
+ });
+
+ console.log(`${found ? '✅' : '❌'} ${item.id}: ${item.name} - ${details}`);
+ });
+
+ return results;
+}
+
+/**
+ * 盘点V1.0明确不做项
+ */
+function auditDontDo() {
+ console.log('\n=== 盘点V1.0明确不做项 ===');
+
+ const results = [];
+
+ V10_DONT_DO.forEach((item) => {
+ const scanResults = scanDirectory(CONFIG.projectRoot, item.checkPattern);
+ const found = scanResults.length > 0;
+
+ results.push({
+ ...item,
+ status: found ? 'violation' : 'compliant',
+ details: found ? `发现${scanResults.length}处违规` : '未发现违规',
+ violations: found ? scanResults.slice(0, 5) : [], // 只保留前5个
+ });
+
+ console.log(`${found ? '❌' : '✅'} ${item.id}: ${item.name} - ${found ? '发现违规' : '合规'}`);
+ });
+
+ return results;
+}
+
+/**
+ * 生成盘点报告
+ */
+function generateReport(mustHaveResults, dontDoResults) {
+ // 创建报告目录
+ if (!fs.existsSync(CONFIG.outputDir)) {
+ fs.mkdirSync(CONFIG.outputDir, { recursive: true });
+ }
+
+ const reportPath = path.join(CONFIG.outputDir, 'project_audit_report.json');
+
+ // 统计
+ const summary = {
+ totalTime: new Date().toISOString(),
+ mustHave: {
+ total: mustHaveResults.length,
+ completed: mustHaveResults.filter((r) => r.status === 'completed').length,
+ missing: mustHaveResults.filter((r) => r.status === 'missing').length,
+ completionRate: 0,
+ },
+ dontDo: {
+ total: dontDoResults.length,
+ compliant: dontDoResults.filter((r) => r.status === 'compliant').length,
+ violation: dontDoResults.filter((r) => r.status === 'violation').length,
+ complianceRate: 0,
+ },
+ };
+
+ summary.mustHave.completionRate = summary.mustHave.total > 0
+ ? ((summary.mustHave.completed / summary.mustHave.total) * 100).toFixed(2) + '%'
+ : '0%';
+
+ summary.dontDo.complianceRate = summary.dontDo.total > 0
+ ? ((summary.dontDo.compliant / summary.dontDo.total) * 100).toFixed(2) + '%'
+ : '0%';
+
+ const reportContent = {
+ summary: summary,
+ mustHave: mustHaveResults,
+ dontDo: dontDoResults,
+ };
+
+ fs.writeFileSync(reportPath, JSON.stringify(reportContent, null, 2));
+
+ // 生成可读报告
+ const readableReportPath = path.join(CONFIG.outputDir, 'project_audit_report.md');
+ let readableReport = `# V1.0全项目盘点报告
+
+生成时间: ${new Date().toISOString()}
+
+## 摘要
+
+### V1.0必须实现项
+- 总数: ${summary.mustHave.total}
+- 已完成: ${summary.mustHave.completed}
+- 缺失: ${summary.mustHave.missing}
+- 完成率: ${summary.mustHave.completionRate}
+
+### V1.0明确不做项
+- 总数: ${summary.dontDo.total}
+- 合规: ${summary.dontDo.compliant}
+- 违规: ${summary.dontDo.violation}
+- 合规率: ${summary.dontDo.complianceRate}
+
+## V1.0必须实现项详情
+
+`;
+
+ mustHaveResults.forEach((item) => {
+ const statusIcon = item.status === 'completed' ? '✅' : '❌';
+ readableReport += `### ${statusIcon} ${item.id}: ${item.name}
+
+- 描述: ${item.description}
+- 状态: ${item.status === 'completed' ? '已完成' : '缺失'}
+- 详情: ${item.details}
+
+`;
+ });
+
+ readableReport += `## V1.0明确不做项详情
+
+`;
+
+ dontDoResults.forEach((item) => {
+ const statusIcon = item.status === 'compliant' ? '✅' : '❌';
+ readableReport += `### ${statusIcon} ${item.id}: ${item.name}
+
+- 描述: ${item.description}
+- 状态: ${item.status === 'compliant' ? '合规' : '违规'}
+- 详情: ${item.details}
+`;
+
+ if (item.violations && item.violations.length > 0) {
+ readableReport += `- 违规详情:
+`;
+ item.violations.forEach((violation) => {
+ readableReport += ` - ${violation.file}:${violation.line} - ${violation.content}
+`;
+ });
+ }
+
+ readableReport += '\n';
+ });
+
+ readableReport += `## 结论
+
+`;
+
+ if (summary.mustHave.missing === 0 && summary.dontDo.violation === 0) {
+ readableReport += '✅ V1.0所有必须实现项已完成,所有明确不做项合规\n';
+ } else {
+ if (summary.mustHave.missing > 0) {
+ readableReport += `❌ V1.0有${summary.mustHave.missing}项必须实现项缺失\n`;
+ }
+ if (summary.dontDo.violation > 0) {
+ readableReport += `❌ V1.0有${summary.dontDo.violation}项明确不做项违规\n`;
+ }
+ }
+
+ fs.writeFileSync(readableReportPath, readableReport);
+
+ console.log(`报告已生成:`);
+ console.log(` - JSON报告: ${reportPath}`);
+ console.log(` - 可读报告: ${readableReportPath}`);
+}
+
+/**
+ * 主函数
+ */
+function main() {
+ console.log('开始V1.0全项目盘点...');
+ console.log(`项目根目录: ${CONFIG.projectRoot}`);
+
+ // 盘点必须实现项
+ const mustHaveResults = auditMustHave();
+
+ // 盘点明确不做项
+ const dontDoResults = auditDontDo();
+
+ // 生成报告
+ console.log('\n正在生成报告...');
+ generateReport(mustHaveResults, dontDoResults);
+
+ // 统计结果
+ const mustHaveCompleted = mustHaveResults.filter((r) => r.status === 'completed').length;
+ const mustHaveMissing = mustHaveResults.filter((r) => r.status === 'missing').length;
+ const dontDoCompliant = dontDoResults.filter((r) => r.status === 'compliant').length;
+ const dontDoViolation = dontDoResults.filter((r) => r.status === 'violation').length;
+
+ console.log('\n盘点完成!');
+ console.log(`必须实现项: ${mustHaveCompleted}/${mustHaveResults.length} 完成`);
+ console.log(`明确不做项: ${dontDoCompliant}/${dontDoResults.length} 合规`);
+
+ // 返回结果
+ return {
+ mustHave: mustHaveResults,
+ dontDo: dontDoResults,
+ };
+}
+
+// 如果直接运行此脚本
+if (require.main === module) {
+ main();
+}
+
+module.exports = {
+ main,
+ auditMustHave,
+ auditDontDo,
+ V10_MUST_HAVE,
+ V10_DONT_DO,
+ CONFIG,
+};
\ No newline at end of file