mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	feat: add invitation and promotion functions
This commit is contained in:
		@@ -124,6 +124,11 @@ type UserChatConfig struct {
 | 
			
		||||
	ApiKeys map[Platform]string `json:"api_keys"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type InviteReward struct {
 | 
			
		||||
	ChatCalls int `json:"chat_calls"`
 | 
			
		||||
	ImgCalls  int `json:"img_calls"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ModelAPIConfig struct {
 | 
			
		||||
	ApiURL      string  `json:"api_url,omitempty"`
 | 
			
		||||
	Temperature float32 `json:"temperature"`
 | 
			
		||||
@@ -135,8 +140,8 @@ type SystemConfig struct {
 | 
			
		||||
	Title            string   `json:"title"`
 | 
			
		||||
	AdminTitle       string   `json:"admin_title"`
 | 
			
		||||
	Models           []string `json:"models"`
 | 
			
		||||
	UserInitCalls    int      `json:"user_init_calls"` // 新用户注册默认总送多少次调用
 | 
			
		||||
	InitImgCalls     int      `json:"init_img_calls"`
 | 
			
		||||
	InitChatCalls    int      `json:"init_chat_calls"` // 新用户注册赠送对话次数
 | 
			
		||||
	InitImgCalls     int      `json:"init_img_calls"`  // 新用户注册赠送绘图次数
 | 
			
		||||
	VipMonthCalls    int      `json:"vip_month_calls"` // 会员每个赠送的调用次数
 | 
			
		||||
	EnabledRegister  bool     `json:"enabled_register"`
 | 
			
		||||
	EnabledMsg       bool     `json:"enabled_msg"`         // 启用短信验证码服务
 | 
			
		||||
@@ -148,4 +153,6 @@ type SystemConfig struct {
 | 
			
		||||
	OrderPayTimeout  int      `json:"order_pay_timeout"`   //订单支付超时时间
 | 
			
		||||
	DefaultModels    []string `json:"default_models"`      // 默认开通的 AI 模型
 | 
			
		||||
	OrderPayInfoText string   `json:"order_pay_info_text"` // 订单支付页面说明文字
 | 
			
		||||
	InviteChatCalls  int      `json:"invite_chat_calls"`   // 邀请用户注册奖励对话次数
 | 
			
		||||
	InviteImgCalls   int      `json:"invite_img_calls"`    // 邀请用户注册奖励绘图次数
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -49,3 +49,11 @@ func (h *BaseHandler) GetUserKey(c *gin.Context) string {
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("users/%v", userId)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *BaseHandler) GetLoginUserId(c *gin.Context) uint {
 | 
			
		||||
	userId, ok := c.Get(types.LoginUserID)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return uint(utils.IntValue(utils.InterfaceToString(userId), 0))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								api/handler/invite_handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								api/handler/invite_handler.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/core"
 | 
			
		||||
	"chatplus/store/model"
 | 
			
		||||
	"chatplus/store/vo"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"chatplus/utils/resp"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InviteHandler 用户邀请
 | 
			
		||||
type InviteHandler struct {
 | 
			
		||||
	BaseHandler
 | 
			
		||||
	db *gorm.DB
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewInviteHandler(app *core.AppServer, db *gorm.DB) *InviteHandler {
 | 
			
		||||
	h := InviteHandler{db: db}
 | 
			
		||||
	h.App = app
 | 
			
		||||
	return &h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Code 获取当前用户邀请码
 | 
			
		||||
func (h *InviteHandler) Code(c *gin.Context) {
 | 
			
		||||
	userId := h.GetLoginUserId(c)
 | 
			
		||||
	var inviteCode model.InviteCode
 | 
			
		||||
	res := h.db.Where("user_id = ?", userId).First(&inviteCode)
 | 
			
		||||
	// 如果邀请码不存在,则创建一个
 | 
			
		||||
	if res.Error != nil {
 | 
			
		||||
		code := strings.ToUpper(utils.RandString(8))
 | 
			
		||||
		for {
 | 
			
		||||
			res = h.db.Where("code = ?", code).First(&inviteCode)
 | 
			
		||||
			if res.Error != nil { // 不存在相同的邀请码则退出
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		inviteCode.UserId = userId
 | 
			
		||||
		inviteCode.Code = code
 | 
			
		||||
		h.db.Create(&inviteCode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var codeVo vo.InviteCode
 | 
			
		||||
	err := utils.CopyObject(inviteCode, &codeVo)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		resp.ERROR(c, "拷贝对象失败")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp.SUCCESS(c, codeVo)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// List Log 用户邀请记录
 | 
			
		||||
func (h *InviteHandler) List(c *gin.Context) {
 | 
			
		||||
 | 
			
		||||
	resp.SUCCESS(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hits 访问邀请码
 | 
			
		||||
func (h *InviteHandler) Hits(c *gin.Context) {
 | 
			
		||||
	code := c.Query("code")
 | 
			
		||||
	h.db.Model(&model.InviteCode{}).Where("code = ?", code).UpdateColumn("hits", gorm.Expr("hits + ?", 1))
 | 
			
		||||
	resp.SUCCESS(c)
 | 
			
		||||
}
 | 
			
		||||
@@ -39,9 +39,10 @@ func NewUserHandler(
 | 
			
		||||
func (h *UserHandler) Register(c *gin.Context) {
 | 
			
		||||
	// parameters process
 | 
			
		||||
	var data struct {
 | 
			
		||||
		Mobile   string `json:"mobile"`
 | 
			
		||||
		Password string `json:"password"`
 | 
			
		||||
		Code     string `json:"code"`
 | 
			
		||||
		Mobile     string `json:"mobile"`
 | 
			
		||||
		Password   string `json:"password"`
 | 
			
		||||
		Code       string `json:"code"`
 | 
			
		||||
		InviteCode string `json:"invite_code"`
 | 
			
		||||
	}
 | 
			
		||||
	if err := c.ShouldBindJSON(&data); err != nil {
 | 
			
		||||
		resp.ERROR(c, types.InvalidArgs)
 | 
			
		||||
@@ -68,6 +69,16 @@ func (h *UserHandler) Register(c *gin.Context) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 验证邀请码
 | 
			
		||||
	inviteCode := model.InviteCode{}
 | 
			
		||||
	if data.InviteCode != "" {
 | 
			
		||||
		res := h.db.Where("code = ?", data.InviteCode).First(&inviteCode)
 | 
			
		||||
		if res.Error != nil {
 | 
			
		||||
			resp.ERROR(c, "无效的邀请码")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check if the username is exists
 | 
			
		||||
	var item model.User
 | 
			
		||||
	res := h.db.Where("mobile = ?", data.Mobile).First(&item)
 | 
			
		||||
@@ -92,7 +103,7 @@ func (h *UserHandler) Register(c *gin.Context) {
 | 
			
		||||
				types.ChatGLM: "",
 | 
			
		||||
			},
 | 
			
		||||
		}),
 | 
			
		||||
		Calls:    h.App.SysConfig.UserInitCalls,
 | 
			
		||||
		Calls:    h.App.SysConfig.InitChatCalls,
 | 
			
		||||
		ImgCalls: h.App.SysConfig.InitImgCalls,
 | 
			
		||||
	}
 | 
			
		||||
	res = h.db.Create(&user)
 | 
			
		||||
@@ -102,6 +113,26 @@ func (h *UserHandler) Register(c *gin.Context) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 记录邀请关系
 | 
			
		||||
	if data.InviteCode != "" {
 | 
			
		||||
		// 增加邀请数量
 | 
			
		||||
		h.db.Model(&model.InviteCode{}).Where("code = ?", data.InviteCode).UpdateColumn("reg_num", gorm.Expr("reg_num + ?", 1))
 | 
			
		||||
		if h.App.SysConfig.InviteChatCalls > 0 {
 | 
			
		||||
			h.db.Model(&model.User{}).Where("id = ?", inviteCode.UserId).UpdateColumn("calls", gorm.Expr("calls + ?", h.App.SysConfig.InviteChatCalls))
 | 
			
		||||
		}
 | 
			
		||||
		if h.App.SysConfig.InviteImgCalls > 0 {
 | 
			
		||||
			h.db.Model(&model.User{}).Where("id = ?", inviteCode.UserId).UpdateColumn("img_calls", gorm.Expr("img_calls + ?", h.App.SysConfig.InviteImgCalls))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 添加邀请记录
 | 
			
		||||
		h.db.Create(&model.InviteLog{
 | 
			
		||||
			InviterId:  inviteCode.UserId,
 | 
			
		||||
			UserId:     user.Id,
 | 
			
		||||
			Username:   user.Mobile,
 | 
			
		||||
			InviteCode: inviteCode.Code,
 | 
			
		||||
			Reward:     utils.JsonEncode(types.InviteReward{ChatCalls: h.App.SysConfig.InviteChatCalls, ImgCalls: h.App.SysConfig.InviteImgCalls}),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if h.App.SysConfig.EnabledMsg {
 | 
			
		||||
		_ = h.redis.Del(c, key) // 注册成功,删除短信验证码
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -346,6 +346,14 @@ func main() {
 | 
			
		||||
			group.GET("list", h.List)
 | 
			
		||||
		}),
 | 
			
		||||
 | 
			
		||||
		fx.Provide(handler.NewInviteHandler),
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, h *handler.InviteHandler) {
 | 
			
		||||
			group := s.Engine.Group("/api/invite/")
 | 
			
		||||
			group.GET("code", h.Code)
 | 
			
		||||
			group.GET("list", h.List)
 | 
			
		||||
			group.GET("hits", h.Hits)
 | 
			
		||||
		}),
 | 
			
		||||
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, db *gorm.DB) {
 | 
			
		||||
			err := s.Run(db)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								api/store/model/invite_code.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								api/store/model/invite_code.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
package model
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
type InviteCode struct {
 | 
			
		||||
	Id        uint `gorm:"primarykey;column:id"`
 | 
			
		||||
	UserId    uint
 | 
			
		||||
	Code      string
 | 
			
		||||
	Hits      int // 点击次数
 | 
			
		||||
	RegNum    int // 注册人数
 | 
			
		||||
	CreatedAt time.Time
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								api/store/model/invite_log.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								api/store/model/invite_log.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package model
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type InviteLog struct {
 | 
			
		||||
	Id         uint `gorm:"primarykey;column:id"`
 | 
			
		||||
	InviterId  uint
 | 
			
		||||
	UserId     uint
 | 
			
		||||
	Username   string
 | 
			
		||||
	InviteCode string
 | 
			
		||||
	Reward     string `gorm:"column:reward_json"` // 邀请奖励
 | 
			
		||||
	CreatedAt  time.Time
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								api/store/vo/invite_code.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								api/store/vo/invite_code.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
package vo
 | 
			
		||||
 | 
			
		||||
type InviteCode struct {
 | 
			
		||||
	Id        uint   `json:"id"`
 | 
			
		||||
	UserId    uint   `json:"user_id"`
 | 
			
		||||
	Code      string `json:"code"`
 | 
			
		||||
	Hits      int    `json:"hits"`
 | 
			
		||||
	RegNum    int    `json:"reg_num"`
 | 
			
		||||
	CreatedAt int64  `json:"created_at"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								api/store/vo/invite_log.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								api/store/vo/invite_log.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package vo
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/core/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type InviteLog struct {
 | 
			
		||||
	Id         uint               `json:"id"`
 | 
			
		||||
	InviterId  uint               `json:"inviter_id"`
 | 
			
		||||
	UserId     uint               `json:"user_id"`
 | 
			
		||||
	Username   string             `json:"username"`
 | 
			
		||||
	InviteCode string             `json:"invite_code"`
 | 
			
		||||
	Reward     types.InviteReward `json:"reward"`
 | 
			
		||||
	CreatedAt  int64              `json:"created_at"`
 | 
			
		||||
}
 | 
			
		||||
@@ -2,13 +2,12 @@ package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	value, err := strconv.Atoi("012345")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println(value)
 | 
			
		||||
	r := time.Now()
 | 
			
		||||
	f := reflect.ValueOf(r)
 | 
			
		||||
	fmt.Println(f.Type().Kind())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
 | 
			
		||||
	"github.com/nfnt/resize"
 | 
			
		||||
	"github.com/skip2/go-qrcode"
 | 
			
		||||
	"image"
 | 
			
		||||
@@ -14,8 +15,6 @@ import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CopyObject 拷贝对象
 | 
			
		||||
@@ -60,6 +59,8 @@ func CopyObject(src interface{}, dst interface{}) error {
 | 
			
		||||
						value.Set(reflect.ValueOf(""))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if field.Type.Kind() != value.Type().Kind() { // 不同类型的字段过滤掉
 | 
			
		||||
				continue
 | 
			
		||||
			} else { // 简单数据类型的强制类型转换
 | 
			
		||||
				switch value.Kind() {
 | 
			
		||||
				case reflect.Int:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								database/update-v3.2.0.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								database/update-v3.2.0.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
 | 
			
		||||
CREATE TABLE `chatgpt_invite_logs` (
 | 
			
		||||
                                      `id` int NOT NULL,
 | 
			
		||||
                                      `inviter_id` int NOT NULL COMMENT '邀请人ID',
 | 
			
		||||
                                      `user_id` int NOT NULL COMMENT '注册用户ID',
 | 
			
		||||
                                      `username` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
 | 
			
		||||
                                      `invite_code` char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '邀请码',
 | 
			
		||||
                                      `calls` smallint NOT NULL COMMENT '奖励对话次数',
 | 
			
		||||
                                      `created_at` datetime NOT NULL
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='邀请注册日志';
 | 
			
		||||
ALTER TABLE `chatgpt_invite_logs` ADD PRIMARY KEY (`id`);
 | 
			
		||||
ALTER TABLE `chatgpt_invite_logs` MODIFY `id` int NOT NULL AUTO_INCREMENT;
 | 
			
		||||
ALTER TABLE `chatgpt_invite_logs` CHANGE `calls` `reward_json` TEXT NOT NULL COMMENT '邀请奖励';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE `chatgpt_invite_codes` (
 | 
			
		||||
                                        `id` int NOT NULL,
 | 
			
		||||
                                        `user_id` int NOT NULL COMMENT '用户ID',
 | 
			
		||||
                                        `code` char(8) NOT NULL COMMENT '邀请码',
 | 
			
		||||
                                        `hits` int NOT NULL COMMENT '点击次数',
 | 
			
		||||
                                        `reg_num` smallint NOT NULL COMMENT '注册数量',
 | 
			
		||||
                                        `created_at` datetime NOT NULL
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户邀请码';
 | 
			
		||||
ALTER TABLE `chatgpt_invite_codes` ADD PRIMARY KEY (`id`);
 | 
			
		||||
ALTER TABLE `chatgpt_invite_codes` MODIFY `id` int NOT NULL AUTO_INCREMENT;
 | 
			
		||||
ALTER TABLE `chatgpt_invite_codes` ADD UNIQUE(`code`);
 | 
			
		||||
							
								
								
									
										323
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										323
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -21,6 +21,7 @@
 | 
			
		||||
        "markdown-it": "^13.0.1",
 | 
			
		||||
        "md-editor-v3": "^2.2.1",
 | 
			
		||||
        "pinia": "^2.1.4",
 | 
			
		||||
        "qrcode": "^1.5.3",
 | 
			
		||||
        "qs": "^6.11.1",
 | 
			
		||||
        "sortablejs": "^1.15.0",
 | 
			
		||||
        "v3-waterfall": "^1.2.1",
 | 
			
		||||
@@ -3361,7 +3362,6 @@
 | 
			
		||||
      "version": "5.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
@@ -4763,6 +4763,14 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/decamelize": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/decode-uri-component": {
 | 
			
		||||
      "version": "0.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
 | 
			
		||||
@@ -4973,6 +4981,11 @@
 | 
			
		||||
      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/dijkstrajs": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/dir-glob": {
 | 
			
		||||
      "version": "3.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
 | 
			
		||||
@@ -5150,8 +5163,7 @@
 | 
			
		||||
    "node_modules/emoji-regex": {
 | 
			
		||||
      "version": "8.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/emojis-list": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
@@ -5162,6 +5174,11 @@
 | 
			
		||||
        "node": ">= 4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/encode-utf8": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/encodeurl": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
 | 
			
		||||
@@ -6035,7 +6052,6 @@
 | 
			
		||||
      "version": "4.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "locate-path": "^5.0.0",
 | 
			
		||||
        "path-exists": "^4.0.0"
 | 
			
		||||
@@ -6181,7 +6197,6 @@
 | 
			
		||||
      "version": "2.0.5",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
 | 
			
		||||
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": "6.* || 8.* || >= 10.*"
 | 
			
		||||
      }
 | 
			
		||||
@@ -6720,7 +6735,6 @@
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
@@ -7089,7 +7103,6 @@
 | 
			
		||||
      "version": "5.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "p-locate": "^4.1.0"
 | 
			
		||||
      },
 | 
			
		||||
@@ -8115,7 +8128,6 @@
 | 
			
		||||
      "version": "2.3.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
 | 
			
		||||
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "p-try": "^2.0.0"
 | 
			
		||||
      },
 | 
			
		||||
@@ -8127,7 +8139,6 @@
 | 
			
		||||
      "version": "4.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "p-limit": "^2.2.0"
 | 
			
		||||
      },
 | 
			
		||||
@@ -8152,7 +8163,6 @@
 | 
			
		||||
      "version": "2.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
@@ -8238,7 +8248,6 @@
 | 
			
		||||
      "version": "4.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
@@ -8358,6 +8367,14 @@
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pngjs": {
 | 
			
		||||
      "version": "5.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=10.13.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/portfinder": {
 | 
			
		||||
      "version": "1.0.28",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.28.tgz",
 | 
			
		||||
@@ -9020,6 +9037,119 @@
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode": {
 | 
			
		||||
      "version": "1.5.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz",
 | 
			
		||||
      "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "dijkstrajs": "^1.0.1",
 | 
			
		||||
        "encode-utf8": "^1.0.3",
 | 
			
		||||
        "pngjs": "^5.0.0",
 | 
			
		||||
        "yargs": "^15.3.1"
 | 
			
		||||
      },
 | 
			
		||||
      "bin": {
 | 
			
		||||
        "qrcode": "bin/qrcode"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=10.13.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/ansi-styles": {
 | 
			
		||||
      "version": "4.3.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
 | 
			
		||||
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "color-convert": "^2.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/camelcase": {
 | 
			
		||||
      "version": "5.3.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
 | 
			
		||||
      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/cliui": {
 | 
			
		||||
      "version": "6.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "string-width": "^4.2.0",
 | 
			
		||||
        "strip-ansi": "^6.0.0",
 | 
			
		||||
        "wrap-ansi": "^6.2.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/color-convert": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "color-name": "~1.1.4"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=7.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/color-name": {
 | 
			
		||||
      "version": "1.1.4",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
 | 
			
		||||
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/wrap-ansi": {
 | 
			
		||||
      "version": "6.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "ansi-styles": "^4.0.0",
 | 
			
		||||
        "string-width": "^4.1.0",
 | 
			
		||||
        "strip-ansi": "^6.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/y18n": {
 | 
			
		||||
      "version": "4.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/yargs": {
 | 
			
		||||
      "version": "15.4.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
 | 
			
		||||
      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "cliui": "^6.0.0",
 | 
			
		||||
        "decamelize": "^1.2.0",
 | 
			
		||||
        "find-up": "^4.1.0",
 | 
			
		||||
        "get-caller-file": "^2.0.1",
 | 
			
		||||
        "require-directory": "^2.1.1",
 | 
			
		||||
        "require-main-filename": "^2.0.0",
 | 
			
		||||
        "set-blocking": "^2.0.0",
 | 
			
		||||
        "string-width": "^4.2.0",
 | 
			
		||||
        "which-module": "^2.0.0",
 | 
			
		||||
        "y18n": "^4.0.0",
 | 
			
		||||
        "yargs-parser": "^18.1.2"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qrcode/node_modules/yargs-parser": {
 | 
			
		||||
      "version": "18.1.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
 | 
			
		||||
      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "camelcase": "^5.0.0",
 | 
			
		||||
        "decamelize": "^1.2.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/qs": {
 | 
			
		||||
      "version": "6.11.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz",
 | 
			
		||||
@@ -9258,7 +9388,6 @@
 | 
			
		||||
      "version": "2.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
@@ -9272,6 +9401,11 @@
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/require-main-filename": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/requires-port": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
 | 
			
		||||
@@ -9547,6 +9681,11 @@
 | 
			
		||||
        "node": ">= 0.8.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/set-blocking": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/setprototypeof": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
 | 
			
		||||
@@ -9852,7 +9991,6 @@
 | 
			
		||||
      "version": "4.2.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
 | 
			
		||||
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "emoji-regex": "^8.0.0",
 | 
			
		||||
        "is-fullwidth-code-point": "^3.0.0",
 | 
			
		||||
@@ -9866,7 +10004,6 @@
 | 
			
		||||
      "version": "6.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "ansi-regex": "^5.0.1"
 | 
			
		||||
      },
 | 
			
		||||
@@ -11194,6 +11331,11 @@
 | 
			
		||||
        "which": "bin/which"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/which-module": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/wildcard": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/wildcard/-/wildcard-2.0.0.tgz",
 | 
			
		||||
@@ -13972,8 +14114,7 @@
 | 
			
		||||
    "ansi-regex": {
 | 
			
		||||
      "version": "5.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "ansi-styles": {
 | 
			
		||||
      "version": "3.2.1",
 | 
			
		||||
@@ -15081,6 +15222,11 @@
 | 
			
		||||
        "ms": "2.1.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "decamelize": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
 | 
			
		||||
    },
 | 
			
		||||
    "decode-uri-component": {
 | 
			
		||||
      "version": "0.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
 | 
			
		||||
@@ -15242,6 +15388,11 @@
 | 
			
		||||
      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "dijkstrajs": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
 | 
			
		||||
    },
 | 
			
		||||
    "dir-glob": {
 | 
			
		||||
      "version": "3.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
 | 
			
		||||
@@ -15399,8 +15550,7 @@
 | 
			
		||||
    "emoji-regex": {
 | 
			
		||||
      "version": "8.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
 | 
			
		||||
    },
 | 
			
		||||
    "emojis-list": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
@@ -15408,6 +15558,11 @@
 | 
			
		||||
      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "encode-utf8": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
 | 
			
		||||
    },
 | 
			
		||||
    "encodeurl": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
 | 
			
		||||
@@ -16104,7 +16259,6 @@
 | 
			
		||||
      "version": "4.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "locate-path": "^5.0.0",
 | 
			
		||||
        "path-exists": "^4.0.0"
 | 
			
		||||
@@ -16210,8 +16364,7 @@
 | 
			
		||||
    "get-caller-file": {
 | 
			
		||||
      "version": "2.0.5",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
 | 
			
		||||
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
 | 
			
		||||
    },
 | 
			
		||||
    "get-intrinsic": {
 | 
			
		||||
      "version": "1.1.1",
 | 
			
		||||
@@ -16639,8 +16792,7 @@
 | 
			
		||||
    "is-fullwidth-code-point": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
 | 
			
		||||
    },
 | 
			
		||||
    "is-glob": {
 | 
			
		||||
      "version": "4.0.3",
 | 
			
		||||
@@ -16933,7 +17085,6 @@
 | 
			
		||||
      "version": "5.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "p-locate": "^4.1.0"
 | 
			
		||||
      }
 | 
			
		||||
@@ -17749,7 +17900,6 @@
 | 
			
		||||
      "version": "2.3.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
 | 
			
		||||
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "p-try": "^2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
@@ -17758,7 +17908,6 @@
 | 
			
		||||
      "version": "4.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "p-limit": "^2.2.0"
 | 
			
		||||
      }
 | 
			
		||||
@@ -17776,8 +17925,7 @@
 | 
			
		||||
    "p-try": {
 | 
			
		||||
      "version": "2.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "param-case": {
 | 
			
		||||
      "version": "3.0.4",
 | 
			
		||||
@@ -17852,8 +18000,7 @@
 | 
			
		||||
    "path-exists": {
 | 
			
		||||
      "version": "4.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
 | 
			
		||||
    },
 | 
			
		||||
    "path-is-absolute": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
@@ -17922,6 +18069,11 @@
 | 
			
		||||
        "find-up": "^4.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "pngjs": {
 | 
			
		||||
      "version": "5.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
 | 
			
		||||
    },
 | 
			
		||||
    "portfinder": {
 | 
			
		||||
      "version": "1.0.28",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.28.tgz",
 | 
			
		||||
@@ -18364,6 +18516,97 @@
 | 
			
		||||
      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "qrcode": {
 | 
			
		||||
      "version": "1.5.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz",
 | 
			
		||||
      "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "dijkstrajs": "^1.0.1",
 | 
			
		||||
        "encode-utf8": "^1.0.3",
 | 
			
		||||
        "pngjs": "^5.0.0",
 | 
			
		||||
        "yargs": "^15.3.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "ansi-styles": {
 | 
			
		||||
          "version": "4.3.0",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
 | 
			
		||||
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "color-convert": "^2.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "camelcase": {
 | 
			
		||||
          "version": "5.3.1",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
 | 
			
		||||
          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
 | 
			
		||||
        },
 | 
			
		||||
        "cliui": {
 | 
			
		||||
          "version": "6.0.0",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
 | 
			
		||||
          "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "string-width": "^4.2.0",
 | 
			
		||||
            "strip-ansi": "^6.0.0",
 | 
			
		||||
            "wrap-ansi": "^6.2.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "color-convert": {
 | 
			
		||||
          "version": "2.0.1",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
 | 
			
		||||
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "color-name": "~1.1.4"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "color-name": {
 | 
			
		||||
          "version": "1.1.4",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
 | 
			
		||||
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
 | 
			
		||||
        },
 | 
			
		||||
        "wrap-ansi": {
 | 
			
		||||
          "version": "6.2.0",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
 | 
			
		||||
          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "ansi-styles": "^4.0.0",
 | 
			
		||||
            "string-width": "^4.1.0",
 | 
			
		||||
            "strip-ansi": "^6.0.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "y18n": {
 | 
			
		||||
          "version": "4.0.3",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
 | 
			
		||||
          "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
 | 
			
		||||
        },
 | 
			
		||||
        "yargs": {
 | 
			
		||||
          "version": "15.4.1",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
 | 
			
		||||
          "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "cliui": "^6.0.0",
 | 
			
		||||
            "decamelize": "^1.2.0",
 | 
			
		||||
            "find-up": "^4.1.0",
 | 
			
		||||
            "get-caller-file": "^2.0.1",
 | 
			
		||||
            "require-directory": "^2.1.1",
 | 
			
		||||
            "require-main-filename": "^2.0.0",
 | 
			
		||||
            "set-blocking": "^2.0.0",
 | 
			
		||||
            "string-width": "^4.2.0",
 | 
			
		||||
            "which-module": "^2.0.0",
 | 
			
		||||
            "y18n": "^4.0.0",
 | 
			
		||||
            "yargs-parser": "^18.1.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "yargs-parser": {
 | 
			
		||||
          "version": "18.1.3",
 | 
			
		||||
          "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
 | 
			
		||||
          "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "camelcase": "^5.0.0",
 | 
			
		||||
            "decamelize": "^1.2.0"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "qs": {
 | 
			
		||||
      "version": "6.11.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz",
 | 
			
		||||
@@ -18559,8 +18802,7 @@
 | 
			
		||||
    "require-directory": {
 | 
			
		||||
      "version": "2.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
 | 
			
		||||
    },
 | 
			
		||||
    "require-from-string": {
 | 
			
		||||
      "version": "2.0.2",
 | 
			
		||||
@@ -18568,6 +18810,11 @@
 | 
			
		||||
      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "require-main-filename": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
 | 
			
		||||
    },
 | 
			
		||||
    "requires-port": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
 | 
			
		||||
@@ -18809,6 +19056,11 @@
 | 
			
		||||
        "send": "0.17.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "set-blocking": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
 | 
			
		||||
    },
 | 
			
		||||
    "setprototypeof": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
 | 
			
		||||
@@ -19077,7 +19329,6 @@
 | 
			
		||||
      "version": "4.2.3",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
 | 
			
		||||
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "emoji-regex": "^8.0.0",
 | 
			
		||||
        "is-fullwidth-code-point": "^3.0.0",
 | 
			
		||||
@@ -19088,7 +19339,6 @@
 | 
			
		||||
      "version": "6.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "ansi-regex": "^5.0.1"
 | 
			
		||||
      }
 | 
			
		||||
@@ -20109,6 +20359,11 @@
 | 
			
		||||
        "isexe": "^2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "which-module": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "wildcard": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmmirror.com/wildcard/-/wildcard-2.0.0.tgz",
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
    "markdown-it": "^13.0.1",
 | 
			
		||||
    "md-editor-v3": "^2.2.1",
 | 
			
		||||
    "pinia": "^2.1.4",
 | 
			
		||||
    "qrcode": "^1.5.3",
 | 
			
		||||
    "qs": "^6.11.1",
 | 
			
		||||
    "sortablejs": "^1.15.0",
 | 
			
		||||
    "v3-waterfall": "^1.2.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,40 +1,118 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="page-invitation" :style="{ height: winHeight + 'px' }">
 | 
			
		||||
  <div class="page-invitation">
 | 
			
		||||
    <div class="inner">
 | 
			
		||||
      <h1>会员推广计划</h1>
 | 
			
		||||
      <h2>页面正在紧锣密鼓开发中,敬请期待!</h2>
 | 
			
		||||
      <h2>会员推广计划</h2>
 | 
			
		||||
      <div class="share-box">
 | 
			
		||||
        <div class="info">
 | 
			
		||||
          我们非常欢迎您把此应用分享给您身边的朋友,分享成功注册后您将获得 {{ inviteChatCalls }} 次对话额度以及
 | 
			
		||||
          {{ inviteImgCalls }} 次AI绘画额度作为奖励。
 | 
			
		||||
          你可以保存下面的二维码或者直接复制分享您的专属推广链接发送给微信好友。
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="invite-qrcode">
 | 
			
		||||
          <el-image :src="qrImg"/>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="invite-url">
 | 
			
		||||
          <span>{{ inviteURL }}</span>
 | 
			
		||||
          <el-button type="primary" plain class="copy-link" :data-clipboard-text="inviteURL">复制链接</el-button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <h2>您推荐用户</h2>
 | 
			
		||||
 | 
			
		||||
      <div class="invite-logs">
 | 
			
		||||
        <el-empty :image-size="100"/>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
import {ref} from "vue"
 | 
			
		||||
import {onMounted, ref} from "vue"
 | 
			
		||||
import QRCode from "qrcode";
 | 
			
		||||
import {httpGet} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
import Clipboard from "clipboard";
 | 
			
		||||
 | 
			
		||||
const winHeight = ref(window.innerHeight)
 | 
			
		||||
const inviteURL = ref("")
 | 
			
		||||
const qrImg = ref("")
 | 
			
		||||
const inviteChatCalls = ref(0)
 | 
			
		||||
const inviteImgCalls = ref(0)
 | 
			
		||||
const users = ref([])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  httpGet("/api/invite/code").then(res => {
 | 
			
		||||
    const text = `${location.protocol}//${location.host}/register?invite_code=${res.data.code}`
 | 
			
		||||
    QRCode.toDataURL(text, {width: 400, height: 400, margin: 2}, (error, url) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        console.error(error)
 | 
			
		||||
      } else {
 | 
			
		||||
        qrImg.value = url;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    inviteURL.value = text
 | 
			
		||||
  }).catch(e => {
 | 
			
		||||
    ElMessage.error("获取邀请码失败:" + e.message)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  // 复制链接
 | 
			
		||||
  const clipboard = new Clipboard('.copy-link');
 | 
			
		||||
  clipboard.on('success', () => {
 | 
			
		||||
    ElMessage.success('复制成功!');
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  clipboard.on('error', () => {
 | 
			
		||||
    ElMessage.error('复制失败!');
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.page-invitation {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items center
 | 
			
		||||
  background-color: #282c34;
 | 
			
		||||
  height 100vh
 | 
			
		||||
 | 
			
		||||
  .inner {
 | 
			
		||||
    text-align center
 | 
			
		||||
 | 
			
		||||
    h1 {
 | 
			
		||||
      color: #202020;
 | 
			
		||||
      font-size: 80px;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      letter-spacing: 0.1em;
 | 
			
		||||
      text-shadow: -1px -1px 1px #111111, 2px 2px 1px #363636;
 | 
			
		||||
    }
 | 
			
		||||
    max-width 800px
 | 
			
		||||
    width 100%
 | 
			
		||||
    color #e1e1e1
 | 
			
		||||
 | 
			
		||||
    h2 {
 | 
			
		||||
      color #ffffff;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .share-box {
 | 
			
		||||
      .info {
 | 
			
		||||
        line-height 1.5
 | 
			
		||||
        border 1px solid #444444
 | 
			
		||||
        border-radius 10px
 | 
			
		||||
        padding 10px
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .invite-qrcode {
 | 
			
		||||
        padding 20px
 | 
			
		||||
        text-align center
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .invite-url {
 | 
			
		||||
        padding 15px
 | 
			
		||||
        display flex
 | 
			
		||||
        justify-content space-between
 | 
			
		||||
        border 1px solid #444444
 | 
			
		||||
        border-radius 10px
 | 
			
		||||
 | 
			
		||||
        span {
 | 
			
		||||
          position relative
 | 
			
		||||
          font-family 'Microsoft YaHei', '微软雅黑', Arial, sans-serif
 | 
			
		||||
          top 5px
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,19 @@
 | 
			
		||||
                </el-row>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div class="block">
 | 
			
		||||
                <el-input placeholder="邀请码"
 | 
			
		||||
                          size="large"
 | 
			
		||||
                          v-model="formData.invite_code"
 | 
			
		||||
                          autocomplete="off">
 | 
			
		||||
                  <template #prefix>
 | 
			
		||||
                    <el-icon>
 | 
			
		||||
                      <Message/>
 | 
			
		||||
                    </el-icon>
 | 
			
		||||
                  </template>
 | 
			
		||||
                </el-input>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <el-row class="btn-row">
 | 
			
		||||
                <el-button class="login-btn" size="large" type="primary" @click="register">注册</el-button>
 | 
			
		||||
              </el-row>
 | 
			
		||||
@@ -103,7 +116,7 @@
 | 
			
		||||
<script setup>
 | 
			
		||||
 | 
			
		||||
import {ref} from "vue";
 | 
			
		||||
import {Checked, Iphone, Lock} from "@element-plus/icons-vue";
 | 
			
		||||
import {Checked, Iphone, Lock, Message} from "@element-plus/icons-vue";
 | 
			
		||||
import {httpGet, httpPost} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
import {useRouter} from "vue-router";
 | 
			
		||||
@@ -121,6 +134,7 @@ const formData = ref({
 | 
			
		||||
  password: '',
 | 
			
		||||
  code: '',
 | 
			
		||||
  repass: '',
 | 
			
		||||
  invite_code: router.currentRoute.value.query['invite_code'],
 | 
			
		||||
})
 | 
			
		||||
const formRef = ref(null)
 | 
			
		||||
const enableMsg = ref(false)
 | 
			
		||||
@@ -134,6 +148,11 @@ httpGet('/api/sms/status').then(res => {
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
httpGet("/api/invite/hits", {code: formData.value.invite_code}).then(() => {
 | 
			
		||||
}).catch(() => {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const register = function () {
 | 
			
		||||
  if (!validateMobile(formData.value.mobile)) {
 | 
			
		||||
    return ElMessage.error('请输入合法的手机号');
 | 
			
		||||
 
 | 
			
		||||
@@ -10,14 +10,20 @@
 | 
			
		||||
          <el-input v-model="system['admin_title']"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="注册赠送对话次数" prop="user_init_calls">
 | 
			
		||||
          <el-input v-model.number="system['user_init_calls']" placeholder="新用户注册赠送对话次数"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="VIP每月对话次数" prop="vip_month_calls">
 | 
			
		||||
          <el-input v-model.number="system['vip_month_calls']" placeholder="VIP用户每月赠送对话次数"/>
 | 
			
		||||
          <el-input v-model.number="system['init_chat_calls']" placeholder="新用户注册赠送对话次数"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="注册赠送绘图次数" prop="init_img_calls">
 | 
			
		||||
          <el-input v-model.number="system['init_img_calls']" placeholder="新用户注册赠送绘图次数"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="邀请赠送对话次数" prop="invite_chat_calls">
 | 
			
		||||
          <el-input v-model.number="system['invite_chat_calls']" placeholder="邀请新用户注册赠送对话次数"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="邀请赠送绘图次数" prop="invite_img_calls">
 | 
			
		||||
          <el-input v-model.number="system['invite_img_calls']" placeholder="邀请新用户注册赠送绘图次数"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="VIP每月对话次数" prop="vip_month_calls">
 | 
			
		||||
          <el-input v-model.number="system['vip_month_calls']" placeholder="VIP用户每月赠送对话次数"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
        <el-form-item label="开放注册服务" prop="enabled_register">
 | 
			
		||||
          <el-switch v-model="system['enabled_register']"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
@@ -319,7 +325,7 @@ onMounted(() => {
 | 
			
		||||
const rules = reactive({
 | 
			
		||||
  title: [{required: true, message: '请输入网站标题', trigger: 'blur',}],
 | 
			
		||||
  admin_title: [{required: true, message: '请输入控制台标题', trigger: 'blur',}],
 | 
			
		||||
  user_init_calls: [{required: true, message: '请输入赠送对话次数', trigger: 'blur'}],
 | 
			
		||||
  init_chat_calls: [{required: true, message: '请输入赠送对话次数', trigger: 'blur'}],
 | 
			
		||||
  user_img_calls: [{required: true, message: '请输入赠送绘图次数', trigger: 'blur'}],
 | 
			
		||||
})
 | 
			
		||||
const save = function (key) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user