From e1c935e06f11dd790dee9badbe5f14aa6a8c2933 Mon Sep 17 00:00:00 2001 From: leiyun Date: Thu, 12 Feb 2026 00:33:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=89=8D=E5=8F=B0=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20-=20=E5=85=A8=E5=B1=8F=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E3=80=81Banner=E8=BD=AE=E6=92=AD=E3=80=81=E6=8D=90=E8=B5=A0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E3=80=81=E5=85=AC=E7=9B=8A=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E3=80=81=E6=96=B0=E9=97=BB=E5=8A=A8=E6=80=81=E3=80=81=E5=90=88?= =?UTF-8?q?=E4=BD=9C=E4=BC=99=E4=BC=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc | 3 + .gitignore | 37 + .kiro/steering/project.md | 155 + .kiro/steering/thinkjs.md | 246 + README.md | 22 + development.js | 12 + nginx.conf | 30 + package.json | 53 + pm2.json | 15 + pnpm-lock.yaml | 7539 ++++++++++++++++++++++ production.js | 11 + sql/init.sql | 85 + sql/update_20260211_article.sql | 34 + sql/update_20260211_banner.sql | 31 + sql/update_20260211_column.sql | 74 + sql/update_20260211_config.sql | 45 + sql/update_20260211_donation.sql | 49 + sql/update_20260211_image.sql | 25 + sql/update_20260211_job.sql | 26 + sql/update_20260211_medicine.sql | 44 + sql/update_20260211_page.sql | 13 + sql/update_20260211_person.sql | 28 + sql/update_20260211_role.sql | 14 + sql/update_20260211_text.sql | 28 + src/bootstrap/master.js | 1 + src/bootstrap/worker.js | 1 + src/config/adapter.js | 110 + src/config/adapter.production.js | 46 + src/config/config.js | 6 + src/config/config.production.js | 4 + src/config/cos.js | 39 + src/config/extend.js | 11 + src/config/middleware.js | 40 + src/config/router.js | 121 + src/controller/admin/auth.js | 52 + src/controller/admin/content/article.js | 129 + src/controller/admin/content/banner.js | 117 + src/controller/admin/content/donation.js | 215 + src/controller/admin/content/image.js | 94 + src/controller/admin/content/job.js | 100 + src/controller/admin/content/page.js | 67 + src/controller/admin/content/person.js | 117 + src/controller/admin/content/text.js | 113 + src/controller/admin/dashboard.js | 37 + src/controller/admin/data/medicine.js | 94 + src/controller/admin/system/column.js | 136 + src/controller/admin/system/config.js | 46 + src/controller/admin/system/role.js | 305 + src/controller/admin/system/user.js | 221 + src/controller/admin/upload.js | 306 + src/controller/base.js | 137 + src/controller/index.js | 117 + src/logic/index.js | 5 + src/model/article.js | 5 + src/model/banner.js | 5 + src/model/column.js | 5 + src/model/config.js | 56 + src/model/donation.js | 5 + src/model/donation_stat.js | 5 + src/model/image.js | 5 + src/model/index.js | 3 + src/model/job.js | 5 + src/model/medicine.js | 5 + src/model/page.js | 5 + src/model/person.js | 5 + src/model/text.js | 5 + test/index.js | 7 + view/admin/auth_login.html | 219 + view/admin/common/_header.html | 41 + view/admin/common/_sidebar.html | 117 + view/admin/content/article_index.html | 436 ++ view/admin/content/banner_index.html | 369 ++ view/admin/content/donation_index.html | 384 ++ view/admin/content/image_index.html | 260 + view/admin/content/job_index.html | 211 + view/admin/content/page_index.html | 198 + view/admin/content/person_index.html | 304 + view/admin/content/text_index.html | 309 + view/admin/dashboard_index.html | 207 + view/admin/data/medicine_index.html | 306 + view/admin/layout.html | 68 + view/admin/system/column_index.html | 428 ++ view/admin/system/config_index.html | 281 + view/admin/system/role_index.html | 290 + view/admin/system/user_index.html | 329 + view/common/_footer.html | 47 + view/common/_header.html | 67 + view/index_index.html | 384 ++ view/layout.html | 56 + www/static/css/.gitkeep | 0 www/static/css/admin.css | 198 + www/static/css/web.css | 554 ++ www/static/image/.gitkeep | 0 www/static/images/logo.png | Bin 0 -> 51026 bytes www/static/js/.gitkeep | 0 95 files changed, 17590 insertions(+) create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 .kiro/steering/project.md create mode 100644 .kiro/steering/thinkjs.md create mode 100644 README.md create mode 100644 development.js create mode 100644 nginx.conf create mode 100644 package.json create mode 100644 pm2.json create mode 100644 pnpm-lock.yaml create mode 100644 production.js create mode 100644 sql/init.sql create mode 100644 sql/update_20260211_article.sql create mode 100644 sql/update_20260211_banner.sql create mode 100644 sql/update_20260211_column.sql create mode 100644 sql/update_20260211_config.sql create mode 100644 sql/update_20260211_donation.sql create mode 100644 sql/update_20260211_image.sql create mode 100644 sql/update_20260211_job.sql create mode 100644 sql/update_20260211_medicine.sql create mode 100644 sql/update_20260211_page.sql create mode 100644 sql/update_20260211_person.sql create mode 100644 sql/update_20260211_role.sql create mode 100644 sql/update_20260211_text.sql create mode 100644 src/bootstrap/master.js create mode 100644 src/bootstrap/worker.js create mode 100644 src/config/adapter.js create mode 100644 src/config/adapter.production.js create mode 100644 src/config/config.js create mode 100644 src/config/config.production.js create mode 100644 src/config/cos.js create mode 100644 src/config/extend.js create mode 100644 src/config/middleware.js create mode 100644 src/config/router.js create mode 100644 src/controller/admin/auth.js create mode 100644 src/controller/admin/content/article.js create mode 100644 src/controller/admin/content/banner.js create mode 100644 src/controller/admin/content/donation.js create mode 100644 src/controller/admin/content/image.js create mode 100644 src/controller/admin/content/job.js create mode 100644 src/controller/admin/content/page.js create mode 100644 src/controller/admin/content/person.js create mode 100644 src/controller/admin/content/text.js create mode 100644 src/controller/admin/dashboard.js create mode 100644 src/controller/admin/data/medicine.js create mode 100644 src/controller/admin/system/column.js create mode 100644 src/controller/admin/system/config.js create mode 100644 src/controller/admin/system/role.js create mode 100644 src/controller/admin/system/user.js create mode 100644 src/controller/admin/upload.js create mode 100644 src/controller/base.js create mode 100644 src/controller/index.js create mode 100644 src/logic/index.js create mode 100644 src/model/article.js create mode 100644 src/model/banner.js create mode 100644 src/model/column.js create mode 100644 src/model/config.js create mode 100644 src/model/donation.js create mode 100644 src/model/donation_stat.js create mode 100644 src/model/image.js create mode 100644 src/model/index.js create mode 100644 src/model/job.js create mode 100644 src/model/medicine.js create mode 100644 src/model/page.js create mode 100644 src/model/person.js create mode 100644 src/model/text.js create mode 100644 test/index.js create mode 100644 view/admin/auth_login.html create mode 100644 view/admin/common/_header.html create mode 100644 view/admin/common/_sidebar.html create mode 100644 view/admin/content/article_index.html create mode 100644 view/admin/content/banner_index.html create mode 100644 view/admin/content/donation_index.html create mode 100644 view/admin/content/image_index.html create mode 100644 view/admin/content/job_index.html create mode 100644 view/admin/content/page_index.html create mode 100644 view/admin/content/person_index.html create mode 100644 view/admin/content/text_index.html create mode 100644 view/admin/dashboard_index.html create mode 100644 view/admin/data/medicine_index.html create mode 100644 view/admin/layout.html create mode 100644 view/admin/system/column_index.html create mode 100644 view/admin/system/config_index.html create mode 100644 view/admin/system/role_index.html create mode 100644 view/admin/system/user_index.html create mode 100644 view/common/_footer.html create mode 100644 view/common/_header.html create mode 100644 view/index_index.html create mode 100644 view/layout.html create mode 100644 www/static/css/.gitkeep create mode 100644 www/static/css/admin.css create mode 100644 www/static/css/web.css create mode 100644 www/static/image/.gitkeep create mode 100644 www/static/images/logo.png create mode 100644 www/static/js/.gitkeep diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..3b1360e --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "think" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb446e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage/ + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules/ + +# IDE config +.idea + +# output +output/ +output.tar.gz + +runtime/ +app/ + +config.development.js +adapter.development.js diff --git a/.kiro/steering/project.md b/.kiro/steering/project.md new file mode 100644 index 0000000..2ca104d --- /dev/null +++ b/.kiro/steering/project.md @@ -0,0 +1,155 @@ +# 北京维康慈善基金会官网项目 + +## 项目概述 + +这是北京维康慈善基金会官方网站项目,基于 ThinkJS 3.x 框架开发。项目包含前台官网展示和后台管理系统两部分。 + +## 技术栈 + +- 后端框架:ThinkJS 3.x (Node.js) +- 模板引擎:Nunjucks +- 数据库:MySQL +- 缓存:文件缓存 (think-cache-file) +- 会话:文件会话 (think-session-file) +- 进程管理:PM2 + +## 项目结构 + +``` +pap_web/ +├── src/ +│ ├── bootstrap/ # 启动配置 (master/worker) +│ ├── config/ # 配置文件 +│ │ ├── adapter.js # 适配器配置 +│ │ ├── config.js # 基础配置 +│ │ ├── middleware.js # 中间件配置 +│ │ └── router.js # 路由配置 +│ ├── controller/ # 控制器 +│ ├── logic/ # 逻辑层 (参数校验) +│ └── model/ # 数据模型 +├── view/ # 视图模板 (Nunjucks) +├── www/static/ # 静态资源 +└── runtime/ # 运行时文件 +``` + +## 原型参考 + +项目原型位于 `pap_web_pm` 目录: + +- `pap_web_pm/web/` - 前台官网原型 +- `pap_web_pm/admin/` - 后台管理原型 + +## 功能模块 + +### 前台官网 + +| 栏目 | 子栏目 | +|------|--------| +| 首页 | Banner轮播、数据看板、药品援助公示、公益项目、新闻动态、合作伙伴 | +| 关于我们 | 基金会简介、组织架构、理事会&监事、资质证书、联系我们 | +| 公益项目 | 妇幼健康促进、"安心医"患者关爱、卫生健康促进、医疗科普公益、品牌建设与传播 | +| 党建专栏 | 党建规章、党建活动、党建学习 | +| 信息公示 | 管理制度、机构年报、审计报告、财务报告、关联方信息、项目执行报告 | +| 新闻中心 | 基金会动态、行业资讯、通知公告 | +| 联系我们 | 基本信息、关注我们、人才招聘、志愿者中心、合作申请 | + +### 后台管理 + +- 控制台 (Dashboard) +- 内容管理 (文章、图片、文本、页面、人员) +- 数据管理 (药品援助记录、捐赠数据) +- 系统设置 (栏目管理、网站配置、用户管理、角色权限、操作日志) + +## 内容类型映射 + +| 类型 | 说明 | 管理页面 | +|------|------|----------| +| article | 文章内容 | article-list.html | +| image | 图片内容 | image-list.html | +| text | 文本/文档 | text-list.html | +| page | 单页内容 | page-manage.html | +| person | 人员信息 | person-list.html | +| form | 表单数据 | form-data.html | +| donation | 捐赠数据 | donation.html | +| job | 招聘信息 | job-manage.html | + +## 开发规范 + +### 前端组件规范 (Element Plus + Vue 3) + +- `el-table-column` 必须使用完整闭合标签,不能使用自闭合: + - 正确:`` + - 错误:`` +- Vue 3 使用 CDN 引入时,delimiters 设置为 `['${', '}']` 避免与 Nunjucks 冲突 +- Element Plus 组件使用 `ElementPlus.ElMessage` 和 `ElementPlus.ElMessageBox` + +### 路由规范 + +- 前端页面跳转 (`window.location.href`、``) 加 `.html` 后缀,如 `/admin/login.html`、`/admin/dashboard.html` +- 后端 `this.redirect()` 也加 `.html` 后缀 +- `router.js` 路由配置不加 `.html` +- API 接口路径不加后缀,如 `/admin/auth/login` + +### 命名约定 + +- Controller: 小写,如 `index.js` +- Model: 小写,如 `article.js` +- View: `{controller}_{action}.html`,如 `index_index.html` +- 路由: RESTful 风格 + +### 代码风格 + +- 使用 ESLint 进行代码检查 +- 运行 `npm run lint` 检查代码 +- 运行 `npm run lint-fix` 自动修复 + +### 常用命令 + +```bash +# 开发环境启动 +npm start + +# 代码检查 +npm run lint + +# 生产环境部署 +pm2 startOrReload pm2.json +``` + +## 数据库设计建议 + +### 核心表 + +- `column` - 栏目表 +- `article` - 文章表 +- `image` - 图片表 +- `page` - 单页表 +- `person` - 人员表 +- `donation` - 捐赠记录表 +- `medicine_aid` - 药品援助记录表 +- `job` - 招聘信息表 +- `form_data` - 表单提交数据表 +- `user` - 管理员用户表 +- `role` - 角色表 +- `log` - 操作日志表 +- `config` - 网站配置表 + +### 通用字段规范 +- `is_deleted`: 软删除 (0=正常, 1=已删除) +- `status`: 状态 (1=启用, 0=停用) +- `create_by/update_by`: 创建人/修改人ID +- `create_time/update_time`: 创建/更新时间 +- JSON字段存储多选值 (如 `disease_ids`, `delivery_methods`) +- 生成的sql文件放到sql文件夹 + +## 注意事项 + +1. 所有涉及金额的字段使用 DECIMAL 类型 +2. 患者姓名等敏感信息需脱敏处理显示 +3. 图片上传需限制大小和格式 +4. 后台操作需记录日志 +5. 前台页面需考虑 SEO 优化 + +## 生成说明 +- 无特殊要求,请使用中文回复 +- 无特殊要求,不要生成说明文档 diff --git a/.kiro/steering/thinkjs.md b/.kiro/steering/thinkjs.md new file mode 100644 index 0000000..e7cbad9 --- /dev/null +++ b/.kiro/steering/thinkjs.md @@ -0,0 +1,246 @@ +# ThinkJS 开发指南 + +## 框架简介 + +ThinkJS 是一个基于 Koa 2.x 的 Node.js MVC 框架,支持 ES6/7 特性,使用 async/await 处理异步。 + +## 目录结构说明 + +### src/config/ + +- `config.js` - 通用配置 +- `config.production.js` - 生产环境配置(会覆盖 config.js) +- `adapter.js` - 适配器配置(数据库、缓存、会话等) +- `router.js` - 自定义路由 +- `middleware.js` - 中间件配置 +- `extend.js` - 扩展配置 + +### src/controller/ + +控制器目录,处理用户请求。 + +```javascript +// src/controller/index.js +module.exports = class extends think.Controller { + async indexAction() { + // 获取参数 + const id = this.get('id'); + const data = this.post(); + + // 调用 model + const list = await this.model('article').select(); + + // 渲染模板 + this.assign('list', list); + return this.display(); + } +}; +``` + +### src/model/ + +数据模型目录,操作数据库。 + +```javascript +// src/model/article.js +module.exports = class extends think.Model { + // 获取文章列表 + async getList(columnId, page = 1, pageSize = 10) { + return this.where({ column_id: columnId, status: 1 }) + .order('create_time DESC') + .page(page, pageSize) + .countSelect(); + } +}; +``` + +### src/logic/ + +逻辑层,用于参数校验。 + +```javascript +// src/logic/article.js +module.exports = class extends think.Logic { + indexAction() { + this.allowMethods = 'get'; + this.rules = { + id: { int: true, required: true } + }; + } +}; +``` + +## 常用 API + +### Controller + +```javascript +// 获取参数 +this.get('name'); // GET 参数 +this.post('name'); // POST 参数 +this.param('name'); // GET + POST +this.file('upload'); // 上传文件 + +// 响应 +this.success(data); // JSON 成功响应 +this.fail(errno, errmsg); // JSON 失败响应 +this.json(data); // JSON 响应 +this.redirect(url); // 重定向 + +// 模板 +this.assign('key', value); // 赋值 +this.display(); // 渲染模板 + +// Session +await this.session('user'); // 获取 +await this.session('user', data); // 设置 + +// Cookie +this.cookie('name'); // 获取 +this.cookie('name', value); // 设置 +``` + +### Model + +```javascript +const model = this.model('article'); + +// 查询 +model.where({ id: 1 }).find(); // 单条 +model.where({ status: 1 }).select(); // 多条 +model.where({ status: 1 }).count(); // 计数 +model.page(1, 10).countSelect(); // 分页 + +// 新增 +model.add({ title: 'xxx', content: 'xxx' }); +model.addMany([{...}, {...}]); + +// 更新 +model.where({ id: 1 }).update({ title: 'new' }); + +// 删除 +model.where({ id: 1 }).delete(); + +// 链式调用 +model.field('id, title') + .where({ status: 1 }) + .order('id DESC') + .limit(10) + .select(); +``` + +## 路由配置 + +```javascript +// src/config/router.js +module.exports = [ + // [匹配规则, 'controller/action', method] + ['/article/:id', 'article/detail', 'get'], + ['/api/article', 'api/article', 'rest'], + ['/admin/:controller/:action?', 'admin/:controller/:action'], +]; +``` + +## 中间件 + +```javascript +// src/config/middleware.js +module.exports = [ + { + handle: 'meta', + options: { logRequest: true } + }, + { + handle: 'resource', + enable: true + }, + 'trace', + 'payload', + 'router', + 'logic', + 'controller' +]; +``` + +## 数据库配置 + +```javascript +// src/config/adapter.js +exports.model = { + type: 'mysql', + common: { + logConnect: true, + logSql: true, + logger: msg => think.logger.info(msg) + }, + mysql: { + handle: mysql, + database: 'pap_web', + prefix: 'pap_', + encoding: 'utf8mb4', + host: '127.0.0.1', + port: '3306', + user: 'root', + password: '', + dateStrings: true + } +}; +``` + +## 视图模板 (Nunjucks) + +```html + +{% extends "layout.html" %} + +{% block content %} +
    + {% for item in list %} +
  • {{ item.title }}
  • + {% endfor %} +
+ +{% if pagination.totalPages > 1 %} + +{% endif %} +{% endblock %} +``` + +## 常见问题 + +### 跨域处理 + +```javascript +// src/config/middleware.js 添加 +{ + handle: 'cors', + options: { + origin: '*', + credentials: true + } +} +``` + +### 文件上传 + +```javascript +// controller +const file = this.file('image'); +if (file) { + const filepath = file.path; + // 移动文件到目标目录 + think.fs.move(filepath, targetPath); +} +``` + +### 事务处理 + +```javascript +const model = this.model('article'); +await model.transaction(async () => { + await model.add(data1); + await this.model('log').add(data2); +}); +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee90448 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ + +Application created by [ThinkJS](http://www.thinkjs.org) + +## Install dependencies + +``` +npm install +``` + +## Start server + +``` +npm start +``` + +## Deploy with pm2 + +Use pm2 to deploy app on production enviroment. + +``` +pm2 startOrReload pm2.json +``` \ No newline at end of file diff --git a/development.js b/development.js new file mode 100644 index 0000000..b4bd1b8 --- /dev/null +++ b/development.js @@ -0,0 +1,12 @@ +const path = require('path'); +const Application = require('thinkjs'); +const watcher = require('think-watcher'); + +const instance = new Application({ + ROOT_PATH: __dirname, + APP_PATH: path.join(__dirname, 'src'), + watcher: watcher, + env: 'development' +}); + +instance.run(); diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..c7854e9 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,30 @@ +server { + listen 80; + server_name example.com www.example.com; + root E:\PAP\project_web\pap_web_pm\pap_web; + set $node_port 8360; + + index index.js index.html index.htm; + if ( -f $request_filename/index.html ){ + rewrite (.*) $1/index.html break; + } + if ( !-f $request_filename ){ + rewrite (.*) /index.js; + } + location = /index.js { + proxy_http_version 1.1; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://127.0.0.1:$node_port$request_uri; + proxy_redirect off; + } + + location ~ /static/ { + etag on; + expires max; + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..bd74538 --- /dev/null +++ b/package.json @@ -0,0 +1,53 @@ +{ + "name": "pap_web", + "description": "application created by thinkjs", + "version": "1.0.0", + "author": "leiyun ", + "scripts": { + "start": "node development.js", + "test": "THINK_UNIT_TEST=1 nyc ava test/ && nyc report --reporter=html", + "lint": "eslint src/", + "lint-fix": "eslint --fix src/" + }, + "dependencies": { + "cos-nodejs-sdk-v5": "^2.14.0", + "jsonwebtoken": "^9.0.3", + "sharp": "^0.33.0", + "think-cache": "^1.0.0", + "think-cache-file": "^1.0.8", + "think-cache-redis": "^1.2.6", + "think-logger3": "^1.0.0", + "think-model": "^1.0.0", + "think-model-mysql": "^1.0.0", + "think-session": "^1.0.0", + "think-session-file": "^1.0.5", + "think-view": "^1.0.0", + "think-view-nunjucks": "^1.0.1", + "thinkjs": "^3.0.0" + }, + "devDependencies": { + "ava": "^0.18.0", + "eslint": "^4.2.0", + "eslint-config-think": "^1.0.0", + "nyc": "^7.0.0", + "think-watcher": "^3.0.0" + }, + "repository": "", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + }, + "readmeFilename": "README.md", + "thinkjs": { + "metadata": { + "name": "pap_web", + "description": "application created by thinkjs", + "author": "leiyun ", + "babel": false + }, + "projectName": "pap_web", + "template": "D:\\Program Files\\nvm\\nvm\\v24.10.0\\node_modules\\think-cli\\default_template", + "clone": false, + "isMultiModule": false + } +} \ No newline at end of file diff --git a/pm2.json b/pm2.json new file mode 100644 index 0000000..9aca5ae --- /dev/null +++ b/pm2.json @@ -0,0 +1,15 @@ +{ + "apps": [{ + "name": "pap_web", + "script": "production.js", + "cwd": "E:\PAP\project_web\pap_web_pm\pap_web", + "exec_mode": "fork", + "max_memory_restart": "1G", + "autorestart": true, + "node_args": [], + "args": [], + "env": { + + } + }] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..7769980 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,7539 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + cos-nodejs-sdk-v5: + specifier: ^2.14.0 + version: 2.15.4 + jsonwebtoken: + specifier: ^9.0.3 + version: 9.0.3 + sharp: + specifier: ^0.33.0 + version: 0.33.5 + think-cache: + specifier: ^1.0.0 + version: 1.1.2 + think-cache-file: + specifier: ^1.0.8 + version: 1.1.2 + think-cache-redis: + specifier: ^1.2.6 + version: 1.2.6 + think-logger3: + specifier: ^1.0.0 + version: 1.4.0 + think-model: + specifier: ^1.0.0 + version: 1.5.4 + think-model-mysql: + specifier: ^1.0.0 + version: 1.1.7 + think-session: + specifier: ^1.0.0 + version: 1.1.6 + think-session-file: + specifier: ^1.0.5 + version: 1.1.4 + think-view: + specifier: ^1.0.0 + version: 1.0.13 + think-view-nunjucks: + specifier: ^1.0.1 + version: 1.0.11 + thinkjs: + specifier: ^3.0.0 + version: 3.2.15 + devDependencies: + ava: + specifier: ^0.18.0 + version: 0.18.2 + eslint: + specifier: ^4.2.0 + version: 4.19.1 + eslint-config-think: + specifier: ^1.0.0 + version: 1.0.3(eslint@4.19.1) + nyc: + specifier: ^7.0.0 + version: 7.1.0 + think-watcher: + specifier: ^3.0.0 + version: 3.0.4 + +packages: + + '@ava/babel-preset-stage-4@1.1.0': + resolution: {integrity: sha512-oWqTnIGXW3k72UFidXzW0ONlO7hnO9x02S/QReJ7NBGeiBH9cUHY9+EfV6C8PXC6YJH++WrliEq03wMSJGNZFg==} + engines: {node: '>=4'} + + '@ava/babel-preset-transform-test-files@2.0.1': + resolution: {integrity: sha512-IWDAF+UbrlMEF3Uacb8eXBOlzBWjSnZw/dlDFmQ/C6wFjQGDHz3GXj+sBWVUMxKqFvll7sgIjeQID0lQBH//Zw==} + engines: {node: '>=4'} + + '@ava/pretty-format@1.1.0': + resolution: {integrity: sha512-dUfHVmktEiqWtSJWGjI3GohO5rNZm6FLBYLN8Fx9cOf8SjYyFuxuvn3u9NLHoaZR63O/7uBv/Uf0VNEYgNJZCA==} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/node@25.2.3': + resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + a-sync-waterfall@1.0.1: + resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@3.0.1: + resolution: {integrity: sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==} + + acorn@3.3.0: + resolution: {integrity: sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@5.7.4: + resolution: {integrity: sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-formats@1.6.1: + resolution: {integrity: sha512-4CjkH20If1lhR5CGtqkrVg3bbOtFEG80X9v6jDOIUhbzzbB+UzPBGy8GQhUNVZ0yvMHdMpawCOcy5ydGMsagGQ==} + peerDependencies: + ajv: ^7.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@2.1.1: + resolution: {integrity: sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==} + peerDependencies: + ajv: ^5.0.0 + + ajv@5.5.2: + resolution: {integrity: sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@7.2.4: + resolution: {integrity: sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A==} + + ansi-align@1.1.0: + resolution: {integrity: sha512-ncgIO/ZeFcsh3cye0NgGPb5h/3vCiKJxp6HvPtqsFvEL/4b/G2tNgrr8EOYN5RSVnGx69k8dFYSBG/w1yKX58Q==} + + ansi-escapes@3.2.0: + resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} + engines: {node: '>=4'} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-styles@1.0.0: + resolution: {integrity: sha512-3iF4FIKdxaVYT3JqQuY3Wat/T2t7TRbbQ94Fu50ZUCbLy4TFbTzr90NOHQodQkNqmeEGCw8WbeP78WNi6SKYUA==} + engines: {node: '>=0.8.0'} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@1.3.2: + resolution: {integrity: sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + arr-diff@2.0.0: + resolution: {integrity: sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==} + engines: {node: '>=0.10.0'} + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-exclude@1.0.0: + resolution: {integrity: sha512-TiXbMMkPQNfoHcVi6jeU6IejGAFlcn0hYgVVe7tCiqL/ZtxbNkhDSMarUQjg/PAe9NQNvRd6YCVNutzo3Fxdug==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-differ@1.0.0: + resolution: {integrity: sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==} + engines: {node: '>=0.10.0'} + + array-find-index@1.0.2: + resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} + engines: {node: '>=0.10.0'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + array-unique@0.2.1: + resolution: {integrity: sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==} + engines: {node: '>=0.10.0'} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + async-each@1.0.6: + resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + atomically@1.7.0: + resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} + engines: {node: '>=10.12.0'} + + auto-bind@1.2.1: + resolution: {integrity: sha512-/W9yj1yKmBLwpexwAujeD9YHwYmRuWFGV8HWE7smQab797VeHa4/cnE2NFeDhA+E+5e/OGBI8763EhLjfZ/MXA==} + engines: {node: '>=4'} + + ava-init@0.2.1: + resolution: {integrity: sha512-lXwK5LM+2g1euDRqW1mcSX/tqzY1QU7EjKpqayFPPtNRmbSYZ8RzPO5tqluTToijmtjp2M+pNpVdbcHssC4glg==} + engines: {node: '>=4'} + + ava@0.18.2: + resolution: {integrity: sha512-uarnGkAe6sHTY1srbC6/Pa2bJdpeeECSaiqaAJPCaFa+YrBPlVsso/cee174OWtGLv2o2Mz6flZvSs52BXHfcA==} + engines: {node: '>=4'} + hasBin: true + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + + babel-code-frame@6.26.0: + resolution: {integrity: sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==} + + babel-core@6.26.3: + resolution: {integrity: sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==} + + babel-eslint@10.1.0: + resolution: {integrity: sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==} + engines: {node: '>=6'} + deprecated: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates. + peerDependencies: + eslint: '>= 4.12.1' + + babel-generator@6.26.1: + resolution: {integrity: sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==} + + babel-helper-builder-binary-assignment-operator-visitor@6.24.1: + resolution: {integrity: sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==} + + babel-helper-call-delegate@6.24.1: + resolution: {integrity: sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==} + + babel-helper-explode-assignable-expression@6.24.1: + resolution: {integrity: sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==} + + babel-helper-function-name@6.24.1: + resolution: {integrity: sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==} + + babel-helper-get-function-arity@6.24.1: + resolution: {integrity: sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==} + + babel-helper-hoist-variables@6.24.1: + resolution: {integrity: sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==} + + babel-helper-regex@6.26.0: + resolution: {integrity: sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==} + + babel-helper-remap-async-to-generator@6.24.1: + resolution: {integrity: sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==} + + babel-helpers@6.24.1: + resolution: {integrity: sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==} + + babel-messages@6.23.0: + resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} + + babel-plugin-ava-throws-helper@1.0.0: + resolution: {integrity: sha512-+cUf3TWqZSLwhQ0OzgBM+0kCoooEsDp0/2RvBRNV7Qx/FkD2mItzvJtj0WdDcCJF+QgIexuPYH7bYw6vX7fJDw==} + engines: {node: '>=4'} + + babel-plugin-check-es2015-constants@6.22.0: + resolution: {integrity: sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==} + + babel-plugin-espower@2.4.0: + resolution: {integrity: sha512-/+SRpy7pKgTI28oEHfn1wkuM5QFAdRq8WNsOOih1dVrdV6A/WbNbRZyl0eX5eyDgtb0lOE27PeDFuCX2j8OxVg==} + + babel-plugin-syntax-async-functions@6.13.0: + resolution: {integrity: sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==} + + babel-plugin-syntax-exponentiation-operator@6.13.0: + resolution: {integrity: sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==} + + babel-plugin-syntax-trailing-function-commas@6.22.0: + resolution: {integrity: sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==} + + babel-plugin-transform-async-to-generator@6.24.1: + resolution: {integrity: sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==} + + babel-plugin-transform-es2015-destructuring@6.23.0: + resolution: {integrity: sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==} + + babel-plugin-transform-es2015-function-name@6.24.1: + resolution: {integrity: sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==} + + babel-plugin-transform-es2015-modules-commonjs@6.26.2: + resolution: {integrity: sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==} + + babel-plugin-transform-es2015-parameters@6.24.1: + resolution: {integrity: sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==} + + babel-plugin-transform-es2015-spread@6.22.0: + resolution: {integrity: sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==} + + babel-plugin-transform-es2015-sticky-regex@6.24.1: + resolution: {integrity: sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==} + + babel-plugin-transform-es2015-unicode-regex@6.24.1: + resolution: {integrity: sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==} + + babel-plugin-transform-exponentiation-operator@6.24.1: + resolution: {integrity: sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==} + + babel-plugin-transform-strict-mode@6.24.1: + resolution: {integrity: sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==} + + babel-register@6.26.0: + resolution: {integrity: sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==} + + babel-runtime@6.26.0: + resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} + + babel-template@6.26.0: + resolution: {integrity: sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==} + + babel-traverse@6.26.0: + resolution: {integrity: sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==} + + babel-types@6.26.0: + resolution: {integrity: sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==} + + babylon@6.18.0: + resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==} + hasBin: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bignumber.js@9.0.0: + resolution: {integrity: sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==} + + binary-extensions@1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + boxen@0.6.0: + resolution: {integrity: sha512-yL8sYzt0avlYGOY6LqtECkGrJOY3cCLAbFPaNfgE+4fD45ZrdYqLdY8yF4bqyTkpfW9e6W0YqBkN7dIn/PrZoA==} + engines: {node: '>=0.10.0'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + braces@1.8.5: + resolution: {integrity: sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==} + engines: {node: '>=0.10.0'} + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + buf-compare@1.0.1: + resolution: {integrity: sha512-Bvx4xH00qweepGc43xFvMs5BKASXTbHaHm6+kDYIK9p/4iFwjATQkmPKHQSgJZzKbAymhztRbXUf1Nqhzl73/Q==} + engines: {node: '>=0.10.0'} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + cache-content-type@1.0.1: + resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} + engines: {node: '>= 6.0.0'} + + caching-transform@1.0.1: + resolution: {integrity: sha512-TYu6IoS+HzPivTKBDbGbkdNE7V3GP9ETNuO1L901jhtIdmMmE4S5SXxXvIMPt4+poeqSGY47NQz1GFh3toDHqw==} + engines: {node: '>=0.10.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + call-matcher@1.1.0: + resolution: {integrity: sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw==} + + call-signature@0.0.2: + resolution: {integrity: sha512-qvYvkAVcoae0obt8OsZn0VEBHeEpvYIZDy1gGYtZDJG0fHawew+Mi0dBjieFz8F8dzQ2Kr19+nsDm+T5XFVs+Q==} + engines: {node: '>=0.10.0'} + + caller-path@0.1.0: + resolution: {integrity: sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==} + engines: {node: '>=0.10.0'} + + callsites@0.2.0: + resolution: {integrity: sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==} + engines: {node: '>=0.10.0'} + + camelcase-keys@2.1.0: + resolution: {integrity: sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==} + engines: {node: '>=0.10.0'} + + camelcase@2.1.1: + resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} + engines: {node: '>=0.10.0'} + + capture-stack-trace@1.0.2: + resolution: {integrity: sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==} + engines: {node: '>=0.10.0'} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + chalk@0.4.0: + resolution: {integrity: sha512-sQfYDlfv2DGVtjdoQqxS0cEZDroyG8h6TamA6rvxwlrU5BaSLDx9xhatBYl2pxZ7gmpNaPFVwBtdGdu5rQ+tYQ==} + engines: {node: '>=0.8.0'} + + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chardet@0.4.2: + resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==} + + chokidar@1.7.0: + resolution: {integrity: sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==} + + ci-info@1.6.0: + resolution: {integrity: sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==} + + circular-json@0.3.3: + resolution: {integrity: sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==} + deprecated: CircularJSON is in maintenance only, flatted is its successor. + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + clean-stack@1.3.0: + resolution: {integrity: sha512-4CCmhqt4yqbQQI9REDKCf+N6U3SToC5o7PoKCq4veHvr30TJ2Vmz1mYYF23VC0E7Z13tf4CXh9jXY0VC+Jtdng==} + engines: {node: '>=4'} + + clean-yaml-object@0.1.0: + resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} + engines: {node: '>=0.10.0'} + + cli-boxes@1.0.0: + resolution: {integrity: sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==} + engines: {node: '>=0.10.0'} + + cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + + cli-spinners@1.3.1: + resolution: {integrity: sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==} + engines: {node: '>=4'} + + cli-truncate@0.2.1: + resolution: {integrity: sha512-f4r4yJnbT++qUPI9NR4XLDLq41gQ+uqnPItWG0F5ZkehuNiTTa3EY0S4AqTSUOeJ7/zU41oWPQSNkW5BqPL9bg==} + engines: {node: '>=0.10.0'} + + cli-width@2.2.1: + resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} + + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + + co-with-promise@4.6.0: + resolution: {integrity: sha512-WVBNmNJDqfiLcCt25n4ruZxESZdcCOT686aZ+D3p+PnJqdRysi+qVfH051dNOmI/hQJUUwFMDj3aCAMGLo8tQA==} + engines: {iojs: '>= 1.0.0', node: '>= 0.10.0'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + code-excerpt@2.1.1: + resolution: {integrity: sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw==} + engines: {node: '>=4'} + + code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + common-path-prefix@1.0.0: + resolution: {integrity: sha512-StWMCZw9nTO+RnxMCcapnQQqeZpaDvCD9+0Rrl8ZphFKWcJPyUGiEl64WoAkA+WJIxwKYzxldhYHU+EW1fQ2mQ==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + conf@9.0.2: + resolution: {integrity: sha512-rLSiilO85qHgaTBIIHQpsv8z+NnVfZq3cKuYNCXN1AOqPzced0GWZEe/A517VldRLyQYXUMyV+vszavE2jSAqw==} + engines: {node: '>=10'} + + configstore@2.1.0: + resolution: {integrity: sha512-BOCxwwxF5WPspp1OBq9j0JLyL5JgJOTssz9PdOHr8VWjFijaC3PpjU48vFEX3uxx8sTusnVQckLbNzBq6fmkGw==} + engines: {node: '>=0.10.0'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-to-spaces@1.0.2: + resolution: {integrity: sha512-cj09EBuObp9gZNQCzc7hByQyrs6jVGE+o9kSJmeUoj+GiPiJvi5LYqEH/Hmme4+MTLHM+Ejtq+FChpjjEnsPdQ==} + engines: {node: '>= 4'} + + cookies@0.8.0: + resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} + engines: {node: '>= 0.8'} + + cookies@0.9.1: + resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} + engines: {node: '>= 0.8'} + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + core-assert@0.2.1: + resolution: {integrity: sha512-IG97qShIP+nrJCXMCgkNZgH7jZQ4n8RpPyPeXX++T6avR/KhLhgLiHKoEn5Rc1KjfycSfA9DMa6m+4C4eguHhw==} + engines: {node: '>=0.10.0'} + + core-js@2.6.12: + resolution: {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. + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cos-nodejs-sdk-v5@2.15.4: + resolution: {integrity: sha512-TP/iYTvKKKhRK89on9SRfSMGEw/9SFAAU8EC1kdT5Fmpx7dAwaCNM2+R2H1TSYoQt+03rwOs8QEfNkX8GOHjHQ==} + engines: {node: '>= 6'} + + create-error-class@3.0.2: + resolution: {integrity: sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==} + engines: {node: '>=0.10.0'} + + cron-parser@2.18.0: + resolution: {integrity: sha512-s4odpheTyydAbTBQepsqd2rNWGa2iV3cyo8g7zbI2QQYGLVsfbhmwukayS1XHppe02Oy1fg7mg6xoaraVJeEcg==} + engines: {node: '>=0.8'} + + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + + currently-unhandled@0.4.1: + resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} + engines: {node: '>=0.10.0'} + + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + date-format@4.0.14: + resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} + engines: {node: '>=4.0'} + + date-time@0.1.1: + resolution: {integrity: sha512-p4psdkgdNA6x0600SKbfWiOomNb33ADBMRHf49GMhYVgJsPefZlMSLXXVWWUpbqSxB3DL5/cxKa6a8i3XPK5Xg==} + engines: {node: '>=0.10.0'} + + debounce-fn@4.0.0: + resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} + engines: {node: '>=10'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + deep-equal@1.0.1: + resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-indent@4.0.0: + resolution: {integrity: sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==} + engines: {node: '>=0.10.0'} + + detect-indent@5.0.0: + resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} + engines: {node: '>=4'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + diff@3.5.1: + resolution: {integrity: sha512-Z3u54A8qGyqFOSr2pk0ijYs8mOE9Qz8kTvtKeBI+upoG9j04Sq+oI7W8zAJiQybDcESET8/uIdHzs0p3k4fZlw==} + engines: {node: '>=0.3.1'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dot-prop@3.0.0: + resolution: {integrity: sha512-k4ELWeEU3uCcwub7+dWydqQBRjAjkV9L33HjVRG5Xo2QybI6ja/v+4W73SRi8ubCqJz0l9XsTP1NbewfyqaSlw==} + engines: {node: '>=0.10.0'} + + dot-prop@4.2.1: + resolution: {integrity: sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==} + engines: {node: '>=4'} + + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + double-ended-queue@2.1.0-0: + resolution: {integrity: sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + empower-core@0.6.2: + resolution: {integrity: sha512-w9QJ4ROqcjJHWNw+TvpKVeLQV1GQtoFO6aqKoj5IlHi0qxG1Y2157Kg6+5ujs5Bxzm8AgOiOvBCRbNkt6RPe9Q==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + equal-length@1.0.1: + resolution: {integrity: sha512-TK2m7MvWPt/v3dan0BCNp99pytIE5UGrUj7F0KZirNX8xz8fDFUAZfgm8uB5FuQq9u0sMeDocYBfEhsd1nwGoA==} + engines: {node: '>=4'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + eslint-config-think@1.0.3: + resolution: {integrity: sha512-TojqumNtS9IPuF1L00b5wBAm66LLVIC5xsGASvThaa3tcvRHEOu95qJPxaXA697lsVSKSuByUwjgKIlhn2Meew==} + engines: {node: '>=6.0.0'} + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-node@5.2.1: + resolution: {integrity: sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==} + engines: {node: '>=4'} + peerDependencies: + eslint: '>=3.1.0' + + eslint-plugin-promise@3.8.0: + resolution: {integrity: sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==} + engines: {node: '>=4'} + + eslint-plugin-standard@3.1.0: + resolution: {integrity: sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==} + peerDependencies: + eslint: '>=3.19.0' + + eslint-scope@3.7.3: + resolution: {integrity: sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==} + engines: {node: '>=4.0.0'} + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + + eslint@4.19.1: + resolution: {integrity: sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==} + engines: {node: '>=4'} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espower-location-detector@1.0.0: + resolution: {integrity: sha512-Y/3H6ytYwqC3YcOc0gOU22Lp3eI5GAFGOymTdzFyfaiglKgtsw2dePOgXY3yrV+QcLPMPiVYwBU9RKaDoh2bbQ==} + + espree@3.5.4: + resolution: {integrity: sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==} + engines: {node: '>=0.10.0'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + espurify@1.8.1: + resolution: {integrity: sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg==} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@0.7.0: + resolution: {integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==} + engines: {node: '>=4'} + + expand-brackets@0.1.5: + resolution: {integrity: sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==} + engines: {node: '>=0.10.0'} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + expand-range@1.8.2: + resolution: {integrity: sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==} + engines: {node: '>=0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + external-editor@2.2.0: + resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==} + engines: {node: '>=0.12'} + + extglob@0.3.2: + resolution: {integrity: sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==} + engines: {node: '>=0.10.0'} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + fast-deep-equal@1.1.0: + resolution: {integrity: sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-xml-parser@4.2.5: + resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} + hasBin: true + + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + + file-entry-cache@2.0.0: + resolution: {integrity: sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==} + engines: {node: '>=0.10.0'} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + filename-regex@2.0.1: + resolution: {integrity: sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==} + engines: {node: '>=0.10.0'} + + fill-range@2.2.4: + resolution: {integrity: sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==} + engines: {node: '>=0.10.0'} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + filled-array@1.1.0: + resolution: {integrity: sha512-4XwZ1k4rgoF3Yap59MyXFmiUh2zu9fht32NYPSRYwLv4o8BWHxi60I1VH5kHje14qGMoS3qyfHQUsN16ROOugQ==} + engines: {node: '>=0.10.0'} + + find-cache-dir@0.1.1: + resolution: {integrity: sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==} + engines: {node: '>=0.10.0'} + + find-up@1.1.2: + resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} + engines: {node: '>=0.10.0'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + + flat-cache@1.3.4: + resolution: {integrity: sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==} + engines: {node: '>=0.10.0'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + flexbuffer@0.0.6: + resolution: {integrity: sha512-OapHwT5Ug1c3iiv8JNrwh/3XGjP45l/2iwfl25chePrvCgl0786ZvsJK+hxCCaUZjPm1lHdh5LHZhmKRxunziA==} + + fn-name@2.0.1: + resolution: {integrity: sha512-oIDB1rXf3BUnn00bh2jVM0byuqr94rBh6g7ZfdKcbmp1we2GQtPzKdloyvBXHs+q3fvxB8EqX5ecFba3RwCSjA==} + engines: {node: '>=0.10.0'} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + for-own@0.1.5: + resolution: {integrity: sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==} + engines: {node: '>=0.10.0'} + + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + + formidable@1.2.6: + resolution: {integrity: sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==} + deprecated: 'Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau' + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: Upgrade to fsevents v2 to mitigate potential security issues + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-port@2.1.0: + resolution: {integrity: sha512-Za6hwpIQjqx3rxtqHZpVdn4r/74EkANdpp4GKJO2GcjsRrnMD5QfiuDIcEckUrtmCIC13FNZqNkhmucZvNrjhg==} + engines: {node: '>=0.10.0'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stdin@4.0.1: + resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} + engines: {node: '>=0.10.0'} + + get-stream@3.0.0: + resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} + engines: {node: '>=4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + glob-base@0.3.0: + resolution: {integrity: sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==} + engines: {node: '>=0.10.0'} + + glob-parent@2.0.0: + resolution: {integrity: sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@9.18.0: + resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} + engines: {node: '>=0.10.0'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@6.1.0: + resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} + engines: {node: '>=0.10.0'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + got@5.7.1: + resolution: {integrity: sha512-1qd54GLxvVgzuidFmw9ze9umxS3rzhdBH6Wt6BTYrTQUXTN01vGGYXwzLzYLowNx8HBH3/c7kRyvx90fh13i7Q==} + engines: {node: '>=0.10.0 <7'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + + har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-color@0.1.7: + resolution: {integrity: sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw==} + engines: {node: '>=0.10.0'} + + has-flag@2.0.0: + resolution: {integrity: sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + has-yarn@1.0.0: + resolution: {integrity: sha512-UAI4b48aqrdez88CwMfC9s+gcJ25O1qg0/hS5eKOsIF5tOw2EYcgGsryYF6TEI5G8SeCYzFBt5Z04D/BDABYSQ==} + engines: {node: '>=4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + home-or-tmp@2.0.0: + resolution: {integrity: sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==} + engines: {node: '>=0.10.0'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + http-assert@1.5.0: + resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} + engines: {node: '>= 0.8'} + + http-errors@1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + ignore@3.3.10: + resolution: {integrity: sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@2.1.0: + resolution: {integrity: sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==} + engines: {node: '>=0.10.0'} + + indent-string@3.2.0: + resolution: {integrity: sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==} + engines: {node: '>=4'} + + inflation@2.1.0: + resolution: {integrity: sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==} + engines: {node: '>= 0.8.0'} + + inflight@1.0.6: + resolution: {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. + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + inquirer@3.3.0: + resolution: {integrity: sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + ioredis@2.5.0: + resolution: {integrity: sha512-2jcmF1oVbNf8z+BJ8OmlwKsT+tqOJsJJuTh8qAX5Hwo0424E92A3qu9qcWM9vRhP0R4gCrJ9Y72QZwuVj8weMw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.10.16'} + + irregular-plurals@1.4.0: + resolution: {integrity: sha512-kniTIJmaZYiwa17eTtWIfm0K342seyugl6vuC8DiiyiRAJWAVlLkqGCI0Im0neo0TkXw+pRcKaBPRdcKHnQJ6Q==} + engines: {node: '>=0.10.0'} + + is-accessor-descriptor@1.0.1: + resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} + engines: {node: '>= 0.10'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@1.2.1: + resolution: {integrity: sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-descriptor@0.1.7: + resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.3: + resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} + engines: {node: '>= 0.4'} + + is-dotfile@1.0.3: + resolution: {integrity: sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==} + engines: {node: '>=0.10.0'} + + is-equal-shallow@0.1.3: + resolution: {integrity: sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==} + engines: {node: '>=0.10.0'} + + is-error@2.2.2: + resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@1.0.0: + resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-finite@1.1.0: + resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-generator-fn@1.0.0: + resolution: {integrity: sha512-95jJZX6O/gdekidH2usRBr9WdRw4LU56CttPstXFxvG0r3QUE9eaIdz2p2Y7zrm6jxz7SjByAo1AtzwGlRvfOg==} + engines: {node: '>=0.10.0'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@2.0.1: + resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-npm@1.0.0: + resolution: {integrity: sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==} + engines: {node: '>=0.10.0'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@2.1.0: + resolution: {integrity: sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==} + engines: {node: '>=0.10.0'} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@4.0.0: + resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} + engines: {node: '>=0.10.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-observable@0.2.0: + resolution: {integrity: sha512-4JymFIKLU+QyN0J+Q1YMWGXGF/FbL/RPkr5R9UlTdvWmSYRQPeoub00WZ4EiWOEVxWz/djoPxNFF+iuBSJzYCw==} + engines: {node: '>=0.10.0'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-posix-bracket@0.1.1: + resolution: {integrity: sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==} + engines: {node: '>=0.10.0'} + + is-primitive@2.0.0: + resolution: {integrity: sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==} + engines: {node: '>=0.10.0'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-redirect@1.0.0: + resolution: {integrity: sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==} + engines: {node: '>=0.10.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-resolvable@1.1.0: + resolution: {integrity: sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==} + + is-retry-allowed@1.2.0: + resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} + engines: {node: '>=0.10.0'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + jest-diff@18.1.0: + resolution: {integrity: sha512-PzsL3/aLCOfJyvF6cqp6N6kzkImNfDXAkWIU/9y84WPPTf82Dnhkxex/LD/3nR6Z38VBrsefGTQLSF4yoPlMgg==} + + jest-file-exists@17.0.0: + resolution: {integrity: sha512-JXkEL1QPduQCc6wgexD0vArivwYAlIXLSMM75HrjXM+LtRZlvX57dWaviudOHUBHraUapyY7O+dTlAu+6hNQ6A==} + + jest-matcher-utils@18.1.0: + resolution: {integrity: sha512-OQoK0lv62J+CgFZlLkIvHsmW93oEUa+poci8m4T5KfdeQvRFTNEnYSaxqbG7Gv/If3Ib1NVx1ILIxyo5aTl5hA==} + + jest-mock@18.0.0: + resolution: {integrity: sha512-Vou/x9kOIB1y8OnCXx/NZJtDSy9aKB0hJVsDLiSOlf6UGMsvcB2g0VA1W8td4zglGQRu0QZkPZ2n3W/X9F1Gig==} + + jest-snapshot@18.1.0: + resolution: {integrity: sha512-EvZk0LjuB881yWOr+yqYuO+XrNtzP7BPOcknexBr4TNiiFrA14w8DZgkZ1U+JmtpRPBj3nIFuYArDYZsnCyFOA==} + + jest-util@18.1.0: + resolution: {integrity: sha512-ffxeN/edEn8QfLiJs8j65M8Cob2QHswpF9zGPBmRKXFi7vr+Aj3J67LwP3kWUMTDm0acS2tirrmJEfd3D/W7LQ==} + + js-tokens@3.0.2: + resolution: {integrity: sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@1.3.0: + resolution: {integrity: sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-schema-traverse@0.3.1: + resolution: {integrity: sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@7.0.3: + resolution: {integrity: sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@0.5.1: + resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} + hasBin: true + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} + + jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + keygrip@1.1.0: + resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} + engines: {node: '>= 0.6'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + koa-compose@4.1.0: + resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} + + koa-convert@2.0.0: + resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} + engines: {node: '>= 10'} + + koa-send@3.3.0: + resolution: {integrity: sha512-5AH9ZrP8k9X13K5aAdyI+XPzqzKDMcM3omVgaWsTntQiZxIL9nkrvxgmjB8fmMXsNobvhIern21RNNSHCLSOeg==} + + koa@2.16.3: + resolution: {integrity: sha512-zPPuIt+ku1iCpFBRwseMcPYQ1cJL8l60rSmKeOuGfOXyE6YnTBmf2aEFNL2HQGrD0cPcLO/t+v9RTgC+fwEh/g==} + engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + + last-line-stream@1.0.0: + resolution: {integrity: sha512-A9su/wrZOLGwo27plXO4hCBttJx9JvALtnmq4UFe9KCAFHuk1rZFuVv+4AXlBAnb/ex7IKf81Tfo32hXDhQuxg==} + engines: {node: '>=0.10.0'} + + latest-version@2.0.0: + resolution: {integrity: sha512-8925wFYLfWBciewimt0VmDyYw0GFCRcbFSTrZGt4JgQ7lh5jb/kodMlUt0uMaxXdRKVi+7F3ib30N7fTv83ikw==} + engines: {node: '>=0.10.0'} + + lazy-req@1.1.0: + resolution: {integrity: sha512-Vn/JuGaYykbelAVNAhfVJxuwHQCOSNE6mqMtD+gnd+QORlAHwWVmVFqQga3yWt84G5vAwEwpT6sAsZ+tgJ88/Q==} + engines: {node: '>=0.10.0'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + load-json-file@1.1.0: + resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} + engines: {node: '>=0.10.0'} + + load-json-file@2.0.0: + resolution: {integrity: sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==} + engines: {node: '>=4'} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + + log4js@6.9.1: + resolution: {integrity: sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==} + engines: {node: '>=8.0'} + + long-timeout@0.1.1: + resolution: {integrity: sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loud-rejection@1.6.0: + resolution: {integrity: sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==} + engines: {node: '>=0.10.0'} + + lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + + make-dir@1.3.0: + resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} + engines: {node: '>=4'} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + matcher@0.1.2: + resolution: {integrity: sha512-e+Sqhn8HEY9cAUCBacJHDqFneV1kc1r9m1uH6QMTCb8vWjaHlBkzDmJ6YLgruFquiWmhxFIJUQqj+xWoiqh/Ew==} + engines: {node: '>=0.10.0'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + math-random@1.0.4: + resolution: {integrity: sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==} + + max-timeout@1.0.0: + resolution: {integrity: sha512-sXo5y3ioLf/ha4MTOOMfSqZx2ymTsBMku9uwKLldT2/hcIK8bOhUvYuv/Wvc0huUwfOEvg97+6jvSAhQJ8cXTw==} + engines: {node: '>=0.10.0'} + + md5-hex@1.3.0: + resolution: {integrity: sha512-lJEPhRxivsaliY4C6REebtP1Lo8yoQsq2bLVP8mJ6Vvzwu3fXQShzHcWnAqdDm1Y42jhZFg0XRpnrKfZ5mYP6w==} + engines: {node: '>=0.10.0'} + + md5-hex@2.0.0: + resolution: {integrity: sha512-0HLfzJTZ7707VBNM1ydr5sTb+IZLhmU4u2TVA+Eenfn/Ed42/gn10smbAPiuEm/jNgjvWKUiMNihqJQ6flus9w==} + engines: {node: '>=4'} + + md5-o-matic@0.1.1: + resolution: {integrity: sha512-QBJSFpsedXUl/Lgs4ySdB2XCzUEcJ3ujpbagdZCkRaYIaC0kFnID8jhc84KEiVv6dNFtIrmW7bqow0lDxgJi6A==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + meow@3.7.0: + resolution: {integrity: sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==} + engines: {node: '>=0.10.0'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@2.3.11: + resolution: {integrity: sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==} + engines: {node: '>=0.10.0'} + + micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@3.1.0: + resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} + engines: {node: '>=8'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + moment-timezone@0.5.48: + resolution: {integrity: sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + ms@0.7.3: + resolution: {integrity: sha512-lrKNzMWqQZgwJahtrtrM+9NgOoDUveDrVmm5aGXrf3BdtL0mq7X6IVzoZaw+TfNti29eHd1/8GI+h45K5cQ6/w==} + + ms@1.0.0: + resolution: {integrity: sha512-85ytwCiGUnD84ui6ULG1KBFMaZgHW3jg5KPr9jt+ZPYt75+XK+JGbYddGrBQ+RSHXOhekCnCZwJywBoFvFl0kw==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multimatch@2.1.0: + resolution: {integrity: sha512-0mzK8ymiWdehTBiJh0vClAzGyQbdtyWqzSVx//EK4N/D+599RFlGfTAsKw2zMSABtDG9C6Ul2+t8f2Lbdjf5mA==} + engines: {node: '>=0.10.0'} + + mute-stream@0.0.7: + resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} + + mysql@2.18.1: + resolution: {integrity: sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==} + engines: {node: '>= 0.6'} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nan@2.25.0: + resolution: {integrity: sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==} + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-schedule@1.3.3: + resolution: {integrity: sha512-uF9Ubn6luOPrcAYKfsXWimcJ1tPFtQ8I85wb4T3NgJQrXazEzojcFZVk46ZlLHby3eEJChgkV/0T689IsXh2Gw==} + + node-status-codes@1.0.0: + resolution: {integrity: sha512-1cBMgRxdMWE8KeWCqk2RIOrvUb0XCwYfEsY5/y2NlXyq4Y/RumnOZvTj4Nbr77+Vb2C+kyBoRTdkNOS8L3d/aQ==} + engines: {node: '>=0.10.0'} + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + + number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + + nunjucks@3.2.4: + resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==} + engines: {node: '>= 6.9.0'} + hasBin: true + peerDependencies: + chokidar: ^3.3.0 + peerDependenciesMeta: + chokidar: + optional: true + + nyc@7.1.0: + resolution: {integrity: sha512-wRbNaMQqz1XoqZA7TI0xxGOcPxCjZbpbMlQqznCr5xHqO6/4EEBc38C6SwPOA0rvciYKHRdmHIENPsIx5v54VA==} + hasBin: true + bundledDependencies: + - arrify + - caching-transform + - convert-source-map + - default-require-extensions + - find-cache-dir + - find-up + - foreground-child + - glob + - istanbul-lib-coverage + - istanbul-lib-hook + - istanbul-lib-instrument + - istanbul-lib-report + - istanbul-lib-source-maps + - istanbul-reports + - md5-hex + - micromatch + - mkdirp + - pkg-up + - resolve-from + - rimraf + - signal-exit + - spawn-wrap + - test-exclude + - yargs + - yargs-parser + + oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.omit@2.0.1: + resolution: {integrity: sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==} + engines: {node: '>=0.10.0'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + observable-to-promise@0.4.0: + resolution: {integrity: sha512-/e9WRNDQoetZciJeB6Wc6r8nF1cwLtATbwG1oQjpL3v8nHmfhIGKRqy7VBq8GgXsQ7pLoslcbj6yMhJTxmx8/g==} + engines: {node: '>=0.10.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + only@0.0.2: + resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} + + option-chain@0.1.1: + resolution: {integrity: sha512-UsON6bnN9BuNmFV7odYf9XSKmUoaRfq/5ru5zCPK5vIzo23dtyhoWnHUBQ3cra8/W8+D33hkn/9OgKcWi2F+yg==} + engines: {node: '>=0.10.0'} + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + osenv@0.1.5: + resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} + deprecated: This package is no longer supported. + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-hash@1.2.0: + resolution: {integrity: sha512-W5ILqaI3G6bXDuYb7TrQ95TFHfFdjiunpp61PAXj7z32TgJ5NIBaoqZVI6AXUQy/qcqPoFnz0hAZY9KyKd4xNA==} + + package-json@2.4.0: + resolution: {integrity: sha512-PRg65iXMTt/uK8Rfh5zvzkUbfAPitF17YaCY+IbHsYgksiLvtzWWTUildHth3mVaZ7871OJ7gtP4LBRBlmAdXg==} + engines: {node: '>=0.10.0'} + + parse-glob@3.0.4: + resolution: {integrity: sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==} + engines: {node: '>=0.10.0'} + + parse-json@2.2.0: + resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} + engines: {node: '>=0.10.0'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-ms@0.1.2: + resolution: {integrity: sha512-VwMglE9412ifMHcRFEVJePEpreQh90wjIiOdP0UQQGKV4l+QprdKI+p5noXTkmGjznBMb40s+VymcclATAVvYA==} + engines: {node: '>=0.10.0'} + + parse-ms@1.0.1: + resolution: {integrity: sha512-LpH1Cf5EYuVjkBvCDBYvkUPh+iv2bk3FHflxHkpCYT0/FZ1d3N3uJaLiHr4yGuMcFUhv6eAivitTvWZI4B/chg==} + engines: {node: '>=0.10.0'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + path-exists@2.1.0: + resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} + engines: {node: '>=0.10.0'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} + + path-type@1.1.0: + resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} + engines: {node: '>=0.10.0'} + + path-type@2.0.0: + resolution: {integrity: sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==} + engines: {node: '>=4'} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pinkie-promise@1.0.0: + resolution: {integrity: sha512-5mvtVNse2Ml9zpFKkWBpGsTPwm3DKhs+c95prO/F6E7d6DN0FPqxs6LONpLNpyD7Iheb7QN4BbUoKJgo+DnkQA==} + engines: {node: '>=0.10.0'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@1.0.0: + resolution: {integrity: sha512-VFVaU1ysKakao68ktZm76PIdOhvEfoNNRaGkyLln9Os7r0/MCxqHjHyBM7dT3pgTiBybqiPtpqKfpENwdBp50Q==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + + pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + + pkg-dir@1.0.0: + resolution: {integrity: sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==} + engines: {node: '>=0.10.0'} + + pkg-up@3.1.0: + resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} + engines: {node: '>=8'} + + plur@1.0.0: + resolution: {integrity: sha512-qSnKBSZeDY8ApxwhfVIwKwF36KVJqb1/9nzYYq3j3vdwocULCXT8f8fQGkiw1Nk9BGfxiDagEe/pwakA+bOBqw==} + engines: {node: '>=0.10.0'} + + plur@2.1.2: + resolution: {integrity: sha512-WhcHk576xg9y/iv6RWOuroZgsqvCbJN+XGvAypCJwLAYs2iWDp5LUmvaCdV6JR2O0SMBf8l6p7A94AyLCFVMlQ==} + engines: {node: '>=0.10.0'} + + pluralize@7.0.0: + resolution: {integrity: sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==} + engines: {node: '>=4'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prepend-http@1.0.4: + resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} + engines: {node: '>=0.10.0'} + + preserve@0.2.0: + resolution: {integrity: sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==} + engines: {node: '>=0.10.0'} + + pretty-format@18.1.0: + resolution: {integrity: sha512-jlKL5u/PZajHEwJyYiTUwZ3P+zUTp7XylRdIxX5zchNpMJT0Z3lR/+I6g6e8JY8EY7Qk8iSj0BdUZTRXQtixYg==} + + pretty-ms@0.2.2: + resolution: {integrity: sha512-ah/vWDJAT0arxQwVcSGp6etaLTZr4IsrXTy/khfjimzdYgSxYWzTMByrtpJUWinAnVY8szDg+qQhsE5MUMz3lQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + pretty-ms@2.1.0: + resolution: {integrity: sha512-H2enpsxzDhuzRl3zeSQpQMirn8dB0Z/gxW96j06tMfTviUWvX14gjKb7qd1gtkUyYhDPuoNe00K5PqNvy2oQNg==} + engines: {node: '>=0.10.0'} + + private@0.1.8: + resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} + engines: {node: '>= 0.6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + + randomatic@3.1.1: + resolution: {integrity: sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==} + engines: {node: '>= 0.10.0'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + read-all-stream@3.1.0: + resolution: {integrity: sha512-DI1drPHbmBcUDWrJ7ull/F2Qb8HkwBncVx8/RpKYFSIACYaVRQReISYPdZz/mt1y1+qMCOrfReTopERmaxtP6w==} + engines: {node: '>=0.10.0'} + + read-pkg-up@1.0.1: + resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} + engines: {node: '>=0.10.0'} + + read-pkg-up@2.0.0: + resolution: {integrity: sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==} + engines: {node: '>=4'} + + read-pkg@1.1.0: + resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} + engines: {node: '>=0.10.0'} + + read-pkg@2.0.0: + resolution: {integrity: sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==} + engines: {node: '>=4'} + + readable-stream@2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readdirp@2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + + redent@1.0.0: + resolution: {integrity: sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==} + engines: {node: '>=0.10.0'} + + redis-commands@1.7.0: + resolution: {integrity: sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==} + + redis-parser@1.3.0: + resolution: {integrity: sha512-pPJS2ChF11wKm+YsHrRKON3m6MLGjBS+o9aXn6AjQqip+qMzk0zIG//jEagK+nKO5zrNljI1IdNV8JcvKrs0Iw==} + engines: {node: '>=0.10.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + + regex-cache@0.4.4: + resolution: {integrity: sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==} + engines: {node: '>=0.10.0'} + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regexpp@1.1.0: + resolution: {integrity: sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==} + engines: {node: '>=4.0.0'} + + regexpu-core@2.0.0: + resolution: {integrity: sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==} + + registry-auth-token@3.4.0: + resolution: {integrity: sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==} + + registry-url@3.1.0: + resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} + engines: {node: '>=0.10.0'} + + regjsgen@0.2.0: + resolution: {integrity: sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==} + + regjsparser@0.1.5: + resolution: {integrity: sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==} + hasBin: true + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + repeating@2.0.1: + resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} + engines: {node: '>=0.10.0'} + + request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-precompiled@0.1.0: + resolution: {integrity: sha512-UWQr7MdatK8cF0JXrrqVPal2sUdhpCj8f4sC7VMDONA/+WSVv5ElRku3qDEZ+FIqoN91zhhfB+t1P3+qQNaYGQ==} + engines: {node: '>=0.10.0'} + + require-uncached@1.0.3: + resolution: {integrity: sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==} + engines: {node: '>=0.10.0'} + + resolve-cwd@1.0.0: + resolution: {integrity: sha512-ac27EnKWWlc2yQ/5GCoCGecqVJ9MSmgiwvUYOS+9A+M0dn1FdP5mnsDZ9gwx+lAvh/d7f4RFn4jLfggRRYxPxw==} + engines: {node: '>=0.10.0'} + + resolve-from@1.0.1: + resolution: {integrity: sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==} + engines: {node: '>=0.10.0'} + + resolve-from@2.0.0: + resolution: {integrity: sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==} + engines: {node: '>=0.10.0'} + + resolve-path@1.4.0: + resolution: {integrity: sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==} + engines: {node: '>= 0.8'} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + rx-lite-aggregates@4.0.8: + resolution: {integrity: sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==} + + rx-lite@4.0.8: + resolution: {integrity: sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + + semver-diff@2.1.0: + resolution: {integrity: sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==} + engines: {node: '>=0.10.0'} + + semver@5.3.0: + resolution: {integrity: sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==} + hasBin: true + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + setprototypeof@1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + + slice-ansi@0.0.4: + resolution: {integrity: sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==} + engines: {node: '>=0.10.0'} + + slice-ansi@1.0.0: + resolution: {integrity: sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==} + engines: {node: '>=4'} + + slide@1.1.6: + resolution: {integrity: sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + sort-keys@2.0.0: + resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} + engines: {node: '>=4'} + + sorted-array-functions@1.3.0: + resolution: {integrity: sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==} + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.4.18: + resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==} + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sqlstring@2.3.1: + resolution: {integrity: sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==} + engines: {node: '>= 0.6'} + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + stack-trace@0.0.9: + resolution: {integrity: sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==} + + stack-utils@1.0.5: + resolution: {integrity: sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==} + engines: {node: '>=8'} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + streamroller@3.1.5: + resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} + engines: {node: '>=8.0'} + + string-hash@1.1.3: + resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} + + string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-ansi@0.1.1: + resolution: {integrity: sha512-behete+3uqxecWlDAm5lmskaSaISA+ThQ4oNNBDTBJt0x2ppR6IPqfZNuj6BLaLJ/Sji4TPZlcRyOis8wXQTLg==} + engines: {node: '>=0.8.0'} + hasBin: true + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-bom-buf@1.0.0: + resolution: {integrity: sha512-1sUIL1jck0T1mhOLP2c696BIznzT525Lkub+n4jjMHjhjhoAQA6Ye659DxdlZBr0aLDMQoTxKIpnlqxgtwjsuQ==} + engines: {node: '>=4'} + + strip-bom@2.0.0: + resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + + strip-indent@1.0.1: + resolution: {integrity: sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==} + engines: {node: '>=0.10.0'} + hasBin: true + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strnum@1.1.2: + resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} + + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-observable@0.2.4: + resolution: {integrity: sha512-6WFhZ1sqIAG3g55T6RJcOYldJmFrdsnM7adeuFUp1aJwo9EWwMFC0zYHNGGyDvJU/aqPzkQyIsMdNek1u9oRzQ==} + engines: {node: '>=0.10.0'} + + table@4.0.2: + resolution: {integrity: sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + think-cache-file@1.1.2: + resolution: {integrity: sha512-LLGDpFurDnE8XFdwzRJszchVipx47NDnxW50xeOOTxKqWve3ptl5ZdIcF14Kc/qUrrmJT+x2SXdcu0VfpjlLWA==} + + think-cache-redis@1.2.6: + resolution: {integrity: sha512-zs6n9RnWcDNjGlrxFOXZkRa8AQ/uWHQhm6CAHSKy1zoBJKKbxMUs0w68RmA5tEiL1Gd+AohW6QeGgHfSnPt44A==} + + think-cache@1.1.2: + resolution: {integrity: sha512-Xgp0vr4IbgN3YacTct1gWNtenxnpgh6vI/0Em5S6z3iQpWLEI1CTV9L5d78/1ZMNELO0GVk0+MdqEUSbaa19wQ==} + engines: {node: '>=6.0.0'} + + think-cluster@1.5.8: + resolution: {integrity: sha512-SkkXO5an9fMcK4IX+6FaIwFrZMR3D6lW16Rjz782X8INUdCYf8bsZNO4ZbCBhwRHIi6B9FzmsIWnGI1Zkdxufg==} + engines: {node: '>=6.0.0'} + + think-config@1.1.3: + resolution: {integrity: sha512-BESywQ9at4xyzwtago8ApgWBxYksfHWKmlwPOqrAWUk+gkpNy1bwcPCvlCcMz5O4MZOZwBeY8wMX5dmH66548g==} + engines: {node: '>=6.0.0'} + + think-controller@1.0.5: + resolution: {integrity: sha512-MP6sEJUPe3/DI7fajWwu2QWdksWdyqG6H8VMdOF9juv9f3tFMvOU/lG/6MKaUR1IUn34oxeCB+W9pl3WIBqpgQ==} + engines: {node: '>=6.0.0'} + + think-crontab@1.0.4: + resolution: {integrity: sha512-iAmhZE3ApAwRuzEhmjigBaGj9VRCBjkT2Bkk85HsFcDKXlFZphO5dEemOqCT0viHo1NuJGj1CTNGB5Glo2Z02A==} + engines: {node: '>=6.0.0'} + + think-debounce@1.0.4: + resolution: {integrity: sha512-DWRFd3dQEGKK1Mh5kENsVA0+O12NxJbFRKk6X3cxpK0aplPQDFbdrfyS+C2Z2jomt1RbPniXUt0mGh1YrNGbAQ==} + engines: {node: '>=6.0.0'} + + think-gc@1.0.3: + resolution: {integrity: sha512-7mSJbGHROylk2+vO7DyZOfg4niQRwE/9r4SCIPuJCyZxwuBItb5yZkDZc5LvN0ojOO7OMQX9S074bpGBCLKGTQ==} + engines: {node: '>=6.0.0'} + + think-helper@1.1.4: + resolution: {integrity: sha512-JRAgo8CuevJ9rXazGKR91EQMbTA2xxe5w0f8/P8yeyQkaen0ZcJv4laurisg/n1gjE/xuy4zyevhCTWKVgxf8g==} + engines: {node: '>=6.0.0'} + + think-instance@1.0.2: + resolution: {integrity: sha512-vLSgu8fBV0Kg+4pS8lyn0Jkeb0GcZZ8hmRYjKKwyOCNVt9wIPeKfrYx1SvKTbTUxJwNjgf5AloW0fJdTCXHLmg==} + engines: {node: '>=6.0.0'} + + think-loader@1.2.2: + resolution: {integrity: sha512-WTZD/8vC7TvNgREFnX5qwpl/iNqwJCwgFD9MoyQHEWDAuYidsuqVgAPJR6WFprRs2vkJvCQ+uBjral/ZzFoozQ==} + engines: {node: '>=6.0.0'} + + think-logger3@1.4.0: + resolution: {integrity: sha512-JySaFRc08BUvOHwB10Rt6qK4TRGpwmdJXxp5lPCS2rjZHmD9I6ko2jNK7q0H3yxmqNSJBcBwXz7TR5ypk003jQ==} + + think-logic@1.2.2: + resolution: {integrity: sha512-nzWubVr51XZYZ2L0c4TxFw+xOZu829s43n5R5+eW2kBzdjppmf2HgcxHttxGy+cafjFMCohHpQF6KP0aSgRIoA==} + engines: {node: '>=6.0.0'} + + think-meta@1.0.6: + resolution: {integrity: sha512-dSQPcjFFrI/2eYEFTXqFMjZXMIDn1aE3vrGhPHCLHTsglMJ/5CxHIoCO+2mvnu+BGnbDdv3WTurJX+VAz2bv7Q==} + engines: {node: '>=6.0.0'} + + think-mock-http@1.0.6: + resolution: {integrity: sha512-z/oxSO+LZShKNVkL8KAb7vqyhFkpL4cT1WRy0kIEWQVVxGmNsRh71uiirBiRNN3Uw34qUlphtd8dBA7TYX4uvA==} + engines: {node: '>=6.0.0'} + + think-model-abstract@1.6.5: + resolution: {integrity: sha512-ojDTK1es/KqX+92iQdIeN8Bo7ABZW4l0rKDbxz60NTWD0nMGSaP5SFLNir1OhI/wxX1llv2Cw0h8JftTRfW+DA==} + + think-model-mysql@1.1.7: + resolution: {integrity: sha512-HQN66b7RcIzKPnfS2xfDAPlgoy5aFaw4oOMBgHzraMzUco5R/CxoyWrbrL+C+zbKTjstY5UMo5GCJFPBqzJOng==} + + think-model@1.5.4: + resolution: {integrity: sha512-oZJGL0c/WHKnQEU+h3f7HfgDwTEc/AvgkY80qV4tvRTAZFjxPPz/uPBqEvyUEj8+ZtHzsBCa2RoVazPR8EoP0A==} + + think-ms@1.0.3: + resolution: {integrity: sha512-2Ppgqt1oxtj52fuarlERMJaLtwGkDvp9zf7x17cDzEpWILBONuBv4/axz9QljK12BwlAkUV/I9jKsB5TKRZv6A==} + engines: {node: '>=6.0.0'} + + think-mysql@1.4.4: + resolution: {integrity: sha512-COn8a6gq+wJqUNbkMRgHpJCgSzo5FGCBU4c05B38bhUoSuOGYVcEkLH0qd+uEy8SpivHPTSCNzzCJn7ZlUtbKA==} + engines: {node: '>=6.0.0'} + + think-payload@1.4.0: + resolution: {integrity: sha512-5oJLC1aOvjF/WF2xskkiezgOuIwDvPhCryZZnxhdmcsG5cwLDTvaMg7blG5NMAWQ3YsGlgso2K8D3ojc559+6w==} + + think-pm2@1.0.0: + resolution: {integrity: sha512-oDSqJj7/iTcquztY/WXiJ9t2YMEiXE/K1gyrOslH6Czd7V73YLMHB/hNIGbJLFdNAuQNufGa26L92TFx/mNzaw==} + engines: {node: '>=6.0.0'} + + think-redis@1.1.4: + resolution: {integrity: sha512-cbUcceOtjCae/O5I4Z6n41/pVRSCjieecYij4Z70G/tlDmqUbJl6C96Ng2dlVn2l5tNXMjNTv01Rpeh88wcRHA==} + + think-resource@1.0.3: + resolution: {integrity: sha512-NEaSBinj95yr5z2rM1Sx89P90iKZMhkIFzW/EgstnYEFQJRQO43mFByqZBhR01pOU3YL34Y+jL8Zjxd0szRrMg==} + engines: {node: '>=6.0.0'} + + think-router@1.3.5: + resolution: {integrity: sha512-0Gclu9ZivfNX1cT2FgL3ISwi8a7jL5CEQgzXtspL/15Ane6pg0qCbuh9c98kJI4c8JIPvmehjeXrPT2u/qikZw==} + engines: {node: '>=6.0.0'} + + think-session-file@1.1.4: + resolution: {integrity: sha512-/xuNRcM4xEwRgDLrlXtIQTF3NrO5wMOh7Qi2bhYauX7WbfDI6fOBckiNCTXLRUbdlpoC0r2tMAym7hl71QZNBA==} + engines: {node: '>=6.0.0'} + + think-session@1.1.6: + resolution: {integrity: sha512-AIinWPjQhpNesUqo3tLgiTJSiNLIsU+lXujaNHl1dTs1u7njo2Gc4wYWSJ0/4tInipbQCM+OdPq+NosBUvKY/w==} + engines: {node: '>=6.0.0'} + + think-store-file@1.1.1: + resolution: {integrity: sha512-t6+62s+z8yKKgY0lYmULarzKQ2T/QqgmNiaDdrlGU0oRCocBIHNSYpC5NPm5n+8kvflzdlZDnwUS5Z0QeoHO8A==} + + think-trace@1.0.18: + resolution: {integrity: sha512-ghTO3movOuT3gmWu1Fbv5XHTOkFCmcSOIFw8xMu4SEoW7em+XLHkG/w5mHRklua5vsZ8xdfYEaNBV06c1b0Rrg==} + + think-validator@1.6.7: + resolution: {integrity: sha512-igc0kNrfjucJ+CCeG33wsAxMHGPW3UdP1R3lFE8WJj5n9MdgqwxNZsT3sqHqp1TuowAV+1hCM+DV+1fXAF6XxA==} + + think-view-nunjucks@1.0.11: + resolution: {integrity: sha512-k3GifChMsXfDvDXodozCMwhkRoLfpYjAp2RJxwFeVeerih42chLZ3yy/Va9szmiKYhVDq+N3csMi5G0zEunQhw==} + + think-view@1.0.13: + resolution: {integrity: sha512-qBrMIp8cqcWm5EZsYBG53ud3oYAdnfpRO2NwKbcchD3iGKV1NAYRVRMOPTIfgYU/jPqrrvBJ20YjZ7BLhLIyHw==} + engines: {node: '>=6.0.0'} + + think-watcher@3.0.4: + resolution: {integrity: sha512-wLF7EAf4vAOEEg7tQWXhsXgrtLxtcIpFXmCQenUNOTyTQvY7NpI0GYJ8UOpQZ7qScMJk99fOV8+sVHRphHxynw==} + engines: {node: '>=6.0.0'} + + thinkjs@3.2.15: + resolution: {integrity: sha512-/jPy+QIIS+92uetRA7itigrlJXL6c/j+xBPJGaVT3LX2/zwlQ1VvjDUWu9SaaatWDYPVY44Em647QxsEjY9TXQ==} + engines: {node: '>=6.0.0'} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + time-require@0.1.2: + resolution: {integrity: sha512-IqcSpa1sVNleRbC9eHnN7p7vwEHNmsjsXUDqjlnvo4+2VLJ7/gIY2XACTBuRhMB4weYbDYKsR3av2ySykRhDIA==} + engines: {node: '>= 0.10.0'} + + timed-out@3.1.3: + resolution: {integrity: sha512-3RB4qgvPkxF/FGPnrzaWLhW1rxNK2sdH0mFjbhxkfTR6QXvcM3EtYm9L44UrhODZrZ+yhDXeMncLqi8QXn2MJg==} + engines: {node: '>=0.10.0'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + to-fast-properties@1.0.3: + resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} + engines: {node: '>=0.10.0'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + + trim-newlines@1.0.0: + resolution: {integrity: sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==} + engines: {node: '>=0.10.0'} + + trim-right@1.0.1: + resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} + engines: {node: '>=0.10.0'} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + uid2@0.0.3: + resolution: {integrity: sha512-5gSP1liv10Gjp8cMEnFd6shzkL/D6W1uhXSFNCxDC+YI8+L8wkCYCbJ7n77Ezb4wE/xzMogecE+DtamEe9PZjg==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + unique-temp-dir@1.0.0: + resolution: {integrity: sha512-tE68ki2FndoVdPioyiz8mYaJeX3xU/9lk4dml7KlLKEkWLtDGAYeg5LGjE2dMkzB8d6R3HbcKTn/I14nukP2dw==} + engines: {node: '>=0.10.0'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + unzip-response@1.0.2: + resolution: {integrity: sha512-pwCcjjhEcpW45JZIySExBHYv5Y9EeL2OIGEfrSKp2dMUFGFv4CpvZkwJbVge8OvGH2BNNtJBx67DuKuJhf+N5Q==} + engines: {node: '>=0.10'} + + update-notifier@1.0.3: + resolution: {integrity: sha512-iQSLFuxB2ZFAxXGN28DTxk/GNGlBmtqawvguYDtChAHI9Xjy0z7c7hpw6ywutK34SEDYTpLEsAM1ATMq5pcQsw==} + engines: {node: '>=0.10.0'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + url-parse-lax@1.0.0: + resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} + engines: {node: '>=0.10.0'} + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@2.0.3: + resolution: {integrity: sha512-FULf7fayPdpASncVy4DLh3xydlXEJJpvIELjYjNeQWYUZ9pclcpvCZSr2gkmN2FrrGcI7G/cJsIEwk5/8vfXpg==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@7.0.3: + resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==} + hasBin: true + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validator@9.4.1: + resolution: {integrity: sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + widest-line@1.0.0: + resolution: {integrity: sha512-r5vvGtqsHUHn98V0jURY4Ts86xJf6+SzK9rpWdV8/73nURB3WFPIHd67aOvPw2fSuunIyHjAUqiJ2TY0x4E5gw==} + engines: {node: '>=0.10.0'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@1.3.4: + resolution: {integrity: sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==} + + write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + + write-json-file@2.3.0: + resolution: {integrity: sha512-84+F0igFp2dPD6UpAQjOUX3CdKUOqUzn6oE9sDBNzUXINR5VceJ1rauZltqQB/bcYsx3EpKys4C7/PivKUAiWQ==} + engines: {node: '>=4'} + + write-pkg@3.2.0: + resolution: {integrity: sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw==} + engines: {node: '>=4'} + + write@0.2.1: + resolution: {integrity: sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==} + engines: {node: '>=0.10.0'} + + xdg-basedir@2.0.0: + resolution: {integrity: sha512-NF1pPn594TaRSUO/HARoB4jK8I+rWgcpVlpQCK6/6o5PHyLUt2CSiDrpUZbQ6rROck+W2EwF8mBJcTs+W98J9w==} + engines: {node: '>=0.10.0'} + + xml2js@0.4.23: + resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + + ylru@1.4.0: + resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==} + engines: {node: '>= 4.0.0'} + +snapshots: + + '@ava/babel-preset-stage-4@1.1.0': + dependencies: + babel-plugin-check-es2015-constants: 6.22.0 + babel-plugin-syntax-trailing-function-commas: 6.22.0 + babel-plugin-transform-async-to-generator: 6.24.1 + babel-plugin-transform-es2015-destructuring: 6.23.0 + babel-plugin-transform-es2015-function-name: 6.24.1 + babel-plugin-transform-es2015-modules-commonjs: 6.26.2 + babel-plugin-transform-es2015-parameters: 6.24.1 + babel-plugin-transform-es2015-spread: 6.22.0 + babel-plugin-transform-es2015-sticky-regex: 6.24.1 + babel-plugin-transform-es2015-unicode-regex: 6.24.1 + babel-plugin-transform-exponentiation-operator: 6.24.1 + package-hash: 1.2.0 + transitivePeerDependencies: + - supports-color + + '@ava/babel-preset-transform-test-files@2.0.1': + dependencies: + babel-plugin-ava-throws-helper: 1.0.0 + babel-plugin-espower: 2.4.0 + package-hash: 1.2.0 + transitivePeerDependencies: + - supports-color + + '@ava/pretty-format@1.1.0': + dependencies: + ansi-styles: 2.2.1 + esutils: 2.0.3 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.8.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@rtsao/scc@1.1.0': {} + + '@types/json5@0.0.29': {} + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 25.2.3 + + '@types/node@25.2.3': + dependencies: + undici-types: 7.16.0 + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 25.2.3 + + a-sync-waterfall@1.0.1: {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@3.0.1: + dependencies: + acorn: 3.3.0 + + acorn@3.3.0: {} + + acorn@5.7.4: {} + + ajv-formats@1.6.1(ajv@7.2.4): + optionalDependencies: + ajv: 7.2.4 + + ajv-keywords@2.1.1(ajv@5.5.2): + dependencies: + ajv: 5.5.2 + + ajv@5.5.2: + dependencies: + co: 4.6.0 + fast-deep-equal: 1.1.0 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.3.1 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@7.2.4: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ansi-align@1.1.0: + dependencies: + string-width: 1.0.2 + + ansi-escapes@3.2.0: {} + + ansi-regex@2.1.1: {} + + ansi-regex@3.0.1: {} + + ansi-styles@1.0.0: {} + + ansi-styles@2.2.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + any-promise@1.3.0: {} + + anymatch@1.3.2: + dependencies: + micromatch: 2.3.11 + normalize-path: 2.1.1 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + arr-diff@2.0.0: + dependencies: + arr-flatten: 1.1.0 + + arr-diff@4.0.0: {} + + arr-exclude@1.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-differ@1.0.0: {} + + array-find-index@1.0.2: {} + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array-union@1.0.2: + dependencies: + array-uniq: 1.0.3 + + array-uniq@1.0.3: {} + + array-unique@0.2.1: {} + + array-unique@0.3.2: {} + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + arrify@1.0.1: {} + + asap@2.0.6: {} + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assert-plus@1.0.0: {} + + assign-symbols@1.0.0: {} + + async-each@1.0.6: {} + + async-function@1.0.0: {} + + asynckit@0.4.0: {} + + atob@2.1.2: {} + + atomically@1.7.0: {} + + auto-bind@1.2.1: {} + + ava-init@0.2.1: + dependencies: + arr-exclude: 1.0.0 + execa: 0.7.0 + has-yarn: 1.0.0 + read-pkg-up: 2.0.0 + write-pkg: 3.2.0 + + ava@0.18.2: + dependencies: + '@ava/babel-preset-stage-4': 1.1.0 + '@ava/babel-preset-transform-test-files': 2.0.1 + '@ava/pretty-format': 1.1.0 + arr-flatten: 1.1.0 + array-union: 1.0.2 + array-uniq: 1.0.3 + arrify: 1.0.1 + auto-bind: 1.2.1 + ava-init: 0.2.1 + babel-code-frame: 6.26.0 + babel-core: 6.26.3 + bluebird: 3.7.2 + caching-transform: 1.0.1 + chalk: 1.1.3 + chokidar: 1.7.0 + clean-stack: 1.3.0 + clean-yaml-object: 0.1.0 + cli-cursor: 2.1.0 + cli-spinners: 1.3.1 + cli-truncate: 0.2.1 + co-with-promise: 4.6.0 + code-excerpt: 2.1.1 + common-path-prefix: 1.0.0 + convert-source-map: 1.9.0 + core-assert: 0.2.1 + currently-unhandled: 0.4.1 + debug: 2.6.9 + diff: 3.5.1 + dot-prop: 4.2.1 + empower-core: 0.6.2 + equal-length: 1.0.1 + figures: 2.0.0 + find-cache-dir: 0.1.1 + fn-name: 2.0.1 + get-port: 2.1.0 + globby: 6.1.0 + has-flag: 2.0.0 + ignore-by-default: 1.0.1 + indent-string: 3.2.0 + is-ci: 1.2.1 + is-generator-fn: 1.0.0 + is-obj: 1.0.1 + is-observable: 0.2.0 + is-promise: 2.2.2 + jest-snapshot: 18.1.0 + last-line-stream: 1.0.0 + lodash.debounce: 4.0.8 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isequal: 4.5.0 + loud-rejection: 1.6.0 + matcher: 0.1.2 + max-timeout: 1.0.0 + md5-hex: 2.0.0 + meow: 3.7.0 + ms: 0.7.3 + multimatch: 2.1.0 + observable-to-promise: 0.4.0 + option-chain: 0.1.1 + package-hash: 1.2.0 + pkg-conf: 2.1.0 + plur: 2.1.2 + pretty-ms: 2.1.0 + require-precompiled: 0.1.0 + resolve-cwd: 1.0.0 + slash: 1.0.0 + source-map-support: 0.4.18 + stack-utils: 1.0.5 + strip-ansi: 3.0.1 + strip-bom-buf: 1.0.0 + time-require: 0.1.2 + unique-temp-dir: 1.0.0 + update-notifier: 1.0.3 + transitivePeerDependencies: + - supports-color + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + aws-sign2@0.7.0: {} + + aws4@1.13.2: {} + + babel-code-frame@6.26.0: + dependencies: + chalk: 1.1.3 + esutils: 2.0.3 + js-tokens: 3.0.2 + + babel-core@6.26.3: + dependencies: + babel-code-frame: 6.26.0 + babel-generator: 6.26.1 + babel-helpers: 6.24.1 + babel-messages: 6.23.0 + babel-register: 6.26.0 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + convert-source-map: 1.9.0 + debug: 2.6.9 + json5: 0.5.1 + lodash: 4.17.23 + minimatch: 3.1.2 + path-is-absolute: 1.0.1 + private: 0.1.8 + slash: 1.0.0 + source-map: 0.5.7 + transitivePeerDependencies: + - supports-color + + babel-eslint@10.1.0(eslint@4.19.1): + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + eslint: 4.19.1 + eslint-visitor-keys: 1.3.0 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + babel-generator@6.26.1: + dependencies: + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + detect-indent: 4.0.0 + jsesc: 1.3.0 + lodash: 4.17.23 + source-map: 0.5.7 + trim-right: 1.0.1 + + babel-helper-builder-binary-assignment-operator-visitor@6.24.1: + dependencies: + babel-helper-explode-assignable-expression: 6.24.1 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-call-delegate@6.24.1: + dependencies: + babel-helper-hoist-variables: 6.24.1 + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-explode-assignable-expression@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-function-name@6.24.1: + dependencies: + babel-helper-get-function-arity: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-get-function-arity@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-helper-hoist-variables@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-helper-regex@6.26.0: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + lodash: 4.17.23 + + babel-helper-remap-async-to-generator@6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helpers@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-messages@6.23.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-ava-throws-helper@1.0.0: + dependencies: + babel-template: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-check-es2015-constants@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-espower@2.4.0: + dependencies: + babel-generator: 6.26.1 + babylon: 6.18.0 + call-matcher: 1.1.0 + core-js: 2.6.12 + espower-location-detector: 1.0.0 + espurify: 1.8.1 + estraverse: 4.3.0 + + babel-plugin-syntax-async-functions@6.13.0: {} + + babel-plugin-syntax-exponentiation-operator@6.13.0: {} + + babel-plugin-syntax-trailing-function-commas@6.22.0: {} + + babel-plugin-transform-async-to-generator@6.24.1: + dependencies: + babel-helper-remap-async-to-generator: 6.24.1 + babel-plugin-syntax-async-functions: 6.13.0 + babel-runtime: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-destructuring@6.23.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-function-name@6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-modules-commonjs@6.26.2: + dependencies: + babel-plugin-transform-strict-mode: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-parameters@6.24.1: + dependencies: + babel-helper-call-delegate: 6.24.1 + babel-helper-get-function-arity: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-spread@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-sticky-regex@6.24.1: + dependencies: + babel-helper-regex: 6.26.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-plugin-transform-es2015-unicode-regex@6.24.1: + dependencies: + babel-helper-regex: 6.26.0 + babel-runtime: 6.26.0 + regexpu-core: 2.0.0 + + babel-plugin-transform-exponentiation-operator@6.24.1: + dependencies: + babel-helper-builder-binary-assignment-operator-visitor: 6.24.1 + babel-plugin-syntax-exponentiation-operator: 6.13.0 + babel-runtime: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-strict-mode@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-register@6.26.0: + dependencies: + babel-core: 6.26.3 + babel-runtime: 6.26.0 + core-js: 2.6.12 + home-or-tmp: 2.0.0 + lodash: 4.17.23 + mkdirp: 0.5.6 + source-map-support: 0.4.18 + transitivePeerDependencies: + - supports-color + + babel-runtime@6.26.0: + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.11.1 + + babel-template@6.26.0: + dependencies: + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + lodash: 4.17.23 + transitivePeerDependencies: + - supports-color + + babel-traverse@6.26.0: + dependencies: + babel-code-frame: 6.26.0 + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + debug: 2.6.9 + globals: 9.18.0 + invariant: 2.2.4 + lodash: 4.17.23 + transitivePeerDependencies: + - supports-color + + babel-types@6.26.0: + dependencies: + babel-runtime: 6.26.0 + esutils: 2.0.3 + lodash: 4.17.23 + to-fast-properties: 1.0.3 + + babylon@6.18.0: {} + + balanced-match@1.0.2: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.1 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + bignumber.js@9.0.0: {} + + binary-extensions@1.13.1: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + optional: true + + bluebird@3.7.2: {} + + boxen@0.6.0: + dependencies: + ansi-align: 1.1.0 + camelcase: 2.1.1 + chalk: 1.1.3 + cli-boxes: 1.0.0 + filled-array: 1.1.0 + object-assign: 4.1.1 + repeating: 2.0.1 + string-width: 1.0.2 + widest-line: 1.0.0 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@1.8.5: + dependencies: + expand-range: 1.8.2 + preserve: 0.2.0 + repeat-element: 1.1.4 + + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + buf-compare@1.0.1: {} + + buffer-equal-constant-time@1.0.1: {} + + buffer-from@1.1.2: {} + + bytes@3.1.2: {} + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.1 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + cache-content-type@1.0.1: + dependencies: + mime-types: 2.1.35 + ylru: 1.4.0 + + caching-transform@1.0.1: + dependencies: + md5-hex: 1.3.0 + mkdirp: 0.5.6 + write-file-atomic: 1.3.4 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + 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 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + call-matcher@1.1.0: + dependencies: + core-js: 2.6.12 + deep-equal: 1.1.2 + espurify: 1.8.1 + estraverse: 4.3.0 + + call-signature@0.0.2: {} + + caller-path@0.1.0: + dependencies: + callsites: 0.2.0 + + callsites@0.2.0: {} + + camelcase-keys@2.1.0: + dependencies: + camelcase: 2.1.1 + map-obj: 1.0.1 + + camelcase@2.1.1: {} + + capture-stack-trace@1.0.2: {} + + caseless@0.12.0: {} + + chalk@0.4.0: + dependencies: + ansi-styles: 1.0.0 + has-color: 0.1.7 + strip-ansi: 0.1.1 + + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chardet@0.4.2: {} + + chokidar@1.7.0: + dependencies: + anymatch: 1.3.2 + async-each: 1.0.6 + glob-parent: 2.0.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 2.0.1 + path-is-absolute: 1.0.1 + readdirp: 2.2.1 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + + ci-info@1.6.0: {} + + circular-json@0.3.3: {} + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + clean-stack@1.3.0: {} + + clean-yaml-object@0.1.0: {} + + cli-boxes@1.0.0: {} + + cli-cursor@2.1.0: + dependencies: + restore-cursor: 2.0.0 + + cli-spinners@1.3.1: {} + + cli-truncate@0.2.1: + dependencies: + slice-ansi: 0.0.4 + string-width: 1.0.2 + + cli-width@2.2.1: {} + + cluster-key-slot@1.1.2: {} + + co-with-promise@4.6.0: + dependencies: + pinkie-promise: 1.0.0 + + co@4.6.0: {} + + code-excerpt@2.1.1: + dependencies: + convert-to-spaces: 1.0.2 + + code-point-at@1.1.0: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.3 + simple-swizzle: 0.2.4 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@5.1.0: {} + + common-path-prefix@1.0.0: {} + + commondir@1.0.1: {} + + component-emitter@1.3.1: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + conf@9.0.2: + dependencies: + ajv: 7.2.4 + ajv-formats: 1.6.1(ajv@7.2.4) + atomically: 1.7.0 + debounce-fn: 4.0.0 + dot-prop: 6.0.1 + env-paths: 2.2.1 + json-schema-typed: 7.0.3 + make-dir: 3.1.0 + onetime: 5.1.2 + pkg-up: 3.1.0 + semver: 7.7.4 + + configstore@2.1.0: + dependencies: + dot-prop: 3.0.0 + graceful-fs: 4.2.11 + mkdirp: 0.5.6 + object-assign: 4.1.1 + os-tmpdir: 1.0.2 + osenv: 0.1.5 + uuid: 2.0.3 + write-file-atomic: 1.3.4 + xdg-basedir: 2.0.0 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@1.9.0: {} + + convert-to-spaces@1.0.2: {} + + cookies@0.8.0: + dependencies: + depd: 2.0.0 + keygrip: 1.1.0 + + cookies@0.9.1: + dependencies: + depd: 2.0.0 + keygrip: 1.1.0 + + copy-descriptor@0.1.1: {} + + core-assert@0.2.1: + dependencies: + buf-compare: 1.0.1 + is-error: 2.2.2 + + core-js@2.6.12: {} + + core-util-is@1.0.2: {} + + core-util-is@1.0.3: {} + + cos-nodejs-sdk-v5@2.15.4: + dependencies: + conf: 9.0.2 + fast-xml-parser: 4.2.5 + mime-types: 2.1.35 + request: 2.88.2 + + create-error-class@3.0.2: + dependencies: + capture-stack-trace: 1.0.2 + + cron-parser@2.18.0: + dependencies: + is-nan: 1.3.2 + moment-timezone: 0.5.48 + + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + + currently-unhandled@0.4.1: + dependencies: + array-find-index: 1.0.2 + + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + date-format@4.0.14: {} + + date-time@0.1.1: {} + + debounce-fn@4.0.0: + dependencies: + mimic-fn: 3.1.0 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + decode-uri-component@0.2.2: {} + + deep-equal@1.0.1: {} + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.2.0 + is-date-object: 1.1.0 + is-regex: 1.2.1 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.4 + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.7 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.3 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.3 + isobject: 3.0.1 + + delayed-stream@1.0.0: {} + + delegates@1.0.0: {} + + depd@1.1.2: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + detect-indent@4.0.0: + dependencies: + repeating: 2.0.1 + + detect-indent@5.0.0: {} + + detect-libc@2.1.2: {} + + diff@3.5.1: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dot-prop@3.0.0: + dependencies: + is-obj: 1.0.1 + + dot-prop@4.2.1: + dependencies: + is-obj: 1.0.1 + + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + double-ended-queue@2.1.0-0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + empower-core@0.6.2: + dependencies: + call-signature: 0.0.2 + core-js: 2.6.12 + + encodeurl@1.0.2: {} + + env-paths@2.2.1: {} + + equal-length@1.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.24.1: + 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.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + eslint-config-think@1.0.3(eslint@4.19.1): + dependencies: + babel-eslint: 10.1.0(eslint@4.19.1) + eslint-plugin-import: 2.32.0(eslint@4.19.1) + eslint-plugin-node: 5.2.1(eslint@4.19.1) + eslint-plugin-promise: 3.8.0 + eslint-plugin-standard: 3.1.0(eslint@4.19.1) + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint@4.19.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + eslint: 4.19.1 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(eslint@4.19.1): + 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: 4.19.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint@4.19.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 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-node@5.2.1(eslint@4.19.1): + dependencies: + eslint: 4.19.1 + ignore: 3.3.10 + minimatch: 3.1.2 + resolve: 1.22.11 + semver: 5.3.0 + + eslint-plugin-promise@3.8.0: {} + + eslint-plugin-standard@3.1.0(eslint@4.19.1): + dependencies: + eslint: 4.19.1 + + eslint-scope@3.7.3: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-visitor-keys@1.3.0: {} + + eslint@4.19.1: + dependencies: + ajv: 5.5.2 + babel-code-frame: 6.26.0 + chalk: 2.4.2 + concat-stream: 1.6.2 + cross-spawn: 5.1.0 + debug: 3.2.7 + doctrine: 2.1.0 + eslint-scope: 3.7.3 + eslint-visitor-keys: 1.3.0 + espree: 3.5.4 + esquery: 1.7.0 + esutils: 2.0.3 + file-entry-cache: 2.0.0 + functional-red-black-tree: 1.0.1 + glob: 7.2.3 + globals: 11.12.0 + ignore: 3.3.10 + imurmurhash: 0.1.4 + inquirer: 3.3.0 + is-resolvable: 1.1.0 + js-yaml: 3.14.2 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.3.0 + lodash: 4.17.23 + minimatch: 3.1.2 + mkdirp: 0.5.6 + natural-compare: 1.4.0 + optionator: 0.8.3 + path-is-inside: 1.0.2 + pluralize: 7.0.0 + progress: 2.0.3 + regexpp: 1.1.0 + require-uncached: 1.0.3 + semver: 5.7.2 + strip-ansi: 4.0.0 + strip-json-comments: 2.0.1 + table: 4.0.2 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espower-location-detector@1.0.0: + dependencies: + is-url: 1.2.4 + path-is-absolute: 1.0.1 + source-map: 0.5.7 + xtend: 4.0.2 + + espree@3.5.4: + dependencies: + acorn: 5.7.4 + acorn-jsx: 3.0.1 + + esprima@4.0.1: {} + + espurify@1.8.1: + dependencies: + core-js: 2.6.12 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + execa@0.7.0: + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + + expand-brackets@0.1.5: + dependencies: + is-posix-bracket: 0.1.1 + + expand-brackets@2.1.4: + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + expand-range@1.8.2: + dependencies: + fill-range: 2.2.4 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extend@3.0.2: {} + + external-editor@2.2.0: + dependencies: + chardet: 0.4.2 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + extglob@0.3.2: + dependencies: + is-extglob: 1.0.0 + + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + extsprintf@1.3.0: {} + + fast-deep-equal@1.1.0: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-xml-parser@4.2.5: + dependencies: + strnum: 1.1.2 + + figures@2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@2.0.0: + dependencies: + flat-cache: 1.3.4 + object-assign: 4.1.1 + + file-uri-to-path@1.0.0: + optional: true + + filename-regex@2.0.1: {} + + fill-range@2.2.4: + dependencies: + is-number: 2.1.0 + isobject: 2.1.0 + randomatic: 3.1.1 + repeat-element: 1.1.4 + repeat-string: 1.6.1 + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + filled-array@1.1.0: {} + + find-cache-dir@0.1.1: + dependencies: + commondir: 1.0.1 + mkdirp: 0.5.6 + pkg-dir: 1.0.0 + + find-up@1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@3.0.0: + dependencies: + locate-path: 3.0.0 + + flat-cache@1.3.4: + dependencies: + circular-json: 0.3.3 + graceful-fs: 4.2.11 + rimraf: 2.6.3 + write: 0.2.1 + + flatted@3.3.3: {} + + flexbuffer@0.0.6: {} + + fn-name@2.0.1: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + for-in@1.0.2: {} + + for-own@0.1.5: + dependencies: + for-in: 1.0.2 + + forever-agent@0.6.1: {} + + form-data@2.3.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + formidable@1.2.6: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fresh@0.5.2: {} + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs.realpath@1.0.0: {} + + fsevents@1.2.13: + dependencies: + bindings: 1.5.0 + nan: 2.25.0 + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functional-red-black-tree@1.0.1: {} + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + get-intrinsic@1.3.0: + 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 + + get-port@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stdin@4.0.1: {} + + get-stream@3.0.0: {} + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-value@2.0.6: {} + + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + + glob-base@0.3.0: + dependencies: + glob-parent: 2.0.0 + is-glob: 2.0.1 + + glob-parent@2.0.0: + dependencies: + is-glob: 2.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@9.18.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@6.1.0: + dependencies: + array-union: 1.0.2 + glob: 7.2.3 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + + gopd@1.2.0: {} + + got@5.7.1: + dependencies: + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.3 + create-error-class: 3.0.2 + duplexer2: 0.1.4 + is-redirect: 1.0.0 + is-retry-allowed: 1.2.0 + is-stream: 1.1.0 + lowercase-keys: 1.0.1 + node-status-codes: 1.0.0 + object-assign: 4.1.1 + parse-json: 2.2.0 + pinkie-promise: 2.0.1 + read-all-stream: 3.1.0 + readable-stream: 2.3.8 + timed-out: 3.1.3 + unzip-response: 1.0.2 + url-parse-lax: 1.0.0 + + graceful-fs@4.2.11: {} + + har-schema@2.0.0: {} + + har-validator@5.1.5: + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-bigints@1.1.0: {} + + has-color@0.1.7: {} + + has-flag@2.0.0: {} + + has-flag@3.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + has-yarn@1.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + home-or-tmp@2.0.0: + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + + hosted-git-info@2.8.9: {} + + http-assert@1.5.0: + dependencies: + deep-equal: 1.0.1 + http-errors: 1.8.1 + + http-errors@1.6.3: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-signature@1.2.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore-by-default@1.0.1: {} + + ignore@3.3.10: {} + + imurmurhash@0.1.4: {} + + indent-string@2.1.0: + dependencies: + repeating: 2.0.1 + + indent-string@3.2.0: {} + + inflation@2.1.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + inquirer@3.3.0: + dependencies: + ansi-escapes: 3.2.0 + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 2.2.0 + figures: 2.0.0 + lodash: 4.17.23 + mute-stream: 0.0.7 + run-async: 2.4.1 + rx-lite: 4.0.8 + rx-lite-aggregates: 4.0.8 + string-width: 2.1.1 + strip-ansi: 4.0.0 + through: 2.3.8 + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + ioredis@2.5.0: + dependencies: + bluebird: 3.7.2 + cluster-key-slot: 1.1.2 + debug: 2.6.9 + double-ended-queue: 2.1.0-0 + flexbuffer: 0.0.6 + lodash: 4.17.23 + redis-commands: 1.7.0 + redis-parser: 1.3.0 + transitivePeerDependencies: + - supports-color + + irregular-plurals@1.4.0: {} + + is-accessor-descriptor@1.0.1: + dependencies: + hasown: 2.0.2 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.4: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-binary-path@1.0.1: + dependencies: + binary-extensions: 1.13.1 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-callable@1.2.7: {} + + is-ci@1.2.1: + dependencies: + ci-info: 1.6.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-descriptor@0.1.7: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.3: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-dotfile@1.0.3: {} + + is-equal-shallow@0.1.3: + dependencies: + is-primitive: 2.0.0 + + is-error@2.2.2: {} + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + + is-extglob@1.0.0: {} + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-finite@1.1.0: {} + + is-fullwidth-code-point@1.0.0: + dependencies: + number-is-nan: 1.0.1 + + is-fullwidth-code-point@2.0.0: {} + + is-generator-fn@1.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@2.0.1: + dependencies: + is-extglob: 1.0.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-nan@1.3.2: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + is-negative-zero@2.0.3: {} + + is-npm@1.0.0: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@2.1.0: + dependencies: + kind-of: 3.2.2 + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@4.0.0: {} + + is-obj@1.0.1: {} + + is-obj@2.0.0: {} + + is-observable@0.2.0: + dependencies: + symbol-observable: 0.2.4 + + is-plain-obj@1.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-posix-bracket@0.1.1: {} + + is-primitive@2.0.0: {} + + is-promise@2.2.2: {} + + is-redirect@1.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-resolvable@1.1.0: {} + + is-retry-allowed@1.2.0: {} + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-stream@1.1.0: {} + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-typedarray@1.0.0: {} + + is-url@1.2.4: {} + + is-utf8@0.2.1: {} + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-windows@1.0.2: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + isstream@0.1.2: {} + + jest-diff@18.1.0: + dependencies: + chalk: 1.1.3 + diff: 3.5.1 + jest-matcher-utils: 18.1.0 + pretty-format: 18.1.0 + + jest-file-exists@17.0.0: {} + + jest-matcher-utils@18.1.0: + dependencies: + chalk: 1.1.3 + pretty-format: 18.1.0 + + jest-mock@18.0.0: {} + + jest-snapshot@18.1.0: + dependencies: + jest-diff: 18.1.0 + jest-file-exists: 17.0.0 + jest-matcher-utils: 18.1.0 + jest-util: 18.1.0 + natural-compare: 1.4.0 + pretty-format: 18.1.0 + + jest-util@18.1.0: + dependencies: + chalk: 1.1.3 + diff: 3.5.1 + graceful-fs: 4.2.11 + jest-file-exists: 17.0.0 + jest-mock: 18.0.0 + mkdirp: 0.5.6 + + js-tokens@3.0.2: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + jsbn@0.1.1: {} + + jsesc@0.5.0: {} + + jsesc@1.3.0: {} + + jsesc@3.1.0: {} + + json-parse-better-errors@1.0.2: {} + + json-schema-traverse@0.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@7.0.3: {} + + json-schema@0.4.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stringify-safe@5.0.1: {} + + json5@0.5.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonwebtoken@9.0.3: + dependencies: + jws: 4.0.1 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.7.4 + + jsprim@1.4.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + keygrip@1.1.0: + dependencies: + tsscmp: 1.0.6 + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@6.0.3: {} + + koa-compose@4.1.0: {} + + koa-convert@2.0.0: + dependencies: + co: 4.6.0 + koa-compose: 4.1.0 + + koa-send@3.3.0: + dependencies: + co: 4.6.0 + debug: 2.6.9 + mz: 2.7.0 + resolve-path: 1.4.0 + transitivePeerDependencies: + - supports-color + + koa@2.16.3: + dependencies: + accepts: 1.3.8 + cache-content-type: 1.0.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookies: 0.9.1 + debug: 4.4.3 + delegates: 1.0.0 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + fresh: 0.5.2 + http-assert: 1.5.0 + http-errors: 1.8.1 + is-generator-function: 1.1.2 + koa-compose: 4.1.0 + koa-convert: 2.0.0 + on-finished: 2.4.1 + only: 0.0.2 + parseurl: 1.3.3 + statuses: 1.5.0 + type-is: 1.6.18 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + last-line-stream@1.0.0: + dependencies: + through2: 2.0.5 + + latest-version@2.0.0: + dependencies: + package-json: 2.4.0 + + lazy-req@1.1.0: {} + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + + load-json-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + pinkie-promise: 2.0.1 + strip-bom: 2.0.0 + + load-json-file@2.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + strip-bom: 3.0.0 + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@3.0.0: + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + + lodash.debounce@4.0.8: {} + + lodash.difference@4.5.0: {} + + lodash.flatten@4.4.0: {} + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isequal@4.5.0: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.merge@4.6.2: {} + + lodash.once@4.1.1: {} + + lodash@4.17.23: {} + + log4js@6.9.1: + dependencies: + date-format: 4.0.14 + debug: 4.4.3 + flatted: 3.3.3 + rfdc: 1.4.1 + streamroller: 3.1.5 + transitivePeerDependencies: + - supports-color + + long-timeout@0.1.1: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loud-rejection@1.6.0: + dependencies: + currently-unhandled: 0.4.1 + signal-exit: 3.0.7 + + lowercase-keys@1.0.1: {} + + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + + make-dir@1.3.0: + dependencies: + pify: 3.0.0 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + map-cache@0.2.2: {} + + map-obj@1.0.1: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + matcher@0.1.2: + dependencies: + escape-string-regexp: 1.0.5 + + math-intrinsics@1.1.0: {} + + math-random@1.0.4: {} + + max-timeout@1.0.0: {} + + md5-hex@1.3.0: + dependencies: + md5-o-matic: 0.1.1 + + md5-hex@2.0.0: + dependencies: + md5-o-matic: 0.1.1 + + md5-o-matic@0.1.1: {} + + media-typer@0.3.0: {} + + meow@3.7.0: + dependencies: + camelcase-keys: 2.1.0 + decamelize: 1.2.0 + loud-rejection: 1.6.0 + map-obj: 1.0.1 + minimist: 1.2.8 + normalize-package-data: 2.5.0 + object-assign: 4.1.1 + read-pkg-up: 1.0.1 + redent: 1.0.0 + trim-newlines: 1.0.0 + + methods@1.1.2: {} + + micromatch@2.3.11: + dependencies: + arr-diff: 2.0.0 + array-unique: 0.2.1 + braces: 1.8.5 + expand-brackets: 0.1.5 + extglob: 0.3.2 + filename-regex: 2.0.1 + is-extglob: 1.0.0 + is-glob: 2.0.1 + kind-of: 3.2.2 + normalize-path: 2.1.1 + object.omit: 2.0.1 + parse-glob: 3.0.4 + regex-cache: 0.4.4 + + micromatch@3.1.10: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@1.2.0: {} + + mimic-fn@2.1.0: {} + + mimic-fn@3.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + moment-timezone@0.5.48: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + + ms@0.7.3: {} + + ms@1.0.0: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + multimatch@2.1.0: + dependencies: + array-differ: 1.0.0 + array-union: 1.0.2 + arrify: 1.0.1 + minimatch: 3.1.2 + + mute-stream@0.0.7: {} + + mysql@2.18.1: + dependencies: + bignumber.js: 9.0.0 + readable-stream: 2.3.7 + safe-buffer: 5.1.2 + sqlstring: 2.3.1 + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nan@2.25.0: + optional: true + + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + node-schedule@1.3.3: + dependencies: + cron-parser: 2.18.0 + long-timeout: 0.1.1 + sorted-array-functions: 1.3.0 + + node-status-codes@1.0.0: {} + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.11 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + + npm-run-path@2.0.2: + dependencies: + path-key: 2.0.1 + + number-is-nan@1.0.1: {} + + nunjucks@3.2.4: + dependencies: + a-sync-waterfall: 1.0.1 + asap: 2.0.6 + commander: 5.1.0 + + nyc@7.1.0: {} + + oauth-sign@0.9.0: {} + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + + object.omit@2.0.1: + dependencies: + for-own: 0.1.5 + is-extendable: 0.1.1 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + observable-to-promise@0.4.0: + dependencies: + is-observable: 0.2.0 + symbol-observable: 0.2.4 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@2.0.1: + dependencies: + mimic-fn: 1.2.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + only@0.0.2: {} + + option-chain@0.1.1: + dependencies: + object-assign: 4.1.1 + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + + os-homedir@1.0.2: {} + + os-tmpdir@1.0.2: {} + + osenv@0.1.5: + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-finally@1.0.0: {} + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@3.0.0: + dependencies: + p-limit: 2.3.0 + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + package-hash@1.2.0: + dependencies: + md5-hex: 1.3.0 + + package-json@2.4.0: + dependencies: + got: 5.7.1 + registry-auth-token: 3.4.0 + registry-url: 3.1.0 + semver: 5.7.2 + + parse-glob@3.0.4: + dependencies: + glob-base: 0.3.0 + is-dotfile: 1.0.3 + is-extglob: 1.0.0 + is-glob: 2.0.1 + + parse-json@2.2.0: + dependencies: + error-ex: 1.3.4 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + + parse-ms@0.1.2: {} + + parse-ms@1.0.1: {} + + parseurl@1.3.3: {} + + pascalcase@0.1.1: {} + + path-exists@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + + path-exists@3.0.0: {} + + path-is-absolute@1.0.1: {} + + path-is-inside@1.0.2: {} + + path-key@2.0.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@1.9.0: + dependencies: + isarray: 0.0.1 + + path-type@1.1.0: + dependencies: + graceful-fs: 4.2.11 + pify: 2.3.0 + pinkie-promise: 2.0.1 + + path-type@2.0.0: + dependencies: + pify: 2.3.0 + + performance-now@2.1.0: {} + + picocolors@1.1.1: {} + + pify@2.3.0: {} + + pify@3.0.0: {} + + pinkie-promise@1.0.0: + dependencies: + pinkie: 1.0.0 + + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@1.0.0: {} + + pinkie@2.0.4: {} + + pkg-conf@2.1.0: + dependencies: + find-up: 2.1.0 + load-json-file: 4.0.0 + + pkg-dir@1.0.0: + dependencies: + find-up: 1.1.2 + + pkg-up@3.1.0: + dependencies: + find-up: 3.0.0 + + plur@1.0.0: {} + + plur@2.1.2: + dependencies: + irregular-plurals: 1.4.0 + + pluralize@7.0.0: {} + + posix-character-classes@0.1.1: {} + + possible-typed-array-names@1.1.0: {} + + prelude-ls@1.1.2: {} + + prepend-http@1.0.4: {} + + preserve@0.2.0: {} + + pretty-format@18.1.0: + dependencies: + ansi-styles: 2.2.1 + + pretty-ms@0.2.2: + dependencies: + parse-ms: 0.1.2 + + pretty-ms@2.1.0: + dependencies: + is-finite: 1.1.0 + parse-ms: 1.0.1 + plur: 1.0.0 + + private@0.1.8: {} + + process-nextick-args@2.0.1: {} + + progress@2.0.3: {} + + pseudomap@1.0.2: {} + + psl@1.15.0: + dependencies: + punycode: 2.3.1 + + punycode@2.3.1: {} + + qs@6.5.3: {} + + randomatic@3.1.1: + dependencies: + is-number: 4.0.0 + kind-of: 6.0.3 + math-random: 1.0.4 + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + read-all-stream@3.1.0: + dependencies: + pinkie-promise: 2.0.1 + readable-stream: 2.3.8 + + read-pkg-up@1.0.1: + dependencies: + find-up: 1.1.2 + read-pkg: 1.1.0 + + read-pkg-up@2.0.0: + dependencies: + find-up: 2.1.0 + read-pkg: 2.0.0 + + read-pkg@1.1.0: + dependencies: + load-json-file: 1.1.0 + normalize-package-data: 2.5.0 + path-type: 1.1.0 + + read-pkg@2.0.0: + dependencies: + load-json-file: 2.0.0 + normalize-package-data: 2.5.0 + path-type: 2.0.0 + + readable-stream@2.3.7: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readdirp@2.2.1: + dependencies: + graceful-fs: 4.2.11 + micromatch: 3.1.10 + readable-stream: 2.3.8 + transitivePeerDependencies: + - supports-color + + redent@1.0.0: + dependencies: + indent-string: 2.1.0 + strip-indent: 1.0.1 + + redis-commands@1.7.0: {} + + redis-parser@1.3.0: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regenerate@1.4.2: {} + + regenerator-runtime@0.11.1: {} + + regex-cache@0.4.4: + dependencies: + is-equal-shallow: 0.1.3 + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + regexp.prototype.flags@1.5.4: + 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 + + regexpp@1.1.0: {} + + regexpu-core@2.0.0: + dependencies: + regenerate: 1.4.2 + regjsgen: 0.2.0 + regjsparser: 0.1.5 + + registry-auth-token@3.4.0: + dependencies: + rc: 1.2.8 + safe-buffer: 5.2.1 + + registry-url@3.1.0: + dependencies: + rc: 1.2.8 + + regjsgen@0.2.0: {} + + regjsparser@0.1.5: + dependencies: + jsesc: 0.5.0 + + remove-trailing-separator@1.1.0: {} + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + repeating@2.0.1: + dependencies: + is-finite: 1.1.0 + + request@2.88.2: + dependencies: + aws-sign2: 0.7.0 + aws4: 1.13.2 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + + require-from-string@2.0.2: {} + + require-precompiled@0.1.0: {} + + require-uncached@1.0.3: + dependencies: + caller-path: 0.1.0 + resolve-from: 1.0.1 + + resolve-cwd@1.0.0: + dependencies: + resolve-from: 2.0.0 + + resolve-from@1.0.1: {} + + resolve-from@2.0.0: {} + + resolve-path@1.4.0: + dependencies: + http-errors: 1.6.3 + path-is-absolute: 1.0.1 + + resolve-url@0.2.1: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + + ret@0.1.15: {} + + rfdc@1.4.1: {} + + rimraf@2.6.3: + dependencies: + glob: 7.2.3 + + run-async@2.4.1: {} + + rx-lite-aggregates@4.0.8: + dependencies: + rx-lite: 4.0.8 + + rx-lite@4.0.8: {} + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safer-buffer@2.1.2: {} + + sax@1.4.4: {} + + semver-diff@2.1.0: + dependencies: + semver: 5.7.2 + + semver@5.3.0: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + + setprototypeof@1.1.0: {} + + setprototypeof@1.2.0: {} + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-regex@1.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + slash@1.0.0: {} + + slice-ansi@0.0.4: {} + + slice-ansi@1.0.0: + dependencies: + is-fullwidth-code-point: 2.0.0 + + slide@1.1.6: {} + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + sort-keys@2.0.0: + dependencies: + is-plain-obj: 1.1.0 + + sorted-array-functions@1.3.0: {} + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-support@0.4.18: + dependencies: + source-map: 0.5.7 + + source-map-url@0.4.1: {} + + source-map@0.5.7: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.22 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.22 + + spdx-license-ids@3.0.22: {} + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + sprintf-js@1.0.3: {} + + sqlstring@2.3.1: {} + + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + + stack-trace@0.0.9: {} + + stack-utils@1.0.5: + dependencies: + escape-string-regexp: 2.0.0 + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + streamroller@3.1.5: + dependencies: + date-format: 4.0.14 + debug: 4.4.3 + fs-extra: 8.1.0 + transitivePeerDependencies: + - supports-color + + string-hash@1.1.3: {} + + string-width@1.0.2: + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-ansi@0.1.1: {} + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-bom-buf@1.0.0: + dependencies: + is-utf8: 0.2.1 + + strip-bom@2.0.0: + dependencies: + is-utf8: 0.2.1 + + strip-bom@3.0.0: {} + + strip-eof@1.0.0: {} + + strip-indent@1.0.1: + dependencies: + get-stdin: 4.0.1 + + strip-json-comments@2.0.1: {} + + strnum@1.1.2: {} + + supports-color@2.0.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-observable@0.2.4: {} + + table@4.0.2: + dependencies: + ajv: 5.5.2 + ajv-keywords: 2.1.1(ajv@5.5.2) + chalk: 2.4.2 + lodash: 4.17.23 + slice-ansi: 1.0.0 + string-width: 2.1.1 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + think-cache-file@1.1.2: + dependencies: + think-debounce: 1.0.4 + think-gc: 1.0.3 + think-helper: 1.1.4 + think-store-file: 1.1.1 + + think-cache-redis@1.2.6: + dependencies: + think-helper: 1.1.4 + think-redis: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-cache@1.1.2: + dependencies: + think-debounce: 1.0.4 + think-helper: 1.1.4 + + think-cluster@1.5.8: + dependencies: + debug: 2.6.9 + string-hash: 1.1.3 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-config@1.1.3: + dependencies: + think-helper: 1.1.4 + + think-controller@1.0.5: + dependencies: + think-helper: 1.1.4 + + think-crontab@1.0.4: + dependencies: + debug: 2.6.9 + node-schedule: 1.3.3 + think-cluster: 1.5.8 + think-helper: 1.1.4 + think-mock-http: 1.0.6 + transitivePeerDependencies: + - supports-color + + think-debounce@1.0.4: {} + + think-gc@1.0.3: + dependencies: + think-helper: 1.1.4 + think-ms: 1.0.3 + + think-helper@1.1.4: + dependencies: + core-util-is: 1.0.3 + lodash.merge: 4.6.2 + ms: 1.0.0 + uuid: 7.0.3 + + think-instance@1.0.2: + dependencies: + think-helper: 1.1.4 + + think-loader@1.2.2: + dependencies: + debug: 2.6.9 + path-to-regexp: 1.9.0 + think-helper: 1.1.4 + thinkjs: 3.2.15 + transitivePeerDependencies: + - supports-color + + think-logger3@1.4.0: + dependencies: + log4js: 6.9.1 + transitivePeerDependencies: + - supports-color + + think-logic@1.2.2: + dependencies: + think-helper: 1.1.4 + + think-meta@1.0.6: + dependencies: + think-helper: 1.1.4 + + think-mock-http@1.0.6: + dependencies: + debug: 2.6.9 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-model-abstract@1.6.5: + dependencies: + debug: 3.2.7 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-model-mysql@1.1.7: + dependencies: + think-debounce: 1.0.4 + think-helper: 1.1.4 + think-model-abstract: 1.6.5 + think-mysql: 1.4.4 + transitivePeerDependencies: + - supports-color + + think-model@1.5.4: + dependencies: + think-cache: 1.1.2 + think-debounce: 1.0.4 + think-helper: 1.1.4 + think-model-abstract: 1.6.5 + transitivePeerDependencies: + - supports-color + + think-ms@1.0.3: + dependencies: + ms: 1.0.0 + + think-mysql@1.4.4: + dependencies: + debug: 2.6.9 + mysql: 2.18.1 + think-debounce: 1.0.4 + think-helper: 1.1.4 + think-instance: 1.0.2 + transitivePeerDependencies: + - supports-color + + think-payload@1.4.0: + dependencies: + formidable: 1.2.6 + inflation: 2.1.0 + on-finished: 2.4.1 + raw-body: 2.5.3 + think-helper: 1.1.4 + xml2js: 0.4.23 + + think-pm2@1.0.0: {} + + think-redis@1.1.4: + dependencies: + ioredis: 2.5.0 + think-debounce: 1.0.4 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-resource@1.0.3: + dependencies: + debug: 2.6.9 + koa-send: 3.3.0 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-router@1.3.5: + dependencies: + debug: 2.6.9 + path-to-regexp: 1.9.0 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-session-file@1.1.4: + dependencies: + debug: 2.6.9 + think-debounce: 1.0.4 + think-gc: 1.0.3 + think-helper: 1.1.4 + think-store-file: 1.1.1 + transitivePeerDependencies: + - supports-color + + think-session@1.1.6: + dependencies: + think-helper: 1.1.4 + + think-store-file@1.1.1: + dependencies: + think-debounce: 1.0.4 + think-helper: 1.1.4 + + think-trace@1.0.18: + dependencies: + source-map-support: 0.4.18 + stack-trace: 0.0.9 + statuses: 1.5.0 + think-helper: 1.1.4 + + think-validator@1.6.7: + dependencies: + think-helper: 1.1.4 + validator: 9.4.1 + + think-view-nunjucks@1.0.11: + dependencies: + nunjucks: 3.2.4 + think-helper: 1.1.4 + transitivePeerDependencies: + - chokidar + + think-view@1.0.13: + dependencies: + debug: 2.6.9 + methods: 1.1.2 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + think-watcher@3.0.4: + dependencies: + debug: 2.6.9 + think-helper: 1.1.4 + transitivePeerDependencies: + - supports-color + + thinkjs@3.2.15: + dependencies: + cookies: 0.8.0 + debug: 3.2.7 + destroy: 1.2.0 + koa: 2.16.3 + on-finished: 2.4.1 + think-cluster: 1.5.8 + think-config: 1.1.3 + think-controller: 1.0.5 + think-crontab: 1.0.4 + think-helper: 1.1.4 + think-loader: 1.2.2 + think-logger3: 1.4.0 + think-logic: 1.2.2 + think-meta: 1.0.6 + think-mock-http: 1.0.6 + think-payload: 1.4.0 + think-pm2: 1.0.0 + think-resource: 1.0.3 + think-router: 1.3.5 + think-trace: 1.0.18 + think-validator: 1.6.7 + transitivePeerDependencies: + - supports-color + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + through@2.3.8: {} + + time-require@0.1.2: + dependencies: + chalk: 0.4.0 + date-time: 0.1.1 + pretty-ms: 0.2.2 + text-table: 0.2.0 + + timed-out@3.1.3: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + to-fast-properties@1.0.3: {} + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + toidentifier@1.0.1: {} + + tough-cookie@2.5.0: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + + trim-newlines@1.0.0: {} + + trim-right@1.0.1: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: + optional: true + + tsscmp@1.0.6: {} + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tweetnacl@0.14.5: {} + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + 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 + + typedarray@0.0.6: {} + + uid2@0.0.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.16.0: {} + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + unique-temp-dir@1.0.0: + dependencies: + mkdirp: 0.5.6 + os-tmpdir: 1.0.2 + uid2: 0.0.3 + + universalify@0.1.2: {} + + unpipe@1.0.0: {} + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + unzip-response@1.0.2: {} + + update-notifier@1.0.3: + dependencies: + boxen: 0.6.0 + chalk: 1.1.3 + configstore: 2.1.0 + is-npm: 1.0.0 + latest-version: 2.0.0 + lazy-req: 1.1.0 + semver-diff: 2.1.0 + xdg-basedir: 2.0.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urix@0.1.0: {} + + url-parse-lax@1.0.0: + dependencies: + prepend-http: 1.0.4 + + use@3.1.1: {} + + util-deprecate@1.0.2: {} + + uuid@2.0.3: {} + + uuid@3.4.0: {} + + uuid@7.0.3: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validator@9.4.1: {} + + vary@1.1.2: {} + + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + widest-line@1.0.0: + dependencies: + string-width: 1.0.2 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + write-file-atomic@1.3.4: + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + slide: 1.1.6 + + write-file-atomic@2.4.3: + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-json-file@2.3.0: + dependencies: + detect-indent: 5.0.0 + graceful-fs: 4.2.11 + make-dir: 1.3.0 + pify: 3.0.0 + sort-keys: 2.0.0 + write-file-atomic: 2.4.3 + + write-pkg@3.2.0: + dependencies: + sort-keys: 2.0.0 + write-json-file: 2.3.0 + + write@0.2.1: + dependencies: + mkdirp: 0.5.6 + + xdg-basedir@2.0.0: + dependencies: + os-homedir: 1.0.2 + + xml2js@0.4.23: + dependencies: + sax: 1.4.4 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xtend@4.0.2: {} + + yallist@2.1.2: {} + + ylru@1.4.0: {} diff --git a/production.js b/production.js new file mode 100644 index 0000000..e959b1f --- /dev/null +++ b/production.js @@ -0,0 +1,11 @@ +const path = require('path'); +const Application = require('thinkjs'); + +const instance = new Application({ + ROOT_PATH: __dirname, + APP_PATH: path.join(__dirname, 'src'), + proxy: true, // use proxy + env: 'production' +}); + +instance.run(); diff --git a/sql/init.sql b/sql/init.sql new file mode 100644 index 0000000..bcbb487 --- /dev/null +++ b/sql/init.sql @@ -0,0 +1,85 @@ +-- 创建数据库 +CREATE DATABASE IF NOT EXISTS `pap_web` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +USE `pap_web`; + +-- ======================================== +-- 系统管理模块 +-- ======================================== + +-- 管理员用户表 +CREATE TABLE `admin_user` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `username` varchar(50) NOT NULL COMMENT '用户名', + `password` varchar(64) NOT NULL COMMENT '密码(MD5)', + `nickname` varchar(50) DEFAULT '' COMMENT '昵称', + `avatar` varchar(255) DEFAULT '' COMMENT '头像', + `email` varchar(100) DEFAULT '' COMMENT '邮箱', + `phone` varchar(20) DEFAULT '' COMMENT '手机号', + `role_id` int(11) unsigned DEFAULT 0 COMMENT '角色ID', + `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间', + `last_login_ip` varchar(50) DEFAULT '' COMMENT '最后登录IP', + `status` tinyint(1) DEFAULT 1 COMMENT '状态: 1启用 0停用', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '软删除: 0正常 1已删除', + `create_by` int(11) unsigned DEFAULT 0 COMMENT '创建人ID', + `update_by` int(11) unsigned DEFAULT 0 COMMENT '修改人ID', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_username` (`username`), + KEY `idx_role_id` (`role_id`), + KEY `idx_status` (`status`), + KEY `idx_is_deleted` (`is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='管理员用户表'; + +-- 角色表 +CREATE TABLE `admin_role` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL COMMENT '角色名称', + `code` varchar(50) DEFAULT '' COMMENT '角色编码', + `description` varchar(200) DEFAULT '' COMMENT '角色描述', + `permissions` json DEFAULT NULL COMMENT '权限列表(JSON)', + `is_default` tinyint(1) DEFAULT 0 COMMENT '是否默认角色: 0否 1是', + `sort` int(11) DEFAULT 0 COMMENT '排序', + `status` tinyint(1) DEFAULT 1 COMMENT '状态: 1启用 0停用', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '软删除: 0正常 1已删除', + `create_by` int(11) unsigned DEFAULT 0 COMMENT '创建人ID', + `update_by` int(11) unsigned DEFAULT 0 COMMENT '修改人ID', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_status` (`status`), + KEY `idx_is_deleted` (`is_deleted`), + KEY `idx_sort` (`sort`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表'; + +-- 操作日志表 +CREATE TABLE `admin_log` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `user_id` int(11) unsigned DEFAULT 0 COMMENT '操作用户ID', + `username` varchar(50) DEFAULT '' COMMENT '操作用户名', + `action` varchar(100) NOT NULL COMMENT '操作类型', + `module` varchar(50) DEFAULT '' COMMENT '操作模块', + `content` text COMMENT '操作内容', + `ip` varchar(50) DEFAULT '' COMMENT 'IP地址', + `user_agent` varchar(500) DEFAULT '' COMMENT 'User-Agent', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_action` (`action`), + KEY `idx_create_time` (`create_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表'; + +-- ======================================== +-- 初始化数据 +-- ======================================== + +-- 插入默认角色 +INSERT INTO `admin_role` (`id`, `name`, `code`, `description`, `permissions`, `is_default`, `sort`, `create_by`) VALUES +(1, '超级管理员', 'ADMIN', '拥有所有权限', '["*"]', 1, 1, 0), +(2, '内容编辑', 'EDITOR', '内容管理权限', '["content:article","content:image","content:page"]', 0, 2, 0), +(3, '审核员', 'AUDITOR', '内容审核权限', '["content:article:view","content:article:audit"]', 0, 3, 0); + +-- 插入默认管理员 (密码: admin123, MD5加密) +INSERT INTO `admin_user` (`username`, `password`, `nickname`, `role_id`, `create_by`) VALUES +('admin', '0192023a7bbd73250516f069df18b500', '超级管理员', 1, 0); diff --git a/sql/update_20260211_article.sql b/sql/update_20260211_article.sql new file mode 100644 index 0000000..a85f819 --- /dev/null +++ b/sql/update_20260211_article.sql @@ -0,0 +1,34 @@ +-- 图文列表表 +CREATE TABLE IF NOT EXISTS `pap_article` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `title` varchar(500) NOT NULL DEFAULT '' COMMENT '文章标题', + `summary` varchar(1000) DEFAULT '' COMMENT '文章摘要', + `content` longtext COMMENT '文章正文', + `cover` varchar(500) DEFAULT '' COMMENT '封面图', + `category` varchar(100) DEFAULT '' COMMENT '分类', + `is_top` tinyint(1) DEFAULT 0 COMMENT '置顶 1是 0否', + `is_recommend` tinyint(1) DEFAULT 0 COMMENT '推荐到首页 1是 0否', + `sort` int(11) DEFAULT 0 COMMENT '排序权重', + `status` tinyint(1) DEFAULT 0 COMMENT '状态 1已发布 2待审核 0草稿', + `publish_time` datetime DEFAULT NULL COMMENT '发布时间', + `seo_title` varchar(200) DEFAULT '' COMMENT 'SEO标题', + `seo_keywords` varchar(500) DEFAULT '' COMMENT 'SEO关键词', + `seo_description` varchar(1000) DEFAULT '' COMMENT 'SEO描述', + `view_count` int(11) DEFAULT 0 COMMENT '浏览量', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_status` (`status`, `is_deleted`), + KEY `idx_top` (`is_top`, `sort`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图文列表'; + +-- 测试数据 +INSERT INTO `pap_article` (`column_id`, `title`, `summary`, `cover`, `category`, `is_top`, `status`, `publish_time`, `sort`) VALUES +(0, '北京维康慈善基金会再次获得2026年度-2028年度公益性捐赠税前扣除资格', '北京维康慈善基金会近日再次获得财政部、国家税务总局联合认定的2026年度至2028年度公益性捐赠税前扣除资格。', '/static/images/article1.jpg', '基金会动态', 1, 1, '2026-01-27 10:30:00', 100), +(0, '北京维康慈善基金会荣获第十五届公益节年度两项大奖', '在第十五届公益节上,北京维康慈善基金会凭借在公益领域的突出贡献,荣获年度两项大奖。', '/static/images/article2.jpg', '基金会动态', 0, 1, '2026-01-26 14:20:00', 0), +(0, '善行边疆,"爱护妳"公益项目走进漠河', '"爱护妳"公益项目团队深入祖国最北端漠河,为当地妇女儿童送去健康关爱。', '/static/images/article3.jpg', '基金会动态', 0, 1, '2026-01-23 09:15:00', 0), +(0, '妇幼健康促进项目', '聚焦妇幼健康促进,为偏远地区家庭带去专业医疗资源与关怀。', '/static/images/project1.jpg', '公益项目', 1, 1, '2026-01-20 08:30:00', 90), +(0, '"安心医"患者关爱项目', '携手医药企业,为经济困难的患者提供药品援助,减轻治疗负担。', '/static/images/project2.jpg', '公益项目', 1, 1, '2026-01-18 15:20:00', 80); diff --git a/sql/update_20260211_banner.sql b/sql/update_20260211_banner.sql new file mode 100644 index 0000000..95b3830 --- /dev/null +++ b/sql/update_20260211_banner.sql @@ -0,0 +1,31 @@ +-- Banner轮播图表 +CREATE TABLE IF NOT EXISTS `pap_banner` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `title` varchar(200) NOT NULL DEFAULT '' COMMENT '主标题', + `subtitle` varchar(200) DEFAULT '' COMMENT '副标题', + `description` text COMMENT '描述文字', + `image` varchar(500) NOT NULL DEFAULT '' COMMENT '图片地址', + `btn1_text` varchar(50) DEFAULT '了解更多' COMMENT '按钮1文字', + `btn1_link` varchar(500) DEFAULT '#' COMMENT '按钮1链接', + `btn1_show` tinyint(1) DEFAULT 1 COMMENT '按钮1显示 1是 0否', + `btn2_text` varchar(50) DEFAULT '我要捐赠' COMMENT '按钮2文字', + `btn2_link` varchar(500) DEFAULT '#' COMMENT '按钮2链接', + `btn2_show` tinyint(1) DEFAULT 1 COMMENT '按钮2显示 1是 0否', + `position` varchar(20) DEFAULT 'left' COMMENT '文字位置 left/center/right', + `glass` tinyint(1) DEFAULT 1 COMMENT '毛玻璃效果 1启用 0关闭', + `sort` int(11) DEFAULT 1 COMMENT '排序', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1启用 0禁用', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_status` (`status`, `is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Banner轮播图'; + +-- 测试数据 +INSERT INTO `pap_banner` (`column_id`, `title`, `subtitle`, `description`, `image`, `btn1_text`, `btn1_link`, `btn1_show`, `btn2_text`, `btn2_link`, `btn2_show`, `position`, `glass`, `sort`) VALUES +(0, '也许因为您的一次帮助', '天真的笑容将再次回到他的脸上', '关注儿童健康成长,让每一份爱心都能传递温暖与希望。北京维康慈善基金会致力于妇幼健康、患者关爱、卫生健康促进等公益事业。', '/static/images/banner1.jpg', '了解更多', '#', 1, '我要捐赠', '#', 1, 'left', 0, 1), +(0, '守护每一份健康', '让爱与希望同行', '聚焦妇幼健康促进,为偏远地区家庭带去专业医疗资源与关怀,让每个生命都被温柔以待。', '/static/images/banner2.jpg', '了解项目', '#', 1, '参与公益', '#', 1, 'left', 1, 2), +(0, '透明公益 值得信赖', '每一笔善款都有迹可循', '严格遵循FTI中基透明指数标准,实时公示捐赠收支明细,让公益在阳光下运行。', '/static/images/banner3.jpg', '查看公示', '#', 1, '信息公开', '#', 0, 'left', 1, 3); diff --git a/sql/update_20260211_column.sql b/sql/update_20260211_column.sql new file mode 100644 index 0000000..b30f49f --- /dev/null +++ b/sql/update_20260211_column.sql @@ -0,0 +1,74 @@ +-- 栏目管理表 +CREATE TABLE IF NOT EXISTS `pap_column` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `parent_id` int(11) DEFAULT '0' COMMENT '父级ID,0为顶级', + `name` varchar(100) NOT NULL COMMENT '栏目名称', + `key` varchar(50) DEFAULT '' COMMENT '栏目标识,用于路由', + `icon` varchar(50) DEFAULT '' COMMENT '图标名称(Element Plus图标)', + `type` varchar(20) DEFAULT '' COMMENT '内容类型:article/image/text/page/person/form/donation/job', + `is_single_page` tinyint(1) DEFAULT '0' COMMENT '一级栏目类型:1=单页面(二级为模块), 0=多页面(二级为独立页面)', + `sort` int(11) DEFAULT '1' COMMENT '排序', + `visible` tinyint(1) DEFAULT '1' COMMENT '显示状态:1=显示, 0=隐藏', + `link` varchar(500) DEFAULT '' COMMENT '外部链接', + `seo_title` varchar(200) DEFAULT '' COMMENT 'SEO标题', + `seo_keywords` varchar(300) DEFAULT '' COMMENT 'SEO关键词', + `seo_description` text COMMENT 'SEO描述', + `slug` varchar(100) DEFAULT '' COMMENT 'URL别名', + `form_config` text COMMENT '表单配置JSON', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) DEFAULT '0' COMMENT '0=正常, 1=删除', + PRIMARY KEY (`id`), + KEY `idx_parent_id` (`parent_id`), + KEY `idx_sort` (`sort`), + KEY `idx_key` (`key`), + KEY `idx_is_deleted` (`is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='栏目管理'; + +-- 如果表已存在,添加字段 +-- ALTER TABLE `pap_column` ADD COLUMN `key` varchar(50) DEFAULT '' COMMENT '栏目标识,用于路由' AFTER `name`; +-- ALTER TABLE `pap_column` ADD COLUMN `icon` varchar(50) DEFAULT '' COMMENT '图标名称(Element Plus图标)' AFTER `key`; +-- ALTER TABLE `pap_column` ADD COLUMN `is_single_page` tinyint(1) DEFAULT '0' COMMENT '一级栏目类型:1=单页面(二级为模块), 0=多页面(二级为独立页面)' AFTER `type`; + +-- 初始数据 +INSERT INTO `pap_column` (`id`, `parent_id`, `name`, `key`, `icon`, `type`, `is_single_page`, `sort`, `visible`) VALUES +(1, 0, '首页', 'home', 'HomeFilled', '', 1, 1, 1), +(2, 1, 'Banner轮播', 'home-banner', '', 'image', 0, 1, 1), +(3, 1, '数据看板', 'home-data', '', 'donation', 0, 2, 1), +(4, 1, '药品援助公示', 'home-medicine', '', 'text', 0, 3, 1), +(5, 1, '公益项目', 'home-project', '', 'article', 0, 4, 1), +(6, 1, '新闻动态', 'home-news', '', 'article', 0, 5, 1), +(7, 1, '合作伙伴', 'home-partner', '', 'image', 0, 6, 1), +(10, 0, '关于我们', 'about', 'OfficeBuilding', '', 0, 2, 1), +(11, 10, '基金会简介', 'about-intro', '', 'page', 0, 1, 1), +(12, 10, '组织架构', 'about-org', '', 'page', 0, 2, 1), +(13, 10, '理事会&监事', 'about-council', '', 'person', 0, 3, 1), +(14, 10, '资质证书', 'about-cert', '', 'image', 0, 4, 1), +(15, 10, '联系我们', 'about-contact', '', 'page', 0, 5, 1), +(20, 0, '公益项目', 'project', 'Present', 'article', 0, 3, 1), +(21, 20, '妇幼健康促进', 'proj-1', '', 'article', 0, 1, 1), +(22, 20, '"安心医"患者关爱', 'proj-2', '', 'article', 0, 2, 1), +(23, 20, '卫生健康促进', 'proj-3', '', 'article', 0, 3, 1), +(24, 20, '医疗科普公益', 'proj-4', '', 'article', 0, 4, 1), +(25, 20, '品牌建设与传播', 'proj-5', '', 'article', 0, 5, 1), +(30, 0, '党建专栏', 'party', 'Flag', '', 0, 4, 1), +(31, 30, '党建规章', 'party-rule', '', 'text', 0, 1, 1), +(32, 30, '党建活动', 'party-act', '', 'article', 0, 2, 1), +(33, 30, '党建学习', 'party-study', '', 'article', 0, 3, 1), +(40, 0, '信息公示', 'disclosure', 'Document', 'text', 0, 5, 1), +(41, 40, '管理制度', 'disc-rule', '', 'text', 0, 1, 1), +(42, 40, '机构年报', 'disc-annual', '', 'text', 0, 2, 1), +(43, 40, '审计报告', 'disc-audit', '', 'text', 0, 3, 1), +(44, 40, '财务报告', 'disc-finance', '', 'text', 0, 4, 1), +(45, 40, '关联方信息', 'disc-related', '', 'text', 0, 5, 1), +(46, 40, '项目执行报告', 'disc-exec', '', 'text', 0, 6, 1), +(50, 0, '新闻中心', 'news', 'Notification', 'article', 0, 6, 1), +(51, 50, '基金会动态', 'news-found', '', 'article', 0, 1, 1), +(52, 50, '行业资讯', 'news-indust', '', 'article', 0, 2, 1), +(53, 50, '通知公告', 'news-notice', '', 'article', 0, 3, 1), +(60, 0, '联系我们', 'contact', 'Phone', '', 0, 7, 1), +(61, 60, '基本信息', 'ct-info', '', 'page', 0, 1, 1), +(62, 60, '关注我们', 'ct-follow', '', 'page', 0, 2, 1), +(63, 60, '人才招聘', 'ct-job', '', 'job', 0, 3, 1), +(64, 60, '志愿者中心', 'ct-volunteer', '', 'form', 0, 4, 1), +(65, 60, '合作申请', 'ct-coop', '', 'form', 0, 5, 1); diff --git a/sql/update_20260211_config.sql b/sql/update_20260211_config.sql new file mode 100644 index 0000000..3a952b8 --- /dev/null +++ b/sql/update_20260211_config.sql @@ -0,0 +1,45 @@ +-- 网站配置表 +-- 执行时间: 2026-02-11 + +CREATE TABLE IF NOT EXISTS `config` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `group` varchar(50) NOT NULL COMMENT '配置分组: basic/seo/contact/social', + `key` varchar(100) NOT NULL COMMENT '配置键', + `value` text COMMENT '配置值', + `type` varchar(20) DEFAULT 'text' COMMENT '类型: text/textarea/image', + `label` varchar(100) COMMENT '显示名称', + `sort` int(11) DEFAULT 0 COMMENT '排序', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_group_key` (`group`, `key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='网站配置表'; + +-- 初始化基础配置 +INSERT INTO `config` (`group`, `key`, `value`, `type`, `label`, `sort`) VALUES +-- 基础设置 +('basic', 'site_name', '北京维康慈善基金会', 'text', '站点名称', 1), +('basic', 'site_subtitle', '促进公众健康,助力医疗公益', 'text', '站点副标题', 2), +('basic', 'site_domain', 'www.vkfoundation.cn', 'text', '网站域名', 3), +('basic', 'icp_number', '', 'text', 'ICP备案号', 4), +('basic', 'copyright', '© 2026 北京维康慈善基金会 版权所有', 'text', '版权信息', 5), +('basic', 'logo', '', 'image', '网站Logo', 6), +('basic', 'wechat_qrcode', '', 'image', '公众号二维码', 7), +-- SEO设置 +('seo', 'page_title', '北京维康慈善基金会 - 促进公众健康,助力医疗公益', 'text', '页面标题', 1), +('seo', 'keywords', '维康慈善基金会,公益,慈善,医疗公益,妇幼健康', 'text', '关键词', 2), +('seo', 'description', '北京维康慈善基金会致力于妇幼健康促进、患者关爱、卫生健康促进、医疗科普等公益事业。', 'textarea', '描述', 3), +('seo', 'favicon', '', 'image', 'Favicon', 4), +-- 联系信息 +('contact', 'phone', '', 'text', '联系电话', 1), +('contact', 'email', '', 'text', '联系邮箱', 2), +('contact', 'address', '', 'text', '办公地址', 3), +('contact', 'postcode', '', 'text', '邮政编码', 4), +('contact', 'map_lng', '', 'text', '地图坐标(经度)', 5), +('contact', 'map_lat', '', 'text', '地图坐标(纬度)', 6), +-- 社交媒体 +('social', 'wechat_name', '', 'text', '微信公众号名称', 1), +('social', 'wechat_id', '', 'text', '微信公众号ID', 2), +('social', 'weibo_url', '', 'text', '微博链接', 3), +('social', 'douyin_url', '', 'text', '抖音链接', 4), +('social', 'video_url', '', 'text', '视频号链接', 5) +ON DUPLICATE KEY UPDATE `label` = VALUES(`label`), `sort` = VALUES(`sort`); diff --git a/sql/update_20260211_donation.sql b/sql/update_20260211_donation.sql new file mode 100644 index 0000000..2492188 --- /dev/null +++ b/sql/update_20260211_donation.sql @@ -0,0 +1,49 @@ +-- 捐赠收支数据表 +CREATE TABLE IF NOT EXISTS `pap_donation` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `type` varchar(20) NOT NULL DEFAULT 'income' COMMENT '类型:income收入/expense支出', + `name` varchar(200) NOT NULL DEFAULT '' COMMENT '捐赠人/单位 或 支出项目', + `amount` decimal(18,2) DEFAULT 0.00 COMMENT '金额', + `purpose` varchar(200) DEFAULT '' COMMENT '用途/项目 或 受益对象', + `source` varchar(20) DEFAULT 'manual' COMMENT '来源:manual手动/kingdee金蝶', + `record_date` date DEFAULT NULL COMMENT '日期', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1已公示 0待公示', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_type` (`type`), + KEY `idx_status` (`status`, `is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='捐赠收支数据'; + +-- 捐赠统计表(单独维护) +CREATE TABLE IF NOT EXISTS `pap_donation_stat` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `total_income` decimal(18,2) DEFAULT 0.00 COMMENT '累计捐赠收入', + `total_expense` decimal(18,2) DEFAULT 0.00 COMMENT '累计公益支出', + `year_income` decimal(18,2) DEFAULT 0.00 COMMENT '本年度收入', + `year_expense` decimal(18,2) DEFAULT 0.00 COMMENT '本年度支出', + `sync_time` datetime DEFAULT NULL COMMENT '最后同步时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `idx_column` (`column_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='捐赠统计'; + +-- 测试数据 +INSERT INTO `pap_donation` (`column_id`, `type`, `name`, `amount`, `purpose`, `source`, `record_date`, `status`) VALUES +(0, 'income', '上海复宏汉霖生物制药有限公司', 948839117.38, '妇幼健康促进项目', 'kingdee', '2026-01-20', 1), +(0, 'income', 'CStone Pharm (HK) Holding Limited', 547853600.47, '"安心医"患者关爱', 'kingdee', '2026-01-15', 1), +(0, 'income', '齐鲁制药有限公司', 395642961.90, '卫生健康促进', 'kingdee', '2026-01-10', 1), +(0, 'income', '江西济民可信医药贸易有限公司', 187654617.64, '医疗科普公益', 'kingdee', '2026-01-05', 1), +(0, 'income', '康方药业有限公司', 141383697.53, '品牌建设与传播', 'kingdee', '2025-12-28', 1), +(0, 'expense', '妇幼健康促进项目-第一季度执行', 948839117.38, '妇幼群体', 'kingdee', '2026-01-28', 1), +(0, 'expense', '"安心医"患者关爱-药品采购', 547853600.47, '患者群体', 'kingdee', '2026-01-20', 1), +(0, 'expense', '卫生健康促进-社区义诊活动', 395642961.90, '社区居民', 'kingdee', '2026-01-15', 1), +(0, 'expense', '医疗科普公益-宣传物料制作', 187654617.64, '公众', 'kingdee', '2026-01-10', 1); + +-- 初始统计数据 +INSERT INTO `pap_donation_stat` (`column_id`, `total_income`, `total_expense`, `year_income`, `year_expense`) VALUES +(0, 178255656.50, 178255656.50, 32456789.00, 28123456.00); diff --git a/sql/update_20260211_image.sql b/sql/update_20260211_image.sql new file mode 100644 index 0000000..a576b3c --- /dev/null +++ b/sql/update_20260211_image.sql @@ -0,0 +1,25 @@ +-- 图片列表表 +CREATE TABLE IF NOT EXISTS `pap_image` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `title` varchar(200) NOT NULL DEFAULT '' COMMENT '标题', + `image` varchar(500) NOT NULL DEFAULT '' COMMENT '图片地址', + `link` varchar(500) DEFAULT '' COMMENT '链接地址', + `sort` int(11) DEFAULT 1 COMMENT '排序', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1启用 0禁用', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_status` (`status`, `is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图片列表'; + +-- 测试数据 +INSERT INTO `pap_image` (`column_id`, `title`, `image`, `link`, `sort`, `status`) VALUES +(0, '合作伙伴1', '/static/images/partner1.png', '', 1, 1), +(0, '合作伙伴2', '/static/images/partner2.png', '', 2, 1), +(0, '合作伙伴3', '/static/images/partner3.png', '', 3, 1), +(0, '合作伙伴4', '/static/images/partner4.png', '', 4, 1), +(0, '合作伙伴5', '/static/images/partner5.png', '', 5, 1), +(0, '合作伙伴6', '/static/images/partner6.png', '', 6, 1); diff --git a/sql/update_20260211_job.sql b/sql/update_20260211_job.sql new file mode 100644 index 0000000..472cf11 --- /dev/null +++ b/sql/update_20260211_job.sql @@ -0,0 +1,26 @@ +-- 岗位管理表 +CREATE TABLE IF NOT EXISTS `pap_job` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `name` varchar(100) NOT NULL DEFAULT '' COMMENT '岗位名称', + `department` varchar(100) DEFAULT '' COMMENT '所属部门', + `location` varchar(100) DEFAULT '' COMMENT '工作地点', + `count` int(11) DEFAULT 1 COMMENT '招聘人数', + `duty` text COMMENT '岗位职责', + `requirement` text COMMENT '任职要求', + `salary` varchar(100) DEFAULT '' COMMENT '薪资范围', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1招聘中 0已关闭', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_status` (`status`, `is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='岗位管理'; + +-- 测试数据 +INSERT INTO `pap_job` (`column_id`, `name`, `department`, `location`, `count`, `duty`, `requirement`, `salary`, `status`) VALUES +(0, '项目专员', '项目部', '北京', 2, '负责公益项目的策划、执行与跟进', '本科及以上学历,1年以上公益项目经验', '8K-12K', 1), +(0, '新媒体运营', '品牌传播部', '北京', 1, '负责基金会新媒体平台内容运营', '本科及以上,熟悉微信公众号运营', '7K-10K', 1), +(0, '财务主管', '财务部', '北京', 1, '负责基金会日常财务管理与报表编制', '本科及以上,3年以上财务工作经验', '12K-18K', 1), +(0, '行政助理', '综合管理部', '北京', 1, '协助行政日常事务处理', '大专及以上学历', '5K-7K', 0); diff --git a/sql/update_20260211_medicine.sql b/sql/update_20260211_medicine.sql new file mode 100644 index 0000000..fdd6d15 --- /dev/null +++ b/sql/update_20260211_medicine.sql @@ -0,0 +1,44 @@ +-- 药品援助记录表 +CREATE TABLE IF NOT EXISTS `pap_medicine` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL COMMENT '药品名称', + `person` varchar(100) NOT NULL COMMENT '受助人', + `region` varchar(100) DEFAULT NULL COMMENT '地区', + `quantity` varchar(50) DEFAULT '1盒' COMMENT '数量', + `amount` decimal(12,2) DEFAULT '0.00' COMMENT '金额', + `status` tinyint(1) DEFAULT '2' COMMENT '状态:1=已发放, 2=待发放, 3=已取消', + `distribute_date` date DEFAULT NULL COMMENT '发放日期', + `year` int(4) DEFAULT NULL COMMENT '年度', + `remark` text COMMENT '备注', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) DEFAULT '0' COMMENT '0=正常, 1=删除', + PRIMARY KEY (`id`), + KEY `idx_year` (`year`), + KEY `idx_status` (`status`), + KEY `idx_is_deleted` (`is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='药品援助记录'; + + +-- 测试数据 +INSERT INTO `pap_medicine` (`name`, `person`, `region`, `quantity`, `amount`, `status`, `distribute_date`, `year`) VALUES +('佳泰莱(芦康沙妥珠单抗)', '张*三', '上海', '1盒', 15000.00, 1, '2026-02-10', 2026), +('佳泰莱(芦康沙妥珠单抗)', '李*四', '四川成都', '1盒', 15000.00, 1, '2026-02-10', 2026), +('佳泰莱(芦康沙妥珠单抗)', '王*五', '湖北武汉', '1盒', 15000.00, 1, '2026-02-09', 2026), +('佳泰莱(芦康沙妥珠单抗)', '赵*六', '北京', '1盒', 15000.00, 1, '2026-02-09', 2026), +('佳泰莱(芦康沙妥珠单抗)', '刘*七', '广东广州', '1盒', 15000.00, 1, '2026-02-08', 2026), +('佳泰莱(芦康沙妥珠单抗)', '陈*八', '浙江杭州', '1盒', 15000.00, 2, '2026-02-08', 2026), +('佳泰莱(芦康沙妥珠单抗)', '周*九', '江苏南京', '1盒', 15000.00, 1, '2026-02-07', 2026), +('佳泰莱(芦康沙妥珠单抗)', '吴*十', '山东济南', '1盒', 15000.00, 1, '2026-02-07', 2026), +('佳泰莱(芦康沙妥珠单抗)', '郑*一', '河南郑州', '1盒', 15000.00, 1, '2026-02-06', 2026), +('佳泰莱(芦康沙妥珠单抗)', '孙*二', '湖南长沙', '1盒', 15000.00, 2, '2026-02-06', 2026), +('达伯舒(信迪利单抗)', '钱*三', '福建福州', '2盒', 28000.00, 1, '2026-02-05', 2026), +('达伯舒(信迪利单抗)', '冯*四', '安徽合肥', '2盒', 28000.00, 1, '2026-02-05', 2026), +('达伯舒(信迪利单抗)', '褚*五', '江西南昌', '2盒', 28000.00, 1, '2026-02-04', 2026), +('达伯舒(信迪利单抗)', '卫*六', '陕西西安', '2盒', 28000.00, 3, '2026-02-04', 2026), +('泰瑞沙(奥希替尼)', '蒋*七', '辽宁沈阳', '1盒', 12800.00, 1, '2026-02-03', 2026), +('泰瑞沙(奥希替尼)', '沈*八', '吉林长春', '1盒', 12800.00, 1, '2026-02-03', 2026), +('泰瑞沙(奥希替尼)', '韩*九', '黑龙江哈尔滨', '1盒', 12800.00, 2, '2026-02-02', 2026), +('泰瑞沙(奥希替尼)', '杨*十', '云南昆明', '1盒', 12800.00, 1, '2026-02-02', 2026), +('可瑞达(帕博利珠单抗)', '朱*一', '贵州贵阳', '1盒', 18500.00, 1, '2026-02-01', 2026), +('可瑞达(帕博利珠单抗)', '秦*二', '广西南宁', '1盒', 18500.00, 1, '2026-02-01', 2026); diff --git a/sql/update_20260211_page.sql b/sql/update_20260211_page.sql new file mode 100644 index 0000000..62bcacd --- /dev/null +++ b/sql/update_20260211_page.sql @@ -0,0 +1,13 @@ +-- 单页内容表 +CREATE TABLE IF NOT EXISTS `pap_page` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `content` longtext COMMENT '页面内容', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1已发布 0草稿', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `update_by` varchar(50) DEFAULT '' COMMENT '最后更新人', + PRIMARY KEY (`id`), + UNIQUE KEY `idx_column` (`column_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='单页内容'; diff --git a/sql/update_20260211_person.sql b/sql/update_20260211_person.sql new file mode 100644 index 0000000..197c1ba --- /dev/null +++ b/sql/update_20260211_person.sql @@ -0,0 +1,28 @@ +-- 人员列表表 +CREATE TABLE IF NOT EXISTS `pap_person` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `name` varchar(50) NOT NULL DEFAULT '' COMMENT '姓名', + `title` varchar(100) DEFAULT '' COMMENT '职务', + `category` varchar(50) DEFAULT '' COMMENT '分类', + `avatar` varchar(500) DEFAULT '' COMMENT '头像', + `description` text COMMENT '简介', + `sort` int(11) DEFAULT 1 COMMENT '排序', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1启用 0禁用', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_category` (`category`), + KEY `idx_status` (`status`, `is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='人员列表'; + +-- 测试数据 +INSERT INTO `pap_person` (`column_id`, `name`, `title`, `category`, `avatar`, `description`, `sort`, `status`) VALUES +(0, '张XX', '理事长', '理事会成员', '', 'XXXX大学医学博士,从事公益事业20余年,曾获"全国优秀公益人物"称号。', 1, 1), +(0, '李XX', '副理事长', '理事会成员', '', '资深医疗行业管理专家,曾任某三甲医院副院长,在医疗公益领域有丰富经验。', 2, 1), +(0, '王XX', '理事', '理事会成员', '', '知名企业家,长期关注并支持慈善公益事业,为基金会发展提供战略指导。', 3, 1), +(0, '陈XX', '秘书长', '理事会成员', '', '负责基金会日常运营管理,协调各部门工作,推动项目落地执行。', 4, 1), +(0, '林XX', '监事', '监事', '', '注册会计师,具有丰富的财务审计经验,负责基金会财务监督工作。', 1, 1), +(0, '黄XX', '监事', '监事', '', '资深律师,专注于非营利组织法律事务,为基金会合规运营提供监督保障。', 2, 1); diff --git a/sql/update_20260211_role.sql b/sql/update_20260211_role.sql new file mode 100644 index 0000000..5d9505a --- /dev/null +++ b/sql/update_20260211_role.sql @@ -0,0 +1,14 @@ +-- 角色表新增字段 +ALTER TABLE `admin_role` +ADD COLUMN `code` varchar(50) DEFAULT '' COMMENT '角色编码' AFTER `name`, +ADD COLUMN `is_default` tinyint(1) DEFAULT 0 COMMENT '是否默认角色: 0否 1是' AFTER `permissions`, +ADD COLUMN `sort` int(11) DEFAULT 0 COMMENT '排序' AFTER `is_default`, +ADD INDEX `idx_sort` (`sort`); + +-- 更新现有角色数据 +UPDATE `admin_role` SET `code` = 'ADMIN', `is_default` = 1, `sort` = 1 WHERE `id` = 1; +UPDATE `admin_role` SET `code` = 'EDITOR', `sort` = 2 WHERE `id` = 2; + +-- 新增审核员角色 +INSERT INTO `admin_role` (`name`, `code`, `description`, `permissions`, `is_default`, `sort`, `create_by`) VALUES +('审核员', 'AUDITOR', '内容审核权限', '["content:article:view","content:article:audit"]', 0, 3, 0); diff --git a/sql/update_20260211_text.sql b/sql/update_20260211_text.sql new file mode 100644 index 0000000..b97b2aa --- /dev/null +++ b/sql/update_20260211_text.sql @@ -0,0 +1,28 @@ +-- 文字列表表 +CREATE TABLE IF NOT EXISTS `pap_text` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `column_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属栏目ID', + `title` varchar(500) NOT NULL DEFAULT '' COMMENT '标题', + `category` varchar(100) DEFAULT '' COMMENT '分类', + `year` varchar(10) DEFAULT '' COMMENT '年度', + `file_url` varchar(500) DEFAULT '' COMMENT '附件地址', + `file_name` varchar(200) DEFAULT '' COMMENT '附件原始文件名', + `file_type` varchar(20) DEFAULT 'PDF' COMMENT '附件类型 PDF/DOC/XLS', + `sort` int(11) DEFAULT 1 COMMENT '排序', + `status` tinyint(1) DEFAULT 1 COMMENT '状态 1已发布 2待审核 0草稿', + `is_deleted` tinyint(1) DEFAULT 0 COMMENT '删除标记', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_column` (`column_id`), + KEY `idx_status` (`status`, `is_deleted`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文字列表'; + +-- 测试数据 +INSERT INTO `pap_text` (`column_id`, `title`, `category`, `year`, `file_type`, `status`, `sort`) VALUES +(0, '佳泰莱(芦康沙妥珠单抗)2026年1月第三批援助公示', '药品援助公示', '2026', 'PDF', 1, 1), +(0, '佳泰莱(芦康沙妥珠单抗)2026年1月第二批援助公示', '药品援助公示', '2026', 'PDF', 1, 2), +(0, '佳泰莱(芦康沙妥珠单抗)2026年1月第一批援助公示', '药品援助公示', '2026', 'PDF', 1, 3), +(0, '北京维康慈善基金会2025年度审计报告', '审计报告', '2025', 'PDF', 1, 4), +(0, '北京维康慈善基金会2025年度工作报告', '机构年报', '2025', 'PDF', 1, 5), +(0, '2025年第四季度财务报告', '财务报告', '2025', 'XLS', 1, 6); diff --git a/src/bootstrap/master.js b/src/bootstrap/master.js new file mode 100644 index 0000000..f59eb6d --- /dev/null +++ b/src/bootstrap/master.js @@ -0,0 +1 @@ +// invoked in master diff --git a/src/bootstrap/worker.js b/src/bootstrap/worker.js new file mode 100644 index 0000000..b53b75d --- /dev/null +++ b/src/bootstrap/worker.js @@ -0,0 +1 @@ +// invoked in worker diff --git a/src/config/adapter.js b/src/config/adapter.js new file mode 100644 index 0000000..7ddfafd --- /dev/null +++ b/src/config/adapter.js @@ -0,0 +1,110 @@ +const fileCache = require('think-cache-file'); +const nunjucks = require('think-view-nunjucks'); +const fileSession = require('think-session-file'); +const mysql = require('think-model-mysql'); +const {Console, File, DateFile} = require('think-logger3'); +const path = require('path'); +const isDev = think.env === 'development'; + +/** + * cache adapter config + * @type {Object} + */ +exports.cache = { + type: 'file', + common: { + timeout: 24 * 60 * 60 * 1000 // millisecond + }, + file: { + handle: fileCache, + cachePath: path.join(think.ROOT_PATH, 'runtime/cache'), // absoulte path is necessarily required + pathDepth: 1, + gcInterval: 24 * 60 * 60 * 1000 // gc interval + } +}; + +/** + * model adapter config + * @type {Object} + */ +exports.model = { + type: 'pap', + common: { + logConnect: isDev, + logSql: isDev, + logger: msg => think.logger.info(msg) + }, + // pap 测试数据库 + pap: { + handle: mysql, + database: 'pap_web', + prefix: '', + encoding: 'utf8mb4', + host: 'sh-cynosdbmysql-grp-jjq5h0fk.sql.tencentcdb.com', + port: '26821', + user: 'root', + password: '5orKUdDN3QhESVcS', + dateStrings: true + } +}; + +/** + * session adapter config + * @type {Object} + */ +exports.session = { + type: 'file', + common: { + cookie: { + name: 'thinkjs' + // keys: ['werwer', 'werwer'], + // signed: true + } + }, + file: { + handle: fileSession, + sessionPath: path.join(think.ROOT_PATH, 'runtime/session') + } +}; + +/** + * view adapter config + * @type {Object} + */ +exports.view = { + type: 'nunjucks', + common: { + viewPath: path.join(think.ROOT_PATH, 'view'), + sep: '_', + extname: '.html' + }, + nunjucks: { + handle: nunjucks + } +}; + +/** + * logger adapter config + * @type {Object} + */ +exports.logger = { + type: isDev ? 'console' : 'dateFile', + console: { + handle: Console + }, + file: { + handle: File, + backups: 10, // max chunk number + absolute: true, + maxLogSize: 50 * 1024, // 50M + filename: path.join(think.ROOT_PATH, 'logs/app.log') + }, + dateFile: { + handle: DateFile, + level: 'ALL', + absolute: true, + pattern: '-yyyy-MM-dd', + alwaysIncludePattern: true, + filename: path.join(think.ROOT_PATH, 'logs/app.log') + } +}; diff --git a/src/config/adapter.production.js b/src/config/adapter.production.js new file mode 100644 index 0000000..4835fb4 --- /dev/null +++ b/src/config/adapter.production.js @@ -0,0 +1,46 @@ +const mysql = require('think-model-mysql'); +const redisCache = require('think-cache-redis'); + +/** + * 生产环境 cache adapter config + * @type {Object} + */ +exports.cache = { + type: 'redis', + common: { + timeout: 24 * 60 * 60 * 1000 + }, + redis: { + handle: redisCache, + host: '127.0.0.1', + port: 6319, + password: '8cLgEgZSdWr57CTe', + timeout: 0, + log_connect: true + } +}; + +/** + * 生产环境 model adapter config + * @type {Object} + */ +exports.model = { + type: 'pap', + common: { + logConnect: false, + logSql: false, + logger: msg => think.logger.info(msg) + }, + // pap 线上数据库 + pap: { + handle: mysql, + database: 'pap_web', + prefix: '', + encoding: 'utf8mb4', + host: 'sh-cynosdbmysql-grp-jjq5h0fk.sql.tencentcdb.com', + port: '26822', + user: 'root', + password: '5orKUdDN3QhESVcS', + dateStrings: true + } +}; diff --git a/src/config/config.js b/src/config/config.js new file mode 100644 index 0000000..679f087 --- /dev/null +++ b/src/config/config.js @@ -0,0 +1,6 @@ +// default config +module.exports = { + workers: 1, + errnoField: 'code', // errno field + errmsgField: 'msg' // errmsg field +}; diff --git a/src/config/config.production.js b/src/config/config.production.js new file mode 100644 index 0000000..eaa19e2 --- /dev/null +++ b/src/config/config.production.js @@ -0,0 +1,4 @@ +// production config, it will load in production enviroment +module.exports = { + workers: 0 +}; diff --git a/src/config/cos.js b/src/config/cos.js new file mode 100644 index 0000000..a1b2e8d --- /dev/null +++ b/src/config/cos.js @@ -0,0 +1,39 @@ +// 腾讯云 COS 配置 +module.exports = { + // COS 配置 + secretId: process.env.COS_SECRET_ID || 'AKIDcH6qOipkT0Lo9HJ8kEhaJrBML8f4GF1l', + secretKey: process.env.COS_SECRET_KEY || 'Yt1vc5LNCnBSdeS2RdbMvHOIyTkoeIjw', + bucket: process.env.COS_BUCKET || 'pap-1314297964', + region: process.env.COS_REGION || 'ap-shanghai', + + // URL 配置 + bucketUrl: 'https://pap-1314297964.cos.ap-shanghai.myqcloud.com', + cdnUrl: 'https://cdn.csybhelp.com', + + // 文件配置 + allowedImageTypes: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/bmp'], + allowedDocTypes: [ + 'application/pdf', + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'text/plain' + ], + allowedVideoTypes: ['video/mp4', 'video/mpeg', 'video/quicktime', 'video/x-msvideo', 'video/x-ms-wmv'], + + // 文件大小限制(字节) + maxImageSize: 10 * 1024 * 1024, // 10MB + maxDocSize: 50 * 1024 * 1024, // 50MB + maxVideoSize: 200 * 1024 * 1024, // 200MB + + // 图片压缩配置 + imageCompress: { + quality: 80, // 压缩质量 0-100 + maxWidth: 1920, // 最大宽度 + maxHeight: 1920, // 最大高度 + minSize: 100 * 1024 // 最小压缩大小(字节),小于此值不压缩,默认 100KB + } +}; diff --git a/src/config/extend.js b/src/config/extend.js new file mode 100644 index 0000000..5c62a62 --- /dev/null +++ b/src/config/extend.js @@ -0,0 +1,11 @@ +const view = require('think-view'); +const model = require('think-model'); +const cache = require('think-cache'); +const session = require('think-session'); + +module.exports = [ + view, // make application support view + model(think.app), + cache, + session +]; diff --git a/src/config/middleware.js b/src/config/middleware.js new file mode 100644 index 0000000..69953b8 --- /dev/null +++ b/src/config/middleware.js @@ -0,0 +1,40 @@ +const path = require('path'); +const isDev = think.env === 'development'; + +module.exports = [ + { + handle: 'meta', + options: { + logRequest: isDev, + sendResponseTime: isDev + } + }, + { + handle: 'resource', + enable: isDev, + options: { + root: path.join(think.ROOT_PATH, 'www'), + publicPath: /^\/(static|favicon\.ico)/ + } + }, + { + handle: 'trace', + enable: !think.isCli, + options: { + debug: isDev + } + }, + { + handle: 'payload', + options: { + keepExtensions: true, + limit: '5mb' + } + }, + { + handle: 'router', + options: {} + }, + 'logic', + 'controller' +]; diff --git a/src/config/router.js b/src/config/router.js new file mode 100644 index 0000000..cdfc8d3 --- /dev/null +++ b/src/config/router.js @@ -0,0 +1,121 @@ +module.exports = [ + // 前台路由 + ['/', 'index/index'], + ['/index', 'index/index'], + + // 后台管理路由 + ['/admin/login', 'admin/auth/login', 'get'], + ['/admin/auth/login', 'admin/auth/doLogin', 'post'], + ['/admin/logout', 'admin/auth/logout'], + + // 后台页面 + ['/admin/dashboard', 'admin/dashboard/index'], + + // 系统管理 - 用户 + ['/admin/system/user', 'admin/system/user/index'], + ['/admin/system/user/list', 'admin/system/user/list'], + ['/admin/system/user/detail', 'admin/system/user/detail'], + ['/admin/system/user/add', 'admin/system/user/add', 'post'], + ['/admin/system/user/edit', 'admin/system/user/edit', 'post'], + ['/admin/system/user/resetPassword', 'admin/system/user/resetPassword', 'post'], + ['/admin/system/user/delete', 'admin/system/user/delete', 'post'], + ['/admin/system/user/toggleStatus', 'admin/system/user/toggleStatus', 'post'], + + // 系统管理 - 角色 + ['/admin/system/role', 'admin/system/role/index'], + ['/admin/system/role/list', 'admin/system/role/list'], + ['/admin/system/role/all', 'admin/system/role/all'], + ['/admin/system/role/detail', 'admin/system/role/detail'], + ['/admin/system/role/add', 'admin/system/role/add', 'post'], + ['/admin/system/role/edit', 'admin/system/role/edit', 'post'], + ['/admin/system/role/delete', 'admin/system/role/delete', 'post'], + ['/admin/system/role/batchDelete', 'admin/system/role/batchDelete', 'post'], + ['/admin/system/role/assignPermissions', 'admin/system/role/assignPermissions', 'post'], + + // 系统管理 - 网站配置 + ['/admin/system/config', 'admin/system/config/index'], + ['/admin/system/config/list', 'admin/system/config/list'], + ['/admin/system/config/save', 'admin/system/config/save', 'post'], + + // 文件上传 + ['/admin/upload', 'admin/upload/index', 'post'], + ['/admin/upload/config', 'admin/upload/config'], + + // 数据管理 - 药品援助 + ['/admin/data/medicine', 'admin/data/medicine/index'], + ['/admin/data/medicine/list', 'admin/data/medicine/list'], + ['/admin/data/medicine/add', 'admin/data/medicine/add', 'post'], + ['/admin/data/medicine/edit', 'admin/data/medicine/edit', 'post'], + ['/admin/data/medicine/delete', 'admin/data/medicine/delete', 'post'], + + // 系统管理 - 栏目管理 + ['/admin/system/column', 'admin/system/column/index'], + ['/admin/system/column/list', 'admin/system/column/list'], + ['/admin/system/column/parents', 'admin/system/column/parents'], + ['/admin/system/column/add', 'admin/system/column/add', 'post'], + ['/admin/system/column/edit', 'admin/system/column/edit', 'post'], + ['/admin/system/column/delete', 'admin/system/column/delete', 'post'], + ['/admin/system/column/saveFormConfig', 'admin/system/column/saveFormConfig', 'post'], + + // 内容管理 - 轮播图 + ['/admin/content/banner', 'admin/content/banner/index'], + ['/admin/content/banner/list', 'admin/content/banner/list'], + ['/admin/content/banner/add', 'admin/content/banner/add', 'post'], + ['/admin/content/banner/edit', 'admin/content/banner/edit', 'post'], + ['/admin/content/banner/delete', 'admin/content/banner/delete', 'post'], + + // 内容管理 - 文字列表 + ['/admin/content/text', 'admin/content/text/index'], + ['/admin/content/text/list', 'admin/content/text/list'], + ['/admin/content/text/add', 'admin/content/text/add', 'post'], + ['/admin/content/text/edit', 'admin/content/text/edit', 'post'], + ['/admin/content/text/delete', 'admin/content/text/delete', 'post'], + ['/admin/content/text/batchDelete', 'admin/content/text/batchDelete', 'post'], + + // 内容管理 - 图文列表 + ['/admin/content/article', 'admin/content/article/index'], + ['/admin/content/article/list', 'admin/content/article/list'], + ['/admin/content/article/detail', 'admin/content/article/detail'], + ['/admin/content/article/add', 'admin/content/article/add', 'post'], + ['/admin/content/article/edit', 'admin/content/article/edit', 'post'], + ['/admin/content/article/delete', 'admin/content/article/delete', 'post'], + ['/admin/content/article/batchDelete', 'admin/content/article/batchDelete', 'post'], + + // 内容管理 - 图片列表 + ['/admin/content/image', 'admin/content/image/index'], + ['/admin/content/image/list', 'admin/content/image/list'], + ['/admin/content/image/add', 'admin/content/image/add', 'post'], + ['/admin/content/image/edit', 'admin/content/image/edit', 'post'], + ['/admin/content/image/delete', 'admin/content/image/delete', 'post'], + + // 内容管理 - 单页 + ['/admin/content/page', 'admin/content/page/index'], + ['/admin/content/page/detail', 'admin/content/page/detail'], + ['/admin/content/page/save', 'admin/content/page/save', 'post'], + + // 内容管理 - 岗位管理 + ['/admin/content/job', 'admin/content/job/index'], + ['/admin/content/job/list', 'admin/content/job/list'], + ['/admin/content/job/add', 'admin/content/job/add', 'post'], + ['/admin/content/job/edit', 'admin/content/job/edit', 'post'], + ['/admin/content/job/delete', 'admin/content/job/delete', 'post'], + + // 内容管理 - 人员列表 + ['/admin/content/person', 'admin/content/person/index'], + ['/admin/content/person/list', 'admin/content/person/list'], + ['/admin/content/person/categories', 'admin/content/person/categories'], + ['/admin/content/person/add', 'admin/content/person/add', 'post'], + ['/admin/content/person/edit', 'admin/content/person/edit', 'post'], + ['/admin/content/person/delete', 'admin/content/person/delete', 'post'], + + // 内容管理 - 捐赠收支 + ['/admin/content/donation', 'admin/content/donation/index'], + ['/admin/content/donation/stat', 'admin/content/donation/stat'], + ['/admin/content/donation/saveStat', 'admin/content/donation/saveStat', 'post'], + ['/admin/content/donation/syncStat', 'admin/content/donation/syncStat', 'post'], + ['/admin/content/donation/list', 'admin/content/donation/list'], + ['/admin/content/donation/export', 'admin/content/donation/export'], + ['/admin/content/donation/add', 'admin/content/donation/add', 'post'], + ['/admin/content/donation/edit', 'admin/content/donation/edit', 'post'], + ['/admin/content/donation/delete', 'admin/content/donation/delete', 'post'], +]; diff --git a/src/controller/admin/auth.js b/src/controller/admin/auth.js new file mode 100644 index 0000000..3b96d31 --- /dev/null +++ b/src/controller/admin/auth.js @@ -0,0 +1,52 @@ +const Base = require('../base'); + +module.exports = class extends Base { + // 登录页面 + loginAction() { + return this.display(); + } + + // 登录接口 + async doLoginAction() { + const { username, password, remember } = this.post(); + + if (!username || !password) { + return this.fail('请输入用户名和密码'); + } + + // 验证用户 + const user = await this.model('admin_user').where({ username, status: 1 }).find(); + + if (think.isEmpty(user)) { + return this.fail('用户名或密码错误'); + } + + // 密码验证 (MD5加密比对) + if (user.password !== think.md5(password)) { + return this.fail('用户名或密码错误'); + } + + // 生成JWT Token + const token = Base.generateToken({ + id: user.id, + username: user.username, + role_id: user.role_id + }); + + // 设置cookie + const maxAge = remember ? Base.JWT_EXPIRES_IN * 1000 : 0; + this.cookie('admin_token', token, { + maxAge, + httpOnly: true, + path: '/' + }); + + return this.success({ token }); + } + + // 退出登录 + logoutAction() { + this.cookie('admin_token', null); + return this.redirect('/admin/login.html'); + } +}; diff --git a/src/controller/admin/content/article.js b/src/controller/admin/content/article.js new file mode 100644 index 0000000..8a3636f --- /dev/null +++ b/src/controller/admin/content/article.js @@ -0,0 +1,129 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('currentPage', col || 'article'); + return this.display(); + } + + async listAction() { + const col = this.get('col') || ''; + const keyword = this.get('keyword') || ''; + const status = this.get('status'); + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 20; + + const model = this.model('article'); + const where = { is_deleted: 0 }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + if (keyword) { + where.title = ['like', `%${keyword}%`]; + } + if (status !== '' && status !== undefined) { + where.status = parseInt(status); + } + + const list = await model.where(where) + .field('id,column_id,title,summary,cover,category,is_top,is_recommend,sort,status,publish_time,view_count,create_time') + .order('is_top DESC, sort DESC, id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + async detailAction() { + const id = this.get('id'); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + const article = await this.model('article').where({ id, is_deleted: 0 }).find(); + return this.json({ code: 0, data: article }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + title: data.title || '', + summary: data.summary || '', + content: data.content || '', + cover: data.cover || '', + category: data.category || '', + is_top: data.is_top ? 1 : 0, + is_recommend: data.is_recommend ? 1 : 0, + sort: data.sort || 0, + status: data.status !== undefined ? data.status : 0, + publish_time: data.publish_time || null, + seo_title: data.seo_title || '', + seo_keywords: data.seo_keywords || '', + seo_description: data.seo_description || '' + }; + + const id = await this.model('article').add(insertData); + return this.json({ code: 0, msg: '添加成功', data: { id } }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + title: data.title || '', + summary: data.summary || '', + content: data.content || '', + cover: data.cover || '', + category: data.category || '', + is_top: data.is_top ? 1 : 0, + is_recommend: data.is_recommend ? 1 : 0, + sort: data.sort || 0, + status: data.status !== undefined ? data.status : 0, + publish_time: data.publish_time || null, + seo_title: data.seo_title || '', + seo_keywords: data.seo_keywords || '', + seo_description: data.seo_description || '' + }; + + await this.model('article').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('article').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } + + async batchDeleteAction() { + const { ids } = this.post(); + if (!ids || !ids.length) { + return this.json({ code: 1, msg: '请选择要删除的记录' }); + } + await this.model('article').where({ id: ['in', ids] }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/content/banner.js b/src/controller/admin/content/banner.js new file mode 100644 index 0000000..6cce557 --- /dev/null +++ b/src/controller/admin/content/banner.js @@ -0,0 +1,117 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + // 获取栏目信息 + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + // 使用栏目key作为currentPage,用于侧边栏选中 + this.assign('currentPage', col || 'banner'); + return this.display(); + } + + async listAction() { + const col = this.get('col') || ''; + const keyword = this.get('keyword') || ''; + const status = this.get('status'); + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 20; + + const model = this.model('banner'); + const where = { is_deleted: 0 }; + + // 根据栏目key查找column_id + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + + if (keyword) { + where.title = ['like', `%${keyword}%`]; + } + if (status !== '' && status !== undefined) { + where.status = parseInt(status); + } + + const list = await model.where(where) + .order('sort ASC, id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + // 获取column_id + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + title: data.title || '', + subtitle: data.subtitle || '', + description: data.description || '', + image: data.image || '', + btn1_text: data.btn1_text || '了解更多', + btn1_link: data.btn1_link || '#', + btn1_show: data.btn1_show ? 1 : 0, + btn2_text: data.btn2_text || '我要捐赠', + btn2_link: data.btn2_link || '#', + btn2_show: data.btn2_show ? 1 : 0, + position: data.position || 'left', + glass: data.glass ? 1 : 0, + sort: data.sort || 1, + status: data.status ? 1 : 0 + }; + + await this.model('banner').add(insertData); + return this.json({ code: 0, msg: '添加成功' }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + title: data.title || '', + subtitle: data.subtitle || '', + description: data.description || '', + image: data.image || '', + btn1_text: data.btn1_text || '', + btn1_link: data.btn1_link || '', + btn1_show: data.btn1_show ? 1 : 0, + btn2_text: data.btn2_text || '', + btn2_link: data.btn2_link || '', + btn2_show: data.btn2_show ? 1 : 0, + position: data.position || 'left', + glass: data.glass ? 1 : 0, + sort: data.sort || 1, + status: data.status ? 1 : 0 + }; + + await this.model('banner').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('banner').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/content/donation.js b/src/controller/admin/content/donation.js new file mode 100644 index 0000000..6f13801 --- /dev/null +++ b/src/controller/admin/content/donation.js @@ -0,0 +1,215 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('currentPage', col || 'donation'); + return this.display(); + } + + // 获取统计数据 + async statAction() { + const col = this.get('col') || ''; + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + let stat = await this.model('donation_stat').where({ column_id: columnId }).find(); + if (!stat || !stat.id) { + stat = { total_income: 0, total_expense: 0, year_income: 0, year_expense: 0, sync_time: null }; + } + return this.json({ code: 0, data: stat }); + } + + // 保存统计数据 + async saveStatAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const saveData = { + total_income: data.total_income || 0, + total_expense: data.total_expense || 0, + year_income: data.year_income || 0, + year_expense: data.year_expense || 0 + }; + + const existing = await this.model('donation_stat').where({ column_id: columnId }).find(); + if (existing && existing.id) { + await this.model('donation_stat').where({ id: existing.id }).update(saveData); + } else { + saveData.column_id = columnId; + await this.model('donation_stat').add(saveData); + } + + return this.json({ code: 0, msg: '保存成功' }); + } + + // 同步统计数据(从明细计算) + async syncStatAction() { + const col = this.post('col') || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const currentYear = new Date().getFullYear(); + const yearStart = `${currentYear}-01-01`; + + // 计算累计收入 + const totalIncome = await this.model('donation') + .where({ column_id: columnId, type: 'income', is_deleted: 0 }) + .sum('amount') || 0; + + // 计算累计支出 + const totalExpense = await this.model('donation') + .where({ column_id: columnId, type: 'expense', is_deleted: 0 }) + .sum('amount') || 0; + + // 计算本年收入 + const yearIncome = await this.model('donation') + .where({ column_id: columnId, type: 'income', is_deleted: 0, record_date: ['>=', yearStart] }) + .sum('amount') || 0; + + // 计算本年支出 + const yearExpense = await this.model('donation') + .where({ column_id: columnId, type: 'expense', is_deleted: 0, record_date: ['>=', yearStart] }) + .sum('amount') || 0; + + const saveData = { + total_income: totalIncome, + total_expense: totalExpense, + year_income: yearIncome, + year_expense: yearExpense, + sync_time: new Date() + }; + + const existing = await this.model('donation_stat').where({ column_id: columnId }).find(); + if (existing && existing.id) { + await this.model('donation_stat').where({ id: existing.id }).update(saveData); + } else { + saveData.column_id = columnId; + await this.model('donation_stat').add(saveData); + } + + return this.json({ code: 0, msg: '同步成功', data: saveData }); + } + + async listAction() { + const col = this.get('col') || ''; + const type = this.get('type') || 'income'; + const keyword = this.get('keyword') || ''; + const source = this.get('source') || ''; + const status = this.get('status'); + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 20; + + const model = this.model('donation'); + const where = { is_deleted: 0, type }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + if (keyword) { + where.name = ['like', `%${keyword}%`]; + } + if (source) { + where.source = source; + } + if (status !== '' && status !== undefined) { + where.status = parseInt(status); + } + + const list = await model.where(where) + .order('record_date DESC, id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + // 导出数据 + async exportAction() { + const col = this.get('col') || ''; + const type = this.get('type') || 'income'; + + const where = { is_deleted: 0, type }; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + + const list = await this.model('donation').where(where).order('record_date DESC').select(); + return this.json({ code: 0, data: list }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + type: data.type || 'income', + name: data.name || '', + amount: data.amount || 0, + purpose: data.purpose || '', + source: data.source || 'manual', + record_date: data.record_date || null, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('donation').add(insertData); + return this.json({ code: 0, msg: '添加成功' }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + type: data.type || 'income', + name: data.name || '', + amount: data.amount || 0, + purpose: data.purpose || '', + source: data.source || 'manual', + record_date: data.record_date || null, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('donation').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('donation').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/content/image.js b/src/controller/admin/content/image.js new file mode 100644 index 0000000..20a9cf2 --- /dev/null +++ b/src/controller/admin/content/image.js @@ -0,0 +1,94 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('currentPage', col || 'image'); + return this.display(); + } + + async listAction() { + const col = this.get('col') || ''; + const keyword = this.get('keyword') || ''; + const status = this.get('status'); + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 50; + + const model = this.model('image'); + const where = { is_deleted: 0 }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + if (keyword) { + where.title = ['like', `%${keyword}%`]; + } + if (status !== '' && status !== undefined) { + where.status = parseInt(status); + } + + const list = await model.where(where) + .order('sort ASC, id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + title: data.title || '', + image: data.image || '', + link: data.link || '', + sort: data.sort || 1, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('image').add(insertData); + return this.json({ code: 0, msg: '添加成功' }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + title: data.title || '', + image: data.image || '', + link: data.link || '', + sort: data.sort || 1, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('image').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('image').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/content/job.js b/src/controller/admin/content/job.js new file mode 100644 index 0000000..f37f9c2 --- /dev/null +++ b/src/controller/admin/content/job.js @@ -0,0 +1,100 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('currentPage', col || 'job'); + return this.display(); + } + + async listAction() { + const col = this.get('col') || ''; + const keyword = this.get('keyword') || ''; + const status = this.get('status'); + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 20; + + const model = this.model('job'); + const where = { is_deleted: 0 }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + if (keyword) { + where.name = ['like', `%${keyword}%`]; + } + if (status !== '' && status !== undefined) { + where.status = parseInt(status); + } + + const list = await model.where(where) + .order('id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + name: data.name || '', + department: data.department || '', + location: data.location || '', + count: data.count || 1, + duty: data.duty || '', + requirement: data.requirement || '', + salary: data.salary || '', + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('job').add(insertData); + return this.json({ code: 0, msg: '添加成功' }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + name: data.name || '', + department: data.department || '', + location: data.location || '', + count: data.count || 1, + duty: data.duty || '', + requirement: data.requirement || '', + salary: data.salary || '', + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('job').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('job').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/content/page.js b/src/controller/admin/content/page.js new file mode 100644 index 0000000..62d566c --- /dev/null +++ b/src/controller/admin/content/page.js @@ -0,0 +1,67 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + let pageData = null; + + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + if (columnInfo && columnInfo.id) { + pageData = await this.model('page').where({ column_id: columnInfo.id, is_deleted: 0 }).find(); + } + } + + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('pageData', pageData || {}); + this.assign('currentPage', col || 'page'); + return this.display(); + } + + async detailAction() { + const col = this.get('col') || ''; + if (!col) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + if (!column || !column.id) { + return this.json({ code: 1, msg: '栏目不存在' }); + } + + const pageData = await this.model('page').where({ column_id: column.id, is_deleted: 0 }).find(); + return this.json({ code: 0, data: pageData || {} }); + } + + async saveAction() { + const data = this.post(); + const col = data.col || ''; + + if (!col) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + if (!column || !column.id) { + return this.json({ code: 1, msg: '栏目不存在' }); + } + + const existing = await this.model('page').where({ column_id: column.id, is_deleted: 0 }).find(); + const saveData = { + content: data.content || '', + status: data.status !== undefined ? data.status : 1, + update_by: this.adminUser?.username || '管理员' + }; + + if (existing && existing.id) { + await this.model('page').where({ id: existing.id }).update(saveData); + } else { + saveData.column_id = column.id; + await this.model('page').add(saveData); + } + + return this.json({ code: 0, msg: '保存成功' }); + } +}; diff --git a/src/controller/admin/content/person.js b/src/controller/admin/content/person.js new file mode 100644 index 0000000..9b1335b --- /dev/null +++ b/src/controller/admin/content/person.js @@ -0,0 +1,117 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('currentPage', col || 'person'); + return this.display(); + } + + async listAction() { + const col = this.get('col') || ''; + const keyword = this.get('keyword') || ''; + const category = this.get('category') || ''; + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 50; + + const model = this.model('person'); + const where = { is_deleted: 0 }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + if (keyword) { + where.name = ['like', `%${keyword}%`]; + } + if (category) { + where.category = category; + } + + const list = await model.where(where) + .order('sort ASC, id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + // 获取分类列表 + async categoriesAction() { + const col = this.get('col') || ''; + const where = { is_deleted: 0 }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + + const list = await this.model('person') + .where(where) + .field('DISTINCT category') + .select(); + + const categories = list.map(item => item.category).filter(c => c); + return this.json({ code: 0, data: categories }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + name: data.name || '', + title: data.title || '', + category: data.category || '', + avatar: data.avatar || '', + description: data.description || '', + sort: data.sort || 1, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('person').add(insertData); + return this.json({ code: 0, msg: '添加成功' }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + name: data.name || '', + title: data.title || '', + category: data.category || '', + avatar: data.avatar || '', + description: data.description || '', + sort: data.sort || 1, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('person').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('person').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/content/text.js b/src/controller/admin/content/text.js new file mode 100644 index 0000000..831237f --- /dev/null +++ b/src/controller/admin/content/text.js @@ -0,0 +1,113 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + async indexAction() { + const col = this.get('col') || ''; + let columnInfo = null; + if (col) { + columnInfo = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + } + this.assign('col', col); + this.assign('columnInfo', columnInfo); + this.assign('currentPage', col || 'text'); + return this.display(); + } + + async listAction() { + const col = this.get('col') || ''; + const keyword = this.get('keyword') || ''; + const year = this.get('year') || ''; + const status = this.get('status'); + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 20; + + const model = this.model('text'); + const where = { is_deleted: 0 }; + + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + where.column_id = column ? column.id : 0; + } + if (keyword) { + where.title = ['like', `%${keyword}%`]; + } + if (year) { + where.year = year; + } + if (status !== '' && status !== undefined) { + where.status = parseInt(status); + } + + const list = await model.where(where) + .order('sort ASC, id DESC') + .page(page, pageSize) + .countSelect(); + + return this.json({ code: 0, data: list }); + } + + async addAction() { + const data = this.post(); + const col = data.col || ''; + + let columnId = 0; + if (col) { + const column = await this.model('column').where({ key: col, is_deleted: 0 }).find(); + columnId = column ? column.id : 0; + } + + const insertData = { + column_id: columnId, + title: data.title || '', + category: data.category || '', + year: data.year || new Date().getFullYear().toString(), + file_url: data.file_url || '', + file_name: data.file_name || '', + file_type: data.file_type || 'PDF', + sort: data.sort || 1, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('text').add(insertData); + return this.json({ code: 0, msg: '添加成功' }); + } + + async editAction() { + const data = this.post(); + if (!data.id) { + return this.json({ code: 1, msg: '参数错误' }); + } + + const updateData = { + title: data.title || '', + category: data.category || '', + year: data.year || '', + file_url: data.file_url || '', + file_name: data.file_name || '', + file_type: data.file_type || 'PDF', + sort: data.sort || 1, + status: data.status !== undefined ? data.status : 1 + }; + + await this.model('text').where({ id: data.id }).update(updateData); + return this.json({ code: 0, msg: '保存成功' }); + } + + async deleteAction() { + const { id } = this.post(); + if (!id) { + return this.json({ code: 1, msg: '参数错误' }); + } + await this.model('text').where({ id }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } + + async batchDeleteAction() { + const { ids } = this.post(); + if (!ids || !ids.length) { + return this.json({ code: 1, msg: '请选择要删除的记录' }); + } + await this.model('text').where({ id: ['in', ids] }).update({ is_deleted: 1 }); + return this.json({ code: 0, msg: '删除成功' }); + } +}; diff --git a/src/controller/admin/dashboard.js b/src/controller/admin/dashboard.js new file mode 100644 index 0000000..18d44d1 --- /dev/null +++ b/src/controller/admin/dashboard.js @@ -0,0 +1,37 @@ +const Base = require('../base'); + +module.exports = class extends Base { + async indexAction() { + // 页面信息 + this.assign('currentPage', 'dashboard'); + this.assign('pageTitle', '控制台'); + + // 统计数据(后续从数据库获取) + this.assign('stats', { + contentCount: 128, + pendingCount: 5, + visitCount: '1,256', + donationTotal: '178.2M' + }); + + // 最近更新列表(后续从数据库获取) + this.assign('recentList', []); + + // 待办事项(后续从数据库获取) + this.assign('todoList', []); + + // 动态栏目菜单(后续从接口获取) + this.assign('columnMenus', await this.getColumnMenus()); + + // 当前登录用户 + this.assign('adminUser', this.adminUser || {}); + + return this.display(); + } + + // 获取动态栏目菜单(暂时返回空,后续从数据库获取) + async getColumnMenus() { + // TODO: 从数据库获取栏目配置 + return []; + } +}; diff --git a/src/controller/admin/data/medicine.js b/src/controller/admin/data/medicine.js new file mode 100644 index 0000000..c239094 --- /dev/null +++ b/src/controller/admin/data/medicine.js @@ -0,0 +1,94 @@ +const Base = require('../../base.js'); + +module.exports = class extends Base { + // 列表页 + async indexAction() { + // 设置当前页面标识 + this.assign('currentPage', 'medicine'); + + // 获取年份列表 + const years = []; + const currentYear = new Date().getFullYear(); + for (let i = currentYear; i >= currentYear - 5; i--) { + years.push(i); + } + this.assign('years', years); + return this.display(); + } + + // 列表数据 + async listAction() { + const page = this.get('page') || 1; + const pageSize = this.get('pageSize') || 10; + const keyword = this.get('keyword') || ''; + const year = this.get('year') || ''; + const status = this.get('status'); + + const model = this.model('medicine'); + const where = { is_deleted: 0 }; + + if (keyword) { + where['name|person'] = ['like', `%${keyword}%`]; + } + if (year) { + where.year = year; + } + if (status !== '' && status !== undefined) { + where.status = status; + } + + const list = await model.where(where) + .order('id DESC') + .page(page, pageSize) + .countSelect(); + + return this.success(list); + } + + // 新增 + async addAction() { + const data = this.post(); + const model = this.model('medicine'); + + // 自动设置年度 + if (data.distribute_date) { + data.year = new Date(data.distribute_date).getFullYear(); + } else { + data.year = new Date().getFullYear(); + } + + const id = await model.add(data); + return this.success({ id }); + } + + // 编辑 + async editAction() { + const data = this.post(); + const id = data.id; + if (!id) { + return this.fail('缺少ID'); + } + + const model = this.model('medicine'); + + // 自动设置年度 + if (data.distribute_date) { + data.year = new Date(data.distribute_date).getFullYear(); + } + + delete data.id; + await model.where({ id }).update(data); + return this.success(); + } + + // 删除 + async deleteAction() { + const id = this.post('id'); + if (!id) { + return this.fail('缺少ID'); + } + + await this.model('medicine').where({ id }).update({ is_deleted: 1 }); + return this.success(); + } +}; diff --git a/src/controller/admin/system/column.js b/src/controller/admin/system/column.js new file mode 100644 index 0000000..f20da62 --- /dev/null +++ b/src/controller/admin/system/column.js @@ -0,0 +1,136 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + // 页面 + async indexAction() { + this.assign('currentPage', 'column'); + return this.display(); + } + + // 获取树形列表 + async listAction() { + const model = this.model('column'); + const list = await model.where({ is_deleted: 0 }).order('sort ASC, id ASC').select(); + + // 构建树形结构 + const tree = []; + const map = {}; + list.forEach(item => { + map[item.id] = { ...item, children: [] }; + }); + list.forEach(item => { + if (item.parent_id === 0) { + tree.push(map[item.id]); + } else if (map[item.parent_id]) { + map[item.parent_id].children.push(map[item.id]); + } + }); + + return this.success(tree); + } + + // 获取所有顶级栏目(用于下拉选择) + async parentsAction() { + const list = await this.model('column') + .where({ parent_id: 0, is_deleted: 0 }) + .order('sort ASC') + .select(); + return this.success(list); + } + + // 新增 + async addAction() { + const data = this.post(); + const model = this.model('column'); + + // 检查key是否重复 + if (data.key) { + const exists = await model.where({ key: data.key, is_deleted: 0 }).find(); + if (!think.isEmpty(exists)) { + return this.fail('栏目标识已存在'); + } + } + + const id = await model.add({ + parent_id: data.parent_id || 0, + name: data.name, + key: data.key || '', + icon: data.icon || '', + type: data.type || '', + is_single_page: data.is_single_page || 0, + sort: data.sort || 1, + visible: data.visible !== undefined ? data.visible : 1, + link: data.link || '', + seo_title: data.seo_title || '', + seo_keywords: data.seo_keywords || '', + seo_description: data.seo_description || '', + slug: data.slug || '' + }); + return this.success({ id }); + } + + // 编辑 + async editAction() { + const data = this.post(); + const id = data.id; + if (!id) { + return this.fail('缺少ID'); + } + + // 检查key是否重复(排除自己) + if (data.key) { + const exists = await this.model('column').where({ key: data.key, is_deleted: 0, id: ['!=', id] }).find(); + if (!think.isEmpty(exists)) { + return this.fail('栏目标识已存在'); + } + } + + await this.model('column').where({ id }).update({ + parent_id: data.parent_id || 0, + name: data.name, + key: data.key || '', + icon: data.icon || '', + type: data.type || '', + is_single_page: data.is_single_page || 0, + sort: data.sort || 1, + visible: data.visible !== undefined ? data.visible : 1, + link: data.link || '', + seo_title: data.seo_title || '', + seo_keywords: data.seo_keywords || '', + seo_description: data.seo_description || '', + slug: data.slug || '' + }); + return this.success(); + } + + // 删除 + async deleteAction() { + const id = this.post('id'); + if (!id) { + return this.fail('缺少ID'); + } + + // 检查是否有子栏目 + const children = await this.model('column').where({ parent_id: id, is_deleted: 0 }).count(); + if (children > 0) { + return this.fail('请先删除子栏目'); + } + + await this.model('column').where({ id }).update({ is_deleted: 1 }); + return this.success(); + } + + // 保存表单配置 + async saveFormConfigAction() { + const id = this.post('id'); + const formConfig = this.post('form_config'); + if (!id) { + return this.fail('缺少ID'); + } + + await this.model('column').where({ id }).update({ + form_config: JSON.stringify(formConfig) + }); + return this.success(); + } +}; diff --git a/src/controller/admin/system/config.js b/src/controller/admin/system/config.js new file mode 100644 index 0000000..cfe1211 --- /dev/null +++ b/src/controller/admin/system/config.js @@ -0,0 +1,46 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + /** + * 配置页面 + */ + async indexAction() { + const configModel = this.model('config'); + const configs = await configModel.getAllGrouped(); + + this.assign('configs', configs); + this.assign('currentPage', 'config'); + this.assign('pageTitle', '网站配置'); + return this.display(); + } + + /** + * 获取配置列表(API) + */ + async listAction() { + const configModel = this.model('config'); + const configs = await configModel.getAllGrouped(); + return this.success(configs); + } + + /** + * 保存配置 + */ + async saveAction() { + const { group, data } = this.post(); + + if (!group || !data) { + return this.fail('参数错误'); + } + + const validGroups = ['basic', 'seo', 'contact', 'social']; + if (!validGroups.includes(group)) { + return this.fail('无效的配置分组'); + } + + const configModel = this.model('config'); + await configModel.saveGroup(group, data); + + return this.success(null, '保存成功'); + } +}; diff --git a/src/controller/admin/system/role.js b/src/controller/admin/system/role.js new file mode 100644 index 0000000..7daa8c8 --- /dev/null +++ b/src/controller/admin/system/role.js @@ -0,0 +1,305 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + // 角色列表页面 + async indexAction() { + this.assign('currentPage', 'sys-role'); + this.assign('pageTitle', '角色权限'); + this.assign('breadcrumb', [ + { name: '系统管理', url: '#' }, + { name: '角色权限' } + ]); + + // 权限树数据 + this.assign('permissionTree', this.getPermissionTree()); + + this.assign('adminUser', this.adminUser || {}); + this.assign('columnMenus', []); + + return this.display(); + } + + // 获取角色列表接口 + async listAction() { + const { keyword, page = 1, pageSize = 20 } = this.get(); + + const where = { is_deleted: 0 }; + + if (keyword) { + where.name = ['like', `%${keyword}%`]; + } + + const list = await this.model('admin_role') + .where(where) + .order('sort ASC, id ASC') + .page(page, pageSize) + .countSelect(); + + return this.success(list); + } + + // 获取所有角色(下拉用) + async allAction() { + const list = await this.model('admin_role') + .where({ is_deleted: 0, status: 1 }) + .order('sort ASC') + .select(); + + return this.success(list); + } + + // 获取单个角色 + async detailAction() { + const { id } = this.get(); + if (!id) return this.fail('参数错误'); + + const role = await this.model('admin_role') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(role)) { + return this.fail('角色不存在'); + } + + return this.success(role); + } + + // 新增角色 + async addAction() { + const { name, code, description, is_default = 0, sort = 0 } = this.post(); + + if (!name) { + return this.fail('角色名称不能为空'); + } + + // 检查名称是否存在 + const exist = await this.model('admin_role') + .where({ name, is_deleted: 0 }) + .find(); + + if (!think.isEmpty(exist)) { + return this.fail('角色名称已存在'); + } + + const data = { + name, + code: code || '', + description: description || '', + permissions: JSON.stringify([]), + is_default: is_default ? 1 : 0, + sort: sort || 0, + create_by: this.adminUser?.id || 0 + }; + + const id = await this.model('admin_role').add(data); + return this.success({ id }); + } + + // 编辑角色 + async editAction() { + const { id, name, code, description, is_default, sort } = this.post(); + + if (!id) return this.fail('参数错误'); + + const role = await this.model('admin_role') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(role)) { + return this.fail('角色不存在'); + } + + // 默认角色不能编辑 + if (role.is_default === 1) { + return this.fail('默认角色不能编辑'); + } + + // 检查名称是否重复 + if (name && name !== role.name) { + const exist = await this.model('admin_role') + .where({ name, is_deleted: 0, id: ['!=', id] }) + .find(); + + if (!think.isEmpty(exist)) { + return this.fail('角色名称已存在'); + } + } + + const data = { + name: name || role.name, + code: code !== undefined ? code : role.code, + description: description !== undefined ? description : role.description, + is_default: is_default !== undefined ? (is_default ? 1 : 0) : role.is_default, + sort: sort !== undefined ? sort : role.sort, + update_by: this.adminUser?.id || 0 + }; + + await this.model('admin_role').where({ id }).update(data); + return this.success(); + } + + // 分配权限 + async assignPermissionsAction() { + const { id, permissions } = this.post(); + + if (!id) return this.fail('参数错误'); + + const role = await this.model('admin_role') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(role)) { + return this.fail('角色不存在'); + } + + await this.model('admin_role') + .where({ id }) + .update({ + permissions: JSON.stringify(permissions || []), + update_by: this.adminUser?.id || 0 + }); + + return this.success(); + } + + // 删除角色 + async deleteAction() { + const { id } = this.post(); + + if (!id) return this.fail('参数错误'); + + const role = await this.model('admin_role') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(role)) { + return this.fail('角色不存在'); + } + + // 默认角色不能删除 + if (role.is_default === 1) { + return this.fail('默认角色不能删除'); + } + + // 检查是否有用户使用该角色 + const userCount = await this.model('admin_user') + .where({ role_id: id, is_deleted: 0 }) + .count(); + + if (userCount > 0) { + return this.fail(`该角色下有 ${userCount} 个用户,无法删除`); + } + + await this.model('admin_role') + .where({ id }) + .update({ + is_deleted: 1, + update_by: this.adminUser?.id || 0 + }); + + return this.success(); + } + + // 批量删除 + async batchDeleteAction() { + const { ids } = this.post(); + + if (!ids || !ids.length) return this.fail('参数错误'); + + // 检查是否包含默认角色 + const defaultCount = await this.model('admin_role') + .where({ id: ['in', ids], is_default: 1, is_deleted: 0 }) + .count(); + + if (defaultCount > 0) { + return this.fail('选中的角色包含默认角色,无法删除'); + } + + // 检查是否有用户使用这些角色 + const userCount = await this.model('admin_user') + .where({ role_id: ['in', ids], is_deleted: 0 }) + .count(); + + if (userCount > 0) { + return this.fail(`选中的角色下有 ${userCount} 个用户,无法删除`); + } + + await this.model('admin_role') + .where({ id: ['in', ids] }) + .update({ + is_deleted: 1, + update_by: this.adminUser?.id || 0 + }); + + return this.success(); + } + + // 获取权限树配置 + getPermissionTree() { + return [ + { + name: '系统管理', + key: 'system', + children: [ + { + name: '用户管理', + key: 'system:user', + children: ['查询', '新增', '编辑', '删除', '重置密码'] + }, + { + name: '角色管理', + key: 'system:role', + children: ['查询', '新增', '编辑', '删除', '分配权限'] + }, + { + name: '操作日志', + key: 'system:log', + children: ['查询', '删除', '导出'] + } + ] + }, + { + name: '内容管理', + key: 'content', + children: [ + { + name: '文章管理', + key: 'content:article', + children: ['查询', '新增', '编辑', '删除', '审核', '发布'] + }, + { + name: '图片管理', + key: 'content:image', + children: ['查询', '新增', '编辑', '删除', '排序'] + }, + { + name: '单页管理', + key: 'content:page', + children: ['查询', '编辑'] + } + ] + }, + { + name: '数据管理', + key: 'data', + children: [ + { + name: '药品援助', + key: 'data:medicine', + children: ['查询', '新增', '编辑', '删除', '导出'] + } + ] + }, + { + name: '栏目管理', + key: 'column', + children: ['查询', '新增', '编辑', '删除', '排序'] + }, + { + name: '网站配置', + key: 'site', + children: ['基础设置', 'SEO设置', '联系信息'] + } + ]; + } +}; diff --git a/src/controller/admin/system/user.js b/src/controller/admin/system/user.js new file mode 100644 index 0000000..66529de --- /dev/null +++ b/src/controller/admin/system/user.js @@ -0,0 +1,221 @@ +const Base = require('../../base'); + +module.exports = class extends Base { + // 用户列表页面 + async indexAction() { + this.assign('currentPage', 'sys-user'); + this.assign('pageTitle', '用户管理'); + this.assign('breadcrumb', [ + { name: '系统管理', url: '#' }, + { name: '用户管理' } + ]); + + // 获取角色列表 + const roles = await this.model('admin_role') + .where({ is_deleted: 0 }) + .select(); + this.assign('roles', roles); + + // 当前登录用户 + this.assign('adminUser', this.adminUser || {}); + this.assign('columnMenus', []); + + return this.display(); + } + + // 获取用户列表接口 + async listAction() { + const { keyword, role_id, status, page = 1, pageSize = 10 } = this.get(); + + const where = { is_deleted: 0 }; + + if (keyword) { + where._complex = { + username: ['like', `%${keyword}%`], + nickname: ['like', `%${keyword}%`], + _logic: 'or' + }; + } + + if (role_id) { + where.role_id = role_id; + } + + if (status !== undefined && status !== '') { + where.status = status; + } + + const list = await this.model('admin_user') + .where(where) + .order('id ASC') + .page(page, pageSize) + .countSelect(); + + // 获取角色名称 + const roleIds = [...new Set(list.data.map(item => item.role_id))]; + const roles = roleIds.length ? await this.model('admin_role') + .where({ id: ['in', roleIds] }) + .select() : []; + const roleMap = {}; + roles.forEach(r => roleMap[r.id] = r.name); + + list.data.forEach(item => { + item.role_name = roleMap[item.role_id] || '-'; + delete item.password; + }); + + return this.success(list); + } + + // 获取单个用户 + async detailAction() { + const { id } = this.get(); + if (!id) return this.fail('参数错误'); + + const user = await this.model('admin_user') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(user)) { + return this.fail('用户不存在'); + } + + delete user.password; + return this.success(user); + } + + // 新增用户 + async addAction() { + const { username, password, nickname, email, phone, role_id, status = 1 } = this.post(); + + if (!username || !password) { + return this.fail('用户名和密码不能为空'); + } + + // 检查用户名是否存在 + const exist = await this.model('admin_user') + .where({ username, is_deleted: 0 }) + .find(); + + if (!think.isEmpty(exist)) { + return this.fail('用户名已存在'); + } + + const data = { + username, + password: think.md5(password), + nickname: nickname || '', + email: email || '', + phone: phone || '', + role_id: role_id || 0, + status, + create_by: this.adminUser?.id || 0 + }; + + const id = await this.model('admin_user').add(data); + return this.success({ id }); + } + + // 编辑用户 + async editAction() { + const { id, nickname, email, phone, role_id, status } = this.post(); + + if (!id) return this.fail('参数错误'); + + const user = await this.model('admin_user') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(user)) { + return this.fail('用户不存在'); + } + + const data = { + nickname: nickname || user.nickname, + email: email || user.email, + phone: phone || user.phone, + role_id: role_id !== undefined ? role_id : user.role_id, + status: status !== undefined ? status : user.status, + update_by: this.adminUser?.id || 0 + }; + + await this.model('admin_user').where({ id }).update(data); + return this.success(); + } + + // 重置密码 + async resetPasswordAction() { + const { id, password } = this.post(); + + if (!id || !password) { + return this.fail('参数错误'); + } + + const user = await this.model('admin_user') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(user)) { + return this.fail('用户不存在'); + } + + await this.model('admin_user') + .where({ id }) + .update({ + password: think.md5(password), + update_by: this.adminUser?.id || 0 + }); + + return this.success(); + } + + // 删除用户(软删除) + async deleteAction() { + const { id } = this.post(); + + if (!id) return this.fail('参数错误'); + + // 不能删除自己 + if (id == this.adminUser?.id) { + return this.fail('不能删除当前登录用户'); + } + + await this.model('admin_user') + .where({ id }) + .update({ + is_deleted: 1, + update_by: this.adminUser?.id || 0 + }); + + return this.success(); + } + + // 切换状态 + async toggleStatusAction() { + const { id } = this.post(); + + if (!id) return this.fail('参数错误'); + + const user = await this.model('admin_user') + .where({ id, is_deleted: 0 }) + .find(); + + if (think.isEmpty(user)) { + return this.fail('用户不存在'); + } + + // 不能禁用自己 + if (id == this.adminUser?.id) { + return this.fail('不能禁用当前登录用户'); + } + + await this.model('admin_user') + .where({ id }) + .update({ + status: user.status === 1 ? 0 : 1, + update_by: this.adminUser?.id || 0 + }); + + return this.success(); + } +}; diff --git a/src/controller/admin/upload.js b/src/controller/admin/upload.js new file mode 100644 index 0000000..4dfe577 --- /dev/null +++ b/src/controller/admin/upload.js @@ -0,0 +1,306 @@ +const Base = require('../base.js'); +const COS = require('cos-nodejs-sdk-v5'); +const fs = require('fs'); +const path = require('path'); +const cosConfig = require('../../config/cos.js'); + +module.exports = class extends Base { + /** + * 文件上传 + * POST /admin/upload + */ + async indexAction() { + // 辅助函数:延迟 + const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); + + // 获取文件(处理 ThinkJS 文件获取延迟问题) + let file = this.file('file'); + let filePath = file ? file.path : ''; + + if (!filePath) { + await sleep(1000); + file = this.file('file'); + filePath = file ? file.path : ''; + if (!filePath) { + await sleep(1000); + file = this.file('file'); + filePath = file ? file.path : ''; + if (!filePath) { + return this.fail('请选择要上传的文件'); + } + } + } + + try { + // 获取文件信息 + const originalName = file.name; + const fileSize = file.size; + const mimeType = file.type; + + // 验证文件类型和大小 + const validation = this.validateFile(mimeType, fileSize); + if (!validation.valid) { + // 删除临时文件 + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } + return this.fail(validation.message); + } + + // 生成存储路径(按日期分类) + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const dateFolder = `${year}/${month}/${day}`; + + // 生成文件名(保留原文件名,添加时间戳避免重复) + const timestamp = Date.now(); + const ext = path.extname(originalName); + const baseName = path.basename(originalName, ext); + const fileName = `${baseName}_${timestamp}${ext}`; + const cosKey = `uploads/${dateFolder}/${fileName}`; + + // 如果是图片,进行压缩处理 + let uploadFilePath = filePath; + let actualFileSize = fileSize; + + if (this.isImage(mimeType)) { + // 检查文件大小是否需要压缩 + if (fileSize < cosConfig.imageCompress.minSize) { + think.logger.info(`图片小于 ${cosConfig.imageCompress.minSize / 1024}KB,跳过压缩`); + } else { + try { + const compressResult = await this.compressImage(filePath, mimeType); + // 比较压缩后的文件大小,如果压缩后更大则使用原图 + if (compressResult.compressedPath && compressResult.compressedSize < fileSize) { + uploadFilePath = compressResult.compressedPath; + actualFileSize = compressResult.compressedSize; + think.logger.info(`图片压缩成功: ${fileSize} -> ${compressResult.compressedSize} (节省 ${((1 - compressResult.compressedSize / fileSize) * 100).toFixed(2)}%)`); + } else { + think.logger.info('压缩后文件更大,使用原图上传'); + // 删除压缩后的文件 + if (compressResult.compressedPath && fs.existsSync(compressResult.compressedPath)) { + try { + fs.unlinkSync(compressResult.compressedPath); + } catch (e) { + think.logger.warn('删除压缩文件失败:', e.message); + } + } + } + } catch (compressError) { + think.logger.warn('图片压缩失败,使用原图上传:', compressError); + // 压缩失败时使用原图 + } + } + } + + // 初始化 COS 客户端 + const cos = new COS({ + SecretId: cosConfig.secretId, + SecretKey: cosConfig.secretKey + }); + + // 上传文件到 COS + const uploadResult = await new Promise((resolve, reject) => { + cos.putObject({ + Bucket: cosConfig.bucket, + Region: cosConfig.region, + Key: cosKey, + Body: fs.createReadStream(uploadFilePath), + ContentType: mimeType, + onProgress: (progressData) => { + // 可以在这里处理上传进度 + } + }, (err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } + }); + }); + + // 清理临时文件(延迟删除,避免 Windows 文件句柄未释放问题) + setTimeout(() => { + try { + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } + } catch (e) { + think.logger.warn('删除临时文件失败:', e.message); + } + try { + if (uploadFilePath !== filePath && fs.existsSync(uploadFilePath)) { + fs.unlinkSync(uploadFilePath); + } + } catch (e) { + think.logger.warn('删除压缩文件失败:', e.message); + } + }, 1000); + + // 返回结果 + if (uploadResult.statusCode === 200) { + const bucketUrl = `https://${uploadResult.Location}`; + const cdnUrl = bucketUrl.replace(cosConfig.bucketUrl, cosConfig.cdnUrl); + + return this.success({ + url: cdnUrl, + name: originalName, + bucket_url: bucketUrl, + file_name: originalName, + file_size: actualFileSize, + mime_type: mimeType + }); + } else { + return this.fail('文件上传失败'); + } + } catch (error) { + think.logger.error('文件上传失败:', error); + // 清理临时文件 + if (file && file.path && fs.existsSync(file.path)) { + try { + fs.unlinkSync(file.path); + } catch (cleanError) { + think.logger.error('清理临时文件失败:', cleanError); + } + } + return this.fail('文件上传失败: ' + error.message); + } + } + + /** + * 验证文件类型和大小 + */ + validateFile(mimeType, fileSize) { + const allAllowedTypes = [ + ...cosConfig.allowedImageTypes, + ...cosConfig.allowedDocTypes, + ...cosConfig.allowedVideoTypes + ]; + + // 验证文件类型 + if (!allAllowedTypes.includes(mimeType)) { + return { + valid: false, + message: '不支持的文件类型' + }; + } + + // 验证文件大小 + let maxSize = 0; + if (cosConfig.allowedImageTypes.includes(mimeType)) { + maxSize = cosConfig.maxImageSize; + } else if (cosConfig.allowedDocTypes.includes(mimeType)) { + maxSize = cosConfig.maxDocSize; + } else if (cosConfig.allowedVideoTypes.includes(mimeType)) { + maxSize = cosConfig.maxVideoSize; + } + + if (fileSize > maxSize) { + const maxSizeMB = (maxSize / 1024 / 1024).toFixed(0); + return { + valid: false, + message: `文件大小不能超过 ${maxSizeMB}MB` + }; + } + + return { valid: true }; + } + + /** + * 判断是否为图片 + */ + isImage(mimeType) { + return cosConfig.allowedImageTypes.includes(mimeType); + } + + /** + * 压缩图片 + * 返回压缩后的文件路径和文件大小 + */ + async compressImage(filePath, mimeType) { + // 尝试加载 sharp,如果没有安装则跳过压缩 + let sharp; + try { + sharp = require('sharp'); + } catch (e) { + think.logger.warn('sharp 模块未安装,跳过图片压缩'); + return { compressedPath: null, compressedSize: 0 }; + } + + const compressedPath = filePath + '_compressed'; + const { quality, maxWidth, maxHeight } = cosConfig.imageCompress; + + try { + const image = sharp(filePath); + const metadata = await image.metadata(); + + // 计算缩放尺寸 + let resizeOptions = {}; + if (metadata.width > maxWidth || metadata.height > maxHeight) { + resizeOptions = { + width: maxWidth, + height: maxHeight, + fit: 'inside', + withoutEnlargement: true + }; + } + + // 根据图片类型选择压缩格式 + let outputOptions = {}; + if (mimeType === 'image/jpeg' || mimeType === 'image/jpg') { + outputOptions = { quality }; + await image.resize(resizeOptions).jpeg(outputOptions).toFile(compressedPath); + } else if (mimeType === 'image/png') { + outputOptions = { quality, compressionLevel: 9 }; + await image.resize(resizeOptions).png(outputOptions).toFile(compressedPath); + } else if (mimeType === 'image/webp') { + outputOptions = { quality }; + await image.resize(resizeOptions).webp(outputOptions).toFile(compressedPath); + } else { + // 其他格式不压缩 + return { + compressedPath: null, + compressedSize: 0 + }; + } + + // 获取压缩后的文件大小 + const stats = fs.statSync(compressedPath); + const compressedSize = stats.size; + + return { + compressedPath, + compressedSize + }; + } catch (error) { + think.logger.error('图片压缩失败:', error); + throw error; + } + } + + /** + * 获取上传配置信息 + * GET /admin/upload/config + */ + async configAction() { + try { + return this.success({ + allowedTypes: { + images: cosConfig.allowedImageTypes, + documents: cosConfig.allowedDocTypes, + videos: cosConfig.allowedVideoTypes + }, + maxSize: { + image: cosConfig.maxImageSize, + document: cosConfig.maxDocSize, + video: cosConfig.maxVideoSize + } + }); + } catch (error) { + think.logger.error('获取上传配置失败:', error); + return this.fail('获取上传配置失败'); + } + } +}; diff --git a/src/controller/base.js b/src/controller/base.js new file mode 100644 index 0000000..d492586 --- /dev/null +++ b/src/controller/base.js @@ -0,0 +1,137 @@ +const jwt = require('jsonwebtoken'); + +// JWT配置 +const JWT_SECRET = think.md5('yzx'); +const JWT_EXPIRES_IN = 24 * 60 * 60; + +// 白名单配置 +const WHITE_LIST = [ + // 后台登录相关 + '/admin/login', + '/admin/auth/login', + '/admin/logout', +]; + +// 前台路由前缀(全部放行) +const PUBLIC_PREFIXES = [ + '/index', + '/api', // 如果有前台API +]; + +// 内容类型对应的URL +const TYPE_URL_MAP = { + 'article': '/admin/content/article.html', + 'image': '/admin/content/image.html', + 'text': '/admin/content/text.html', + 'page': '/admin/content/page.html', + 'person': '/admin/content/person.html', + 'form': '/admin/content/form.html', + 'donation': '/admin/content/donation.html', + 'job': '/admin/content/job.html', + 'banner': '/admin/content/banner.html' +}; + +module.exports = class extends think.Controller { + async __before() { + const path = this.ctx.path; + + // 前台路由全部放行 + for (const prefix of PUBLIC_PREFIXES) { + if (path.startsWith(prefix) || path === '/') { + return; + } + } + + // 白名单放行 + if (WHITE_LIST.includes(path)) { + return; + } + + // 后台路由需要验证JWT + if (path.startsWith('/admin')) { + const token = this.cookie('admin_token') || this.header('authorization')?.replace('Bearer ', ''); + + if (!token) { + return this.handleUnauthorized(); + } + + try { + const decoded = jwt.verify(token, JWT_SECRET); + this.adminUser = decoded; + + // 加载栏目菜单数据(非Ajax请求时) + if (!this.isAjax()) { + await this.loadColumnMenus(); + } + } catch (err) { + return this.handleUnauthorized(); + } + } + } + + // 加载栏目菜单 + async loadColumnMenus() { + const model = this.model('column'); + const list = await model.where({ is_deleted: 0 }).order('sort ASC, id ASC').select(); + + // 获取当前col参数,用于判断菜单选中 + const currentCol = this.get('col') || ''; + + // 构建树形结构 + const menus = []; + const map = {}; + let menuGroup = ''; // 当前选中的父级菜单key + + list.forEach(item => { + map[item.id] = { ...item, children: [] }; + }); + + list.forEach(item => { + if (item.parent_id === 0) { + // 一级栏目 + menus.push(map[item.id]); + } else if (map[item.parent_id]) { + // 二级栏目 + const child = map[item.id]; + child.url = TYPE_URL_MAP[item.type] ? `${TYPE_URL_MAP[item.type]}?col=${item.key}` : '#'; + map[item.parent_id].children.push(child); + + // 如果当前col匹配,设置父级菜单key + if (currentCol && item.key === currentCol) { + menuGroup = map[item.parent_id].key; + } + } + }); + + this.assign('columnMenus', menus); + this.assign('menuGroup', menuGroup); + } + + // 未授权处理 + handleUnauthorized() { + if (this.isAjax()) { + return this.fail(401, '请先登录'); + } + return this.redirect('/admin/login.html'); + } + + // 判断是否Ajax请求 + isAjax() { + return this.header('x-requested-with') === 'XMLHttpRequest' || + this.header('accept')?.includes('application/json'); + } + + // 生成JWT Token + static generateToken(payload) { + return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN }); + } + + // 获取JWT配置 + static get JWT_SECRET() { + return JWT_SECRET; + } + + static get JWT_EXPIRES_IN() { + return JWT_EXPIRES_IN; + } +}; diff --git a/src/controller/index.js b/src/controller/index.js new file mode 100644 index 0000000..6447f83 --- /dev/null +++ b/src/controller/index.js @@ -0,0 +1,117 @@ +const Base = require('./base.js'); + +module.exports = class extends Base { + async indexAction() { + // 获取栏目配置 + const columns = await this.model('column').where({ is_deleted: 0, visible: 1 }).order('sort ASC').select(); + + // 构建导航菜单树 + const navMenus = this.buildNavTree(columns); + + // 获取首页栏目ID映射 + const homeColumn = columns.find(c => c.key === 'home'); + const homeChildren = columns.filter(c => c.parent_id === homeColumn?.id); + const colMap = {}; + homeChildren.forEach(c => { colMap[c.key] = c.id; }); + + // 获取Banner数据(根据栏目key查找column_id,或者column_id=0表示通用) + const bannerColId = colMap['home-banner'] || 0; + const banners = await this.model('banner').where({ + status: 1, + is_deleted: 0 + }).where('column_id = ' + bannerColId + ' OR column_id = 0').order('sort ASC').select(); + + // 获取捐赠统计 + const dataColId = colMap['home-data'] || 0; + let donationStat = await this.model('donation_stat').where({ + column_id: dataColId + }).find(); + if (!donationStat || !donationStat.id) { + donationStat = await this.model('donation_stat').where({ column_id: 0 }).find(); + } + donationStat = donationStat || { total_income: 0, total_expense: 0, year_income: 0 }; + + // 获取捐赠明细(收入/支出各取最新10条) + const donationIncome = await this.model('donation').where({ + type: 'income', + status: 1, + is_deleted: 0 + }).where('column_id = ' + dataColId + ' OR column_id = 0').order('record_date DESC').limit(10).select(); + + const donationExpense = await this.model('donation').where({ + type: 'expense', + status: 1, + is_deleted: 0 + }).where('column_id = ' + dataColId + ' OR column_id = 0').order('record_date DESC').limit(10).select(); + + // 获取药品援助数据(只显示已发放的) + const medicines = await this.model('medicine').where({ + status: 1, + is_deleted: 0 + }).order('distribute_date DESC').limit(20).select(); + + // 获取公益项目 + const projectColId = colMap['home-project'] || 0; + const projects = await this.model('article').where({ + status: 1, + is_deleted: 0 + }).where('column_id = ' + projectColId + ' OR column_id = 0').order('sort DESC, publish_time DESC').limit(5).select(); + + // 获取新闻动态 + const newsColId = colMap['home-news'] || 0; + const newsList = await this.model('article').where({ + status: 1, + is_deleted: 0 + }).where('column_id = ' + newsColId + ' OR column_id = 0').order('is_top DESC, publish_time DESC').limit(5).select(); + + // 获取合作伙伴 + const partnerColId = colMap['home-partner'] || 0; + const partners = await this.model('image').where({ + status: 1, + is_deleted: 0 + }).where('column_id = ' + partnerColId + ' OR column_id = 0').order('sort ASC').select(); + + // 获取网站配置 + const configList = await this.model('config').select(); + const siteConfig = {}; + configList.forEach(c => { + siteConfig[c.key] = c.value; + }); + + this.assign({ + navMenus, + banners, + donationStat, + donationIncome, + donationExpense, + medicines, + projects, + newsList, + partners, + siteConfig, + now: new Date() + }); + + return this.display(); + } + + // 构建导航树 + buildNavTree(columns) { + const tree = []; + const map = {}; + + columns.forEach(item => { + map[item.id] = { ...item, children: [] }; + }); + + columns.forEach(item => { + if (item.parent_id === 0) { + tree.push(map[item.id]); + } else if (map[item.parent_id]) { + map[item.parent_id].children.push(map[item.id]); + } + }); + + return tree; + } +}; diff --git a/src/logic/index.js b/src/logic/index.js new file mode 100644 index 0000000..54c1cc2 --- /dev/null +++ b/src/logic/index.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Logic { + indexAction() { + + } +}; diff --git a/src/model/article.js b/src/model/article.js new file mode 100644 index 0000000..09c0e7b --- /dev/null +++ b/src/model/article.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_article'; + } +}; diff --git a/src/model/banner.js b/src/model/banner.js new file mode 100644 index 0000000..69be7ea --- /dev/null +++ b/src/model/banner.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_banner'; + } +}; diff --git a/src/model/column.js b/src/model/column.js new file mode 100644 index 0000000..a756842 --- /dev/null +++ b/src/model/column.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_column'; + } +}; diff --git a/src/model/config.js b/src/model/config.js new file mode 100644 index 0000000..830bb27 --- /dev/null +++ b/src/model/config.js @@ -0,0 +1,56 @@ +module.exports = class extends think.Model { + /** + * 获取所有配置(按分组) + */ + async getAllGrouped() { + const list = await this.order('`group` ASC, sort ASC').select(); + const grouped = {}; + for (const item of list) { + if (!grouped[item.group]) { + grouped[item.group] = []; + } + grouped[item.group].push(item); + } + return grouped; + } + + /** + * 获取指定分组的配置 + */ + async getByGroup(group) { + return this.where({ group }).order('sort ASC').select(); + } + + /** + * 获取单个配置值 + */ + async getValue(group, key) { + const item = await this.where({ group, key }).find(); + return item ? item.value : null; + } + + /** + * 批量保存配置 + */ + async saveGroup(group, data) { + for (const key in data) { + await this.where({ group, key }).update({ value: data[key] }); + } + return true; + } + + /** + * 获取前台需要的配置(转为对象形式) + */ + async getForFrontend() { + const list = await this.select(); + const config = {}; + for (const item of list) { + if (!config[item.group]) { + config[item.group] = {}; + } + config[item.group][item.key] = item.value; + } + return config; + } +}; diff --git a/src/model/donation.js b/src/model/donation.js new file mode 100644 index 0000000..9911aba --- /dev/null +++ b/src/model/donation.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_donation'; + } +}; diff --git a/src/model/donation_stat.js b/src/model/donation_stat.js new file mode 100644 index 0000000..0c0637f --- /dev/null +++ b/src/model/donation_stat.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_donation_stat'; + } +}; diff --git a/src/model/image.js b/src/model/image.js new file mode 100644 index 0000000..45c7e9f --- /dev/null +++ b/src/model/image.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_image'; + } +}; diff --git a/src/model/index.js b/src/model/index.js new file mode 100644 index 0000000..cab52cf --- /dev/null +++ b/src/model/index.js @@ -0,0 +1,3 @@ +module.exports = class extends think.Model { + +}; diff --git a/src/model/job.js b/src/model/job.js new file mode 100644 index 0000000..125f1f8 --- /dev/null +++ b/src/model/job.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_job'; + } +}; diff --git a/src/model/medicine.js b/src/model/medicine.js new file mode 100644 index 0000000..7288800 --- /dev/null +++ b/src/model/medicine.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_medicine'; + } +}; diff --git a/src/model/page.js b/src/model/page.js new file mode 100644 index 0000000..161155a --- /dev/null +++ b/src/model/page.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_page'; + } +}; diff --git a/src/model/person.js b/src/model/person.js new file mode 100644 index 0000000..49bf567 --- /dev/null +++ b/src/model/person.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_person'; + } +}; diff --git a/src/model/text.js b/src/model/text.js new file mode 100644 index 0000000..029f245 --- /dev/null +++ b/src/model/text.js @@ -0,0 +1,5 @@ +module.exports = class extends think.Model { + get tableName() { + return 'pap_text'; + } +}; diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..6d6f39f --- /dev/null +++ b/test/index.js @@ -0,0 +1,7 @@ +const test = require('ava'); +const path = require('path'); +require(path.join(process.cwd(), 'production.js')); + +test('first test', t => { + const indexModel = think.model('index'); +}) diff --git a/view/admin/auth_login.html b/view/admin/auth_login.html new file mode 100644 index 0000000..e7f2d6b --- /dev/null +++ b/view/admin/auth_login.html @@ -0,0 +1,219 @@ + + + + + + 登录 - 北京维康慈善基金会管理系统 + + + + + + + + + + diff --git a/view/admin/common/_header.html b/view/admin/common/_header.html new file mode 100644 index 0000000..3a887a4 --- /dev/null +++ b/view/admin/common/_header.html @@ -0,0 +1,41 @@ +
+
+ +
+
+ + +
+
{{ adminUser.nickname[0] if adminUser.nickname else '管' }}
+ {{ adminUser.nickname or adminUser.username or '管理员' }} +
+
+
+ diff --git a/view/admin/common/_sidebar.html b/view/admin/common/_sidebar.html new file mode 100644 index 0000000..c12efe5 --- /dev/null +++ b/view/admin/common/_sidebar.html @@ -0,0 +1,117 @@ + + + diff --git a/view/admin/content/article_index.html b/view/admin/content/article_index.html new file mode 100644 index 0000000..84f73d5 --- /dev/null +++ b/view/admin/content/article_index.html @@ -0,0 +1,436 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '图文列表' }}{% endblock %} + +{% block css %} + + + +{% endblock %} + +{% block content %} +
+ + + + +
+ + + + + + + 搜索 + 重置 +
+ + +
+ 已选择 ${ selectedIds.length } 项,共 ${ total } 条记录 +
+ 批量删除 +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + +
+ +
+ + + + + + + + +
+
+
+
+
+
+
+ + +
+
+
发布设置
+ + + + + + + + + + + + + + + + + + + +
+ 置顶 + 推荐到首页 +
+
+
+ +
+
封面图
+
+ 封面图 +
+ + 点击上传封面图 +
+
+ + 移除封面 +
+ +
+
SEO 设置
+ + + + + + + + + + + +
+
+
+ + +
+
+{% endblock %} + +{% block js %} + + + +{% endblock %} diff --git a/view/admin/content/banner_index.html b/view/admin/content/banner_index.html new file mode 100644 index 0000000..a6af286 --- /dev/null +++ b/view/admin/content/banner_index.html @@ -0,0 +1,369 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else 'Banner管理' }}{% endblock %} + +{% block content %} +
+ + + + +
+ + + + + + 搜索 + 重置 +
+ + + + + +
+ +
+
+ + + +
+ + + +
+
+ +
+ + 点击上传图片 +
+
+ +
建议尺寸 1920×800,支持 JPG/PNG
+
+
+ + + + + + + + + + + + + + 按钮配置 +
+ + + + + + + + + +
+
+ + + + + + + + + +
+ + + 样式设置 + + + 左侧 + 居中 + 右侧 + + + + + 启用后文字区域会有半透明模糊背景 + +
+ + + + + + +
+ + + 前台预览 + +
+
+ + +
+
+ + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/content/donation_index.html b/view/admin/content/donation_index.html new file mode 100644 index 0000000..262f5d8 --- /dev/null +++ b/view/admin/content/donation_index.html @@ -0,0 +1,384 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '捐赠收支' }}{% endblock %} + +{% block content %} +
+ +
+
+
累计捐赠收入
+
${ formatMoney(stat.total_income) }
+
+
+
累计公益支出
+
${ formatMoney(stat.total_expense) }
+
+
+
本年度收入
+
${ formatMoney(stat.year_income) }
+
+
+
本年度支出
+
${ formatMoney(stat.year_expense) }
+
+
+ + + +
+ 统计数据管理 + 编辑统计 + 从明细同步 + 上次同步: ${ stat.sync_time?.slice(0,16).replace('T',' ') } +
+
+ + +
+
捐赠收入
+
公益支出
+
+ + + +
+ + + + + + + + + + 搜索 + 重置 +
+ + 手动录入 + 导出 +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + 捐赠收入 + 公益支出 + + + + + +
+ + + + + + +
+ + + +
+ + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + +{% endblock %} + +{% block js %} + + + + +{% endblock %} diff --git a/view/admin/content/image_index.html b/view/admin/content/image_index.html new file mode 100644 index 0000000..bf3fe58 --- /dev/null +++ b/view/admin/content/image_index.html @@ -0,0 +1,260 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '图片列表' }}{% endblock %} + +{% block content %} +
+ + + + +
+ + + + + + 搜索 + 重置 +
+ + +
+
+
+ + ${ item.sort } +
+
+
${ item.title }
+
+ ${ item.status ? '启用' : '禁用' } + ${ item.create_time?.slice(0,10) } +
+
+
+ 编辑 + 删除 +
+
+ +
+
+ + 新增图片 +
+
+
+ + +
+ +
+
+ + + +
+ + + +
+
+ +
+ + 点击上传图片 +
+
+ +
支持 JPG/PNG/GIF,建议宽度不小于 800px
+
+
+ + + + + + + +
+ + + + + + +
+
+
+ +
+
+ + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/content/job_index.html b/view/admin/content/job_index.html new file mode 100644 index 0000000..d810938 --- /dev/null +++ b/view/admin/content/job_index.html @@ -0,0 +1,211 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '岗位管理' }}{% endblock %} + +{% block content %} +
+ + + + +
+ + + + + + 搜索 + 重置 +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + +
+ + + + +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + +
+
+ +
+
+ + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/content/page_index.html b/view/admin/content/page_index.html new file mode 100644 index 0000000..0b76073 --- /dev/null +++ b/view/admin/content/page_index.html @@ -0,0 +1,198 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '单页管理' }}{% endblock %} + +{% block content %} +
+ + + + +
+
+
+
+ + +
+
+ 发布状态: + +
+
+ 预览 + 保存 +
+
+
+
+ + +{% endblock %} + +{% block js %} + + + + + +{% endblock %} diff --git a/view/admin/content/person_index.html b/view/admin/content/person_index.html new file mode 100644 index 0000000..e005f72 --- /dev/null +++ b/view/admin/content/person_index.html @@ -0,0 +1,304 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '人员列表' }}{% endblock %} + +{% block content %} +
+ + + + +
+ + + + + 搜索 + 重置 +
+ + +
+
+
+ + ${ getInitial(item.name) } +
+
+
${ item.name }
+
${ item.title }
+
+ ${ item.category } +
+
${ item.description }
+
+ 排序: ${ item.sort } + 编辑 + 删除 +
+
+
+ +
+
+ + 新增人员 +
+
+
+ + +
+ +
+
+ + + +
+ + + +
+
+ + +
+ +
建议尺寸 200×200,支持 JPG/PNG
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + + + + + +
+
+
+ +
+
+ + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/content/text_index.html b/view/admin/content/text_index.html new file mode 100644 index 0000000..fcebb90 --- /dev/null +++ b/view/admin/content/text_index.html @@ -0,0 +1,309 @@ +{% extends "../layout.html" %} + +{% block title %}{{ columnInfo.name if columnInfo else '文字列表' }}{% endblock %} + +{% block content %} +
+ + + + +
+ + + + + + + + + + 搜索 + 重置 +
+ + +
+ ${ total } 条记录 +
+ 批量删除 +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + +
+ + + + + + + + + + +
+ +
+ + 选择文件 + +
+
支持 PDF、DOC、XLS 格式
+
+
+ + + + + + + + + + + + + + +
+
+ +
+
+ + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/dashboard_index.html b/view/admin/dashboard_index.html new file mode 100644 index 0000000..3cab6cc --- /dev/null +++ b/view/admin/dashboard_index.html @@ -0,0 +1,207 @@ +{% extends "./layout.html" %} + +{% block title %}控制台{% endblock %} + +{% block css %} + +{% endblock %} + +{% block content %} + +
+
+
+ +
+
+
{{ stats.contentCount or 0 }}
+
内容总数
+
+ +
+
+
+ +
+
+
{{ stats.pendingCount or 0 }}
+
待审核
+
+ +
+
+
+ +
+
+
{{ stats.visitCount or '0' }}
+
本月访问
+
+ +
+
+
+ +
+
+
¥{{ stats.donationTotal or '0' }}
+
累计捐赠
+
+ +
+
+ + +
+ +
+
+ 最近更新 + +
+ + + + + + + + + + + {% if recentList and recentList.length %} + {% for item in recentList %} + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
标题栏目状态更新时间
{{ item.title }}{{ item.column_name }} + {% if item.status == 1 %} + 已发布 + {% else %} + 待审核 + {% endif %} + {{ item.update_time }}
暂无数据
+
+ + +
+ + + + +
+
+ 待办事项 +
+
+ {% if todoList and todoList.length %} + {% for item in todoList %} +
+ + {{ item.title }} +
+ {% endfor %} + {% else %} +
+ + 暂无待办事项 +
+ {% endif %} +
+
+
+
+{% endblock %} diff --git a/view/admin/data/medicine_index.html b/view/admin/data/medicine_index.html new file mode 100644 index 0000000..2af09c2 --- /dev/null +++ b/view/admin/data/medicine_index.html @@ -0,0 +1,306 @@ +{% extends "../layout.html" %} + +{% block title %}药品援助记录{% endblock %} + +{% block content %} +
+ + + + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/layout.html b/view/admin/layout.html new file mode 100644 index 0000000..40410b9 --- /dev/null +++ b/view/admin/layout.html @@ -0,0 +1,68 @@ + + + + + + {% block title %}管理后台{% endblock %} - 北京维康慈善基金会 + + + + + + + + + {% block css %}{% endblock %} + + +
+ {% include "./common/_sidebar.html" %} + +
+ {% include "./common/_header.html" %} + +
+ {% block content %}{% endblock %} +
+
+
+ + + + + + + + + +{% block js %}{% endblock %} + + + diff --git a/view/admin/system/column_index.html b/view/admin/system/column_index.html new file mode 100644 index 0000000..62b6adc --- /dev/null +++ b/view/admin/system/column_index.html @@ -0,0 +1,428 @@ +{% extends "../layout.html" %} + +{% block title %}栏目管理{% endblock %} + +{% block content %} +
+ + + + + + + + + + + + + + + + + + + + +
+ + + 选择图标 + + ${ form.icon } + 清除 +
+
+ + + 单页面(二级为模块) + 多页面(二级为独立页面) + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + 选择图标 + + ${ form.icon } + 清除 +
+
+ + + 单页面(二级为模块) + 多页面(二级为独立页面) + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + 取消 + 保存 + +
+ + + + +
+
+ + ${ icon } +
+
+
+ + + +
+ + 添加字段 +
+
暂无字段
+
+ + + + + + + + + + + + + + + + + + + +
+ +
+
+ + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/system/config_index.html b/view/admin/system/config_index.html new file mode 100644 index 0000000..5173b7c --- /dev/null +++ b/view/admin/system/config_index.html @@ -0,0 +1,281 @@ +{% extends "../layout.html" %} + +{% block title %}网站配置{% endblock %} + +{% block content %} +
+ + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + 点击上传 +
+
+ 建议尺寸: 200×60px,PNG格式 +
+
+ +
+
+ +
+ + 上传二维码 +
+
+ 建议尺寸: 300×300px +
+
+ + 保存配置 + +
+
+ + + + + + + + + + + + + + +
+
+ +
+ + 上传 +
+
+ 建议尺寸: 32×32px,ICO/PNG格式 +
+
+ + 保存配置 + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + 保存配置 + + + + + + + + + + + + + + + + + + + + + + + + 保存配置 + + + +
+
+{% endblock %} + +{% block css %} + +{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/system/role_index.html b/view/admin/system/role_index.html new file mode 100644 index 0000000..d933c13 --- /dev/null +++ b/view/admin/system/role_index.html @@ -0,0 +1,290 @@ +{% extends "../layout.html" %} + +{% block title %}角色权限{% endblock %} + +{% block content %} +
+ + + + + + + + 搜索 + 重置 + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 全部展开 +
+ + +
+
+{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/admin/system/user_index.html b/view/admin/system/user_index.html new file mode 100644 index 0000000..70d81f7 --- /dev/null +++ b/view/admin/system/user_index.html @@ -0,0 +1,329 @@ +{% extends "../layout.html" %} + +{% block title %}用户管理{% endblock %} + +{% block content %} +
+ + + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/common/_footer.html b/view/common/_footer.html new file mode 100644 index 0000000..056b953 --- /dev/null +++ b/view/common/_footer.html @@ -0,0 +1,47 @@ + +
+ + + +
diff --git a/view/common/_header.html b/view/common/_header.html new file mode 100644 index 0000000..6ba69ed --- /dev/null +++ b/view/common/_header.html @@ -0,0 +1,67 @@ + +
+ + + + + +
+ 我要捐赠 + + +
+
+ + +
+
+
+ + +
+ + +
diff --git a/view/index_index.html b/view/index_index.html new file mode 100644 index 0000000..db599f4 --- /dev/null +++ b/view/index_index.html @@ -0,0 +1,384 @@ +{% extends "layout.html" %} + +{% block content %} + +
+
首页
+
数据公示
+
公益项目
+
新闻动态
+
合作伙伴
+
+ + +
+
+ + +
+
+ +
+
+ SCROLL +
+
+
+ + +
+
+
+
+

捐赠及支出公示

+
Every Penny, Tracked with Integrity
+
+
+
+
历年公益捐赠收入
+
0
+
截至今日
+
+
+
本年度捐赠收入
+
0
+
本年度
+
+
+
历年公益支出
+
0
+
截至今日
+
+
+
+
+

捐赠收入明细

+
+ + +
捐赠方金额
+
+
+ + + {% for item in donationIncome %} + + {% endfor %} + {% for item in donationIncome %} + + {% endfor %} + +
{{item.name}}{{item.amount}}
{{item.name}}{{item.amount}}
+
+
+
+
+
+

公益支出明细

+
+ + +
支付对象金额
+
+
+ + + {% for item in donationExpense %} + + {% endfor %} + {% for item in donationExpense %} + + {% endfor %} + +
{{item.name}}{{item.amount}}
{{item.name}}{{item.amount}}
+
+
+
+
+
+

药品援助公示

+
+ + +
发放日期患者姓名地区药品名称
+
+
+ + + {% for item in medicines %} + + + + + + + {% endfor %} + {% for item in medicines %} + + + + + + + {% endfor %} + +
{{item.distribute_date}}{{item.person}}{{item.region}}{{item.name}}
{{item.distribute_date}}{{item.person}}{{item.region}}{{item.name}}
+
+
+
+
+
+
+
+
+ + + +
+
+ + {% for proj in projects %} +
+ {% endfor %} + + +
+
项目介绍
+

{% if projects[0] %}{{projects[0].title}}{% endif %}

+
+

{% if projects[0] %}{{projects[0].summary}}{% endif %}

+ 了解详情 → +
+ + +
+ {% for proj in projects %} +
{{proj.title}}
+ {% endfor %} +
+ + 查看全部项目 +
+
+ + +
+
+
+
+

新闻 & 动态

+
Latest News and Updates
+
+
+ {% if newsList[0] %} + + {{newsList[0].title}} +
+

{{newsList[0].title}}

+
{{newsList[0].publish_time}}
+
+
+ {% endif %} +
+ {% for news in newsList %} + {% if loop.index > 1 %} + +
+
{{loop.index}}
+
{{news.publish_time}}
+
+
+

{{news.title}}

+

{{news.summary}}

+
+
+ {% endif %} + {% endfor %} + +
+
+
+
+
+ + +
+ +
+ +
+
+{% endblock %} + +{% block js %} + +{% endblock %} diff --git a/view/layout.html b/view/layout.html new file mode 100644 index 0000000..7bd6e43 --- /dev/null +++ b/view/layout.html @@ -0,0 +1,56 @@ + + + + + + {% block title %}{{siteConfig.page_title or siteConfig.site_name}}{% endblock %} + + + {% if siteConfig.favicon %} + + {% endif %} + + + {% block css %}{% endblock %} + + + {% include "common/_header.html" %} + + {% block content %}{% endblock %} + + + + {% block js %}{% endblock %} + + diff --git a/www/static/css/.gitkeep b/www/static/css/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/www/static/css/admin.css b/www/static/css/admin.css new file mode 100644 index 0000000..1b2d8df --- /dev/null +++ b/www/static/css/admin.css @@ -0,0 +1,198 @@ +/* ===== Admin Layout - vue3-element-admin style ===== */ +/* 基础重置 - 使用较低优先级,不覆盖 Tailwind 工具类 */ +*,*::before,*::after{box-sizing:border-box;} +ul,ol{list-style:none;margin:0;padding:0;} +:root{ + --primary:#E8751A; + --primary-dark:#C96012; + --primary-light:#F5A623; + --primary-bg:rgba(232,117,26,.08); + --blue:#1A3550; + --white:#fff; + --bg:#f0f2f5; + --card:#fff; + --text:#303133; + --text-regular:#606266; + --text-secondary:#909399; + --text-placeholder:#c0c4cc; + --border:#e4e7ed; + --border-light:#ebeef5; + --success:#67c23a; + --warning:#e6a23c; + --danger:#f56c6c; + --info:#909399; + --sidebar-bg:#1d1e1f; + --sidebar-text:rgba(255,255,255,.65); + --sidebar-active-bg:var(--primary); + --sidebar-width:210px; + --header-height:50px; + --font-cn:"Source Han Sans SC","Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif; + --font-en:"Roboto",sans-serif; + --radius:4px; + --shadow:0 2px 12px rgba(0,0,0,.06); +} +html{font-size:14px;} +body{font-family:var(--font-cn);color:var(--text);background:var(--bg);min-height:100vh;} +a{text-decoration:none;color:inherit;} +img{max-width:100%;display:block;} + +/* ===== Layout ===== */ +.admin-layout{display:flex;min-height:100vh;} + +/* ===== Sidebar ===== */ +.sidebar{ + width:var(--sidebar-width);background:var(--sidebar-bg); + position:fixed;top:0;left:0;bottom:0;z-index:100; + display:flex;flex-direction:column;transition:.3s;overflow:hidden; +} +.sidebar-logo{ + height:var(--header-height);display:flex;align-items:center; + padding:0 16px;border-bottom:1px solid rgba(255,255,255,.08);gap:10px;flex-shrink:0; + background:var(--white); +} +.sidebar-logo img{height:36px;width:auto;} +.sidebar-logo svg{width:28px;height:28px;color:var(--primary);flex-shrink:0;} +.sidebar-logo span{font-size:14px;font-weight:600;color:var(--white);white-space:nowrap;overflow:hidden;} + +.sidebar-menu{flex:1;overflow-y:auto;padding:6px 0;} +.sidebar-menu::-webkit-scrollbar{width:0;} + +.menu-group{margin-bottom:2px;} +.menu-group-title{ + padding:20px 16px 6px;font-size:11px;color:rgba(255,255,255,.3); + text-transform:uppercase;letter-spacing:1px;font-weight:500; +} +.menu-item{ + display:flex;align-items:center;gap:10px;padding:0 16px;height:42px; + color:var(--sidebar-text);cursor:pointer;transition:.15s;position:relative; + font-size:13px;border-radius:0; +} +.menu-item:hover{color:rgba(255,255,255,.9);background:rgba(255,255,255,.06);} +.menu-item.active{color:var(--white);background:var(--primary);} +.menu-item svg{width:18px;height:18px;flex-shrink:0;opacity:.7;} +.menu-item.active svg{opacity:1;} +.menu-item span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;} + +/* 子菜单 */ +.submenu-items{display:none;overflow:hidden;} +.menu-parent.open .submenu-items{display:block;} +.menu-parent>.menu-item .arrow{ + margin-left:auto;transition:.2s;opacity:.5;display:flex;align-items:center; +} +.menu-parent>.menu-item .arrow svg{width:10px;height:10px;} +.menu-parent.open>.menu-item .arrow{transform:rotate(180deg);} +.menu-parent.open>.menu-item .arrow{transform:rotate(90deg);} +.submenu-items .menu-item{padding-left:46px;height:38px;font-size:12.5px;} + +/* ===== Main Area ===== */ +.main-area{flex:1;margin-left:var(--sidebar-width);display:flex;flex-direction:column;min-height:100vh;} + +/* ===== Top Header ===== */ +.top-header{ + height:var(--header-height);background:var(--white); + border-bottom:1px solid var(--border-light);display:flex; + align-items:center;justify-content:space-between;padding:0 20px; + position:sticky;top:0;z-index:90; +} +.header-left{display:flex;align-items:center;gap:16px;} +.breadcrumb{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-secondary);} +.breadcrumb a{color:var(--text-secondary);transition:.15s;} +.breadcrumb a:hover{color:var(--primary);} +.breadcrumb .sep{color:var(--text-placeholder);} +.breadcrumb .current{color:var(--text);} + +.header-right{display:flex;align-items:center;gap:16px;} +.header-btn{ + width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center; + cursor:pointer;transition:.15s;color:var(--text-secondary);background:none;border:none; +} +.header-btn:hover{background:var(--bg);color:var(--text);} +.header-btn svg{width:18px;height:18px;} +.header-avatar{ + display:flex;align-items:center;gap:8px;cursor:pointer;padding:4px 8px; + border-radius:var(--radius);transition:.15s; +} +.header-avatar:hover{background:var(--bg);} +.header-avatar img{width:30px;height:30px;border-radius:50%;background:var(--border);} +.avatar-placeholder{ + width:30px;height:30px;border-radius:50%;background:var(--primary); + color:var(--white);display:flex;align-items:center;justify-content:center; + font-size:12px;font-weight:600; +} +.header-avatar span{font-size:13px;color:var(--text-regular);} + +/* ===== Content ===== */ +.page-content{flex:1;padding:20px;} + +/* ===== Tags View ===== */ +.tags-view{ + display:flex;align-items:center;gap:6px;padding:6px 20px; + background:var(--white);border-bottom:1px solid var(--border-light); + overflow-x:auto;flex-shrink:0; +} +.tags-view::-webkit-scrollbar{height:0;} +.tag-item{ + display:flex;align-items:center;gap:4px;padding:4px 12px; + border-radius:3px;font-size:12px;cursor:pointer;white-space:nowrap; + border:1px solid var(--border);color:var(--text-secondary);transition:.15s; + background:var(--white); +} +.tag-item:hover{color:var(--primary);border-color:var(--primary);} +.tag-item.active{background:var(--primary);color:var(--white);border-color:var(--primary);} +.tag-item .tag-close{ + font-size:10px;margin-left:2px;opacity:.6;transition:.15s; + width:14px;height:14px;display:flex;align-items:center;justify-content:center; + border-radius:50%; +} +.tag-item .tag-close:hover{opacity:1;background:rgba(0,0,0,.1);} +.tag-item.active .tag-close:hover{background:rgba(255,255,255,.3);} + +/* ===== Common Components ===== */ +.card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);padding:20px;} +.card-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;} +.card-title{font-size:15px;font-weight:600;color:var(--text);} + +/* Table - 仅保留颜色 */ +.el-table{font-size:13px;} + +/* Buttons - 仅保留颜色 */ +.el-btn{color:var(--text-regular);cursor:pointer;} +.el-btn:hover{color:var(--primary);} +.el-btn-primary{background:var(--primary);color:var(--white);} +.el-btn-primary:hover{background:var(--primary-dark);color:var(--white);} +.el-btn-success{background:var(--success);color:var(--white);} +.el-btn-danger{background:var(--danger);color:var(--white);} +.el-btn-text{color:var(--primary);cursor:pointer;} +.el-btn-text:hover{color:var(--primary-dark);} + +/* Badge / Tag - 仅保留颜色 */ +.el-tag-success{background:#f0f9eb;color:var(--success);} +.el-tag-warning{background:#fdf6ec;color:var(--warning);} +.el-tag-danger{background:#fef0f0;color:var(--danger);} +.el-tag-info{background:#f4f4f5;color:var(--info);} +.el-tag-primary{background:var(--primary-bg);color:var(--primary);} + +/* Pagination */ +.pagination{display:flex;align-items:center;justify-content:flex-end;gap:4px;margin-top:16px;font-size:13px;} +.pagination .page-info{color:var(--text-secondary);margin-right:8px;} +.page-btn{ + min-width:30px;height:30px;display:flex;align-items:center;justify-content:center; + border:1px solid var(--border);border-radius:var(--radius);cursor:pointer; + background:var(--white);color:var(--text-regular);font-size:13px;transition:.15s; + padding:0 6px; +} +.page-btn:hover{color:var(--primary);border-color:var(--primary);} +.page-btn.active{background:var(--primary);color:var(--white);border-color:var(--primary);} +.page-btn.disabled{color:var(--text-placeholder);cursor:not-allowed;} + +/* Form inputs - 仅保留颜色 */ +.el-input:focus{border-color:var(--primary);} +.el-input::placeholder{color:var(--text-placeholder);} + +/* Search bar */ +.filter-bar{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;} +.filter-bar label{font-size:13px;color:var(--text-secondary);white-space:nowrap;} + +/* ===== 页面标题栏(通用) ===== */ +.page-title-bar{display:flex;align-items:center;gap:12px;margin-bottom:16px;} +.page-title-text{font-size:16px;font-weight:600;color:var(--text);} diff --git a/www/static/css/web.css b/www/static/css/web.css new file mode 100644 index 0000000..8778eb5 --- /dev/null +++ b/www/static/css/web.css @@ -0,0 +1,554 @@ +/* ===== Reset & Variables ===== */ +*,*::before,*::after{margin:0;padding:0;box-sizing:border-box;} +ul,ol{list-style:none;} +:root{ + --orange:#E8751A; + --orange-dark:#C96012; + --orange-light:#F5A623; + --red:#CC2929; + --red-light:#E84040; + --blue:#3B82C4; + --blue-dark:#1A3550; + --white:#fff; + --gray-bg:#F5F6F8; + --gray-100:#ECEEF1; + --gray-300:#C4C8CE; + --gray-500:#7A8290; + --gray-700:#3D4451; + --gray-900:#1A1D24; + --font-cn:"Microsoft YaHei","PingFang SC",sans-serif; + --font-en:"Roboto",sans-serif; +} +html,body{height:100%;font-family:var(--font-cn);color:var(--gray-900);line-height:1.7;background:#000;} +a{text-decoration:none;color:inherit;transition:.2s;} +img{max-width:100%;display:block;} + +/* ===== Fixed Header ===== */ +.fixed-header{ + position:fixed;top:0;left:0;right:0;z-index:1000; + display:flex;align-items:center;justify-content:space-between; + padding:0 60px;height:72px; + background:rgba(255,255,255,.92);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px); + box-shadow:0 2px 12px rgba(0,0,0,.04); + transition:all .4s; +} +.logo{display:flex;align-items:center;} +.logo-img{height:44px;width:auto;transition:.3s;} + +.header-right{display:flex;align-items:center;gap:12px;} +.header-nav{display:flex;align-items:center;gap:6px;} +.nav-link{ + position:relative;padding:8px 18px;font-size:15px;font-weight:500; + color:var(--gray-700);letter-spacing:1px;transition:.25s;border-radius:4px; +} +.nav-link:hover,.nav-link.active{color:var(--orange);background:rgba(232,117,26,.08);} + +/* Dropdown */ +.nav-dropdown{position:relative;} +.nav-dropdown .dropdown-menu{ + position:absolute;top:100%;left:50%;transform:translateX(-50%) translateY(8px); + min-width:160px;background:rgba(255,255,255,.98);backdrop-filter:blur(12px);border-radius:8px; + box-shadow:0 8px 32px rgba(0,0,0,.12);padding:8px 0;border:1px solid rgba(0,0,0,.06); + opacity:0;visibility:hidden;transition:.25s;pointer-events:none; +} +.nav-dropdown:hover .dropdown-menu{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);pointer-events:auto;} +.dropdown-menu a{display:block;padding:10px 24px;font-size:14px;color:var(--gray-700);white-space:nowrap;transition:.15s;} +.dropdown-menu a:hover{color:var(--orange);background:rgba(232,117,26,.04);} + +.header-donate{ + padding:0 24px;border-radius:20px;font-size:14px;font-weight:600; + background:var(--orange);color:#fff;border:1px solid var(--orange); + cursor:pointer;transition:.3s;letter-spacing:1px;height:38px; + display:flex;align-items:center;justify-content:center; +} +.header-donate:hover{background:var(--orange-dark);border-color:var(--orange-dark);color:#fff;} + +/* Mobile Menu Button */ +.mobile-menu-btn{ + display:none;width:32px;height:32px;background:none;border:none;cursor:pointer; + flex-direction:column;justify-content:center;align-items:center;gap:5px;padding:4px; +} +.mobile-menu-btn span{display:block;width:20px;height:2px;background:var(--gray-700);transition:.3s;} + +/* Mobile Menu Overlay */ +.mobile-menu-overlay{ + position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1001; + opacity:0;visibility:hidden;transition:.3s; +} +.mobile-menu-overlay.open{opacity:1;visibility:visible;} + +/* Mobile Menu Drawer */ +.mobile-menu{ + position:fixed;top:0;right:-280px;width:280px;height:100%; + background:#fff;z-index:1002;transition:.3s; + display:flex;flex-direction:column; +} +.mobile-menu.open{right:0;} +.mobile-menu-header{ + display:flex;align-items:center;justify-content:space-between; + padding:16px 20px;border-bottom:1px solid var(--gray-100); +} +.mobile-logo{height:32px;} +.mobile-menu-close{ + width:32px;height:32px;background:none;border:none; + font-size:24px;color:var(--gray-500);cursor:pointer; +} +.mobile-nav{flex:1;overflow-y:auto;padding:12px 0;} +.mobile-nav-item{border-bottom:1px solid var(--gray-100);} +.mobile-nav-link{ + display:flex;align-items:center;justify-content:space-between; + padding:14px 20px;font-size:15px;color:var(--gray-700); +} +.mobile-nav-arrow{font-size:18px;transition:.3s;} +.mobile-nav-item.open .mobile-nav-arrow{transform:rotate(90deg);} +.mobile-nav-sub{display:none;background:var(--gray-bg);padding:8px 0;} +.mobile-nav-item.open .mobile-nav-sub{display:block;} +.mobile-nav-sub a{display:block;padding:10px 20px 10px 36px;font-size:14px;color:var(--gray-500);} +.mobile-nav-sub a:hover{color:var(--orange);} +.mobile-menu-footer{padding:20px;border-top:1px solid var(--gray-100);} +.mobile-donate-btn{ + display:block;width:100%;padding:12px;text-align:center; + background:var(--orange);color:#fff;border-radius:24px;font-weight:600; +} + + +/* ===== Swiper Fullpage ===== */ +.swiper-fullpage{width:100%;height:100vh;overflow:hidden;} +.swiper-fullpage .swiper-slide{height:100vh!important;overflow:hidden;position:relative;} + +/* ===== Slide Labels (right side dots) ===== */ +.slide-labels{ + position:fixed;right:36px;top:50%;transform:translateY(-50%);z-index:999; + display:flex;flex-direction:column;gap:24px; +} +.slide-label{ + display:flex;align-items:center;gap:10px;cursor:pointer; + flex-direction:row-reverse; +} +.slide-label .dot{ + width:10px;height:10px;border-radius:50%; + background:rgba(255,255,255,.3);border:2px solid rgba(255,255,255,.5); + transition:.3s;flex-shrink:0; +} +.slide-label.active .dot{ + background:var(--orange);border-color:var(--orange); + width:10px;height:24px;border-radius:5px; +} +.slide-label .txt{ + font-size:12px;color:rgba(255,255,255,.5);letter-spacing:1px; + opacity:0;transform:translateX(8px);transition:.25s;white-space:nowrap; +} +.slide-label:hover .txt{opacity:1;transform:translateX(0);} +.slide-label.active .txt{opacity:1;transform:translateX(0);color:var(--orange);} +.slide-labels.light .slide-label .dot{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.2);} +.slide-labels.light .slide-label.active .dot{background:var(--orange);border-color:var(--orange);} +.slide-labels.light .slide-label .txt{color:rgba(0,0,0,.3);} +.slide-labels.light .slide-label.active .txt{color:var(--orange);} + +/* ===== Slide 1: Banner ===== */ +.slide-banner{background:#0a0a0a;height:100vh;position:relative;} +.banner-swiper{width:100%;height:100%;} +.banner-swiper .swiper-slide{height:100vh!important;overflow:hidden;} +.banner-slide-bg{ + position:absolute;inset:0; + background:center/cover no-repeat; + filter:brightness(.85);transition:transform 6s ease-out; +} +.banner-swiper .swiper-slide-active .banner-slide-bg{transform:scale(1.05);} +.banner-slide-content{ + position:absolute;top:50%;left:120px;transform:translateY(-50%); + z-index:2;display:flex;flex-direction:column; + align-items:flex-start;max-width:700px; +} +.banner-slide-content.pos-left{left:120px;right:auto;align-items:flex-start;text-align:left;} +.banner-slide-content.pos-center{left:50%;transform:translate(-50%,-50%);align-items:center;text-align:center;} +.banner-slide-content.pos-right{left:auto;right:120px;align-items:flex-end;text-align:right;} +.banner-slide-content.glass-on{ + background:rgba(0,0,0,.25);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px); + border-radius:16px;border:1px solid rgba(255,255,255,.1); + padding:48px 60px; +} +.banner-slide-content.pos-center.glass-on{transform:translate(-50%,-50%);} +.banner-slide-content h1{ + font-size:48px;font-weight:700;color:#fff;line-height:1.3; + margin-bottom:20px;letter-spacing:2px; + opacity:0;transform:translateY(40px);transition:all .8s .3s; +} +.banner-swiper .swiper-slide-active .banner-slide-content h1{opacity:1;transform:translateY(0);} +.banner-slide-content .desc{ + font-size:16px;color:rgba(255,255,255,.75);line-height:1.9;max-width:600px; + margin-bottom:40px; + opacity:0;transform:translateY(30px);transition:all .8s .5s; +} +.banner-swiper .swiper-slide-active .banner-slide-content .desc{opacity:1;transform:translateY(0);} +.banner-slide-content .btns{ + display:flex;gap:16px; + opacity:0;transform:translateY(20px);transition:all .8s .7s; +} +.banner-swiper .swiper-slide-active .banner-slide-content .btns{opacity:1;transform:translateY(0);} +.banner-swiper .swiper-pagination{bottom:90px!important;} +.banner-swiper .swiper-pagination-bullet{ + width:32px;height:4px;border-radius:2px; + background:rgba(255,255,255,.35);opacity:1;border:none;transition:.3s; +} +.banner-swiper .swiper-pagination-bullet-active{width:48px;background:var(--orange);} + +.btn-primary{ + padding:14px 40px;border-radius:30px;font-size:15px;font-weight:600; + background:var(--orange);color:#fff;letter-spacing:1px;transition:.3s; + display:inline-block; +} +.btn-primary:hover{background:var(--orange-dark);transform:translateY(-2px);box-shadow:0 8px 24px rgba(232,117,26,.3);} +.btn-ghost{ + padding:14px 40px;border-radius:30px;font-size:15px;font-weight:600; + background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.5); + letter-spacing:1px;transition:.3s;display:inline-block; +} +.btn-ghost:hover{border-color:#fff;background:rgba(255,255,255,.1);} + +.scroll-hint{ + position:absolute;bottom:40px;left:50%;transform:translateX(-50%);z-index:2; + display:flex;flex-direction:column;align-items:center;gap:8px; + color:rgba(255,255,255,.5);font-size:12px;letter-spacing:2px; +} +.scroll-hint .mouse{ + width:24px;height:38px;border:2px solid rgba(255,255,255,.4);border-radius:12px; + position:relative; +} +.scroll-hint .mouse::after{ + content:"";position:absolute;top:6px;left:50%;transform:translateX(-50%); + width:3px;height:8px;background:rgba(255,255,255,.6);border-radius:2px; + animation:scrollDown 1.8s infinite; +} +@keyframes scrollDown{0%{opacity:1;top:6px;}100%{opacity:0;top:22px;}} + +/* ===== Slide 2: Donation Data ===== */ +.slide-donation{ + background:linear-gradient(135deg,#fff8f0 0%,#fff 50%,#f0f7ff 100%); + display:flex;align-items:center;justify-content:center; + height:100vh;padding-top:72px; +} +.donation-wrap{ + width:100%;max-width:1300px;padding:0 40px; + max-height:calc(100vh - 72px);overflow:hidden; + opacity:0;transform:translateY(50px);transition:all .9s .2s; + display:flex;flex-direction:column; +} +.swiper-slide-active .donation-wrap{opacity:1;transform:translateY(0);} + +.section-head{text-align:center;margin-bottom:2vh;} +.section-head h2{font-size:clamp(24px,3vw,36px);font-weight:700;color:var(--gray-900);margin-bottom:4px;} +.section-head h2::after{content:"";display:block;width:40px;height:3px;background:linear-gradient(90deg,var(--red),var(--orange));margin:8px auto 0;border-radius:2px;} +.section-head .en{font-family:var(--font-en);font-size:13px;color:var(--gray-300);letter-spacing:3px;text-transform:uppercase;} + +.data-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:2vh;} +.data-card{ + background:rgba(255,255,255,.65);backdrop-filter:blur(16px); + border-radius:14px;padding:18px 16px;text-align:center; + box-shadow:0 8px 32px rgba(0,0,0,.06),inset 0 1px 0 rgba(255,255,255,.8); + border:1px solid rgba(255,255,255,.6);transition:.3s; +} +.data-card:hover{transform:translateY(-4px);box-shadow:0 16px 48px rgba(232,117,26,.12);border-color:var(--orange-light);} +.data-card .label{font-size:14px;color:var(--gray-500);margin-bottom:4px;} +.data-card .amount{font-family:var(--font-en);font-size:clamp(20px,2.2vw,28px);font-weight:700;color:var(--orange);} +.data-card .amount .unit{font-size:14px;color:var(--gray-500);font-weight:400;margin-left:4px;} +.data-card .note{font-size:12px;color:var(--gray-300);margin-top:2px;} + +.donation-tables{display:grid;grid-template-columns:1fr 1fr;gap:16px;flex:1;min-height:0;} +.dtable{ + background:rgba(255,255,255,.6);backdrop-filter:blur(16px); + border-radius:14px;padding:14px; + box-shadow:0 8px 32px rgba(0,0,0,.06);border:1px solid rgba(255,255,255,.6); +} +.dtable h3{font-size:14px;font-weight:600;color:var(--gray-900);margin-bottom:6px;padding-bottom:5px;border-bottom:2px solid var(--orange-light);} +.dtable table{width:100%;border-collapse:collapse;font-size:13px;table-layout:fixed;} +.dtable th{text-align:center;padding:5px 8px;color:var(--gray-500);font-weight:500;border-bottom:1px solid var(--gray-100);} +.dtable td{text-align:center;padding:5px 8px;color:var(--gray-700);border-bottom:1px solid var(--gray-100);} +.dtable .td-r{font-family:var(--font-en);font-weight:500;color:var(--orange);} +.dtable-scroll-wrap{max-height:140px;overflow:hidden;position:relative;} +.dtable-scroll-inner{animation:dtableScroll 12s cubic-bezier(.45,.05,.55,.95) infinite;} +.dtable:nth-child(2) .dtable-scroll-inner{animation-delay:1.5s;} +.dtable-scroll-wrap:hover .dtable-scroll-inner{animation-play-state:paused;} +@keyframes dtableScroll{0%,15%{transform:translateY(0);}50%,65%{transform:translateY(-50%);}100%{transform:translateY(0);}} + +.dtable-drug{grid-column:1/-1;} +.dtable-drug h3{border-bottom-color:var(--orange);} +.dtable-drug .drug-name{color:var(--orange);font-weight:500;} +.drug-scroll-wrap{max-height:120px;overflow:hidden;position:relative;} +.drug-scroll-inner{animation:drugScroll 18s linear infinite;} +.drug-scroll-wrap:hover .drug-scroll-inner{animation-play-state:paused;} +@keyframes drugScroll{0%{transform:translateY(0);}100%{transform:translateY(-50%);}} + + +/* ===== Slide 3: Projects ===== */ +.slide-projects{ + position:relative;height:100vh;overflow:hidden;cursor:grab; +} +.slide-projects.dragging{cursor:grabbing;} +.slide-projects .proj-bg{ + position:absolute;inset:0; + background:center/cover no-repeat; + filter:brightness(.65); + transition:opacity .8s,transform 6s ease-out; + opacity:0; +} +.slide-projects .proj-bg.active{opacity:1;} +.swiper-slide-active .slide-projects .proj-bg.active{transform:scale(1.04);} + +.proj-info-card{ + position:absolute;top:50%;right:8%;transform:translateY(-50%); + width:380px; + background:rgba(232,117,26,.88);backdrop-filter:blur(8px); + border-radius:4px;padding:48px 40px;color:#fff; + opacity:0;transform:translateY(-50%) translateX(40px); + transition:all .7s .3s;z-index:5; +} +.swiper-slide-active .proj-info-card{opacity:1;transform:translateY(-50%) translateX(0);} +.proj-info-card .card-label{ + font-size:13px;letter-spacing:3px;opacity:.8;margin-bottom:12px; + display:flex;align-items:center;gap:8px; +} +.proj-info-card .card-label::before{ + content:"";display:block;width:24px;height:2px;background:var(--red-light);opacity:.8; +} +.proj-info-card h3{font-size:28px;font-weight:700;line-height:1.4;margin-bottom:16px;} +.proj-info-card .card-divider{width:40px;height:2px;background:#fff;opacity:.5;margin-bottom:16px;} +.proj-info-card p{font-size:15px;line-height:1.9;opacity:.9;margin-bottom:24px;} +.proj-info-card .card-btn{ + display:inline-flex;align-items:center;gap:6px; + padding:10px 28px;border:1.5px solid rgba(255,255,255,.6);border-radius:24px; + font-size:14px;color:#fff;transition:.3s; +} +.proj-info-card .card-btn:hover{background:rgba(255,255,255,.15);border-color:#fff;} + +.proj-tabs{ + position:absolute;bottom:60px;left:50%;transform:translateX(-50%); + z-index:5;display:flex;gap:0; +} +.proj-tab{ + padding:14px 28px;cursor:pointer; + font-size:14px;color:rgba(255,255,255,.6); + border-bottom:3px solid transparent; + transition:.3s;white-space:nowrap;letter-spacing:1px; +} +.proj-tab:hover{color:rgba(255,255,255,.85);} +.proj-tab.active{color:#fff;border-bottom-color:var(--red);font-weight:600;} + +.proj-more-link{ + position:absolute;bottom:24px;left:50%;transform:translateX(-50%); + z-index:5;font-size:13px;color:rgba(255,255,255,.5); + letter-spacing:2px;transition:.2s; +} +.proj-more-link:hover{color:var(--orange);} + +/* ===== Slide 4: News ===== */ +.slide-news{ + background:#fff; + display:flex;align-items:center;justify-content:center; + height:100vh;padding-top:72px; +} +.news-wrap{ + width:100%;max-width:1200px;padding:0 60px; + max-height:calc(100vh - 72px);overflow:hidden; + opacity:0;transform:translateY(50px);transition:all .9s .2s; +} +.swiper-slide-active .news-wrap{opacity:1;transform:translateY(0);} + +.news-grid{display:grid;grid-template-columns:1fr 1fr;gap:36px;align-items:start;} +.news-featured{border-radius:14px;overflow:hidden;position:relative;cursor:pointer;} +.news-featured img{width:100%;height:clamp(280px,40vh,400px);object-fit:cover;transition:.5s;} +.news-featured:hover img{transform:scale(1.03);} +.news-featured .overlay{ + position:absolute;bottom:0;left:0;right:0; + padding:24px;background:linear-gradient(transparent,rgba(0,0,0,.7)); + color:#fff; +} +.news-featured .overlay h3{font-size:16px;font-weight:600;margin-bottom:4px;} +.news-featured .overlay .date{font-size:13px;opacity:.7;} + +.news-list{display:flex;flex-direction:column;gap:0;} +.news-item{ + display:flex;align-items:flex-start;gap:16px; + padding:14px 0;border-bottom:1px solid var(--gray-100); + cursor:pointer;transition:.2s; +} +.news-item:hover{padding-left:8px;} +.news-item .date-box{flex-shrink:0;width:54px;text-align:center;} +.news-item .date-box .day{font-family:var(--font-en);font-size:24px;font-weight:700;color:var(--orange);line-height:1;} +.news-item .date-box .ym{font-size:12px;color:var(--gray-300);} +.news-item .text h4{font-size:14px;font-weight:500;color:var(--gray-900);margin-bottom:4px;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;} +.news-item .text p{font-size:13px;color:var(--gray-500);display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;} + +.more-link{font-size:13px;color:var(--orange);letter-spacing:1px;} +.more-link:hover{text-decoration:underline;} + +/* ===== Slide 5: Partners + Footer ===== */ +.slide-footer{ + background:#F8F9FA; + display:flex;flex-direction:column;justify-content:flex-start;align-items:center; + height:100vh;padding-top:72px;overflow:hidden; +} +.partners-section{ + width:100%;max-width:1200px;padding:40px 60px;flex:1; + display:flex;flex-direction:column; + opacity:0;transform:translateY(50px);transition:all .9s .2s; +} +.swiper-slide-active .partners-section{opacity:1;transform:translateY(0);} + +.partners-grid{ + display:grid;grid-template-columns:repeat(5,1fr);gap:20px; + flex:1;align-content:center; +} +.partner-item{ + background:#fff;border-radius:12px;padding:20px; + display:flex;align-items:center;justify-content:center; + box-shadow:0 2px 12px rgba(0,0,0,.03);border:1px solid var(--gray-100); + transition:.3s;min-height:90px; +} +.partner-item:hover{box-shadow:0 8px 24px rgba(0,0,0,.08);transform:translateY(-2px);} +.partner-item img{max-height:48px;width:auto;filter:grayscale(.3);transition:.3s;} +.partner-item:hover img{filter:grayscale(0);} + +/* Footer */ +.footer-component{ + width:100%;background:#371806;position:relative; + display:flex;flex-direction:column;flex-shrink:0; +} +.footer-main{flex:1;display:flex;align-items:center;padding:32px 0;} +.footer-content{ + max-width:1200px;width:100%;margin:0 auto;padding:0 40px; + display:flex;justify-content:space-between;align-items:center; +} +.footer-left{flex:1;} +.footer-title{font-size:24px;font-weight:600;color:#BC6627;margin-bottom:20px;letter-spacing:1px;} +.footer-info{display:flex;flex-direction:column;gap:8px;} +.footer-info p{font-size:14px;color:#BC6627;line-height:1.6;} +.footer-right{display:flex;align-items:center;gap:16px;} +.footer-qr{text-align:center;} +.footer-qr img{width:100px;height:100px;border-radius:4px;margin-bottom:8px;background:#fff;} +.footer-qr span{font-size:12px;color:#BC6627;display:block;} + +.footer-bottom{border-top:1px solid #603D2E;padding:16px 0;} +.footer-bottom-content{ + max-width:1200px;width:100%;margin:0 auto;padding:0 40px; + display:flex;justify-content:space-between;align-items:center; +} +.footer-copyright{font-size:12px;color:#86543F;} +.footer-links{display:flex;gap:24px;align-items:center;} +.footer-links a{font-size:12px;color:#86543F;transition:color .2s;} +.footer-links a:hover{color:#BC6627;} +.footer-links .separator{color:#86543F;opacity:.3;} + + +/* ===== Responsive ===== */ +@media(max-width:1024px){ + .fixed-header{padding:0 24px;} + .banner-slide-content{left:40px;max-width:600px;} + .banner-slide-content.pos-left{left:40px;} + .banner-slide-content.pos-right{right:40px;} + .banner-slide-content.glass-on{padding:36px 40px;} + .banner-slide-content h1{font-size:32px;} + .data-cards{gap:12px;} + .donation-tables{gap:12px;} + .donation-wrap,.news-wrap{padding:0 32px;} + .proj-info-card{width:340px;padding:36px 32px;right:5%;} + .proj-info-card h3{font-size:24px;} + .proj-info-card p{font-size:14px;} + .proj-tab{padding:12px 20px;font-size:13px;} + .news-grid{gap:24px;} + .partners-grid{grid-template-columns:repeat(4,1fr);} + .partners-section{padding:40px 32px;} + .slide-labels{display:none;} +} + +@media(max-width:768px){ + .header-nav{display:none;} + .mobile-menu-btn{display:flex;} + .header-donate{display:none;} + .banner-slide-content{left:24px;right:24px;max-width:calc(100% - 48px);} + .banner-slide-content.pos-left{left:24px;right:auto;max-width:calc(100% - 48px);} + .banner-slide-content.pos-center{left:50%;right:auto;} + .banner-slide-content.pos-right{left:auto;right:24px;max-width:calc(100% - 48px);} + .banner-slide-content.glass-on{padding:24px 28px;} + .banner-slide-content h1{font-size:26px;} + .donation-wrap,.news-wrap{padding:0 20px;} + .data-cards{grid-template-columns:repeat(3,1fr);gap:8px;} + .data-card{padding:12px 8px;} + .data-card .amount{font-size:18px;} + .data-card .label{font-size:12px;} + .data-card .note{font-size:11px;} + .donation-tables{grid-template-columns:1fr;gap:8px;} + .dtable-drug{grid-column:1/-1;} + .dtable-scroll-wrap{max-height:90px;} + .drug-scroll-wrap{max-height:70px;} + .dtable{padding:10px 12px;} + .dtable h3{font-size:13px;margin-bottom:4px;padding-bottom:4px;} + .dtable td,.dtable th{font-size:12px;padding:4px 6px;} + .proj-info-card{ + width:auto;left:20px;right:20px;top:auto;bottom:100px; + transform:none;padding:20px; + max-height:calc(100vh - 200px);overflow-y:auto; + } + .swiper-slide-active .proj-info-card{transform:none;opacity:1;} + .proj-info-card h3{font-size:20px;margin-bottom:10px;} + .proj-info-card p{font-size:14px;margin-bottom:16px;line-height:1.6;} + .proj-tabs{bottom:16px;left:16px;right:16px;transform:none;flex-wrap:wrap;justify-content:center;gap:4px;} + .proj-tab{padding:6px 12px;font-size:12px;} + .proj-more-link{display:none;} + .news-grid{grid-template-columns:1fr;} + .news-featured img{height:200px;} + .partners-grid{grid-template-columns:repeat(3,1fr);gap:12px;} + .partners-section{padding:24px 20px;} + .footer-content{flex-direction:column;align-items:flex-start;gap:24px;} + .footer-main{padding:24px 0;} + .footer-bottom-content{flex-direction:column;gap:12px;text-align:center;} + .footer-links{flex-wrap:wrap;justify-content:center;gap:8px 12px;} + .section-head{margin-bottom:1vh;} +} + +@media(max-width:480px){ + .fixed-header{padding:0 16px;height:56px;} + .logo-img{height:32px;} + .banner-slide-content{left:16px;right:16px;max-width:calc(100% - 32px);} + .banner-slide-content.pos-left{left:16px;right:auto;} + .banner-slide-content.pos-right{left:auto;right:16px;} + .banner-slide-content.glass-on{padding:20px 24px;} + .banner-slide-content h1{font-size:20px;} + .banner-slide-content .desc{font-size:14px;} + .btn-primary,.btn-ghost{padding:10px 24px;font-size:13px;} + .donation-wrap,.news-wrap{padding:0 12px;} + .section-head h2{font-size:20px;} + .data-cards{gap:6px;} + .data-card{padding:8px 6px;border-radius:10px;} + .data-card .label{font-size:11px;margin-bottom:2px;} + .data-card .amount{font-size:16px;} + .data-card .note{font-size:10px;} + .donation-tables{gap:8px;} + .dtable{padding:8px 10px;border-radius:10px;} + .dtable h3{font-size:12px;margin-bottom:4px;padding-bottom:4px;} + .dtable td,.dtable th{font-size:11px;padding:3px 4px;} + .dtable-scroll-wrap{max-height:72px;} + .drug-scroll-wrap{max-height:60px;} + .dtable-drug th:nth-child(3),.dtable-drug td:nth-child(3){display:none;} + .proj-info-card{left:12px;right:12px;bottom:80px;padding:16px 14px;} + .proj-info-card h3{font-size:18px;} + .proj-info-card p{font-size:13px;margin-bottom:12px;-webkit-line-clamp:3;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;} + .proj-info-card .card-label{font-size:11px;margin-bottom:8px;} + .proj-info-card .card-btn{padding:8px 20px;font-size:12px;} + .proj-tabs{bottom:8px;left:8px;right:8px;} + .proj-tab{padding:5px 8px;font-size:11px;} + .news-item .date-box .day{font-size:20px;} + .news-item .text h4{font-size:13px;} + .partners-grid{grid-template-columns:repeat(2,1fr);gap:8px;} + .partner-item{padding:12px;border-radius:8px;min-height:70px;} + .partner-item img{max-height:36px;} + .footer-title{font-size:18px;margin-bottom:12px;} + .footer-info p{font-size:12px;} + .footer-qr img{width:80px;height:80px;} + .footer-qr span{font-size:11px;} + .section-head{margin-bottom:0.5vh;} + .section-head .en{display:none;} + .slide-footer{padding-top:56px;} + .slide-donation{padding-top:56px;} + .slide-news{padding-top:56px;} +} diff --git a/www/static/image/.gitkeep b/www/static/image/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/www/static/images/logo.png b/www/static/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3345afd0516ed35f85f0bd9b215b43c4eb5ec541 GIT binary patch literal 51026 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 literal 0 HcmV?d00001 diff --git a/www/static/js/.gitkeep b/www/static/js/.gitkeep new file mode 100644 index 0000000..e69de29