人生啊人生 há 2 meses atrás
pai
commit
ab52ab18bc
45 ficheiros alterados com 23219 adições e 0 exclusões
  1. 26 0
      exe/.gitignore
  2. 21 0
      exe/clean_app_folder.js
  3. 21 0
      exe/clean_app_src_folder.js
  4. BIN
      exe/logo.ico
  5. BIN
      exe/mainSqllite.db
  6. BIN
      exe/myFile/node_modules_zip/node_modules.z01
  7. BIN
      exe/myFile/node_modules_zip/node_modules.z02
  8. BIN
      exe/myFile/node_modules_zip/node_modules.z03
  9. BIN
      exe/myFile/node_modules_zip/node_modules.z04
  10. BIN
      exe/myFile/node_modules_zip/node_modules.z05
  11. BIN
      exe/myFile/node_modules_zip/node_modules.zip
  12. 1 0
      exe/new_src/ServerPort.txt
  13. 156 0
      exe/new_src/WebSocket/css/main.css
  14. 806 0
      exe/new_src/WebSocket/js/common/MyWebSocket.js
  15. 1 0
      exe/new_src/WebSocket/js/common/jquery-1.11.3.min.js
  16. 522 0
      exe/new_src/WebSocket/js/main.js
  17. 105 0
      exe/new_src/WebSocket/main.html
  18. 1 0
      exe/new_src/WebSocketPort.txt
  19. 19 0
      exe/new_src/index.html
  20. 82 0
      exe/new_src/loading.html
  21. 1 0
      exe/new_src/version.txt
  22. 11857 0
      exe/package-lock.json
  23. 70 0
      exe/package.json
  24. 580 0
      exe/src/common/moudles/CommonVar.js
  25. 317 0
      exe/src/common/moudles/MigrateSqllite.js
  26. 955 0
      exe/src/common/moudles/MyFile.js
  27. 422 0
      exe/src/common/moudles/MyHttp.js
  28. 197 0
      exe/src/common/moudles/MyImg.js
  29. 290 0
      exe/src/common/moudles/MySqllite.js
  30. 499 0
      exe/src/common/moudles/SystemInformation.js
  31. 234 0
      exe/src/common/moudles/TechnologicalProcess.js
  32. 628 0
      exe/src/main/index.js
  33. 270 0
      exe/src/myWebServerRote/WebServer.js
  34. 118 0
      exe/src/myWebServerRote/file.js
  35. 298 0
      exe/src/myWebServerRote/http.js
  36. 398 0
      exe/src/myWebServerRote/main.js
  37. 1949 0
      exe/src/myWebServerRote/project.js
  38. 285 0
      exe/src/myWebServerRote/sqllite.js
  39. 360 0
      exe/src/myWebServerRote/systemDemo.js
  40. 141 0
      exe/src/myWebServerRote/time.js
  41. 222 0
      exe/src/myWebServerRote/upload.js
  42. 251 0
      exe/src/myWebServerRote/userObj.js
  43. 975 0
      exe/src/myWebSocket/WebSocketEvent.js
  44. 71 0
      exe/webpack.main.build.config.js
  45. 70 0
      exe/webpack.main.config.js

+ 26 - 0
exe/.gitignore

@@ -0,0 +1,26 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+outApp/*
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 21 - 0
exe/clean_app_folder.js

@@ -0,0 +1,21 @@
+const fs = require('fs-extra');
+const path = require('path');
+
+const appFolderPath = path.join(__dirname, './outApp/HelloWorld-win32-x64/resources/app');
+
+// 检查文件夹是否存在
+fs.pathExists(appFolderPath)
+.then((exists) => {
+    if (exists) {
+        // 删除文件夹
+        return fs.remove(appFolderPath);
+    }
+    console.log(appFolderPath + ' 文件夹不存在,无需删除。');
+    return Promise.resolve();
+})
+.then(() => {
+    console.log(appFolderPath + ' 文件夹已成功删除。');
+})
+.catch((err) => {
+    console.error('删除 ' + appFolderPath + ' 文件夹时出错:', err);
+});

+ 21 - 0
exe/clean_app_src_folder.js

@@ -0,0 +1,21 @@
+const fs = require('fs-extra');
+const path = require('path');
+
+const appFolderPath = path.join(__dirname, './outApp/HelloWorld-win32-x64/resources/app/src');
+
+// 检查文件夹是否存在
+fs.pathExists(appFolderPath)
+.then((exists) => {
+    if (exists) {
+        // 删除文件夹
+        return fs.remove(appFolderPath);
+    }
+    console.log(appFolderPath + ' 文件夹不存在,无需删除。');
+    return Promise.resolve();
+})
+.then(() => {
+    console.log(appFolderPath + ' 文件夹已成功删除。');
+})
+.catch((err) => {
+    console.error('删除 ' + appFolderPath + ' 文件夹时出错:', err);
+});

BIN
exe/logo.ico


BIN
exe/mainSqllite.db


BIN
exe/myFile/node_modules_zip/node_modules.z01


BIN
exe/myFile/node_modules_zip/node_modules.z02


BIN
exe/myFile/node_modules_zip/node_modules.z03


BIN
exe/myFile/node_modules_zip/node_modules.z04


BIN
exe/myFile/node_modules_zip/node_modules.z05


BIN
exe/myFile/node_modules_zip/node_modules.zip


+ 1 - 0
exe/new_src/ServerPort.txt

@@ -0,0 +1 @@
+6789

+ 156 - 0
exe/new_src/WebSocket/css/main.css

@@ -0,0 +1,156 @@
+* {
+    padding: 0px;
+    margin: 0px;
+    box-sizing:border-box;
+    -moz-box-sizing:border-box; /* Firefox */
+    -webkit-box-sizing:border-box; /* Safari */
+}
+
+html, body {
+    width: 100%;
+    height: 100%;
+    /* 解决移动端点击闪烁问题 */
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+img {
+    /*去除中间腰部间隙*/
+    vertical-align:middle;
+    /*去除顶部间隙*/
+    vertical-align:bottom;
+    /*去除中间顶部间隙*/
+    vertical-align:top;
+    /*注意该方法在对img控件使用的时候,使用 float 和 font-size 解决左右间隙问题
+    会导致img在div中无法居中,此时可以在img控件外设置新的一个div来设置居中进行实现居中
+    所以 float 和 font-size 一般特意指定几个目标范围内img控件解决左右间隙问题 例如.abc img{}
+    意思就是 设置了 class="abc" 里面所有的img控件执行样式
+    */
+    /*进行浮动解决左右两侧出现间隙 与 font-size: 0px; 一起配合 */
+    /*float: left;*/
+    /*这个也设置解决系统自带空白间隙问题 与 float: left; 一起配合*/
+    /*font-size: 0px;*/
+}
+
+.app {
+
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    overflow-x: scroll;
+    overflow-y: scroll;
+
+}
+
+.common {
+    width: 100%;
+    height: auto;
+    padding: 3px;
+}
+
+.content {
+    width: 100%;
+    height: 300px;
+    background-color: rgb(233, 233, 233);
+    position: relative;
+}
+
+.leftTitle {
+    position: absolute;
+    top: 1%;
+    left: 1%;
+    height: 6%;
+    right: 38%;
+    background-color: #ffffff;
+}
+
+.leftTxt {
+    position: absolute;
+    top: 8%;
+    left: 1%;
+    bottom: 1%;
+    right: 38%;
+    background-color: #ffffff;
+    overflow-y: scroll;
+    /* 文本换行 */
+    text-wrap: normal;
+    word-break: break-all;
+    /* white-space: pre-wrap; */
+
+}
+
+.rightTitle {
+    position: absolute;
+    top: 1%;
+    left: 63%;
+    height: 6%;
+    right: 1%;
+    background-color: #ffffff;
+}
+
+
+.rightUser {
+    position: absolute;
+    top: 8%;
+    left: 63%;
+    bottom: 1%;
+    right: 1%;
+    background-color: #ffffff;
+
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    -khtml-user-select: none;
+    user-select: none;
+
+    overflow-y: scroll;
+
+}
+
+.select {
+    /* 文本换行 */
+    text-wrap: normal;
+    word-break: break-all;
+    padding: 5px;
+    border: 1px solid #00aeff;
+    margin: 1px;
+    /* 手势 */
+    cursor : pointer;
+    background-color: #ffffff;
+    color: #000000;
+}
+
+.selectYes {
+    background-color: #00aeff;
+    color: #ffffff;
+}
+
+.submitEdit {
+    width: 100%;
+    padding: 3px;
+}
+
+.chat {
+    width: 100%;
+    height: auto;
+    padding: 5px;
+}
+
+.chatTitle {
+    font-size: 14px;
+    color: darkgreen;
+}
+
+.chatTxt {
+    font-size: 14px;
+    color: rgb(128, 128, 128);
+}
+
+.chatSys {
+    color: #636363;
+}
+
+.chatObj {
+    color: #017771;
+}

+ 806 - 0
exe/new_src/WebSocket/js/common/MyWebSocket.js

@@ -0,0 +1,806 @@
+/*eslint-disable*/
+
+/**
+ * 用于处理websocket实时通讯使用
+ */
+export class MyWebSocket {
+
+    // 每次 new 出对象则会调用这个构造函数
+    constructor() {
+        
+        // 端口号
+        this.prot = 3000;
+        // new出webSocket通讯对象
+        this.objWebSocket = null;
+
+        // webSocket 服务端ip
+        this.ip = "127.0.0.1";
+        // 如果是平时开发后,发布到服务器,域名访问,那么就用这个
+        // this.ip = document.domain;
+
+        // 用于触发重连的计时器
+        this.webSocketRestConnectTime = null;
+
+        // 记录当前进入的房间号
+        this.room = null;
+        // 记录当前自己的socketId值
+        this.socketId = null;
+
+        /**
+         * 记录当前的userId,用户登陆后
+         * 就会固定唯一的 userId, 之后就不会在改变
+         * 这里的userId 可以是数据库的,没有数据库的
+         * 可以用第一次登陆的 socketId 作为记录
+         * 
+         * 用于后续统一通讯告诉大家例如角色,还是别的数据使用
+         * 不会因为后续每次断开重连,导致 socketId 的变化
+         * 而要重置已经存在在别的地方的渲染数据使用
+         */
+        this.userId = null;
+
+        /**
+         * 记录当前用户自己本身的参数
+         */
+        this.myConfig = null;
+
+        // 昵称
+        this.nickname = null;
+
+        // 记录最后一次进入的房间号,用于后续触发重连的逻辑
+        this.roomId = null;
+        // 当断开连接,重置false,后面触发重连进入房间逻辑
+        this.joinRoomBool = false;
+
+        /**
+         * 记录当前房间号的用户列表 json 结构
+         * 每当用户进入,或者退出,该参数优先更新逻辑
+         */
+        this.roomListJson = {
+            // "唯一cid" : "对应json数据",
+        };
+
+        /**
+         * 记录当前房间号的用户列表
+         * 对应 cid 的数据记录在 this.roomListJson
+         */
+        this.roomList = [];
+
+        /**
+         * 每当房间里发送变化的时候触发回调
+         * 
+         * type         类型
+         *              roomUserExit        有用户退出
+         *              roomUserJoin        有用户加入
+         *              roomUserDbUpdate    用户数据发送了变化
+         * 
+         * cidJson      加入或者退出的用户的 json数据
+         * dbUpdate     当 type 是 roomUserDbUpdate 的时候,才有的参数回调,具体变化的字段数据
+         * 
+         */
+        this.roomUpdateCallback = null;
+
+        /**
+         * 每次房间里有群发消息的时候回调
+         * cidJson  用户的 json数据
+         * message  消息的内容
+         */
+        this.roomChatAllCallback = null;
+
+        /**
+         * 每次有其他用户单独发送消息给你回调
+         * sendCidJson          发起消息用户的json数据
+         * getCidJson           接收消息用户的json数据
+         * message              消息内容
+         */
+        this.cidSendCallback = null;
+
+    }
+
+    // 实现单例模式
+    static find() {
+        if (!MyWebSocket.instance) {
+            MyWebSocket.instance = new MyWebSocket();
+        }
+        return MyWebSocket.instance;
+    }
+    
+
+    /**
+     * webSocket 初始化连接
+     * */
+    webSocketInit = function() {
+
+        let thisClass = this;
+
+        // 只有是空的时候
+        if (thisClass.objWebSocket == null || thisClass.objWebSocket == 'undefined') {
+
+            var webSocketUrl = "ws://" + this.ip + ":" + this.prot;
+            // 连接 webSocket
+            thisClass.objWebSocket = new WebSocket(webSocketUrl);
+            thisClass.webSocketEvent();
+
+        }
+
+    }
+
+    /**
+     * 断开后,自动触发重新连接通讯逻辑
+     */
+    webSocketRestConnect = function() {
+        let thisClass = this;
+
+        if (thisClass.webSocketRestConnectTime != null && thisClass.webSocketRestConnectTime != 'undefined') {
+            return this;
+        }
+
+        if (thisClass.objWebSocket != null && thisClass.objWebSocket != 'undefined') {
+            return this;
+        }
+
+        thisClass.joinRoomBool = false;
+        thisClass.webSocketRestConnectTime = setInterval(function() {
+
+            clearInterval(thisClass.webSocketRestConnectTime);
+            thisClass.webSocketRestConnectTime = null;
+            thisClass.webSocketInit();
+
+        }, 1000);
+
+    }
+
+    /**
+     * 连接成功后,调用该方法,设置 objWebSocket 的事件
+     * */
+    webSocketEvent = function() {
+
+        let thisClass = this;
+
+        /**
+         * 实例对象的 onopen 属性
+         * 当WebSocket客户端与服务器建立连接并完成握手后会回调此函数。
+         * 参数 evt 就是 数据的返回
+         * */
+        thisClass.objWebSocket.onopen = function(evt) {
+            console.log([ "连接成功", evt ]);
+        }
+
+        /**
+         * 实例对象的 onmessage 属性
+         * 当服务器收到来自客户端的数据帧时会回调此函数。
+         * 参数 evt 就是 数据的返回
+         * */
+        thisClass.objWebSocket.onmessage = function(evt) {
+            // console.log("onmessage 回调数据");
+            // console.log(evt);
+            // console.log(evt.data);
+            thisClass.commonMessage(evt.data);
+        }
+
+        /**
+         * 实例对象的 onclose 属性
+         * 目标客户端id 退出关闭的时候,会触发该事件
+         * 服务端关闭也会触发该事件
+         * 参数 evt 就是 数据的返回
+         * */
+        thisClass.objWebSocket.onclose = function(evt) {
+
+            // console.log("onclose 回调数据");
+            // console.log(evt);
+            // 此时将目标对象重置为null,方便后续重新连接
+            thisClass.objWebSocket = null;
+            thisClass.webSocketRestConnect();
+
+        }
+
+        /**
+         * 报错的时候执行这里,例如连接失败
+         * */
+        thisClass.objWebSocket.onerror = function(evt, e) {
+
+            // console.log("onerror 回调数据");
+            // console.log(evt);
+            // // console.log(evt.data);
+            // 此时将目标对象重置为null,方便后续重新连接
+            thisClass.objWebSocket = null;
+            thisClass.webSocketRestConnect();
+            
+        }
+
+    }
+    
+    /**
+     * 统一处理接收到的消息
+     * serverData       接收服务端的消息
+     */
+    commonMessage = function(serverData) {
+
+        let thisClass = this;
+
+        let json = {};
+        try {
+            json = JSON.parse(serverData);
+        } catch(e) {
+            return thisClass;
+        }
+
+        // console.log("commonMessage", json);
+        
+        // 当前是哪个cid发来的消息
+        let cid = json["cid"];
+        let data = json["data"];
+        let dataType = data["type"];
+
+        console.log("commonMessage", json, dataType, data);
+
+        if (typeof dataType == "string") {
+            
+            switch (dataType) {
+
+                // 心跳包的ping,用于验证用户是否还在正常连接,没有回复pong,则服务端强制退出
+                case "ping":
+                    thisClass.commonSend("pong", "");
+                    break;
+                // 第一次连接通讯后,服务端发来的消息
+                case "login":
+                    thisClass.loginEvent(json);
+                    break;
+                // 每次用户自己在服务器成功更新了哪些字段数据,则得到对应更新的字段数据
+                case "myDbUpdate":
+                    thisClass.myDbUpdateEvent(json);
+
+                    // 如果自己已经加入过房间号,则自动再触发进入房间逻辑,实现重连后进入房间的逻辑
+                    if (
+                        thisClass.roomId != null && thisClass.roomId != undefined
+                        && thisClass.joinRoomBool == false
+                    ) {
+                        thisClass.joinRoom(room);
+                    }
+
+                    break;
+
+                // 当房间里有新用户进入的时候,给当前房间号的所有用户发送消息
+                case "roomUserJoin":
+                    thisClass.roomUserJoinEvent(json);
+                    break;
+
+                // 当房间里有用户退出离开的时候的时候,给当前房间号的所有用户发送消息
+                case "roomUserExit":
+                    thisClass.roomUserExitEvent(json);
+                    break;
+
+                // 当房间里某个用户更新了数据字段的时候
+                case "roomUserDbUpdate":
+                    thisClass.roomUserDbUpdateEvent(json);
+                    break;
+
+                // 当前房间接收到聊天群发的消息
+                case "roomChatAll":
+                    thisClass.roomChatAllEvent(json);
+                    break;
+
+                // 给指定用户私聊
+                case "cidSend":
+                    thisClass.cidSendEvent(json);
+                    break;
+
+            }
+
+        }
+        
+        return thisClass;
+
+    }
+    
+    /**
+     * 统一发送消息给服务端格式
+     * 服务端会根据接收不同的类型,执行操作,例如更新用户数据,或者是群发消息,或者是进入房间,或者是给指定的用户单独发送消息等逻辑触发
+     * 
+     * type                 类型,不同的类型,会触发的逻辑不一样
+     *      upUser          更新当前用户的参数,例如昵称,或者坐标点
+     *      joinRoom        用户进入房间或者切换到另外一个房间
+     *      roomSendAll     房间里群发消息,房间里所有用户可以接收到消息,是一个通用的传输数据
+     *                      这里只做实时通讯消息发送,具体最后前端进行逻辑处理
+     *      cidSend         给指定用户私聊
+     * 
+     * message      给服务端发送的消息,可以是字符串,也可以是json结构
+     * 
+     * * */
+    commonSend = function(type, message) {
+
+        let thisClass = this;
+
+        if (thisClass.objWebSocket == null || thisClass.objWebSocket == undefined) {
+            return thisClass;
+        }
+
+        // 设置发送消息的时间戳,精确到毫秒
+        let thisTime = new Date().getTime();
+
+        // 消息传输统一格式,格式不正确则无法正常通讯
+        var submitJson = {
+            "type" : type,
+            "message" : message,
+            // // 客户端发送时间
+            // "sendTime" : new Date().Format("yyyy-MM-dd hh:mm:ss"),
+            "thisTime" : thisTime,
+        };
+
+        thisClass.objWebSocket.send(JSON.stringify(submitJson));
+
+        return thisClass;
+    }
+
+    /**
+     * 处理当前用户第一次登陆的时候的逻辑
+     * json         接收服务端的参数
+     */
+    loginEvent = function(json) {
+
+        let thisClass = this;
+
+        // 当前是哪个cid发来的消息
+        let cid = json["cid"];
+        let data = json["data"];
+        
+        let dataMessage = data["message"];
+        let dataMessageUserDb = dataMessage["userDb"];
+        let dataMessageUserDbCid = dataMessageUserDb["cid"];
+        
+        thisClass.socketId = dataMessageUserDbCid;
+        if (thisClass.userId == null || thisClass.userId == undefined) {
+            thisClass.userId = dataMessageUserDbCid;
+        }
+
+        thisClass.myConfig = dataMessageUserDb;
+
+        // console.log(
+        //     thisClass.socketId,
+        //     thisClass.myConfig,
+        //     thisClass.userId
+        // );
+
+        thisClass.loginUserUpdate();
+        
+        return thisClass;
+
+    }
+
+    /**
+     * 登陆后,先更新初始的用户数据
+     */
+    loginUserUpdate = function() {
+
+        let thisClass = this;
+        
+        thisClass.commonSend(
+            "upUser",
+            {
+                "name" : thisClass.nickname,
+                "userId" : thisClass.userId,
+            }
+        );
+
+        return thisClass;
+
+    }
+
+    /**
+     * 每次用户自己在服务器成功更新了哪些字段数据,则得到对应更新的字段数据
+     * json
+     */
+    myDbUpdateEvent = function(json) {
+
+        let thisClass = this;
+
+        // 当前是哪个cid发来的消息
+        let cid = json["cid"];
+        let data = json["data"];
+        
+        let dataMessage = data["message"];
+        let updateJson = dataMessage["updateJson"];
+        
+        // 更新的字段数据
+        for (let key in updateJson) {
+            let val = updateJson[key];
+            thisClass.myConfig[key] = val;
+        }
+        
+        return thisClass;
+
+    }
+    
+    /**
+     * 进入房间
+     * room     房间号
+     */
+    joinRoom = function(room) {
+        
+        let thisClass = this;
+
+        if (thisClass.userId == null && thisClass.userId == undefined) {
+            console.log("连接通讯后请先更新 userId 字段才可进入房间");
+            return;
+        }
+        
+        var submitJson = {
+            "roomId" : room,
+        };
+
+        thisClass.roomId = room;
+
+        thisClass.commonSend(
+            "joinRoom",
+            submitJson
+        );
+
+        thisClass.joinRoomBool = true;
+
+        return thisClass;
+
+    }
+
+
+    /**
+     * 当房间里有新用户进入的时候,给当前房间号的所有用户发送消息
+     * json
+     */
+    roomUserJoinEvent = function(json) {
+
+        let thisClass = this;
+        
+        // 当前是哪个cid发来的消息
+        let cid = json["cid"];
+        let data = json["data"];
+        
+        let dataMessage = data["message"];
+        
+        // 此时是该cid进入房间
+        let sendCid = dataMessage["sendCid"];
+        // 得到当前房间列表的所有用户信息
+        let roomList = dataMessage["message"];
+
+        // 加入用户的数据
+        let joinUser = null;
+
+        // 循环更新对应房间数据
+        for (let i = 0; i < roomList.length; i++) {
+
+            let objRoomList = roomList[i];
+            let objRoomListCid = objRoomList["cid"];
+
+            // 此时说明是该用户加入的房间
+            if (objRoomListCid == sendCid) {
+                // console.log("用户加入房间", objRoomList);
+                joinUser = objRoomList;
+            }
+            
+            thisClass.roomListJson[objRoomListCid] = objRoomList;
+
+        }
+
+        // 更新房间列表用户数据
+        thisClass.roomList = roomList;
+
+        if (thisClass.roomUpdateCallback != null && thisClass.roomUpdateCallback != undefined) {
+            thisClass.roomUpdateCallback("roomUserJoin", joinUser, null);
+        }
+        
+        return thisClass;
+
+    }
+
+    /**
+     * 当房间里有用户退出离开的时候的时候,给当前房间号的所有用户发送消息
+     * json
+     */
+    roomUserExitEvent = function(json) {
+
+        let thisClass = this;
+
+        // 当前是哪个cid发来的消息
+        let cid = json["cid"];
+        let data = json["data"];
+        
+        let dataMessage = data["message"];
+
+        // 此时是该cid退出房间
+        let sendCid = dataMessage["sendCid"];
+        // 得到当前房间列表的所有用户信息
+        let roomList = dataMessage["message"];
+
+        // 循环更新对应房间数据
+        for (let i = 0; i < roomList.length; i++) {
+
+            let objRoomList = roomList[i];
+            let objRoomListCid = objRoomList["cid"];
+            thisClass.roomListJson[objRoomListCid] = objRoomList;
+
+        }
+
+        // 更新房间列表用户数据
+        thisClass.roomList = roomList;
+        
+        // 退出的用户数据
+        let userExit = null;
+
+        // 找到哪个用户退出
+        if (thisClass.roomListJson[sendCid] != null && thisClass.roomListJson[sendCid] != undefined) {
+
+            // 这里进行一个转换,让它变成独立的对象
+            userExit = JSON.parse(JSON.stringify(thisClass.roomListJson[sendCid]));
+            // console.log("用户退出房间", userExit);
+
+            // 退出用户的数据清除
+            thisClass.roomListJson[sendCid] = null;
+            delete thisClass.roomListJson[sendCid];
+
+        }
+
+        if (thisClass.roomUpdateCallback != null && thisClass.roomUpdateCallback != undefined) {
+            thisClass.roomUpdateCallback("roomUserExit", userExit, null);
+        }
+        
+        return thisClass;
+
+    }
+
+
+    /**
+     * 当房间里某个用户更新了数据字段的时候
+     * json
+     */
+    roomUserDbUpdateEvent = function(json) {
+
+        let thisClass = this;
+
+        // 当前是哪个cid发来的消息
+        let cid = json["cid"];
+        let data = json["data"];
+
+        let dataMessage = data["message"];
+
+        // 此时是该cid更新的字段数据
+        let sendCid = dataMessage["sendCid"];
+        // 更新了哪些字段数据
+        let dbUpdate = dataMessage["message"];
+
+        console.log(
+            "当房间里某个用户更新了数据字段的时候 roomUserDbUpdateEvent ",
+            // json,
+            sendCid,
+            dbUpdate,
+            // this.roomListJson,
+            // this.roomList
+        );
+        
+        let dbUpdateUserId = null;
+        // 如果更新的字段带有 userId
+        if (dbUpdate["userId"] != null && dbUpdate["userId"] != null) {
+            dbUpdateUserId = dbUpdate["userId"];
+        }
+
+        // 找到被更新的用户数据
+        let updateUser = null;
+
+        // 循环房间的所有数据
+        for (let i = 0; i < this.roomList.length; i++) {
+
+            let objRoomList = this.roomList[i];
+            let objRoomListCid = objRoomList["cid"];
+            let objRoomListUserId = objRoomList["userId"];
+
+            // console.log(
+            //     "roomUserDbUpdateEvent objRoomList ===》", objRoomList
+            // );
+
+            // 是否找到
+            let objBool = false;
+
+            // 优先以 userId 进行寻找对象
+            if (
+                dbUpdateUserId != null && dbUpdateUserId != undefined
+                && dbUpdateUserId == objRoomListUserId
+            ) {
+                objBool = true;
+            } else if (objRoomListCid == sendCid) {
+                objBool = true;
+            }
+
+            if (objBool == true) {
+
+                // console.log(
+                //     "roomUserDbUpdateEvent objBool ===》", objRoomList
+                // );
+
+                // 开始更新对应的字段数据
+                for (var key in dbUpdate) {
+                    objRoomList[key] = dbUpdate[key];
+                }
+
+                // 更新指定目标cid的用户相关数据
+                if (this.roomListJson[objRoomListCid] != null && this.roomListJson[objRoomListCid] != undefined) {
+                    // 开始更新对应的字段数据
+                    for (var key in dbUpdate) {
+                        this.roomListJson[objRoomListCid][key] = dbUpdate[key];
+                    }
+                }
+
+                updateUser = objRoomList;
+
+            }
+            
+        }
+
+
+        // console.log(
+        //     "roomUserDbUpdateEvent ===》", this.roomListJson, this.roomList
+        // );
+
+        if (thisClass.roomUpdateCallback != null && thisClass.roomUpdateCallback != undefined) {
+            thisClass.roomUpdateCallback("roomUserDbUpdate", updateUser, dbUpdate);
+        }
+        
+        return thisClass;
+
+    }
+
+
+    /**
+     * 给当前自己所在房间号发送消息
+     * type         自定义类型,该类型你定义的是什么,在返回的房间里,就会返回什么类型
+     *              如果你是通知所有房间群发聊天填写  chatAll
+     *              否则你填写别的类型,然后再根据这个类型,单独处理逻辑
+     * 
+     * message      给服务端发送的消息,可以是字符串,也可以是json结构
+     *              该参数后续根据 type 参数,来配合开发新的逻辑
+     *              例如我填写 type = chatAll , 该参数就传字符串聊天的内容
+     *              如果传别的类型,可以传json结构,然后通过该接收的消息,进行特殊处理别的逻辑
+     */
+    roomSend = function(type, message) {
+
+        let thisClass = this;
+
+        if (this.myConfig == null || this.myConfig == undefined) {
+            return thisClass;
+        }
+
+        if (this.myConfig["roomId"] == null || this.myConfig["roomId"] == undefined) {
+            return thisClass;
+        }
+
+        let roomId = this.myConfig["roomId"];
+        // console.log("roomSend myConfig", this.myConfig, type, message, roomId);
+        let submit = {
+            "roomId" : roomId,
+            "type" : type,
+            "content" : message,
+        };
+        
+        thisClass.commonSend("roomSendAll", submit);
+
+        return thisClass;
+    }
+
+
+    /**
+     * 给指定cid私聊发送消息
+     * type         自定义类型,该类型你定义的是什么,就会返回什么类型
+     *              如果你是单独处理聊天则填写  chat
+     *              否则你填写别的类型,然后再根据这个类型,单独处理逻辑
+     * 
+     * cid          跟对方私聊的cid值
+     * 
+     * message      给服务端发送的消息,可以是字符串,也可以是json结构
+     *              该参数后续根据 type 参数,来配合开发新的逻辑
+     *              例如我填写 type = chat , 该参数就传字符串聊天的内容
+     *              如果传别的类型,可以传json结构,然后通过该接收的消息,进行特殊处理别的逻辑
+     */
+    cidSend = function(type, cid, message) {
+
+        let thisClass = this;
+
+        let submit = {
+            "cid" : cid,
+            "type" : type,
+            "content" : message,
+        };
+        
+        thisClass.commonSend("cidSend", submit);
+
+        return thisClass;
+    }
+
+
+    /**
+     * 当前房间接收到聊天群发的消息
+     * json
+     */
+    roomChatAllEvent = function(json) {
+
+        let thisClass = this;
+
+        // console.log("roomChatAllEvent", json);
+
+        let cid = json["cid"];
+        let data = json["data"];
+        let dataMessage = data["message"];
+
+        let dataMessageSendCid = dataMessage["sendCid"];
+        let dataMessageMessage = dataMessage["message"];
+        
+        // console.log("roomChatAllEvent", dataMessageSendCid, dataMessageMessage);
+
+        if (thisClass.roomListJson[dataMessageSendCid] == null || thisClass.roomListJson[dataMessageSendCid] == undefined) {
+            return thisClass;
+        }
+
+        let cidJson = thisClass.roomListJson[dataMessageSendCid];
+        if (typeof thisClass.roomChatAllCallback == 'function') {
+            thisClass.roomChatAllCallback(cidJson, dataMessageMessage);
+        }
+
+        return thisClass;
+
+    }
+    
+    /**
+     * 给指定用户发送消息
+     * json
+     */
+    cidSendEvent = function(json) {
+
+        let thisClass = this;
+
+        // console.log( "cidSendEvent", json );
+
+        let cid = json["cid"];
+        let data = json["data"];
+        let dataMessage = data["message"];
+
+        // 哪个cid发起的
+        let dataMessageSendCid = dataMessage["sendCid"];
+        // 接收消息的cid
+        let dataMessageGetCid = dataMessage["getCid"];
+
+        let dataMessageSubmitJson = dataMessage["submitJson"];
+        let dataMessageSubmitJsonMessage = dataMessageSubmitJson["message"];
+        
+        if (thisClass.roomListJson[dataMessageSendCid] == null || thisClass.roomListJson[dataMessageSendCid] == undefined) {
+            return thisClass;
+        }
+
+        if (thisClass.roomListJson[dataMessageGetCid] == null || thisClass.roomListJson[dataMessageGetCid] == undefined) {
+            return thisClass;
+        }
+
+        let sendCidJson = thisClass.roomListJson[dataMessageSendCid];
+        let getCidJson = thisClass.roomListJson[dataMessageGetCid];
+
+        // console.log(
+        //     "cidSendEvent",
+        //     dataMessageSendCid,
+        //     dataMessageSubmitJson,
+        //     dataMessageSubmitJsonMessage,
+        //     dataMessageGetCid,
+        //     sendCidJson,
+        //     getCidJson
+        // );
+
+        if (typeof thisClass.cidSendCallback == 'function') {
+            thisClass.cidSendCallback(sendCidJson, getCidJson, dataMessageSubmitJsonMessage);
+        }
+
+        return thisClass;
+
+    }
+    
+}
+
+
+
+
+
+
+
+

Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 0
exe/new_src/WebSocket/js/common/jquery-1.11.3.min.js


+ 522 - 0
exe/new_src/WebSocket/js/main.js

@@ -0,0 +1,522 @@
+/*eslint-disable*/
+
+import { MyWebSocket } from "./common/MyWebSocket.js";
+
+/**
+ * 主程序
+ */
+export class Main {
+
+    // 每次 new 出对象则会调用这个构造函数
+    constructor() {
+        
+        // 记录当前要私聊的cid
+        this.objUserCid = null;
+        // websocket 的端口号,可以在调用接口后更新
+        this.protWebSocket = 3000;
+
+    }
+
+    // 实现单例模式
+    static find() {
+        if (!Main.instance) {
+            Main.instance = new Main();
+        }
+        return Main.instance;
+    }
+    
+    /**
+     * 视图
+     */
+    view = function() {
+
+        let thisClass = this;
+
+        // 更新websocket的端口号
+        MyWebSocket.find().prot = thisClass.protWebSocket;
+
+        let thisTime = new Date().getTime();
+        document.getElementById("nickname").value = "自定义昵称_" + thisTime;
+        document.getElementById("nickname").onchange = function(e) {
+
+            // console.log(
+            //     "nickname", this.value
+            // );
+            
+            /**
+             * 更新自己当前用户的数据字段,
+             * 更新后,同时会自动通知自己
+             * 所在房间的所有用户,更新了哪些字段数据
+             */
+            MyWebSocket.find().commonSend(
+                "upUser",
+                /**
+                 * 更新的字段数据,如果字段不存在,则会再服务器里自动追加对应的字段数据
+                 * 如果存在,则是更新
+                 */
+                {
+                    "name" : this.value,
+                }
+            );
+
+        }
+        
+        document.getElementById("socketStart").onclick = function() {
+            
+            MyWebSocket.find().nickname = document.getElementById("nickname").value;
+            
+            // 这里的 userId 后面如果你想要跟数据库的id对应才填写,否则这里会自动生成一个唯一的userId
+            // MyWebSocket.find().userId = null;
+
+            MyWebSocket.find().webSocketInit();
+
+            // 房间里发送变化触发回调
+            MyWebSocket.find().roomUpdateCallback = function(
+                // 类型
+                type,
+                // 某个用户退出,或者加入的时候,该用户的相关数据
+                cidJson,
+                // 某个用户更新了具体哪些字段,后续例如同步用户昵称,坐标等数据使用
+                dbUpdate
+            ) {
+
+                console.log(
+                    "roomUpdateCallback", type, cidJson, dbUpdate
+                );
+
+                if (typeof type == "string") {
+
+                    switch (type) {
+                        // 有用户退出
+                        case "roomUserExit":
+                            thisClass.roomUserExitEvent(cidJson);
+                            break;
+
+                        // 有用户加入
+                        case "roomUserJoin":
+                            thisClass.roomUserJoinEvent(cidJson);
+                            break;
+
+                        // 用户数据发送了变化
+                        case "roomUserDbUpdate":
+                            thisClass.roomUserDbUpdateEvent(cidJson, dbUpdate);
+                            break;
+                    }
+
+                }
+                
+                // // 更新当前房间号的列表数据
+                // console.log("更新当前房间号的列表数据", MyWebSocket.find().roomList);
+                thisClass.rightUserListEvent();
+
+            }
+
+            // 每次房间里有群发消息的时候回调
+            MyWebSocket.find().roomChatAllCallback = function(
+                // 用户的 json数据
+                cidJson,
+                // 消息的内容
+                message
+            ) {
+
+                // console.log(
+                //     "MyWebSocket.find().roomChatAllCallback",
+                //     cidJson, message
+                // );
+
+                thisClass.roomChatAllCallbackEvent(cidJson, message);
+
+            }
+
+            /**
+             * 每次有其他用户单独发送消息给你回调
+             */
+            MyWebSocket.find().cidSendCallback = function(
+                // 发起消息用户的json数据
+                sendCidJson,
+                // 接收消息用户的json数据
+                getCidJson,
+                // 消息内容
+                message
+            ) {
+                thisClass.cidSendCallbackEvent(sendCidJson, getCidJson, message);
+            }
+            
+        }
+
+        document.getElementById("joinRoom").onclick = function() {
+
+            var room = document.getElementById("room").value;
+            MyWebSocket.find().joinRoom(room);
+
+        }
+
+
+        document.getElementById("subSend").onclick = function() {
+
+            var objTxtSend = document.getElementById("txtSend");
+            var sendTxt = objTxtSend.value;
+
+            if (sendTxt == null || sendTxt == undefined) {
+                return;
+            }
+
+            // console.log(
+            //     "发送消息的内容", sendTxt
+            // );
+
+            if (thisClass.objUserCid != null && thisClass.objUserCid != undefined) {
+
+                // 给指定的用户发送消息
+                MyWebSocket.find().cidSend("chat", thisClass.objUserCid, sendTxt);
+
+            } else {
+                // 房间里群聊
+                MyWebSocket.find().roomSend("chatAll", sendTxt);
+            }
+            
+            objTxtSend.value = "";
+
+        }
+
+        document.getElementById("objUserExit").onclick = function() {
+            
+            thisClass.objUserCid = null;
+            document.getElementById("objUserCid").innerHTML = "";
+            // 重新更新UI
+            thisClass.rightUserListEvent();
+
+        }
+
+    }
+
+    /**
+     * 更新当前的用户列表
+     */
+    rightUserListEvent = function() {
+
+        // console.log("更新当前房间号的列表数据 rightUserListEvent", MyWebSocket.find().roomList);
+
+        let thisClass = this;
+
+        var html = "";
+
+        for (var i = 0; i < MyWebSocket.find().roomList.length; i++) {
+
+            var thisRoomList = MyWebSocket.find().roomList[i];
+            // console.log(
+            //     "thisRoomList", thisRoomList
+            // );
+
+            var name = thisRoomList["name"];
+            var cid = thisRoomList["cid"];
+            var userId = thisRoomList["userId"];
+            var roomId = thisRoomList["roomId"];
+
+            let classNew = "select ";
+
+            if (thisClass.objUserCid == cid) {
+                classNew += "selectYes ";
+            }
+
+            var addHtml = '<div class="' + classNew + '" cid="'
+            + cid +'" userId="'
+            + userId +'" roomId="'
+            + roomId + '" >'
+            + name
+            +'</div>';
+
+            html += addHtml;
+
+        }
+
+        document.getElementById("rightUserList").innerHTML = html;
+
+        $("#rightUserList").find(".select").click(function(e) {
+            
+            var obj = $(this);
+            var cid = obj.attr("cid");
+            var userId = obj.attr("userId");
+            var roomId = obj.attr("roomId");
+
+            console.log("userObj", cid, userId, roomId);
+
+            thisClass.objUserCid = cid;
+            document.getElementById("objUserCid").innerHTML = thisClass.objUserCid;
+
+            // 重新更新UI,让被选中的 cid 目标有样式
+            thisClass.rightUserListEvent();
+
+        });
+
+        return thisClass;
+        
+    }
+
+    /**
+     * 房间有用户加入
+     * cidJson          该用户的相关数据
+     */
+    roomUserJoinEvent = function(cidJson) {
+
+        let thisClass = this;
+
+        // console.log(
+        //     "房间有用户加入 roomUserJoinEvent", cidJson
+        // );
+
+        let name = cidJson.name;
+        let userId = cidJson.userId;
+
+        /**
+         * 如果加入房间的是自己用户,说明是自己第一次进入房间
+         * 后续开发,这里就需要特殊进行处理,自己第一次登陆
+         * 则要根据房间里所有用户的数据,同步,例如游戏中玩家的坐标,穿着等各种数据参数
+         */
+        if (userId == MyWebSocket.find().userId) {
+            name = "自己";
+        }
+
+        let objDiv = document.createElement("div");
+        objDiv.className = "chat";
+
+        let addHtml = '';
+        addHtml += '<p class="chatTitle chatSys">' + name + '</p>';
+        addHtml += '<p class="chatTxt chatSys">用户-进入-房间</p>';
+
+        objDiv.innerHTML = addHtml;
+        document.getElementById('chatList').appendChild(objDiv);
+        thisClass.chatListEvent();
+
+    }
+
+    /**
+     * 房间有用户退出
+     * cidJson          该用户的相关数据
+     */
+    roomUserExitEvent = function(cidJson) {
+
+        let thisClass = this;
+
+        // console.log(
+        //     "房间有用户退出 roomUserExitEvent", cidJson
+        // );
+
+        let name = cidJson.name;
+        let userId = cidJson.userId;
+
+        /**
+         * 如果是自己退出,后续可能会有些单独处理的逻辑
+         */
+        if (userId == MyWebSocket.find().userId) {
+            name = "自己";
+        }
+
+        let objDiv = document.createElement("div");
+        objDiv.className = "chat";
+
+        let addHtml = '';
+        addHtml += '<p class="chatTitle chatSys">' + name + '</p>';
+        addHtml += '<p class="chatTxt chatSys">用户-退出-房间</p>';
+
+        objDiv.innerHTML = addHtml;
+        document.getElementById('chatList').appendChild(objDiv);
+        thisClass.chatListEvent();
+        
+    }
+
+    /**
+     * 当前房间里的某个用户数据发生了变化
+     * cidJson          该用户的相关数据
+     * dbUpdate         具体变化了哪些数据
+     */
+    roomUserDbUpdateEvent = function(cidJson, dbUpdate) {
+
+        let thisClass = this;
+
+        let name = cidJson.name;
+        let userId = cidJson.userId;
+
+        /**
+         * 如果是自己退出,后续可能会有些单独处理的逻辑
+         */
+        if (userId == MyWebSocket.find().userId) {
+            console.log("自己在房间里更新了数据", dbUpdate);
+        }
+
+        console.log(
+            "当前房间里的某个用户数据发生了变化 roomUserDbUpdateEvent",
+            cidJson, dbUpdate
+        );
+        
+
+    }
+
+    /**
+     * 每次房间里有群发消息的时候回调
+     * cidJson          该用户的相关数据
+     * message          消息的内容
+     */
+    roomChatAllCallbackEvent = function(cidJson, message) {
+
+        let thisClass = this;
+
+        // console.log(
+        //     "roomChatAllCallbackEvent", cidJson, message
+        // );
+
+        let name = cidJson.name;
+        let userId = cidJson.userId;
+        let jsonMessage = message.message;
+
+        if (typeof jsonMessage["type"] != 'string') {
+            return thisClass;
+        }
+
+        let jsonMessageType = jsonMessage.type;
+
+        // console.log(
+        //     "roomChatAllCallbackEvent", jsonMessageType, jsonMessage
+        // );
+
+        // 这里根据自定义不同类型,来判断触发不同逻辑
+        switch (jsonMessageType) {
+
+            // 群发聊天消息
+            case "chatAll":
+
+                let content = jsonMessage.content;
+
+                /**
+                 * 如果是自己退出,后续可能会有些单独处理的逻辑
+                 */
+                if (userId == MyWebSocket.find().userId) {
+                    name = "自己";
+                }
+
+                let objDiv = document.createElement("div");
+                objDiv.className = "chat";
+
+                let addHtml = '';
+                addHtml += '<p class="chatTitle">' + name + '</p>';
+                addHtml += '<p class="chatTxt">' + content + '</p>';
+
+                objDiv.innerHTML = addHtml;
+                document.getElementById('chatList').appendChild(objDiv);
+                thisClass.chatListEvent();
+
+                break;
+
+            // // 
+            // case "":
+                
+            //     break;
+
+            // // 
+            // case "":
+                
+            //     break;
+
+            // // 
+            // case "":
+                
+            //     break;
+
+        }
+        
+        return thisClass;
+
+    }
+
+    /**
+     * 每次有其他用户单独发送消息给你回调
+     * sendCidJson      发起消息用户的json数据
+     * getCidJson       接收消息用户的json数据
+     * message          消息内容
+     */
+    cidSendCallbackEvent = function(sendCidJson, getCidJson, message) {
+
+        let thisClass = this;
+
+        // console.log(
+        //     "cidSendCallbackEvent", sendCidJson, getCidJson, message
+        // );
+
+        let sendCidJsonName = sendCidJson["name"];
+        /**
+         * 如果是自己退出,后续可能会有些单独处理的逻辑
+         */
+        if (sendCidJson["userId"] == MyWebSocket.find().userId) {
+            sendCidJsonName = "自己";
+        }
+        
+        let getCidJsonName = getCidJson["name"];
+        /**
+         * 如果是自己退出,后续可能会有些单独处理的逻辑
+         */
+        if (getCidJson["userId"] == MyWebSocket.find().userId) {
+            getCidJsonName = "自己";
+        }
+
+
+        let type = message["type"];
+        let content = message["content"];
+
+         // 这里根据自定义不同类型,来判断触发不同逻辑
+        switch (type) {
+
+            // 处理私聊聊天内容
+            case "chat":
+
+                let objDiv = document.createElement("div");
+                objDiv.className = "chat";
+
+                let addHtml = '';
+                addHtml += '<p class="chatTitle chatObj">' + sendCidJsonName + ' 给 ' + getCidJsonName + ' 发送的私聊消息' + '</p>';
+                addHtml += '<p class="chatTxt chatObj">' + content + '</p>';
+
+                objDiv.innerHTML = addHtml;
+                document.getElementById('chatList').appendChild(objDiv);
+                thisClass.chatListEvent();
+
+                break;
+
+            // // 
+            // case "":
+                
+            //     break;
+
+            // // 
+            // case "":
+                
+            //     break;
+
+            // // 
+            // case "":
+                
+            //     break;
+
+        }
+
+
+        return thisClass;
+
+    }
+
+    // 滚动条滚动到最底部
+    chatListEvent = function() {
+        // 滚动条滚动到最底部
+        document.getElementById("chatList").scrollTop = document.getElementById("chatList").scrollHeight;
+    }
+
+    
+
+}
+
+
+
+
+
+
+
+

+ 105 - 0
exe/new_src/WebSocket/main.html

@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link rel="stylesheet" href="./css/main.css">
+    <title>demo</title>
+</head>
+<body>
+
+    <div class="app">
+
+        <div class="common">
+            <input type="button" value="开始连接通讯" id="socketStart" />
+        </div>
+
+        <div class="common">
+            <label>房间号:<input type="text" id="room" value="1" /></label>
+            <input type="button" value="进入房间" id="joinRoom" />
+            <label>昵称:<input type="text" id="nickname" value="自定义昵称" /></label>
+        </div>
+
+        <div class="common">
+            <input type="button" value="取消私聊目标" id="objUserExit" />
+            <span>当前私聊的目标cid: <span id="objUserCid">无</span> </span>
+        </div>
+
+        <div class="content">
+
+            <div class="leftTitle" >聊天内容</div>
+            <div class="leftTxt" id="chatList" >
+                
+                <!-- <div class="chat">
+                    <p class="chatTitle">谁发送的</p>
+                    <p class="chatTxt">聊天的内容</p>
+                </div>
+                <div class="chat">
+                    <p class="chatTitle">谁发送的</p>
+                    <p class="chatTxt">聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容</p>
+                </div>
+                <div class="chat">
+                    <p class="chatTitle">谁发送的</p>
+                    <p class="chatTxt">聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容</p>
+                </div>
+                <div class="chat">
+                    <p class="chatTitle">谁发送的</p>
+                    <p class="chatTxt">聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容</p>
+                </div>
+                <div class="chat">
+                    <p class="chatTitle">谁发送的</p>
+                    <p class="chatTxt">聊天的内容聊天的内容聊天的内容聊天的内容聊天的内容</p>
+                </div> -->
+
+            </div>
+
+            <div class="rightTitle" >用户列表</div>
+            <div class="rightUser" id="rightUserList" >
+                <!-- <div class="select">1111111</div>
+                <div class="select">2222222222</div>
+                <div class="select">33333333333</div>
+                <div class="select">444444444444444444</div>
+                <div class="select">555555555555555555555555</div>
+                <div class="select">66666666666666666666666666666</div>
+                <div class="select">66666666666666666666666666666</div>
+                <div class="select">66666666666666666666666666666</div> -->
+            </div>
+
+        </div>
+
+        <div class="submitEdit">
+            <textarea id="txtSend" cols="1" rows="1" style="width: 100%;height: 50px;" ></textarea>
+            <input type="button" value="发送" id="subSend" style="position: relative;left: 90%;" />
+        </div>
+
+
+    </div>
+
+    <script src="js/common/jquery-1.11.3.min.js" ></script>
+    <script type="module" >
+        import { Main } from './js/Main.js';
+
+        // 请求得到 websocket 自定义的端口号
+        var apiUrl = "../WebSocketPort.txt";
+        fetch(apiUrl, {
+            method: 'GET',
+            headers: {
+                'Content-Type' : 'application/x-www-form-urlencoded',
+            },
+        }).then(res => {
+            return res.text();
+        }).then(res => {
+
+            // console.log("得到的端口号", res);
+
+            Main.find().protWebSocket = res;
+            Main.find().view();
+            
+        }).catch(error => {
+            
+        });
+        
+    </script>
+    
+</body>
+</html>

+ 1 - 0
exe/new_src/WebSocketPort.txt

@@ -0,0 +1 @@
+6788

+ 19 - 0
exe/new_src/index.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>demo</title>
+</head>
+<body>
+    <p>Demo</p>
+    <p> <input type="button" value="WebSocket实时通讯案例" onclick="toWebSocketEvent()" /> </p>
+    <script>
+
+        function toWebSocketEvent() {
+            window.location.href = 'WebSocket/main.html';
+        }
+
+    </script>
+</body>
+</html>

+ 82 - 0
exe/new_src/loading.html

@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <style>
+        * { padding: 0px;margin: 0px; }
+        html, body { width: 100%;height: 100%; }
+        body {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            background-color: #1a1a1a;
+        }
+
+        canvas {
+            /* border: 1px solid #333;
+            border: 1px solid #333; */
+        }
+
+        * {
+            -moz-user-select: none;
+            -webkit-user-select: none;
+            -ms-user-select: none;
+            -khtml-user-select: none;
+            user-select: none;
+        }
+
+        .mainTxt {
+            position: fixed;top: 0px;left: 0px;width: 100%;height: 100%;background-color: #1a1a1a;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 18px;
+            color: #ffffff;
+            font-weight: 700;
+        }
+
+    </style>
+    <title>程序启动中</title>
+</head>
+<body>
+    <div class="mainTxt">
+        程序启动中
+    </div>
+    <!-- <canvas id="loadingCanvas" width="200" height="200"></canvas>
+    <script>
+        const canvas = document.getElementById('loadingCanvas');
+        const ctx = canvas.getContext('2d');
+        const centerX = canvas.width / 2;
+        const centerY = canvas.height / 2;
+        const radius = 70;
+        let startAngle = 0;
+        const speed = 0.03;
+
+        // 创建渐变色
+        const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
+        gradient.addColorStop(0, '#00ff00');
+        gradient.addColorStop(0.5, '#00ffff');
+        gradient.addColorStop(1, '#ff00ff');
+
+        function draw() {
+            ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+            // 设置阴影
+            ctx.shadowBlur = 20;
+            ctx.shadowColor = '#00ff00';
+
+            ctx.beginPath();
+            ctx.arc(centerX, centerY, radius, startAngle, startAngle + Math.PI * 1.5);
+            ctx.lineWidth = 15;
+            ctx.strokeStyle = gradient;
+            ctx.stroke();
+
+            startAngle += speed;
+            requestAnimationFrame(draw);
+        }
+
+        draw();
+    </script> -->
+</body>
+</html>

+ 1 - 0
exe/new_src/version.txt

@@ -0,0 +1 @@
+1.0

+ 11857 - 0
exe/package-lock.json

@@ -0,0 +1,11857 @@
+{
+    "name": "electronmain",
+    "version": "1.0.0",
+    "lockfileVersion": 3,
+    "requires": true,
+    "packages": {
+        "": {
+            "name": "electronmain",
+            "version": "1.0.0",
+            "license": "ISC",
+            "dependencies": {
+                "axios": "^0.21.1",
+                "body-parser": "^1.19.0",
+                "compressing": "^1.5.1",
+                "cookie-parser": "^1.4.5",
+                "cors": "^2.8.5",
+                "date-fns": "^2.22.1",
+                "electron-reloader": "^1.2.3",
+                "express": "^4.17.1",
+                "express-static": "^1.2.6",
+                "file-type": "^16.5.2",
+                "fs-extra": "^10.0.0",
+                "gm": "^1.23.1",
+                "iconv-lite": "^0.6.3",
+                "image-size": "^1.0.0",
+                "log4js": "^6.7.1",
+                "mime": "^2.5.2",
+                "moment": "^2.29.1",
+                "multer": "^1.4.2",
+                "node-cmd": "^4.0.0",
+                "nprogress": "^0.2.0",
+                "pm2": "^5.2.2",
+                "print-js": "^1.6.0",
+                "Printer": "^1.0.0",
+                "read-chunk": "^3.2.0",
+                "rebuild": "^0.1.2",
+                "serve-index": "^1.9.1",
+                "silly-datetime": "^0.1.2",
+                "socket.io": "^2.0.4",
+                "sqlite3": "^5.0.11",
+                "uuid": "^8.3.2",
+                "ws": "^7.5.3"
+            },
+            "devDependencies": {
+                "@babel/core": "^7.26.10",
+                "@babel/preset-env": "^7.26.9",
+                "asar": "^3.2.0",
+                "babel-loader": "^10.0.0",
+                "browserify": "^17.0.0",
+                "electron": "^35.1.4",
+                "electron-packager": "^17.1.2",
+                "html-webpack-plugin": "^5.6.3",
+                "nodemon": "^2.0.12",
+                "webpack": "^5.99.5",
+                "webpack-cli": "^6.0.1",
+                "webpack-merge": "^6.0.1"
+            }
+        },
+        "node_modules/@ampproject/remapping": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+            "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@jridgewell/gen-mapping": "^0.3.5",
+                "@jridgewell/trace-mapping": "^0.3.24"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@babel/code-frame": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+            "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.27.1",
+                "js-tokens": "^4.0.0",
+                "picocolors": "^1.1.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/compat-data": {
+            "version": "7.27.5",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz",
+            "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/core": {
+            "version": "7.27.4",
+            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz",
+            "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@ampproject/remapping": "^2.2.0",
+                "@babel/code-frame": "^7.27.1",
+                "@babel/generator": "^7.27.3",
+                "@babel/helper-compilation-targets": "^7.27.2",
+                "@babel/helper-module-transforms": "^7.27.3",
+                "@babel/helpers": "^7.27.4",
+                "@babel/parser": "^7.27.4",
+                "@babel/template": "^7.27.2",
+                "@babel/traverse": "^7.27.4",
+                "@babel/types": "^7.27.3",
+                "convert-source-map": "^2.0.0",
+                "debug": "^4.1.0",
+                "gensync": "^1.0.0-beta.2",
+                "json5": "^2.2.3",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/babel"
+            }
+        },
+        "node_modules/@babel/generator": {
+            "version": "7.27.5",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
+            "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/parser": "^7.27.5",
+                "@babel/types": "^7.27.3",
+                "@jridgewell/gen-mapping": "^0.3.5",
+                "@jridgewell/trace-mapping": "^0.3.25",
+                "jsesc": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-annotate-as-pure": {
+            "version": "7.27.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+            "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/types": "^7.27.3"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-compilation-targets": {
+            "version": "7.27.2",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+            "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/compat-data": "^7.27.2",
+                "@babel/helper-validator-option": "^7.27.1",
+                "browserslist": "^4.24.0",
+                "lru-cache": "^5.1.1",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-create-class-features-plugin": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz",
+            "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.27.1",
+                "@babel/helper-member-expression-to-functions": "^7.27.1",
+                "@babel/helper-optimise-call-expression": "^7.27.1",
+                "@babel/helper-replace-supers": "^7.27.1",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+                "@babel/traverse": "^7.27.1",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-create-regexp-features-plugin": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz",
+            "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.27.1",
+                "regexpu-core": "^6.2.0",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-define-polyfill-provider": {
+            "version": "0.6.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz",
+            "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-compilation-targets": "^7.22.6",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "debug": "^4.1.1",
+                "lodash.debounce": "^4.0.8",
+                "resolve": "^1.14.2"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+            }
+        },
+        "node_modules/@babel/helper-member-expression-to-functions": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz",
+            "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/traverse": "^7.27.1",
+                "@babel/types": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-module-imports": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+            "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/traverse": "^7.27.1",
+                "@babel/types": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-module-transforms": {
+            "version": "7.27.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
+            "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-module-imports": "^7.27.1",
+                "@babel/helper-validator-identifier": "^7.27.1",
+                "@babel/traverse": "^7.27.3"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-optimise-call-expression": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+            "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/types": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-plugin-utils": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+            "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-remap-async-to-generator": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+            "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.27.1",
+                "@babel/helper-wrap-function": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-replace-supers": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz",
+            "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-member-expression-to-functions": "^7.27.1",
+                "@babel/helper-optimise-call-expression": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+            "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/traverse": "^7.27.1",
+                "@babel/types": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-string-parser": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+            "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-validator-identifier": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+            "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-validator-option": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+            "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helper-wrap-function": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz",
+            "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/template": "^7.27.1",
+                "@babel/traverse": "^7.27.1",
+                "@babel/types": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/helpers": {
+            "version": "7.27.6",
+            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
+            "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/template": "^7.27.2",
+                "@babel/types": "^7.27.6"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/parser": {
+            "version": "7.27.5",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz",
+            "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/types": "^7.27.3"
+            },
+            "bin": {
+                "parser": "bin/babel-parser.js"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz",
+            "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz",
+            "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz",
+            "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz",
+            "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+                "@babel/plugin-transform-optional-chaining": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.13.0"
+            }
+        },
+        "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz",
+            "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-proposal-private-property-in-object": {
+            "version": "7.21.0-placeholder-for-preset-env.2",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+            "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-syntax-import-assertions": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz",
+            "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-syntax-import-attributes": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz",
+            "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+            "version": "7.18.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+            "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+                "@babel/helper-plugin-utils": "^7.18.6"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-arrow-functions": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
+            "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-async-generator-functions": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz",
+            "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-remap-async-to-generator": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-async-to-generator": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz",
+            "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-module-imports": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-remap-async-to-generator": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-block-scoped-functions": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz",
+            "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-block-scoping": {
+            "version": "7.27.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz",
+            "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-class-properties": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz",
+            "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-class-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-class-static-block": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz",
+            "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-class-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.12.0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-classes": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz",
+            "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.27.1",
+                "@babel/helper-compilation-targets": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-replace-supers": "^7.27.1",
+                "@babel/traverse": "^7.27.1",
+                "globals": "^11.1.0"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-computed-properties": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz",
+            "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/template": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-destructuring": {
+            "version": "7.27.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz",
+            "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-dotall-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz",
+            "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-duplicate-keys": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz",
+            "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz",
+            "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-dynamic-import": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz",
+            "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-exponentiation-operator": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz",
+            "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-export-namespace-from": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+            "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-for-of": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+            "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-function-name": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+            "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-compilation-targets": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-json-strings": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz",
+            "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-literals": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+            "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz",
+            "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-member-expression-literals": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz",
+            "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-modules-amd": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz",
+            "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-module-transforms": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-modules-commonjs": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz",
+            "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-module-transforms": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-modules-systemjs": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz",
+            "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-module-transforms": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-validator-identifier": "^7.27.1",
+                "@babel/traverse": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-modules-umd": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz",
+            "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-module-transforms": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz",
+            "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-new-target": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz",
+            "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz",
+            "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-numeric-separator": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz",
+            "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-object-rest-spread": {
+            "version": "7.27.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz",
+            "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-compilation-targets": "^7.27.2",
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/plugin-transform-destructuring": "^7.27.3",
+                "@babel/plugin-transform-parameters": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-object-super": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz",
+            "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-replace-supers": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-optional-catch-binding": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz",
+            "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-optional-chaining": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
+            "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-parameters": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz",
+            "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-private-methods": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz",
+            "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-class-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-private-property-in-object": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz",
+            "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.27.1",
+                "@babel/helper-create-class-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-property-literals": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz",
+            "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-regenerator": {
+            "version": "7.27.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz",
+            "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-regexp-modifiers": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz",
+            "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-reserved-words": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz",
+            "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-shorthand-properties": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
+            "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-spread": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz",
+            "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-sticky-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+            "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-template-literals": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+            "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-typeof-symbol": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz",
+            "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-unicode-escapes": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz",
+            "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-unicode-property-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz",
+            "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-unicode-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
+            "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+            "version": "7.27.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz",
+            "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+                "@babel/helper-plugin-utils": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/preset-env": {
+            "version": "7.27.2",
+            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.27.2.tgz",
+            "integrity": "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/compat-data": "^7.27.2",
+                "@babel/helper-compilation-targets": "^7.27.2",
+                "@babel/helper-plugin-utils": "^7.27.1",
+                "@babel/helper-validator-option": "^7.27.1",
+                "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1",
+                "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1",
+                "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1",
+                "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1",
+                "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1",
+                "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+                "@babel/plugin-syntax-import-assertions": "^7.27.1",
+                "@babel/plugin-syntax-import-attributes": "^7.27.1",
+                "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+                "@babel/plugin-transform-arrow-functions": "^7.27.1",
+                "@babel/plugin-transform-async-generator-functions": "^7.27.1",
+                "@babel/plugin-transform-async-to-generator": "^7.27.1",
+                "@babel/plugin-transform-block-scoped-functions": "^7.27.1",
+                "@babel/plugin-transform-block-scoping": "^7.27.1",
+                "@babel/plugin-transform-class-properties": "^7.27.1",
+                "@babel/plugin-transform-class-static-block": "^7.27.1",
+                "@babel/plugin-transform-classes": "^7.27.1",
+                "@babel/plugin-transform-computed-properties": "^7.27.1",
+                "@babel/plugin-transform-destructuring": "^7.27.1",
+                "@babel/plugin-transform-dotall-regex": "^7.27.1",
+                "@babel/plugin-transform-duplicate-keys": "^7.27.1",
+                "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1",
+                "@babel/plugin-transform-dynamic-import": "^7.27.1",
+                "@babel/plugin-transform-exponentiation-operator": "^7.27.1",
+                "@babel/plugin-transform-export-namespace-from": "^7.27.1",
+                "@babel/plugin-transform-for-of": "^7.27.1",
+                "@babel/plugin-transform-function-name": "^7.27.1",
+                "@babel/plugin-transform-json-strings": "^7.27.1",
+                "@babel/plugin-transform-literals": "^7.27.1",
+                "@babel/plugin-transform-logical-assignment-operators": "^7.27.1",
+                "@babel/plugin-transform-member-expression-literals": "^7.27.1",
+                "@babel/plugin-transform-modules-amd": "^7.27.1",
+                "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+                "@babel/plugin-transform-modules-systemjs": "^7.27.1",
+                "@babel/plugin-transform-modules-umd": "^7.27.1",
+                "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1",
+                "@babel/plugin-transform-new-target": "^7.27.1",
+                "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
+                "@babel/plugin-transform-numeric-separator": "^7.27.1",
+                "@babel/plugin-transform-object-rest-spread": "^7.27.2",
+                "@babel/plugin-transform-object-super": "^7.27.1",
+                "@babel/plugin-transform-optional-catch-binding": "^7.27.1",
+                "@babel/plugin-transform-optional-chaining": "^7.27.1",
+                "@babel/plugin-transform-parameters": "^7.27.1",
+                "@babel/plugin-transform-private-methods": "^7.27.1",
+                "@babel/plugin-transform-private-property-in-object": "^7.27.1",
+                "@babel/plugin-transform-property-literals": "^7.27.1",
+                "@babel/plugin-transform-regenerator": "^7.27.1",
+                "@babel/plugin-transform-regexp-modifiers": "^7.27.1",
+                "@babel/plugin-transform-reserved-words": "^7.27.1",
+                "@babel/plugin-transform-shorthand-properties": "^7.27.1",
+                "@babel/plugin-transform-spread": "^7.27.1",
+                "@babel/plugin-transform-sticky-regex": "^7.27.1",
+                "@babel/plugin-transform-template-literals": "^7.27.1",
+                "@babel/plugin-transform-typeof-symbol": "^7.27.1",
+                "@babel/plugin-transform-unicode-escapes": "^7.27.1",
+                "@babel/plugin-transform-unicode-property-regex": "^7.27.1",
+                "@babel/plugin-transform-unicode-regex": "^7.27.1",
+                "@babel/plugin-transform-unicode-sets-regex": "^7.27.1",
+                "@babel/preset-modules": "0.1.6-no-external-plugins",
+                "babel-plugin-polyfill-corejs2": "^0.4.10",
+                "babel-plugin-polyfill-corejs3": "^0.11.0",
+                "babel-plugin-polyfill-regenerator": "^0.6.1",
+                "core-js-compat": "^3.40.0",
+                "semver": "^6.3.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/@babel/preset-modules": {
+            "version": "0.1.6-no-external-plugins",
+            "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+            "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.0.0",
+                "@babel/types": "^7.4.4",
+                "esutils": "^2.0.2"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+            }
+        },
+        "node_modules/@babel/runtime": {
+            "version": "7.27.6",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
+            "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/template": {
+            "version": "7.27.2",
+            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+            "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/code-frame": "^7.27.1",
+                "@babel/parser": "^7.27.2",
+                "@babel/types": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/traverse": {
+            "version": "7.27.4",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz",
+            "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/code-frame": "^7.27.1",
+                "@babel/generator": "^7.27.3",
+                "@babel/parser": "^7.27.4",
+                "@babel/template": "^7.27.2",
+                "@babel/types": "^7.27.3",
+                "debug": "^4.3.1",
+                "globals": "^11.1.0"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@babel/types": {
+            "version": "7.27.6",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz",
+            "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-string-parser": "^7.27.1",
+                "@babel/helper-validator-identifier": "^7.27.1"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/@discoveryjs/json-ext": {
+            "version": "0.6.3",
+            "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
+            "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=14.17.0"
+            }
+        },
+        "node_modules/@eggjs/yauzl": {
+            "version": "2.11.0",
+            "resolved": "https://registry.npmjs.org/@eggjs/yauzl/-/yauzl-2.11.0.tgz",
+            "integrity": "sha512-Jq+k2fCZJ3i3HShb0nxLUiAgq5pwo8JTT1TrH22JoehZQ0Nm2dvByGIja1NYfNyuE4Tx5/Dns5nVsBN/mlC8yg==",
+            "license": "MIT",
+            "dependencies": {
+                "buffer-crc32": "~0.2.3",
+                "fd-slicer2": "^1.2.0"
+            }
+        },
+        "node_modules/@electron/asar": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz",
+            "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "commander": "^5.0.0",
+                "glob": "^7.1.6",
+                "minimatch": "^3.0.4"
+            },
+            "bin": {
+                "asar": "bin/asar.js"
+            },
+            "engines": {
+                "node": ">=10.12.0"
+            }
+        },
+        "node_modules/@electron/get": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
+            "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.1.1",
+                "env-paths": "^2.2.0",
+                "fs-extra": "^8.1.0",
+                "got": "^11.8.5",
+                "progress": "^2.0.3",
+                "semver": "^6.2.0",
+                "sumchecker": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "optionalDependencies": {
+                "global-agent": "^3.0.0"
+            }
+        },
+        "node_modules/@electron/get/node_modules/fs-extra": {
+            "version": "8.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+            "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^4.0.0",
+                "universalify": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=6 <7 || >=8"
+            }
+        },
+        "node_modules/@electron/get/node_modules/jsonfile": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+            "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+            "dev": true,
+            "license": "MIT",
+            "optionalDependencies": {
+                "graceful-fs": "^4.1.6"
+            }
+        },
+        "node_modules/@electron/get/node_modules/universalify": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+            "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/@electron/notarize": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.4.tgz",
+            "integrity": "sha512-W5GQhJEosFNafewnS28d3bpQ37/s91CDWqxVchHfmv2dQSTWpOzNlUVQwYzC1ay5bChRV/A9BTL68yj0Pa+TSg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.1.1",
+                "fs-extra": "^9.0.1"
+            },
+            "engines": {
+                "node": ">= 10.0.0"
+            }
+        },
+        "node_modules/@electron/notarize/node_modules/fs-extra": {
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+            "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "at-least-node": "^1.0.0",
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@electron/osx-sign": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz",
+            "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "compare-version": "^0.1.2",
+                "debug": "^4.3.4",
+                "fs-extra": "^10.0.0",
+                "isbinaryfile": "^4.0.8",
+                "minimist": "^1.2.6",
+                "plist": "^3.0.5"
+            },
+            "bin": {
+                "electron-osx-flat": "bin/electron-osx-flat.js",
+                "electron-osx-sign": "bin/electron-osx-sign.js"
+            },
+            "engines": {
+                "node": ">=12.0.0"
+            }
+        },
+        "node_modules/@electron/universal": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.5.1.tgz",
+            "integrity": "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@electron/asar": "^3.2.1",
+                "@malept/cross-spawn-promise": "^1.1.0",
+                "debug": "^4.3.1",
+                "dir-compare": "^3.0.0",
+                "fs-extra": "^9.0.1",
+                "minimatch": "^3.0.4",
+                "plist": "^3.0.4"
+            },
+            "engines": {
+                "node": ">=8.6"
+            }
+        },
+        "node_modules/@electron/universal/node_modules/fs-extra": {
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+            "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "at-least-node": "^1.0.0",
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@gar/promisify": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
+            "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/@jridgewell/gen-mapping": {
+            "version": "0.3.8",
+            "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+            "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@jridgewell/set-array": "^1.2.1",
+                "@jridgewell/sourcemap-codec": "^1.4.10",
+                "@jridgewell/trace-mapping": "^0.3.24"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@jridgewell/resolve-uri": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+            "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@jridgewell/set-array": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+            "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@jridgewell/source-map": {
+            "version": "0.3.6",
+            "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+            "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@jridgewell/gen-mapping": "^0.3.5",
+                "@jridgewell/trace-mapping": "^0.3.25"
+            }
+        },
+        "node_modules/@jridgewell/sourcemap-codec": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+            "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@jridgewell/trace-mapping": {
+            "version": "0.3.25",
+            "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+            "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@jridgewell/resolve-uri": "^3.1.0",
+                "@jridgewell/sourcemap-codec": "^1.4.14"
+            }
+        },
+        "node_modules/@malept/cross-spawn-promise": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
+            "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "individual",
+                    "url": "https://github.com/sponsors/malept"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
+                }
+            ],
+            "license": "Apache-2.0",
+            "dependencies": {
+                "cross-spawn": "^7.0.1"
+            },
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/@npmcli/fs": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
+            "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "@gar/promisify": "^1.0.1",
+                "semver": "^7.3.5"
+            }
+        },
+        "node_modules/@npmcli/fs/node_modules/semver": {
+            "version": "7.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+            "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+            "license": "ISC",
+            "optional": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@npmcli/move-file": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
+            "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
+            "deprecated": "This functionality has been moved to @npmcli/fs",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "mkdirp": "^1.0.4",
+                "rimraf": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@npmcli/move-file/node_modules/mkdirp": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+            "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+            "license": "MIT",
+            "optional": true,
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@pm2/agent": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.4.tgz",
+            "integrity": "sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==",
+            "license": "AGPL-3.0",
+            "dependencies": {
+                "async": "~3.2.0",
+                "chalk": "~3.0.0",
+                "dayjs": "~1.8.24",
+                "debug": "~4.3.1",
+                "eventemitter2": "~5.0.1",
+                "fast-json-patch": "^3.0.0-1",
+                "fclone": "~1.0.11",
+                "nssocket": "0.6.0",
+                "pm2-axon": "~4.0.1",
+                "pm2-axon-rpc": "~0.7.0",
+                "proxy-agent": "~6.3.0",
+                "semver": "~7.5.0",
+                "ws": "~7.5.10"
+            }
+        },
+        "node_modules/@pm2/agent/node_modules/chalk": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+            "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/@pm2/agent/node_modules/dayjs": {
+            "version": "1.8.36",
+            "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz",
+            "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==",
+            "license": "MIT"
+        },
+        "node_modules/@pm2/agent/node_modules/debug": {
+            "version": "4.3.7",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+            "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.3"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@pm2/agent/node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "license": "ISC",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@pm2/agent/node_modules/semver": {
+            "version": "7.5.4",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+            "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+            "license": "ISC",
+            "dependencies": {
+                "lru-cache": "^6.0.0"
+            },
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@pm2/agent/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC"
+        },
+        "node_modules/@pm2/io": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.0.1.tgz",
+            "integrity": "sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==",
+            "license": "Apache-2",
+            "dependencies": {
+                "async": "~2.6.1",
+                "debug": "~4.3.1",
+                "eventemitter2": "^6.3.1",
+                "require-in-the-middle": "^5.0.0",
+                "semver": "~7.5.4",
+                "shimmer": "^1.2.0",
+                "signal-exit": "^3.0.3",
+                "tslib": "1.9.3"
+            },
+            "engines": {
+                "node": ">=6.0"
+            }
+        },
+        "node_modules/@pm2/io/node_modules/async": {
+            "version": "2.6.4",
+            "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+            "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+            "license": "MIT",
+            "dependencies": {
+                "lodash": "^4.17.14"
+            }
+        },
+        "node_modules/@pm2/io/node_modules/debug": {
+            "version": "4.3.7",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+            "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.3"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@pm2/io/node_modules/eventemitter2": {
+            "version": "6.4.9",
+            "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
+            "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==",
+            "license": "MIT"
+        },
+        "node_modules/@pm2/io/node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "license": "ISC",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@pm2/io/node_modules/semver": {
+            "version": "7.5.4",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+            "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+            "license": "ISC",
+            "dependencies": {
+                "lru-cache": "^6.0.0"
+            },
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@pm2/io/node_modules/tslib": {
+            "version": "1.9.3",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+            "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+            "license": "Apache-2.0"
+        },
+        "node_modules/@pm2/io/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC"
+        },
+        "node_modules/@pm2/js-api": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz",
+            "integrity": "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==",
+            "license": "Apache-2",
+            "dependencies": {
+                "async": "^2.6.3",
+                "debug": "~4.3.1",
+                "eventemitter2": "^6.3.1",
+                "extrareqp2": "^1.0.0",
+                "ws": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/@pm2/js-api/node_modules/async": {
+            "version": "2.6.4",
+            "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+            "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+            "license": "MIT",
+            "dependencies": {
+                "lodash": "^4.17.14"
+            }
+        },
+        "node_modules/@pm2/js-api/node_modules/debug": {
+            "version": "4.3.7",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+            "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.3"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@pm2/js-api/node_modules/eventemitter2": {
+            "version": "6.4.9",
+            "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
+            "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==",
+            "license": "MIT"
+        },
+        "node_modules/@pm2/pm2-version-check": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz",
+            "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.3.1"
+            }
+        },
+        "node_modules/@sindresorhus/is": {
+            "version": "4.6.0",
+            "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
+            "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sindresorhus/is?sponsor=1"
+            }
+        },
+        "node_modules/@szmarczak/http-timer": {
+            "version": "4.0.6",
+            "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
+            "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "defer-to-connect": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/@tokenizer/token": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
+            "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
+            "license": "MIT"
+        },
+        "node_modules/@tootallnate/once": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+            "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/@tootallnate/quickjs-emscripten": {
+            "version": "0.23.0",
+            "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+            "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
+            "license": "MIT"
+        },
+        "node_modules/@types/cacheable-request": {
+            "version": "6.0.3",
+            "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
+            "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/http-cache-semantics": "*",
+                "@types/keyv": "^3.1.4",
+                "@types/node": "*",
+                "@types/responselike": "^1.0.0"
+            }
+        },
+        "node_modules/@types/eslint": {
+            "version": "9.6.1",
+            "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+            "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/estree": "*",
+                "@types/json-schema": "*"
+            }
+        },
+        "node_modules/@types/eslint-scope": {
+            "version": "3.7.7",
+            "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+            "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/eslint": "*",
+                "@types/estree": "*"
+            }
+        },
+        "node_modules/@types/estree": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+            "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@types/glob": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+            "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "@types/minimatch": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/html-minifier-terser": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+            "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@types/http-cache-semantics": {
+            "version": "4.0.4",
+            "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
+            "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@types/json-schema": {
+            "version": "7.0.15",
+            "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+            "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@types/keyv": {
+            "version": "3.1.4",
+            "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
+            "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/minimatch": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+            "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/@types/node": {
+            "version": "24.0.3",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz",
+            "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "undici-types": "~7.8.0"
+            }
+        },
+        "node_modules/@types/responselike": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
+            "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/yauzl": {
+            "version": "2.10.3",
+            "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
+            "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@webassemblyjs/ast": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+            "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/helper-numbers": "1.13.2",
+                "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+            }
+        },
+        "node_modules/@webassemblyjs/floating-point-hex-parser": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+            "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@webassemblyjs/helper-api-error": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+            "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@webassemblyjs/helper-buffer": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+            "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@webassemblyjs/helper-numbers": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+            "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+                "@webassemblyjs/helper-api-error": "1.13.2",
+                "@xtuc/long": "4.2.2"
+            }
+        },
+        "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+            "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@webassemblyjs/helper-wasm-section": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+            "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/ast": "1.14.1",
+                "@webassemblyjs/helper-buffer": "1.14.1",
+                "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+                "@webassemblyjs/wasm-gen": "1.14.1"
+            }
+        },
+        "node_modules/@webassemblyjs/ieee754": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+            "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@xtuc/ieee754": "^1.2.0"
+            }
+        },
+        "node_modules/@webassemblyjs/leb128": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+            "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@xtuc/long": "4.2.2"
+            }
+        },
+        "node_modules/@webassemblyjs/utf8": {
+            "version": "1.13.2",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+            "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@webassemblyjs/wasm-edit": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+            "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/ast": "1.14.1",
+                "@webassemblyjs/helper-buffer": "1.14.1",
+                "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+                "@webassemblyjs/helper-wasm-section": "1.14.1",
+                "@webassemblyjs/wasm-gen": "1.14.1",
+                "@webassemblyjs/wasm-opt": "1.14.1",
+                "@webassemblyjs/wasm-parser": "1.14.1",
+                "@webassemblyjs/wast-printer": "1.14.1"
+            }
+        },
+        "node_modules/@webassemblyjs/wasm-gen": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+            "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/ast": "1.14.1",
+                "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+                "@webassemblyjs/ieee754": "1.13.2",
+                "@webassemblyjs/leb128": "1.13.2",
+                "@webassemblyjs/utf8": "1.13.2"
+            }
+        },
+        "node_modules/@webassemblyjs/wasm-opt": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+            "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/ast": "1.14.1",
+                "@webassemblyjs/helper-buffer": "1.14.1",
+                "@webassemblyjs/wasm-gen": "1.14.1",
+                "@webassemblyjs/wasm-parser": "1.14.1"
+            }
+        },
+        "node_modules/@webassemblyjs/wasm-parser": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+            "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/ast": "1.14.1",
+                "@webassemblyjs/helper-api-error": "1.13.2",
+                "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+                "@webassemblyjs/ieee754": "1.13.2",
+                "@webassemblyjs/leb128": "1.13.2",
+                "@webassemblyjs/utf8": "1.13.2"
+            }
+        },
+        "node_modules/@webassemblyjs/wast-printer": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+            "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@webassemblyjs/ast": "1.14.1",
+                "@xtuc/long": "4.2.2"
+            }
+        },
+        "node_modules/@webpack-cli/configtest": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz",
+            "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18.12.0"
+            },
+            "peerDependencies": {
+                "webpack": "^5.82.0",
+                "webpack-cli": "6.x.x"
+            }
+        },
+        "node_modules/@webpack-cli/info": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz",
+            "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18.12.0"
+            },
+            "peerDependencies": {
+                "webpack": "^5.82.0",
+                "webpack-cli": "6.x.x"
+            }
+        },
+        "node_modules/@webpack-cli/serve": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz",
+            "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18.12.0"
+            },
+            "peerDependencies": {
+                "webpack": "^5.82.0",
+                "webpack-cli": "6.x.x"
+            },
+            "peerDependenciesMeta": {
+                "webpack-dev-server": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@xmldom/xmldom": {
+            "version": "0.8.10",
+            "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+            "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10.0.0"
+            }
+        },
+        "node_modules/@xtuc/ieee754": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+            "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+            "dev": true,
+            "license": "BSD-3-Clause"
+        },
+        "node_modules/@xtuc/long": {
+            "version": "4.2.2",
+            "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+            "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+            "dev": true,
+            "license": "Apache-2.0"
+        },
+        "node_modules/abbrev": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+            "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/abort-controller": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+            "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+            "license": "MIT",
+            "dependencies": {
+                "event-target-shim": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=6.5"
+            }
+        },
+        "node_modules/accepts": {
+            "version": "1.3.8",
+            "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+            "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+            "license": "MIT",
+            "dependencies": {
+                "mime-types": "~2.1.34",
+                "negotiator": "0.6.3"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/acorn": {
+            "version": "7.4.1",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+            "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/acorn-node": {
+            "version": "1.8.2",
+            "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+            "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "acorn": "^7.0.0",
+                "acorn-walk": "^7.0.0",
+                "xtend": "^4.0.2"
+            }
+        },
+        "node_modules/acorn-walk": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+            "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/after": {
+            "version": "0.8.2",
+            "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+            "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==",
+            "license": "MIT"
+        },
+        "node_modules/agent-base": {
+            "version": "7.1.3",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+            "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/agentkeepalive": {
+            "version": "4.6.0",
+            "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
+            "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "humanize-ms": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 8.0.0"
+            }
+        },
+        "node_modules/aggregate-error": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+            "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "clean-stack": "^2.0.0",
+                "indent-string": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ajv": {
+            "version": "8.17.1",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+            "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "fast-deep-equal": "^3.1.3",
+                "fast-uri": "^3.0.1",
+                "json-schema-traverse": "^1.0.0",
+                "require-from-string": "^2.0.2"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/epoberezkin"
+            }
+        },
+        "node_modules/ajv-formats": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+            "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ajv": "^8.0.0"
+            },
+            "peerDependencies": {
+                "ajv": "^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "ajv": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/ajv-keywords": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+            "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "fast-deep-equal": "^3.1.3"
+            },
+            "peerDependencies": {
+                "ajv": "^8.8.2"
+            }
+        },
+        "node_modules/amp": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz",
+            "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==",
+            "license": "MIT"
+        },
+        "node_modules/amp-message": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz",
+            "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==",
+            "license": "MIT",
+            "dependencies": {
+                "amp": "0.3.1"
+            }
+        },
+        "node_modules/ansi-colors": {
+            "version": "4.1.3",
+            "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+            "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "devOptional": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "license": "MIT",
+            "dependencies": {
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/anymatch": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+            "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+            "license": "ISC",
+            "dependencies": {
+                "normalize-path": "^3.0.0",
+                "picomatch": "^2.0.4"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/append-field": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
+            "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
+            "license": "MIT"
+        },
+        "node_modules/aproba": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
+            "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/are-we-there-yet": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
+            "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
+            "deprecated": "This package is no longer supported.",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "delegates": "^1.0.0",
+                "readable-stream": "^3.6.0"
+            },
+            "engines": {
+                "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+            }
+        },
+        "node_modules/are-we-there-yet/node_modules/readable-stream": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/argparse": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+            "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+            "license": "Python-2.0"
+        },
+        "node_modules/array-flatten": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+            "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+            "license": "MIT"
+        },
+        "node_modules/array-parallel": {
+            "version": "0.1.3",
+            "resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz",
+            "integrity": "sha512-TDPTwSWW5E4oiFiKmz6RGJ/a80Y91GuLgUYuLd49+XBS75tYo8PNgaT2K/OxuQYqkoI852MDGBorg9OcUSTQ8w==",
+            "license": "MIT"
+        },
+        "node_modules/array-series": {
+            "version": "0.1.5",
+            "resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz",
+            "integrity": "sha512-L0XlBwfx9QetHOsbLDrE/vh2t018w9462HM3iaFfxRiK83aJjAt/Ja3NMkOW7FICwWTlQBa3ZbL5FKhuQWkDrg==",
+            "license": "MIT"
+        },
+        "node_modules/arraybuffer.slice": {
+            "version": "0.0.7",
+            "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+            "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
+            "license": "MIT"
+        },
+        "node_modules/asar": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
+            "integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==",
+            "deprecated": "Please use @electron/asar moving forward.  There is no API change, just a package name change",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "chromium-pickle-js": "^0.2.0",
+                "commander": "^5.0.0",
+                "glob": "^7.1.6",
+                "minimatch": "^3.0.4"
+            },
+            "bin": {
+                "asar": "bin/asar.js"
+            },
+            "engines": {
+                "node": ">=10.12.0"
+            },
+            "optionalDependencies": {
+                "@types/glob": "^7.1.1"
+            }
+        },
+        "node_modules/asn1.js": {
+            "version": "4.10.1",
+            "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+            "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^4.0.0",
+                "inherits": "^2.0.1",
+                "minimalistic-assert": "^1.0.0"
+            }
+        },
+        "node_modules/asn1.js/node_modules/bn.js": {
+            "version": "4.12.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
+            "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/assert": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz",
+            "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "object.assign": "^4.1.4",
+                "util": "^0.10.4"
+            }
+        },
+        "node_modules/assert/node_modules/inherits": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+            "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/assert/node_modules/util": {
+            "version": "0.10.4",
+            "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+            "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "2.0.3"
+            }
+        },
+        "node_modules/ast-types": {
+            "version": "0.13.4",
+            "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
+            "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+            "license": "MIT",
+            "dependencies": {
+                "tslib": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/async": {
+            "version": "3.2.6",
+            "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+            "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+            "license": "MIT"
+        },
+        "node_modules/at-least-node": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+            "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+            "dev": true,
+            "license": "ISC",
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/author-regex": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz",
+            "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/available-typed-arrays": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+            "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "possible-typed-array-names": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/axios": {
+            "version": "0.21.4",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+            "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+            "license": "MIT",
+            "dependencies": {
+                "follow-redirects": "^1.14.0"
+            }
+        },
+        "node_modules/babel-loader": {
+            "version": "10.0.0",
+            "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz",
+            "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "find-up": "^5.0.0"
+            },
+            "engines": {
+                "node": "^18.20.0 || ^20.10.0 || >=22.0.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.12.0",
+                "webpack": ">=5.61.0"
+            }
+        },
+        "node_modules/babel-plugin-polyfill-corejs2": {
+            "version": "0.4.13",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz",
+            "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/compat-data": "^7.22.6",
+                "@babel/helper-define-polyfill-provider": "^0.6.4",
+                "semver": "^6.3.1"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+            }
+        },
+        "node_modules/babel-plugin-polyfill-corejs3": {
+            "version": "0.11.1",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+            "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-define-polyfill-provider": "^0.6.3",
+                "core-js-compat": "^3.40.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+            }
+        },
+        "node_modules/babel-plugin-polyfill-regenerator": {
+            "version": "0.6.4",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz",
+            "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@babel/helper-define-polyfill-provider": "^0.6.4"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+            }
+        },
+        "node_modules/backo2": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+            "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
+            "license": "MIT"
+        },
+        "node_modules/balanced-match": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+            "devOptional": true,
+            "license": "MIT"
+        },
+        "node_modules/base64-arraybuffer": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+            "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==",
+            "engines": {
+                "node": ">= 0.6.0"
+            }
+        },
+        "node_modules/base64-js": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+            "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT"
+        },
+        "node_modules/base64id": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+            "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+            "license": "MIT",
+            "engines": {
+                "node": "^4.5.0 || >= 5.9"
+            }
+        },
+        "node_modules/basic-ftp": {
+            "version": "5.0.5",
+            "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
+            "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=10.0.0"
+            }
+        },
+        "node_modules/batch": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+            "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+            "license": "MIT"
+        },
+        "node_modules/binary-extensions": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+            "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/bindings": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+            "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+            "license": "MIT",
+            "dependencies": {
+                "file-uri-to-path": "1.0.0"
+            }
+        },
+        "node_modules/bl": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+            "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+            "license": "MIT",
+            "dependencies": {
+                "readable-stream": "^2.3.5",
+                "safe-buffer": "^5.1.1"
+            }
+        },
+        "node_modules/blessed": {
+            "version": "0.1.81",
+            "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz",
+            "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==",
+            "license": "MIT",
+            "bin": {
+                "blessed": "bin/tput.js"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/blob": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+            "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
+            "license": "MIT"
+        },
+        "node_modules/bluebird": {
+            "version": "3.7.2",
+            "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+            "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/bn.js": {
+            "version": "5.2.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz",
+            "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/bodec": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz",
+            "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==",
+            "license": "MIT"
+        },
+        "node_modules/body-parser": {
+            "version": "1.20.3",
+            "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+            "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+            "license": "MIT",
+            "dependencies": {
+                "bytes": "3.1.2",
+                "content-type": "~1.0.5",
+                "debug": "2.6.9",
+                "depd": "2.0.0",
+                "destroy": "1.2.0",
+                "http-errors": "2.0.0",
+                "iconv-lite": "0.4.24",
+                "on-finished": "2.4.1",
+                "qs": "6.13.0",
+                "raw-body": "2.5.2",
+                "type-is": "~1.6.18",
+                "unpipe": "1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8",
+                "npm": "1.2.8000 || >= 1.4.16"
+            }
+        },
+        "node_modules/body-parser/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/body-parser/node_modules/iconv-lite": {
+            "version": "0.4.24",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+            "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/body-parser/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/boolbase": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+            "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/boolean": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
+            "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
+            "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+            "dev": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/brace-expansion": {
+            "version": "1.1.12",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+            "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+            "devOptional": true,
+            "license": "MIT",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/braces": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+            "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+            "license": "MIT",
+            "dependencies": {
+                "fill-range": "^7.1.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/brorand": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+            "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/browser-pack": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+            "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "combine-source-map": "~0.8.0",
+                "defined": "^1.0.0",
+                "JSONStream": "^1.0.3",
+                "safe-buffer": "^5.1.1",
+                "through2": "^2.0.0",
+                "umd": "^3.0.0"
+            },
+            "bin": {
+                "browser-pack": "bin/cmd.js"
+            }
+        },
+        "node_modules/browser-resolve": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz",
+            "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "resolve": "^1.17.0"
+            }
+        },
+        "node_modules/browserify": {
+            "version": "17.0.1",
+            "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.1.tgz",
+            "integrity": "sha512-pxhT00W3ylMhCHwG5yfqtZjNnFuX5h2IJdaBfSo4ChaaBsIp9VLrEMQ1bHV+Xr1uLPXuNDDM1GlJkjli0qkRsw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "assert": "^1.4.0",
+                "browser-pack": "^6.0.1",
+                "browser-resolve": "^2.0.0",
+                "browserify-zlib": "~0.2.0",
+                "buffer": "~5.2.1",
+                "cached-path-relative": "^1.0.0",
+                "concat-stream": "^1.6.0",
+                "console-browserify": "^1.1.0",
+                "constants-browserify": "~1.0.0",
+                "crypto-browserify": "^3.0.0",
+                "defined": "^1.0.0",
+                "deps-sort": "^2.0.1",
+                "domain-browser": "^1.2.0",
+                "duplexer2": "~0.1.2",
+                "events": "^3.0.0",
+                "glob": "^7.1.0",
+                "hasown": "^2.0.0",
+                "htmlescape": "^1.1.0",
+                "https-browserify": "^1.0.0",
+                "inherits": "~2.0.1",
+                "insert-module-globals": "^7.2.1",
+                "JSONStream": "^1.0.3",
+                "labeled-stream-splicer": "^2.0.0",
+                "mkdirp-classic": "^0.5.2",
+                "module-deps": "^6.2.3",
+                "os-browserify": "~0.3.0",
+                "parents": "^1.0.1",
+                "path-browserify": "^1.0.0",
+                "process": "~0.11.0",
+                "punycode": "^1.3.2",
+                "querystring-es3": "~0.2.0",
+                "read-only-stream": "^2.0.0",
+                "readable-stream": "^2.0.2",
+                "resolve": "^1.1.4",
+                "shasum-object": "^1.0.0",
+                "shell-quote": "^1.6.1",
+                "stream-browserify": "^3.0.0",
+                "stream-http": "^3.0.0",
+                "string_decoder": "^1.1.1",
+                "subarg": "^1.0.0",
+                "syntax-error": "^1.1.1",
+                "through2": "^2.0.0",
+                "timers-browserify": "^1.0.1",
+                "tty-browserify": "0.0.1",
+                "url": "~0.11.0",
+                "util": "~0.12.0",
+                "vm-browserify": "^1.0.0",
+                "xtend": "^4.0.0"
+            },
+            "bin": {
+                "browserify": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/browserify-aes": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+            "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "buffer-xor": "^1.0.3",
+                "cipher-base": "^1.0.0",
+                "create-hash": "^1.1.0",
+                "evp_bytestokey": "^1.0.3",
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/browserify-cipher": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+            "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "browserify-aes": "^1.0.4",
+                "browserify-des": "^1.0.0",
+                "evp_bytestokey": "^1.0.0"
+            }
+        },
+        "node_modules/browserify-des": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+            "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "cipher-base": "^1.0.1",
+                "des.js": "^1.0.0",
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.1.2"
+            }
+        },
+        "node_modules/browserify-rsa": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
+            "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^5.2.1",
+                "randombytes": "^2.1.0",
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/browserify-sign": {
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz",
+            "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "bn.js": "^5.2.1",
+                "browserify-rsa": "^4.1.0",
+                "create-hash": "^1.2.0",
+                "create-hmac": "^1.1.7",
+                "elliptic": "^6.5.5",
+                "hash-base": "~3.0",
+                "inherits": "^2.0.4",
+                "parse-asn1": "^5.1.7",
+                "readable-stream": "^2.3.8",
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.12"
+            }
+        },
+        "node_modules/browserify-zlib": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+            "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "pako": "~1.0.5"
+            }
+        },
+        "node_modules/browserslist": {
+            "version": "4.25.0",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz",
+            "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/browserslist"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/browserslist"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "caniuse-lite": "^1.0.30001718",
+                "electron-to-chromium": "^1.5.160",
+                "node-releases": "^2.0.19",
+                "update-browserslist-db": "^1.1.3"
+            },
+            "bin": {
+                "browserslist": "cli.js"
+            },
+            "engines": {
+                "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+            }
+        },
+        "node_modules/buffer": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+            "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "base64-js": "^1.0.2",
+                "ieee754": "^1.1.4"
+            }
+        },
+        "node_modules/buffer-alloc": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+            "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+            "license": "MIT",
+            "dependencies": {
+                "buffer-alloc-unsafe": "^1.1.0",
+                "buffer-fill": "^1.0.0"
+            }
+        },
+        "node_modules/buffer-alloc-unsafe": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+            "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+            "license": "MIT"
+        },
+        "node_modules/buffer-crc32": {
+            "version": "0.2.13",
+            "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+            "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+            "license": "MIT",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/buffer-equal": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
+            "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/buffer-fill": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+            "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==",
+            "license": "MIT"
+        },
+        "node_modules/buffer-from": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+            "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+            "license": "MIT"
+        },
+        "node_modules/buffer-xor": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+            "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/builtin-status-codes": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+            "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/busboy": {
+            "version": "0.2.14",
+            "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
+            "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
+            "dependencies": {
+                "dicer": "0.2.5",
+                "readable-stream": "1.1.x"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/busboy/node_modules/isarray": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+            "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+            "license": "MIT"
+        },
+        "node_modules/busboy/node_modules/readable-stream": {
+            "version": "1.1.14",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+            "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+            "license": "MIT",
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.1",
+                "isarray": "0.0.1",
+                "string_decoder": "~0.10.x"
+            }
+        },
+        "node_modules/busboy/node_modules/string_decoder": {
+            "version": "0.10.31",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+            "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+            "license": "MIT"
+        },
+        "node_modules/bytes": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+            "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/cacache": {
+            "version": "15.3.0",
+            "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
+            "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "@npmcli/fs": "^1.0.0",
+                "@npmcli/move-file": "^1.0.1",
+                "chownr": "^2.0.0",
+                "fs-minipass": "^2.0.0",
+                "glob": "^7.1.4",
+                "infer-owner": "^1.0.4",
+                "lru-cache": "^6.0.0",
+                "minipass": "^3.1.1",
+                "minipass-collect": "^1.0.2",
+                "minipass-flush": "^1.0.5",
+                "minipass-pipeline": "^1.2.2",
+                "mkdirp": "^1.0.3",
+                "p-map": "^4.0.0",
+                "promise-inflight": "^1.0.1",
+                "rimraf": "^3.0.2",
+                "ssri": "^8.0.1",
+                "tar": "^6.0.2",
+                "unique-filename": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/cacache/node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/cacache/node_modules/mkdirp": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+            "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+            "license": "MIT",
+            "optional": true,
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/cacache/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/cacheable-lookup": {
+            "version": "5.0.4",
+            "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+            "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10.6.0"
+            }
+        },
+        "node_modules/cacheable-request": {
+            "version": "7.0.4",
+            "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
+            "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "clone-response": "^1.0.2",
+                "get-stream": "^5.1.0",
+                "http-cache-semantics": "^4.0.0",
+                "keyv": "^4.0.0",
+                "lowercase-keys": "^2.0.0",
+                "normalize-url": "^6.0.1",
+                "responselike": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/cached-path-relative": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz",
+            "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/call-bind": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+            "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bind-apply-helpers": "^1.0.0",
+                "es-define-property": "^1.0.0",
+                "get-intrinsic": "^1.2.4",
+                "set-function-length": "^1.2.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/call-bind-apply-helpers": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+            "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0",
+                "function-bind": "^1.1.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/call-bound": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+            "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+            "license": "MIT",
+            "dependencies": {
+                "call-bind-apply-helpers": "^1.0.2",
+                "get-intrinsic": "^1.3.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/camel-case": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
+            "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "pascal-case": "^3.1.2",
+                "tslib": "^2.0.3"
+            }
+        },
+        "node_modules/caniuse-lite": {
+            "version": "1.0.30001723",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
+            "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/browserslist"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ],
+            "license": "CC-BY-4.0"
+        },
+        "node_modules/chalk": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
+            }
+        },
+        "node_modules/charm": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz",
+            "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==",
+            "license": "MIT/X11"
+        },
+        "node_modules/chokidar": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+            "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+            "license": "MIT",
+            "dependencies": {
+                "anymatch": "~3.1.2",
+                "braces": "~3.0.2",
+                "glob-parent": "~5.1.2",
+                "is-binary-path": "~2.1.0",
+                "is-glob": "~4.0.1",
+                "normalize-path": "~3.0.0",
+                "readdirp": "~3.6.0"
+            },
+            "engines": {
+                "node": ">= 8.10.0"
+            },
+            "funding": {
+                "url": "https://paulmillr.com/funding/"
+            },
+            "optionalDependencies": {
+                "fsevents": "~2.3.2"
+            }
+        },
+        "node_modules/chownr": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+            "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+            "license": "ISC",
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/chrome-trace-event": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+            "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.0"
+            }
+        },
+        "node_modules/chromium-pickle-js": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
+            "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/cipher-base": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz",
+            "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.4",
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/clean-css": {
+            "version": "5.3.3",
+            "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
+            "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "source-map": "~0.6.0"
+            },
+            "engines": {
+                "node": ">= 10.0"
+            }
+        },
+        "node_modules/clean-css/node_modules/source-map": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/clean-stack": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+            "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/cli-tableau": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz",
+            "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==",
+            "dependencies": {
+                "chalk": "3.0.0"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/cli-tableau/node_modules/chalk": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+            "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/clone-deep": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+            "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-plain-object": "^2.0.4",
+                "kind-of": "^6.0.2",
+                "shallow-clone": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/clone-response": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
+            "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "mimic-response": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "license": "MIT",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+            "license": "MIT"
+        },
+        "node_modules/color-support": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+            "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+            "license": "ISC",
+            "optional": true,
+            "bin": {
+                "color-support": "bin.js"
+            }
+        },
+        "node_modules/colorette": {
+            "version": "2.0.20",
+            "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+            "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/combine-source-map": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+            "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "convert-source-map": "~1.1.0",
+                "inline-source-map": "~0.6.0",
+                "lodash.memoize": "~3.0.3",
+                "source-map": "~0.5.3"
+            }
+        },
+        "node_modules/combine-source-map/node_modules/convert-source-map": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+            "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/commander": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+            "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/compare-version": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
+            "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/component-bind": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+            "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw=="
+        },
+        "node_modules/component-emitter": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
+            "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
+            "license": "MIT",
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/component-inherit": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+            "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA=="
+        },
+        "node_modules/compressing": {
+            "version": "1.10.3",
+            "resolved": "https://registry.npmjs.org/compressing/-/compressing-1.10.3.tgz",
+            "integrity": "sha512-F3RxWLU4UNfNYFVNwCK58HwQnv/5drvUW176FC//3i0pwpdahoZxMM7dkxWuA2MEafqfwDc+iudk70Sx/VMUIw==",
+            "license": "MIT",
+            "dependencies": {
+                "@eggjs/yauzl": "^2.11.0",
+                "flushwritable": "^1.0.0",
+                "get-ready": "^1.0.0",
+                "iconv-lite": "^0.5.0",
+                "mkdirp": "^0.5.1",
+                "pump": "^3.0.0",
+                "streamifier": "^0.1.1",
+                "tar-stream": "^1.5.2",
+                "yazl": "^2.4.2"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/compressing/node_modules/iconv-lite": {
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz",
+            "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==",
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/concat-map": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+            "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+            "devOptional": true,
+            "license": "MIT"
+        },
+        "node_modules/concat-stream": {
+            "version": "1.6.2",
+            "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+            "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+            "engines": [
+                "node >= 0.8"
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "buffer-from": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^2.2.2",
+                "typedarray": "^0.0.6"
+            }
+        },
+        "node_modules/console-browserify": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+            "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+            "dev": true
+        },
+        "node_modules/console-control-strings": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+            "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/constants-browserify": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+            "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/content-disposition": {
+            "version": "0.5.4",
+            "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+            "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/content-type": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+            "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/convert-source-map": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+            "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/cookie": {
+            "version": "0.7.2",
+            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+            "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/cookie-parser": {
+            "version": "1.4.7",
+            "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
+            "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
+            "license": "MIT",
+            "dependencies": {
+                "cookie": "0.7.2",
+                "cookie-signature": "1.0.6"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/cookie-signature": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+            "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+            "license": "MIT"
+        },
+        "node_modules/core-js-compat": {
+            "version": "3.43.0",
+            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz",
+            "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "browserslist": "^4.25.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/core-js"
+            }
+        },
+        "node_modules/core-util-is": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+            "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+            "license": "MIT"
+        },
+        "node_modules/cors": {
+            "version": "2.8.5",
+            "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+            "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+            "license": "MIT",
+            "dependencies": {
+                "object-assign": "^4",
+                "vary": "^1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/create-ecdh": {
+            "version": "4.0.4",
+            "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+            "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^4.1.0",
+                "elliptic": "^6.5.3"
+            }
+        },
+        "node_modules/create-ecdh/node_modules/bn.js": {
+            "version": "4.12.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
+            "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/create-hash": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+            "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "cipher-base": "^1.0.1",
+                "inherits": "^2.0.1",
+                "md5.js": "^1.3.4",
+                "ripemd160": "^2.0.1",
+                "sha.js": "^2.4.0"
+            }
+        },
+        "node_modules/create-hmac": {
+            "version": "1.1.7",
+            "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+            "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "cipher-base": "^1.0.3",
+                "create-hash": "^1.1.0",
+                "inherits": "^2.0.1",
+                "ripemd160": "^2.0.0",
+                "safe-buffer": "^5.0.1",
+                "sha.js": "^2.4.8"
+            }
+        },
+        "node_modules/croner": {
+            "version": "4.1.97",
+            "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz",
+            "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==",
+            "license": "MIT"
+        },
+        "node_modules/cross-spawn": {
+            "version": "7.0.6",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+            "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+            "license": "MIT",
+            "dependencies": {
+                "path-key": "^3.1.0",
+                "shebang-command": "^2.0.0",
+                "which": "^2.0.1"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/cross-spawn-windows-exe": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/cross-spawn-windows-exe/-/cross-spawn-windows-exe-1.2.0.tgz",
+            "integrity": "sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "individual",
+                    "url": "https://github.com/sponsors/malept"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/subscription/pkg/npm-cross-spawn-windows-exe?utm_medium=referral&utm_source=npm_fund"
+                }
+            ],
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@malept/cross-spawn-promise": "^1.1.0",
+                "is-wsl": "^2.2.0",
+                "which": "^2.0.2"
+            },
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/crypto-browserify": {
+            "version": "3.12.1",
+            "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
+            "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "browserify-cipher": "^1.0.1",
+                "browserify-sign": "^4.2.3",
+                "create-ecdh": "^4.0.4",
+                "create-hash": "^1.2.0",
+                "create-hmac": "^1.1.7",
+                "diffie-hellman": "^5.0.3",
+                "hash-base": "~3.0.4",
+                "inherits": "^2.0.4",
+                "pbkdf2": "^3.1.2",
+                "public-encrypt": "^4.0.3",
+                "randombytes": "^2.1.0",
+                "randomfill": "^1.0.4"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/css-select": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+            "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-what": "^6.0.1",
+                "domhandler": "^4.3.1",
+                "domutils": "^2.8.0",
+                "nth-check": "^2.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/css-what": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+            "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/culvert": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz",
+            "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==",
+            "license": "MIT"
+        },
+        "node_modules/dash-ast": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+            "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+            "dev": true,
+            "license": "Apache-2.0"
+        },
+        "node_modules/data-uri-to-buffer": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
+            "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/date-fns": {
+            "version": "2.30.0",
+            "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+            "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+            "license": "MIT",
+            "dependencies": {
+                "@babel/runtime": "^7.21.0"
+            },
+            "engines": {
+                "node": ">=0.11"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/date-fns"
+            }
+        },
+        "node_modules/date-format": {
+            "version": "4.0.14",
+            "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz",
+            "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/date-time": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz",
+            "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==",
+            "license": "MIT",
+            "dependencies": {
+                "time-zone": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/dayjs": {
+            "version": "1.11.13",
+            "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+            "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
+            "license": "MIT"
+        },
+        "node_modules/debug": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+            "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.3"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/decompress-response": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+            "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+            "license": "MIT",
+            "dependencies": {
+                "mimic-response": "^3.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/decompress-response/node_modules/mimic-response": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+            "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/deep-extend": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+            "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/defer-to-connect": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+            "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/define-data-property": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+            "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-define-property": "^1.0.0",
+                "es-errors": "^1.3.0",
+                "gopd": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/define-properties": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+            "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "define-data-property": "^1.0.1",
+                "has-property-descriptors": "^1.0.0",
+                "object-keys": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/defined": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz",
+            "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==",
+            "dev": true,
+            "license": "MIT",
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/degenerator": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+            "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ast-types": "^0.13.4",
+                "escodegen": "^2.1.0",
+                "esprima": "^4.0.1"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/delegates": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+            "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/depd": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+            "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/deps-sort": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz",
+            "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "JSONStream": "^1.0.3",
+                "shasum-object": "^1.0.0",
+                "subarg": "^1.0.0",
+                "through2": "^2.0.0"
+            },
+            "bin": {
+                "deps-sort": "bin/cmd.js"
+            }
+        },
+        "node_modules/des.js": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
+            "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "minimalistic-assert": "^1.0.0"
+            }
+        },
+        "node_modules/destroy": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+            "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8",
+                "npm": "1.2.8000 || >= 1.4.16"
+            }
+        },
+        "node_modules/detect-libc": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+            "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
+            "license": "Apache-2.0",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/detect-node": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+            "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/detective": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz",
+            "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "acorn-node": "^1.8.2",
+                "defined": "^1.0.0",
+                "minimist": "^1.2.6"
+            },
+            "bin": {
+                "detective": "bin/detective.js"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/dicer": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
+            "integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
+            "dependencies": {
+                "readable-stream": "1.1.x",
+                "streamsearch": "0.1.2"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/dicer/node_modules/isarray": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+            "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+            "license": "MIT"
+        },
+        "node_modules/dicer/node_modules/readable-stream": {
+            "version": "1.1.14",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+            "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+            "license": "MIT",
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.1",
+                "isarray": "0.0.1",
+                "string_decoder": "~0.10.x"
+            }
+        },
+        "node_modules/dicer/node_modules/string_decoder": {
+            "version": "0.10.31",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+            "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+            "license": "MIT"
+        },
+        "node_modules/diffie-hellman": {
+            "version": "5.0.3",
+            "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+            "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^4.1.0",
+                "miller-rabin": "^4.0.0",
+                "randombytes": "^2.0.0"
+            }
+        },
+        "node_modules/diffie-hellman/node_modules/bn.js": {
+            "version": "4.12.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
+            "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/dir-compare": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz",
+            "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "buffer-equal": "^1.0.0",
+                "minimatch": "^3.0.4"
+            }
+        },
+        "node_modules/dom-converter": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+            "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "utila": "~0.4"
+            }
+        },
+        "node_modules/dom-serializer": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+            "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "domelementtype": "^2.0.1",
+                "domhandler": "^4.2.0",
+                "entities": "^2.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+            }
+        },
+        "node_modules/domain-browser": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+            "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4",
+                "npm": ">=1.2"
+            }
+        },
+        "node_modules/domelementtype": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+            "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ],
+            "license": "BSD-2-Clause"
+        },
+        "node_modules/domhandler": {
+            "version": "4.3.1",
+            "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+            "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "domelementtype": "^2.2.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domhandler?sponsor=1"
+            }
+        },
+        "node_modules/domutils": {
+            "version": "2.8.0",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+            "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "dom-serializer": "^1.0.1",
+                "domelementtype": "^2.2.0",
+                "domhandler": "^4.2.0"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domutils?sponsor=1"
+            }
+        },
+        "node_modules/dot-case": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+            "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "no-case": "^3.0.4",
+                "tslib": "^2.0.3"
+            }
+        },
+        "node_modules/dunder-proto": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+            "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+            "license": "MIT",
+            "dependencies": {
+                "call-bind-apply-helpers": "^1.0.1",
+                "es-errors": "^1.3.0",
+                "gopd": "^1.2.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/duplexer2": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+            "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "dependencies": {
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/ee-first": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+            "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+            "license": "MIT"
+        },
+        "node_modules/electron": {
+            "version": "35.5.1",
+            "resolved": "https://registry.npmjs.org/electron/-/electron-35.5.1.tgz",
+            "integrity": "sha512-kkbGXz56safvXcxqAZyMS2nJGYK9NFG/iKOJsAO5e0HPH8y3EnV4Fi87tvbfFpeLiaruFS+eN0YFy6f1StpSgQ==",
+            "dev": true,
+            "hasInstallScript": true,
+            "license": "MIT",
+            "dependencies": {
+                "@electron/get": "^2.0.0",
+                "@types/node": "^22.7.7",
+                "extract-zip": "^2.0.1"
+            },
+            "bin": {
+                "electron": "cli.js"
+            },
+            "engines": {
+                "node": ">= 12.20.55"
+            }
+        },
+        "node_modules/electron-is-dev": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz",
+            "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==",
+            "license": "MIT"
+        },
+        "node_modules/electron-packager": {
+            "version": "17.1.2",
+            "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-17.1.2.tgz",
+            "integrity": "sha512-XofXdikjYI7MVBcnXeoOvRR+yFFFHOLs3J7PF5KYQweigtgLshcH4W660PsvHr4lYZ03JBpLyEcUB8DzHZ+BNw==",
+            "deprecated": "Please use @electron/packager moving forward. There is no API change, just a package name change",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "@electron/asar": "^3.2.1",
+                "@electron/get": "^2.0.0",
+                "@electron/notarize": "^1.2.3",
+                "@electron/osx-sign": "^1.0.5",
+                "@electron/universal": "^1.3.2",
+                "cross-spawn-windows-exe": "^1.2.0",
+                "debug": "^4.0.1",
+                "extract-zip": "^2.0.0",
+                "filenamify": "^4.1.0",
+                "fs-extra": "^11.1.0",
+                "galactus": "^1.0.0",
+                "get-package-info": "^1.0.0",
+                "junk": "^3.1.0",
+                "parse-author": "^2.0.0",
+                "plist": "^3.0.0",
+                "rcedit": "^3.0.1",
+                "resolve": "^1.1.6",
+                "semver": "^7.1.3",
+                "yargs-parser": "^21.1.1"
+            },
+            "bin": {
+                "electron-packager": "bin/electron-packager.js"
+            },
+            "engines": {
+                "node": ">= 14.17.5"
+            },
+            "funding": {
+                "url": "https://github.com/electron/electron-packager?sponsor=1"
+            }
+        },
+        "node_modules/electron-packager/node_modules/fs-extra": {
+            "version": "11.3.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+            "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=14.14"
+            }
+        },
+        "node_modules/electron-packager/node_modules/semver": {
+            "version": "7.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+            "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+            "dev": true,
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/electron-reloader": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/electron-reloader/-/electron-reloader-1.2.3.tgz",
+            "integrity": "sha512-aDnACAzNg0QvQhzw7LYOx/nVS10mEtbuG6M0QQvNQcLnJEwFs6is+EGRCnM+KQlQ4KcTbdwnt07nd7ZjHpY4iw==",
+            "license": "MIT",
+            "dependencies": {
+                "chalk": "^4.1.0",
+                "chokidar": "^3.5.0",
+                "date-time": "^3.1.0",
+                "electron-is-dev": "^1.2.0",
+                "find-up": "^5.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/electron-to-chromium": {
+            "version": "1.5.170",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz",
+            "integrity": "sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/electron/node_modules/@types/node": {
+            "version": "22.15.32",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.32.tgz",
+            "integrity": "sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "undici-types": "~6.21.0"
+            }
+        },
+        "node_modules/electron/node_modules/undici-types": {
+            "version": "6.21.0",
+            "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+            "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/elliptic": {
+            "version": "6.6.1",
+            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
+            "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^4.11.9",
+                "brorand": "^1.1.0",
+                "hash.js": "^1.0.0",
+                "hmac-drbg": "^1.0.1",
+                "inherits": "^2.0.4",
+                "minimalistic-assert": "^1.0.1",
+                "minimalistic-crypto-utils": "^1.0.1"
+            }
+        },
+        "node_modules/elliptic/node_modules/bn.js": {
+            "version": "4.12.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
+            "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/encodeurl": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+            "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/encoding": {
+            "version": "0.1.13",
+            "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+            "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "iconv-lite": "^0.6.2"
+            }
+        },
+        "node_modules/end-of-stream": {
+            "version": "1.4.5",
+            "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+            "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+            "license": "MIT",
+            "dependencies": {
+                "once": "^1.4.0"
+            }
+        },
+        "node_modules/engine.io": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.2.tgz",
+            "integrity": "sha512-C4JjGQZLY3kWlIDx0BQNKizbrfpb7NahxDztGdN5jrPK2ghmXiNDN+E/t0JzDeNRZxPVaszxEng42Pmj27X/0w==",
+            "license": "MIT",
+            "dependencies": {
+                "accepts": "~1.3.4",
+                "base64id": "2.0.0",
+                "cookie": "~0.4.1",
+                "debug": "~4.1.0",
+                "engine.io-parser": "~2.2.0",
+                "ws": "~7.5.10"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/engine.io-client": {
+            "version": "3.5.4",
+            "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.4.tgz",
+            "integrity": "sha512-ydc8uuMMDxC5KCKNJN3zZKYJk2sgyTuTZQ7Aj1DJSsLKAcizA/PzWivw8fZMIjJVBo2CJOYzntv4FSjY/Lr//g==",
+            "license": "MIT",
+            "dependencies": {
+                "component-emitter": "~1.3.0",
+                "component-inherit": "0.0.3",
+                "debug": "~3.1.0",
+                "engine.io-parser": "~2.2.0",
+                "has-cors": "1.1.0",
+                "indexof": "0.0.1",
+                "parseqs": "0.0.6",
+                "parseuri": "0.0.6",
+                "ws": "~7.5.10",
+                "xmlhttprequest-ssl": "~1.6.2",
+                "yeast": "0.1.2"
+            }
+        },
+        "node_modules/engine.io-client/node_modules/debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/engine.io-client/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/engine.io-parser": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
+            "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
+            "license": "MIT",
+            "dependencies": {
+                "after": "0.8.2",
+                "arraybuffer.slice": "~0.0.7",
+                "base64-arraybuffer": "0.1.4",
+                "blob": "0.0.5",
+                "has-binary2": "~1.0.2"
+            }
+        },
+        "node_modules/engine.io/node_modules/cookie": {
+            "version": "0.4.2",
+            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+            "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/engine.io/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/enhanced-resolve": {
+            "version": "5.18.1",
+            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+            "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "graceful-fs": "^4.2.4",
+                "tapable": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/enquirer": {
+            "version": "2.3.6",
+            "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+            "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-colors": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=8.6"
+            }
+        },
+        "node_modules/entities": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+            "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/env-paths": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+            "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+            "devOptional": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/envinfo": {
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
+            "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "envinfo": "dist/cli.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/err-code": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+            "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/error-ex": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+            "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-arrayish": "^0.2.1"
+            }
+        },
+        "node_modules/es-define-property": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+            "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-errors": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+            "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-module-lexer": {
+            "version": "1.7.0",
+            "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+            "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/es-object-atoms": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+            "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es6-error": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+            "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/escalade": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+            "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/escape-html": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+            "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+            "license": "MIT"
+        },
+        "node_modules/escape-string-regexp": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+            "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/escodegen": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+            "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "esprima": "^4.0.1",
+                "estraverse": "^5.2.0",
+                "esutils": "^2.0.2"
+            },
+            "bin": {
+                "escodegen": "bin/escodegen.js",
+                "esgenerate": "bin/esgenerate.js"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "optionalDependencies": {
+                "source-map": "~0.6.1"
+            }
+        },
+        "node_modules/escodegen/node_modules/source-map": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+            "license": "BSD-3-Clause",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/eslint-scope": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+            "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "esrecurse": "^4.3.0",
+                "estraverse": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/eslint-scope/node_modules/estraverse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esprima": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+            "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+            "license": "BSD-2-Clause",
+            "bin": {
+                "esparse": "bin/esparse.js",
+                "esvalidate": "bin/esvalidate.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/esrecurse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+            "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "estraverse": "^5.2.0"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "license": "BSD-2-Clause",
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esutils": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+            "license": "BSD-2-Clause",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/etag": {
+            "version": "1.8.1",
+            "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+            "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/event-target-shim": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+            "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/eventemitter2": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz",
+            "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==",
+            "license": "MIT"
+        },
+        "node_modules/events": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+            "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.x"
+            }
+        },
+        "node_modules/evp_bytestokey": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+            "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "md5.js": "^1.3.4",
+                "safe-buffer": "^5.1.1"
+            }
+        },
+        "node_modules/expand-template": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+            "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+            "license": "(MIT OR WTFPL)",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/express": {
+            "version": "4.21.2",
+            "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+            "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+            "license": "MIT",
+            "dependencies": {
+                "accepts": "~1.3.8",
+                "array-flatten": "1.1.1",
+                "body-parser": "1.20.3",
+                "content-disposition": "0.5.4",
+                "content-type": "~1.0.4",
+                "cookie": "0.7.1",
+                "cookie-signature": "1.0.6",
+                "debug": "2.6.9",
+                "depd": "2.0.0",
+                "encodeurl": "~2.0.0",
+                "escape-html": "~1.0.3",
+                "etag": "~1.8.1",
+                "finalhandler": "1.3.1",
+                "fresh": "0.5.2",
+                "http-errors": "2.0.0",
+                "merge-descriptors": "1.0.3",
+                "methods": "~1.1.2",
+                "on-finished": "2.4.1",
+                "parseurl": "~1.3.3",
+                "path-to-regexp": "0.1.12",
+                "proxy-addr": "~2.0.7",
+                "qs": "6.13.0",
+                "range-parser": "~1.2.1",
+                "safe-buffer": "5.2.1",
+                "send": "0.19.0",
+                "serve-static": "1.16.2",
+                "setprototypeof": "1.2.0",
+                "statuses": "2.0.1",
+                "type-is": "~1.6.18",
+                "utils-merge": "1.0.1",
+                "vary": "~1.1.2"
+            },
+            "engines": {
+                "node": ">= 0.10.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/express"
+            }
+        },
+        "node_modules/express-static": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/express-static/-/express-static-1.2.6.tgz",
+            "integrity": "sha512-pmp8fSe+bCxGCTk5+X6HzIF2APYMvrAq3Y7sT/WOELc0JZZxJhMTVgCbxcoUgMRBSqnQ9EfTw/Uv3J1ONoIAuA==",
+            "license": "MIT",
+            "dependencies": {
+                "mime2": "latest"
+            },
+            "bin": {
+                "express-static": "bin/server.js"
+            }
+        },
+        "node_modules/express/node_modules/cookie": {
+            "version": "0.7.1",
+            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+            "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/express/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/express/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/extract-zip": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+            "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "debug": "^4.1.1",
+                "get-stream": "^5.1.0",
+                "yauzl": "^2.10.0"
+            },
+            "bin": {
+                "extract-zip": "cli.js"
+            },
+            "engines": {
+                "node": ">= 10.17.0"
+            },
+            "optionalDependencies": {
+                "@types/yauzl": "^2.9.1"
+            }
+        },
+        "node_modules/extrareqp2": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/extrareqp2/-/extrareqp2-1.0.0.tgz",
+            "integrity": "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==",
+            "license": "MIT",
+            "dependencies": {
+                "follow-redirects": "^1.14.0"
+            }
+        },
+        "node_modules/fast-deep-equal": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+            "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/fast-json-patch": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
+            "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==",
+            "license": "MIT"
+        },
+        "node_modules/fast-safe-stringify": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+            "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/fast-uri": {
+            "version": "3.0.6",
+            "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+            "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fastify"
+                },
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/fastify"
+                }
+            ],
+            "license": "BSD-3-Clause"
+        },
+        "node_modules/fastest-levenshtein": {
+            "version": "1.0.16",
+            "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+            "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 4.9.1"
+            }
+        },
+        "node_modules/fclone": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz",
+            "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==",
+            "license": "MIT"
+        },
+        "node_modules/fd-slicer": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+            "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "pend": "~1.2.0"
+            }
+        },
+        "node_modules/fd-slicer2": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/fd-slicer2/-/fd-slicer2-1.2.0.tgz",
+            "integrity": "sha512-3lBUNUckhMZduCc4g+Pw4Ve16LD9vpX9b8qUkkKq2mgDRLYWzblszZH2luADnJqjJe+cypngjCuKRm/IW12rRw==",
+            "license": "MIT",
+            "dependencies": {
+                "pend": "^1.2.0"
+            }
+        },
+        "node_modules/file-type": {
+            "version": "16.5.4",
+            "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
+            "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
+            "license": "MIT",
+            "dependencies": {
+                "readable-web-to-node-stream": "^3.0.0",
+                "strtok3": "^6.2.4",
+                "token-types": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sindresorhus/file-type?sponsor=1"
+            }
+        },
+        "node_modules/file-uri-to-path": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+            "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+            "license": "MIT"
+        },
+        "node_modules/filename-reserved-regex": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+            "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/filenamify": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
+            "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "filename-reserved-regex": "^2.0.0",
+                "strip-outer": "^1.0.1",
+                "trim-repeated": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/fill-range": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+            "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+            "license": "MIT",
+            "dependencies": {
+                "to-regex-range": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/finalhandler": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+            "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "2.6.9",
+                "encodeurl": "~2.0.0",
+                "escape-html": "~1.0.3",
+                "on-finished": "2.4.1",
+                "parseurl": "~1.3.3",
+                "statuses": "2.0.1",
+                "unpipe": "~1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/finalhandler/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/finalhandler/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/find-up": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+            "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+            "license": "MIT",
+            "dependencies": {
+                "locate-path": "^6.0.0",
+                "path-exists": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/flat": {
+            "version": "5.0.2",
+            "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+            "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "bin": {
+                "flat": "cli.js"
+            }
+        },
+        "node_modules/flatted": {
+            "version": "3.3.3",
+            "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+            "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+            "license": "ISC"
+        },
+        "node_modules/flora-colossus": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz",
+            "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.3.4",
+                "fs-extra": "^10.1.0"
+            },
+            "engines": {
+                "node": ">= 12"
+            }
+        },
+        "node_modules/flushwritable": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/flushwritable/-/flushwritable-1.0.0.tgz",
+            "integrity": "sha512-3VELfuWCLVzt5d2Gblk8qcqFro6nuwvxwMzHaENVDHI7rxcBRtMCwTk/E9FXcgh+82DSpavPNDueA9+RxXJoFg==",
+            "license": "MIT"
+        },
+        "node_modules/follow-redirects": {
+            "version": "1.15.9",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+            "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+            "funding": [
+                {
+                    "type": "individual",
+                    "url": "https://github.com/sponsors/RubenVerborgh"
+                }
+            ],
+            "license": "MIT",
+            "engines": {
+                "node": ">=4.0"
+            },
+            "peerDependenciesMeta": {
+                "debug": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/for-each": {
+            "version": "0.3.5",
+            "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+            "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-callable": "^1.2.7"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/forwarded": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+            "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/fresh": {
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+            "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/fs-constants": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+            "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+            "license": "MIT"
+        },
+        "node_modules/fs-extra": {
+            "version": "10.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+            "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+            "license": "MIT",
+            "dependencies": {
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^6.0.1",
+                "universalify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/fs-minipass": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+            "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+            "license": "ISC",
+            "dependencies": {
+                "minipass": "^3.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/fs.realpath": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+            "devOptional": true,
+            "license": "ISC"
+        },
+        "node_modules/fsevents": {
+            "version": "2.3.3",
+            "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+            "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+            "hasInstallScript": true,
+            "license": "MIT",
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+            }
+        },
+        "node_modules/function-bind": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+            "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+            "license": "MIT",
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/galactus": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz",
+            "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.3.4",
+                "flora-colossus": "^2.0.0",
+                "fs-extra": "^10.1.0"
+            },
+            "engines": {
+                "node": ">= 12"
+            }
+        },
+        "node_modules/gauge": {
+            "version": "4.0.4",
+            "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
+            "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
+            "deprecated": "This package is no longer supported.",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "aproba": "^1.0.3 || ^2.0.0",
+                "color-support": "^1.1.3",
+                "console-control-strings": "^1.1.0",
+                "has-unicode": "^2.0.1",
+                "signal-exit": "^3.0.7",
+                "string-width": "^4.2.3",
+                "strip-ansi": "^6.0.1",
+                "wide-align": "^1.1.5"
+            },
+            "engines": {
+                "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+            }
+        },
+        "node_modules/gensync": {
+            "version": "1.0.0-beta.2",
+            "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+            "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/get-assigned-identifiers": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+            "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+            "dev": true,
+            "license": "Apache-2.0"
+        },
+        "node_modules/get-intrinsic": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+            "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+            "license": "MIT",
+            "dependencies": {
+                "call-bind-apply-helpers": "^1.0.2",
+                "es-define-property": "^1.0.1",
+                "es-errors": "^1.3.0",
+                "es-object-atoms": "^1.1.1",
+                "function-bind": "^1.1.2",
+                "get-proto": "^1.0.1",
+                "gopd": "^1.2.0",
+                "has-symbols": "^1.1.0",
+                "hasown": "^2.0.2",
+                "math-intrinsics": "^1.1.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/get-package-info": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz",
+            "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bluebird": "^3.1.1",
+                "debug": "^2.2.0",
+                "lodash.get": "^4.0.0",
+                "read-pkg-up": "^2.0.0"
+            },
+            "engines": {
+                "node": ">= 4.0"
+            }
+        },
+        "node_modules/get-package-info/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/get-package-info/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/get-proto": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+            "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+            "license": "MIT",
+            "dependencies": {
+                "dunder-proto": "^1.0.1",
+                "es-object-atoms": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/get-ready": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/get-ready/-/get-ready-1.0.0.tgz",
+            "integrity": "sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==",
+            "license": "MIT"
+        },
+        "node_modules/get-stream": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+            "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "pump": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/get-uri": {
+            "version": "6.0.4",
+            "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz",
+            "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==",
+            "license": "MIT",
+            "dependencies": {
+                "basic-ftp": "^5.0.2",
+                "data-uri-to-buffer": "^6.0.2",
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/git-node-fs": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz",
+            "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==",
+            "license": "MIT"
+        },
+        "node_modules/git-sha1": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz",
+            "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==",
+            "license": "MIT"
+        },
+        "node_modules/github-from-package": {
+            "version": "0.0.0",
+            "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+            "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+            "license": "MIT"
+        },
+        "node_modules/glob": {
+            "version": "7.2.3",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+            "deprecated": "Glob versions prior to v9 are no longer supported",
+            "devOptional": true,
+            "license": "ISC",
+            "dependencies": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.1.1",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/glob-parent": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+            "license": "ISC",
+            "dependencies": {
+                "is-glob": "^4.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/glob-to-regexp": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+            "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+            "dev": true,
+            "license": "BSD-2-Clause"
+        },
+        "node_modules/global-agent": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
+            "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "optional": true,
+            "dependencies": {
+                "boolean": "^3.0.1",
+                "es6-error": "^4.1.1",
+                "matcher": "^3.0.0",
+                "roarr": "^2.15.3",
+                "semver": "^7.3.2",
+                "serialize-error": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=10.0"
+            }
+        },
+        "node_modules/global-agent/node_modules/semver": {
+            "version": "7.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+            "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+            "dev": true,
+            "license": "ISC",
+            "optional": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/globals": {
+            "version": "11.12.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+            "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/globalthis": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+            "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "define-properties": "^1.2.1",
+                "gopd": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/gm": {
+            "version": "1.25.1",
+            "resolved": "https://registry.npmjs.org/gm/-/gm-1.25.1.tgz",
+            "integrity": "sha512-jgcs2vKir9hFogGhXIfs0ODhJTfIrbECCehg38tqFgHm8zqXx7kAJyCYAFK4jTjx71AxrkFtkJBawbAxYUPX9A==",
+            "deprecated": "The gm module has been sunset. Please migrate to an alternative. https://github.com/aheckmann/gm?tab=readme-ov-file#2025-02-24-this-project-is-not-maintained",
+            "license": "MIT",
+            "dependencies": {
+                "array-parallel": "~0.1.3",
+                "array-series": "~0.1.5",
+                "cross-spawn": "^7.0.5",
+                "debug": "^3.1.0"
+            },
+            "engines": {
+                "node": ">=14"
+            }
+        },
+        "node_modules/gm/node_modules/debug": {
+            "version": "3.2.7",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+            "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/gopd": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+            "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/got": {
+            "version": "11.8.6",
+            "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
+            "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@sindresorhus/is": "^4.0.0",
+                "@szmarczak/http-timer": "^4.0.5",
+                "@types/cacheable-request": "^6.0.1",
+                "@types/responselike": "^1.0.0",
+                "cacheable-lookup": "^5.0.3",
+                "cacheable-request": "^7.0.2",
+                "decompress-response": "^6.0.0",
+                "http2-wrapper": "^1.0.0-beta.5.2",
+                "lowercase-keys": "^2.0.0",
+                "p-cancelable": "^2.0.0",
+                "responselike": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10.19.0"
+            },
+            "funding": {
+                "url": "https://github.com/sindresorhus/got?sponsor=1"
+            }
+        },
+        "node_modules/graceful-fs": {
+            "version": "4.2.11",
+            "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+            "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+            "license": "ISC"
+        },
+        "node_modules/has-binary2": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+            "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+            "license": "MIT",
+            "dependencies": {
+                "isarray": "2.0.1"
+            }
+        },
+        "node_modules/has-binary2/node_modules/isarray": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+            "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
+            "license": "MIT"
+        },
+        "node_modules/has-cors": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+            "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==",
+            "license": "MIT"
+        },
+        "node_modules/has-flag": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/has-property-descriptors": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+            "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-define-property": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/has-symbols": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+            "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/has-tostringtag": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+            "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-symbols": "^1.0.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/has-unicode": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+            "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/hash-base": {
+            "version": "3.0.5",
+            "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz",
+            "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.4",
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/hash.js": {
+            "version": "1.1.7",
+            "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+            "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "minimalistic-assert": "^1.0.1"
+            }
+        },
+        "node_modules/hasown": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+            "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+            "license": "MIT",
+            "dependencies": {
+                "function-bind": "^1.1.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/he": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+            "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "he": "bin/he"
+            }
+        },
+        "node_modules/hmac-drbg": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+            "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "hash.js": "^1.0.3",
+                "minimalistic-assert": "^1.0.0",
+                "minimalistic-crypto-utils": "^1.0.1"
+            }
+        },
+        "node_modules/hosted-git-info": {
+            "version": "2.8.9",
+            "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+            "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/html-minifier-terser": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+            "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "camel-case": "^4.1.2",
+                "clean-css": "^5.2.2",
+                "commander": "^8.3.0",
+                "he": "^1.2.0",
+                "param-case": "^3.0.4",
+                "relateurl": "^0.2.7",
+                "terser": "^5.10.0"
+            },
+            "bin": {
+                "html-minifier-terser": "cli.js"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/html-minifier-terser/node_modules/commander": {
+            "version": "8.3.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+            "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 12"
+            }
+        },
+        "node_modules/html-webpack-plugin": {
+            "version": "5.6.3",
+            "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz",
+            "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/html-minifier-terser": "^6.0.0",
+                "html-minifier-terser": "^6.0.2",
+                "lodash": "^4.17.21",
+                "pretty-error": "^4.0.0",
+                "tapable": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/html-webpack-plugin"
+            },
+            "peerDependencies": {
+                "@rspack/core": "0.x || 1.x",
+                "webpack": "^5.20.0"
+            },
+            "peerDependenciesMeta": {
+                "@rspack/core": {
+                    "optional": true
+                },
+                "webpack": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/htmlescape": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+            "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/htmlparser2": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+            "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+            "dev": true,
+            "funding": [
+                "https://github.com/fb55/htmlparser2?sponsor=1",
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "domelementtype": "^2.0.1",
+                "domhandler": "^4.0.0",
+                "domutils": "^2.5.2",
+                "entities": "^2.0.0"
+            }
+        },
+        "node_modules/http-cache-semantics": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
+            "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
+            "devOptional": true,
+            "license": "BSD-2-Clause"
+        },
+        "node_modules/http-errors": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+            "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+            "license": "MIT",
+            "dependencies": {
+                "depd": "2.0.0",
+                "inherits": "2.0.4",
+                "setprototypeof": "1.2.0",
+                "statuses": "2.0.1",
+                "toidentifier": "1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/http-proxy-agent": {
+            "version": "7.0.2",
+            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+            "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^7.1.0",
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/http2-wrapper": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
+            "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "quick-lru": "^5.1.1",
+                "resolve-alpn": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=10.19.0"
+            }
+        },
+        "node_modules/https-browserify": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+            "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/https-proxy-agent": {
+            "version": "7.0.6",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+            "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^7.1.2",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/humanize-ms": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+            "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "ms": "^2.0.0"
+            }
+        },
+        "node_modules/iconv-lite": {
+            "version": "0.6.3",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+            "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/ieee754": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+            "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "BSD-3-Clause"
+        },
+        "node_modules/ignore-by-default": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+            "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/image-size": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
+            "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
+            "license": "MIT",
+            "dependencies": {
+                "queue": "6.0.2"
+            },
+            "bin": {
+                "image-size": "bin/image-size.js"
+            },
+            "engines": {
+                "node": ">=16.x"
+            }
+        },
+        "node_modules/import-local": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+            "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "pkg-dir": "^4.2.0",
+                "resolve-cwd": "^3.0.0"
+            },
+            "bin": {
+                "import-local-fixture": "fixtures/cli.js"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/imurmurhash": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+            "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.8.19"
+            }
+        },
+        "node_modules/indent-string": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+            "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/indexof": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+            "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
+        },
+        "node_modules/infer-owner": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+            "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/inflight": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+            "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+            "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.",
+            "devOptional": true,
+            "license": "ISC",
+            "dependencies": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/inherits": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+            "license": "ISC"
+        },
+        "node_modules/ini": {
+            "version": "1.3.8",
+            "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+            "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+            "license": "ISC"
+        },
+        "node_modules/inline-source-map": {
+            "version": "0.6.3",
+            "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.3.tgz",
+            "integrity": "sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "source-map": "~0.5.3"
+            }
+        },
+        "node_modules/insert-module-globals": {
+            "version": "7.2.1",
+            "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz",
+            "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "acorn-node": "^1.5.2",
+                "combine-source-map": "^0.8.0",
+                "concat-stream": "^1.6.1",
+                "is-buffer": "^1.1.0",
+                "JSONStream": "^1.0.3",
+                "path-is-absolute": "^1.0.1",
+                "process": "~0.11.0",
+                "through2": "^2.0.0",
+                "undeclared-identifiers": "^1.1.2",
+                "xtend": "^4.0.0"
+            },
+            "bin": {
+                "insert-module-globals": "bin/cmd.js"
+            }
+        },
+        "node_modules/interpret": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+            "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/ip-address": {
+            "version": "9.0.5",
+            "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+            "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+            "license": "MIT",
+            "dependencies": {
+                "jsbn": "1.1.0",
+                "sprintf-js": "^1.1.3"
+            },
+            "engines": {
+                "node": ">= 12"
+            }
+        },
+        "node_modules/ip-address/node_modules/sprintf-js": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+            "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+            "license": "BSD-3-Clause"
+        },
+        "node_modules/ipaddr.js": {
+            "version": "1.9.1",
+            "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+            "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/is-arguments": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+            "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "has-tostringtag": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-arrayish": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+            "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/is-binary-path": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+            "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+            "license": "MIT",
+            "dependencies": {
+                "binary-extensions": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/is-callable": {
+            "version": "1.2.7",
+            "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+            "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-core-module": {
+            "version": "2.16.1",
+            "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+            "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+            "license": "MIT",
+            "dependencies": {
+                "hasown": "^2.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-docker": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+            "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "is-docker": "cli.js"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/is-extglob": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+            "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-fullwidth-code-point": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+            "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/is-generator-function": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+            "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.3",
+                "get-proto": "^1.0.0",
+                "has-tostringtag": "^1.0.2",
+                "safe-regex-test": "^1.1.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-glob": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+            "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+            "license": "MIT",
+            "dependencies": {
+                "is-extglob": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-lambda": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
+            "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/is-number": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+            "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/is-plain-object": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+            "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "isobject": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-regex": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+            "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "gopd": "^1.2.0",
+                "has-tostringtag": "^1.0.2",
+                "hasown": "^2.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-typed-array": {
+            "version": "1.1.15",
+            "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+            "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "which-typed-array": "^1.1.16"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-wsl": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+            "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-docker": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+            "license": "MIT"
+        },
+        "node_modules/isbinaryfile": {
+            "version": "4.0.10",
+            "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
+            "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 8.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/gjtorikian/"
+            }
+        },
+        "node_modules/isexe": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+            "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+            "license": "ISC"
+        },
+        "node_modules/isobject": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+            "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/jest-worker": {
+            "version": "27.5.1",
+            "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+            "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/node": "*",
+                "merge-stream": "^2.0.0",
+                "supports-color": "^8.0.0"
+            },
+            "engines": {
+                "node": ">= 10.13.0"
+            }
+        },
+        "node_modules/jest-worker/node_modules/supports-color": {
+            "version": "8.1.1",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+            "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-flag": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/supports-color?sponsor=1"
+            }
+        },
+        "node_modules/js-git": {
+            "version": "0.7.8",
+            "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz",
+            "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==",
+            "license": "MIT",
+            "dependencies": {
+                "bodec": "^0.1.0",
+                "culvert": "^0.1.2",
+                "git-sha1": "^0.1.2",
+                "pako": "^0.2.5"
+            }
+        },
+        "node_modules/js-git/node_modules/pako": {
+            "version": "0.2.9",
+            "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+            "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
+            "license": "MIT"
+        },
+        "node_modules/js-tokens": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+            "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/js-yaml": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+            "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+            "license": "MIT",
+            "dependencies": {
+                "argparse": "^2.0.1"
+            },
+            "bin": {
+                "js-yaml": "bin/js-yaml.js"
+            }
+        },
+        "node_modules/jsbn": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+            "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+            "license": "MIT"
+        },
+        "node_modules/jsesc": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+            "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "jsesc": "bin/jsesc"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/json-buffer": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+            "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/json-parse-even-better-errors": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+            "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/json-schema-traverse": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+            "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/json-stringify-safe": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+            "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/json5": {
+            "version": "2.2.3",
+            "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+            "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "json5": "lib/cli.js"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/jsonfile": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+            "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+            "license": "MIT",
+            "dependencies": {
+                "universalify": "^2.0.0"
+            },
+            "optionalDependencies": {
+                "graceful-fs": "^4.1.6"
+            }
+        },
+        "node_modules/jsonparse": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+            "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+            "dev": true,
+            "engines": [
+                "node >= 0.2.0"
+            ],
+            "license": "MIT"
+        },
+        "node_modules/JSONStream": {
+            "version": "1.3.5",
+            "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+            "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+            "dev": true,
+            "license": "(MIT OR Apache-2.0)",
+            "dependencies": {
+                "jsonparse": "^1.2.0",
+                "through": ">=2.2.7 <3"
+            },
+            "bin": {
+                "JSONStream": "bin.js"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/junk": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
+            "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/keyv": {
+            "version": "4.5.4",
+            "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+            "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "json-buffer": "3.0.1"
+            }
+        },
+        "node_modules/kind-of": {
+            "version": "6.0.3",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+            "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/labeled-stream-splicer": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz",
+            "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "stream-splicer": "^2.0.0"
+            }
+        },
+        "node_modules/lazy": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz",
+            "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.2.0"
+            }
+        },
+        "node_modules/load-json-file": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+            "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "parse-json": "^2.2.0",
+                "pify": "^2.0.0",
+                "strip-bom": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/load-json-file/node_modules/pify": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+            "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/loader-runner": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+            "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.11.5"
+            }
+        },
+        "node_modules/locate-path": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+            "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+            "license": "MIT",
+            "dependencies": {
+                "p-locate": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/lodash": {
+            "version": "4.17.21",
+            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+            "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+            "license": "MIT"
+        },
+        "node_modules/lodash.debounce": {
+            "version": "4.0.8",
+            "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+            "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.get": {
+            "version": "4.4.2",
+            "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+            "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+            "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/lodash.memoize": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+            "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/log4js": {
+            "version": "6.9.1",
+            "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz",
+            "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==",
+            "license": "Apache-2.0",
+            "dependencies": {
+                "date-format": "^4.0.14",
+                "debug": "^4.3.4",
+                "flatted": "^3.2.7",
+                "rfdc": "^1.3.0",
+                "streamroller": "^3.1.5"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/lower-case": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+            "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "tslib": "^2.0.3"
+            }
+        },
+        "node_modules/lowercase-keys": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+            "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/lru-cache": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+            "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "yallist": "^3.0.2"
+            }
+        },
+        "node_modules/make-fetch-happen": {
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
+            "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "agentkeepalive": "^4.1.3",
+                "cacache": "^15.2.0",
+                "http-cache-semantics": "^4.1.0",
+                "http-proxy-agent": "^4.0.1",
+                "https-proxy-agent": "^5.0.0",
+                "is-lambda": "^1.0.1",
+                "lru-cache": "^6.0.0",
+                "minipass": "^3.1.3",
+                "minipass-collect": "^1.0.2",
+                "minipass-fetch": "^1.3.2",
+                "minipass-flush": "^1.0.5",
+                "minipass-pipeline": "^1.2.4",
+                "negotiator": "^0.6.2",
+                "promise-retry": "^2.0.1",
+                "socks-proxy-agent": "^6.0.0",
+                "ssri": "^8.0.0"
+            },
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/make-fetch-happen/node_modules/agent-base": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+            "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+            "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "@tootallnate/once": "1",
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/make-fetch-happen/node_modules/https-proxy-agent": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+            "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/make-fetch-happen/node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/make-fetch-happen/node_modules/socks-proxy-agent": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
+            "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "agent-base": "^6.0.2",
+                "debug": "^4.3.3",
+                "socks": "^2.6.2"
+            },
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/make-fetch-happen/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/matcher": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+            "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "escape-string-regexp": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/math-intrinsics": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+            "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/md5.js": {
+            "version": "1.3.5",
+            "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+            "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "hash-base": "^3.0.0",
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.1.2"
+            }
+        },
+        "node_modules/media-typer": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+            "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/merge-descriptors": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+            "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+            "license": "MIT",
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/merge-stream": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+            "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/methods": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+            "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/miller-rabin": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+            "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^4.0.0",
+                "brorand": "^1.0.1"
+            },
+            "bin": {
+                "miller-rabin": "bin/miller-rabin"
+            }
+        },
+        "node_modules/miller-rabin/node_modules/bn.js": {
+            "version": "4.12.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
+            "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/mime": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+            "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+            "license": "MIT",
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/mime-db": {
+            "version": "1.52.0",
+            "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+            "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/mime-types": {
+            "version": "2.1.35",
+            "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+            "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+            "license": "MIT",
+            "dependencies": {
+                "mime-db": "1.52.0"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/mime2": {
+            "version": "0.0.11",
+            "resolved": "https://registry.npmjs.org/mime2/-/mime2-0.0.11.tgz",
+            "integrity": "sha512-Ch599Y8U4vUgG9AaQgLEnIdXRRLoZPfjAdWFDLYePBEJS1nsS43H2pzbZn0u8lkbYx+yInuKxLsUEgM3fa9ZLQ==",
+            "license": "MIT"
+        },
+        "node_modules/mimic-response": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+            "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/minimalistic-assert": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+            "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/minimalistic-crypto-utils": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+            "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+            "devOptional": true,
+            "license": "ISC",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/minimist": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+            "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+            "license": "MIT",
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/minipass": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+            "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+            "license": "ISC",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/minipass-collect": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+            "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^3.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/minipass-fetch": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
+            "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^3.1.0",
+                "minipass-sized": "^1.0.3",
+                "minizlib": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "optionalDependencies": {
+                "encoding": "^0.1.12"
+            }
+        },
+        "node_modules/minipass-flush": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+            "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^3.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/minipass-pipeline": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+            "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/minipass-sized": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+            "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/minipass/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC"
+        },
+        "node_modules/minizlib": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+            "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+            "license": "MIT",
+            "dependencies": {
+                "minipass": "^3.0.0",
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/minizlib/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC"
+        },
+        "node_modules/mkdirp": {
+            "version": "0.5.6",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+            "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+            "license": "MIT",
+            "dependencies": {
+                "minimist": "^1.2.6"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/mkdirp-classic": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+            "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+            "license": "MIT"
+        },
+        "node_modules/module-deps": {
+            "version": "6.2.3",
+            "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz",
+            "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "browser-resolve": "^2.0.0",
+                "cached-path-relative": "^1.0.2",
+                "concat-stream": "~1.6.0",
+                "defined": "^1.0.0",
+                "detective": "^5.2.0",
+                "duplexer2": "^0.1.2",
+                "inherits": "^2.0.1",
+                "JSONStream": "^1.0.3",
+                "parents": "^1.0.0",
+                "readable-stream": "^2.0.2",
+                "resolve": "^1.4.0",
+                "stream-combiner2": "^1.1.1",
+                "subarg": "^1.0.0",
+                "through2": "^2.0.0",
+                "xtend": "^4.0.0"
+            },
+            "bin": {
+                "module-deps": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/module-details-from-path": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz",
+            "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==",
+            "license": "MIT"
+        },
+        "node_modules/moment": {
+            "version": "2.30.1",
+            "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+            "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+            "license": "MIT",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/ms": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+            "license": "MIT"
+        },
+        "node_modules/multer": {
+            "version": "1.4.4",
+            "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
+            "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
+            "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.",
+            "license": "MIT",
+            "dependencies": {
+                "append-field": "^1.0.0",
+                "busboy": "^0.2.11",
+                "concat-stream": "^1.5.2",
+                "mkdirp": "^0.5.4",
+                "object-assign": "^4.1.1",
+                "on-finished": "^2.3.0",
+                "type-is": "^1.6.4",
+                "xtend": "^4.0.0"
+            },
+            "engines": {
+                "node": ">= 0.10.0"
+            }
+        },
+        "node_modules/mute-stream": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+            "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+            "license": "ISC"
+        },
+        "node_modules/napi-build-utils": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+            "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+            "license": "MIT"
+        },
+        "node_modules/needle": {
+            "version": "2.4.0",
+            "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz",
+            "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^3.2.6",
+                "iconv-lite": "^0.4.4",
+                "sax": "^1.2.4"
+            },
+            "bin": {
+                "needle": "bin/needle"
+            },
+            "engines": {
+                "node": ">= 4.4.x"
+            }
+        },
+        "node_modules/needle/node_modules/debug": {
+            "version": "3.2.7",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+            "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/needle/node_modules/iconv-lite": {
+            "version": "0.4.24",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+            "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/negotiator": {
+            "version": "0.6.3",
+            "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+            "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/neo-async": {
+            "version": "2.6.2",
+            "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+            "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/netmask": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
+            "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/no-case": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+            "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "lower-case": "^2.0.2",
+                "tslib": "^2.0.3"
+            }
+        },
+        "node_modules/node-abi": {
+            "version": "3.75.0",
+            "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
+            "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==",
+            "license": "MIT",
+            "dependencies": {
+                "semver": "^7.3.5"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/node-abi/node_modules/semver": {
+            "version": "7.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+            "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/node-addon-api": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+            "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+            "license": "MIT"
+        },
+        "node_modules/node-cmd": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-4.0.0.tgz",
+            "integrity": "sha512-3OHy8KI8MuwADyugQRZBsaqe3c0r3yxQSoLsDBVk7vAjPmfG01512MPBQjfmBJxrH+2qURbiBf/ZyoimrhdA6A==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.4.0"
+            }
+        },
+        "node_modules/node-gyp": {
+            "version": "8.4.1",
+            "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
+            "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "env-paths": "^2.2.0",
+                "glob": "^7.1.4",
+                "graceful-fs": "^4.2.6",
+                "make-fetch-happen": "^9.1.0",
+                "nopt": "^5.0.0",
+                "npmlog": "^6.0.0",
+                "rimraf": "^3.0.2",
+                "semver": "^7.3.5",
+                "tar": "^6.1.2",
+                "which": "^2.0.2"
+            },
+            "bin": {
+                "node-gyp": "bin/node-gyp.js"
+            },
+            "engines": {
+                "node": ">= 10.12.0"
+            }
+        },
+        "node_modules/node-gyp/node_modules/semver": {
+            "version": "7.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+            "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+            "license": "ISC",
+            "optional": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/node-releases": {
+            "version": "2.0.19",
+            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+            "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/nodemon": {
+            "version": "2.0.22",
+            "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
+            "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "chokidar": "^3.5.2",
+                "debug": "^3.2.7",
+                "ignore-by-default": "^1.0.1",
+                "minimatch": "^3.1.2",
+                "pstree.remy": "^1.1.8",
+                "semver": "^5.7.1",
+                "simple-update-notifier": "^1.0.7",
+                "supports-color": "^5.5.0",
+                "touch": "^3.1.0",
+                "undefsafe": "^2.0.5"
+            },
+            "bin": {
+                "nodemon": "bin/nodemon.js"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/nodemon"
+            }
+        },
+        "node_modules/nodemon/node_modules/debug": {
+            "version": "3.2.7",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+            "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/nodemon/node_modules/has-flag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+            "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/nodemon/node_modules/semver": {
+            "version": "5.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+            "dev": true,
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/nodemon/node_modules/supports-color": {
+            "version": "5.5.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+            "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/nopt": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+            "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "abbrev": "1"
+            },
+            "bin": {
+                "nopt": "bin/nopt.js"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/normalize-package-data": {
+            "version": "2.5.0",
+            "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+            "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "hosted-git-info": "^2.1.4",
+                "resolve": "^1.10.0",
+                "semver": "2 || 3 || 4 || 5",
+                "validate-npm-package-license": "^3.0.1"
+            }
+        },
+        "node_modules/normalize-package-data/node_modules/semver": {
+            "version": "5.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+            "dev": true,
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/normalize-path": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+            "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/normalize-url": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+            "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/npmlog": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
+            "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
+            "deprecated": "This package is no longer supported.",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "are-we-there-yet": "^3.0.0",
+                "console-control-strings": "^1.1.0",
+                "gauge": "^4.0.3",
+                "set-blocking": "^2.0.0"
+            },
+            "engines": {
+                "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+            }
+        },
+        "node_modules/nprogress": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
+            "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==",
+            "license": "MIT"
+        },
+        "node_modules/nssocket": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz",
+            "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==",
+            "license": "MIT",
+            "dependencies": {
+                "eventemitter2": "~0.4.14",
+                "lazy": "~1.0.11"
+            },
+            "engines": {
+                "node": ">= 0.10.x"
+            }
+        },
+        "node_modules/nssocket/node_modules/eventemitter2": {
+            "version": "0.4.14",
+            "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+            "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==",
+            "license": "MIT"
+        },
+        "node_modules/nth-check": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+            "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "boolbase": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/nth-check?sponsor=1"
+            }
+        },
+        "node_modules/object-assign": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+            "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/object-inspect": {
+            "version": "1.13.4",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+            "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/object-keys": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+            "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/object.assign": {
+            "version": "4.1.7",
+            "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+            "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bind": "^1.0.8",
+                "call-bound": "^1.0.3",
+                "define-properties": "^1.2.1",
+                "es-object-atoms": "^1.0.0",
+                "has-symbols": "^1.1.0",
+                "object-keys": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/on-finished": {
+            "version": "2.4.1",
+            "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+            "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+            "license": "MIT",
+            "dependencies": {
+                "ee-first": "1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/once": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+            "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+            "license": "ISC",
+            "dependencies": {
+                "wrappy": "1"
+            }
+        },
+        "node_modules/optimist": {
+            "version": "0.3.7",
+            "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+            "integrity": "sha512-TCx0dXQzVtSCg2OgY/bO9hjM9cV4XYx09TVK+s3+FhkjT6LovsLe+pPMzpWf+6yXK/hUizs2gUoTw3jHM0VaTQ==",
+            "license": "MIT/X11",
+            "dependencies": {
+                "wordwrap": "~0.0.2"
+            }
+        },
+        "node_modules/os-browserify": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+            "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/p-cancelable": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
+            "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/p-finally": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+            "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/p-limit": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+            "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+            "license": "MIT",
+            "dependencies": {
+                "yocto-queue": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/p-locate": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+            "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+            "license": "MIT",
+            "dependencies": {
+                "p-limit": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/p-map": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+            "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "aggregate-error": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/p-try": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+            "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/pac-proxy-agent": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz",
+            "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==",
+            "license": "MIT",
+            "dependencies": {
+                "@tootallnate/quickjs-emscripten": "^0.23.0",
+                "agent-base": "^7.1.2",
+                "debug": "^4.3.4",
+                "get-uri": "^6.0.1",
+                "http-proxy-agent": "^7.0.0",
+                "https-proxy-agent": "^7.0.6",
+                "pac-resolver": "^7.0.1",
+                "socks-proxy-agent": "^8.0.5"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/pac-resolver": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+            "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
+            "license": "MIT",
+            "dependencies": {
+                "degenerator": "^5.0.0",
+                "netmask": "^2.0.2"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/pako": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+            "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+            "dev": true,
+            "license": "(MIT AND Zlib)"
+        },
+        "node_modules/param-case": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
+            "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "dot-case": "^3.0.4",
+                "tslib": "^2.0.3"
+            }
+        },
+        "node_modules/parents": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+            "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "path-platform": "~0.11.15"
+            }
+        },
+        "node_modules/parse-asn1": {
+            "version": "5.1.7",
+            "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz",
+            "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "asn1.js": "^4.10.1",
+                "browserify-aes": "^1.2.0",
+                "evp_bytestokey": "^1.0.3",
+                "hash-base": "~3.0",
+                "pbkdf2": "^3.1.2",
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/parse-author": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz",
+            "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "author-regex": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/parse-json": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+            "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "error-ex": "^1.2.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/parseqs": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+            "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==",
+            "license": "MIT"
+        },
+        "node_modules/parseuri": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+            "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==",
+            "license": "MIT"
+        },
+        "node_modules/parseurl": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+            "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/pascal-case": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
+            "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "no-case": "^3.0.4",
+                "tslib": "^2.0.3"
+            }
+        },
+        "node_modules/path-browserify": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+            "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/path-exists": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+            "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/path-is-absolute": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+            "devOptional": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/path-key": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+            "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/path-parse": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+            "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+            "license": "MIT"
+        },
+        "node_modules/path-platform": {
+            "version": "0.11.15",
+            "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+            "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/path-to-regexp": {
+            "version": "0.1.12",
+            "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+            "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+            "license": "MIT"
+        },
+        "node_modules/path-type": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+            "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "pify": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/path-type/node_modules/pify": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+            "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/pbkdf2": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
+            "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "create-hash": "^1.1.2",
+                "create-hmac": "^1.1.4",
+                "ripemd160": "^2.0.1",
+                "safe-buffer": "^5.0.1",
+                "sha.js": "^2.4.8"
+            },
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
+        "node_modules/peek-readable": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
+            "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/Borewit"
+            }
+        },
+        "node_modules/pend": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+            "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+            "license": "MIT"
+        },
+        "node_modules/picocolors": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+            "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/picomatch": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+            "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/jonschlinkert"
+            }
+        },
+        "node_modules/pidusage": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz",
+            "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==",
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/pify": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+            "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/pkg-dir": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+            "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "find-up": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/find-up": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+            "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "locate-path": "^5.0.0",
+                "path-exists": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/locate-path": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+            "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-locate": "^4.1.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/p-limit": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+            "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-try": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/p-locate": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+            "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-limit": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/plist": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
+            "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@xmldom/xmldom": "^0.8.8",
+                "base64-js": "^1.5.1",
+                "xmlbuilder": "^15.1.1"
+            },
+            "engines": {
+                "node": ">=10.4.0"
+            }
+        },
+        "node_modules/pm2": {
+            "version": "5.4.3",
+            "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.4.3.tgz",
+            "integrity": "sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ==",
+            "license": "AGPL-3.0",
+            "dependencies": {
+                "@pm2/agent": "~2.0.0",
+                "@pm2/io": "~6.0.1",
+                "@pm2/js-api": "~0.8.0",
+                "@pm2/pm2-version-check": "latest",
+                "async": "~3.2.0",
+                "blessed": "0.1.81",
+                "chalk": "3.0.0",
+                "chokidar": "^3.5.3",
+                "cli-tableau": "^2.0.0",
+                "commander": "2.15.1",
+                "croner": "~4.1.92",
+                "dayjs": "~1.11.5",
+                "debug": "^4.3.1",
+                "enquirer": "2.3.6",
+                "eventemitter2": "5.0.1",
+                "fclone": "1.0.11",
+                "js-yaml": "~4.1.0",
+                "mkdirp": "1.0.4",
+                "needle": "2.4.0",
+                "pidusage": "~3.0",
+                "pm2-axon": "~4.0.1",
+                "pm2-axon-rpc": "~0.7.1",
+                "pm2-deploy": "~1.0.2",
+                "pm2-multimeter": "^0.1.2",
+                "promptly": "^2",
+                "semver": "^7.2",
+                "source-map-support": "0.5.21",
+                "sprintf-js": "1.1.2",
+                "vizion": "~2.2.1"
+            },
+            "bin": {
+                "pm2": "bin/pm2",
+                "pm2-dev": "bin/pm2-dev",
+                "pm2-docker": "bin/pm2-docker",
+                "pm2-runtime": "bin/pm2-runtime"
+            },
+            "engines": {
+                "node": ">=12.0.0"
+            },
+            "optionalDependencies": {
+                "pm2-sysmonit": "^1.2.8"
+            }
+        },
+        "node_modules/pm2-axon": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz",
+            "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==",
+            "license": "MIT",
+            "dependencies": {
+                "amp": "~0.3.1",
+                "amp-message": "~0.1.1",
+                "debug": "^4.3.1",
+                "escape-string-regexp": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=5"
+            }
+        },
+        "node_modules/pm2-axon-rpc": {
+            "version": "0.7.1",
+            "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz",
+            "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.3.1"
+            },
+            "engines": {
+                "node": ">=5"
+            }
+        },
+        "node_modules/pm2-deploy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz",
+            "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==",
+            "license": "MIT",
+            "dependencies": {
+                "run-series": "^1.1.8",
+                "tv4": "^1.3.0"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/pm2-multimeter": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz",
+            "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==",
+            "license": "MIT/X11",
+            "dependencies": {
+                "charm": "~0.1.1"
+            }
+        },
+        "node_modules/pm2-sysmonit": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz",
+            "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==",
+            "license": "Apache",
+            "optional": true,
+            "dependencies": {
+                "async": "^3.2.0",
+                "debug": "^4.3.1",
+                "pidusage": "^2.0.21",
+                "systeminformation": "^5.7",
+                "tx2": "~1.0.4"
+            }
+        },
+        "node_modules/pm2-sysmonit/node_modules/pidusage": {
+            "version": "2.0.21",
+            "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz",
+            "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pm2/node_modules/chalk": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+            "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pm2/node_modules/commander": {
+            "version": "2.15.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+            "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+            "license": "MIT"
+        },
+        "node_modules/pm2/node_modules/mkdirp": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+            "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+            "license": "MIT",
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/pm2/node_modules/semver": {
+            "version": "7.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+            "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/possible-typed-array-names": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+            "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/prebuild-install": {
+            "version": "7.1.3",
+            "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+            "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
+            "license": "MIT",
+            "dependencies": {
+                "detect-libc": "^2.0.0",
+                "expand-template": "^2.0.3",
+                "github-from-package": "0.0.0",
+                "minimist": "^1.2.3",
+                "mkdirp-classic": "^0.5.3",
+                "napi-build-utils": "^2.0.0",
+                "node-abi": "^3.3.0",
+                "pump": "^3.0.0",
+                "rc": "^1.2.7",
+                "simple-get": "^4.0.0",
+                "tar-fs": "^2.0.0",
+                "tunnel-agent": "^0.6.0"
+            },
+            "bin": {
+                "prebuild-install": "bin.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/pretty-error": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
+            "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "lodash": "^4.17.20",
+                "renderkid": "^3.0.0"
+            }
+        },
+        "node_modules/print-js": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/print-js/-/print-js-1.6.0.tgz",
+            "integrity": "sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==",
+            "license": "MIT"
+        },
+        "node_modules/Printer": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/Printer/-/Printer-1.0.0.tgz",
+            "integrity": "sha512-Lo5QQBOElfIeeRGGRynWsaThcYveWHPdRWXY3TReuS62OlWvWNAtSOO5yYLTEOGFqQzTNzwGzD00L3X+FotFQA==",
+            "license": "ISC"
+        },
+        "node_modules/process": {
+            "version": "0.11.10",
+            "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+            "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6.0"
+            }
+        },
+        "node_modules/process-nextick-args": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+            "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+            "license": "MIT"
+        },
+        "node_modules/progress": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+            "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/promise-inflight": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+            "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/promise-retry": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+            "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "err-code": "^2.0.2",
+                "retry": "^0.12.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/promptly": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz",
+            "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==",
+            "license": "MIT",
+            "dependencies": {
+                "read": "^1.0.4"
+            }
+        },
+        "node_modules/proxy-addr": {
+            "version": "2.0.7",
+            "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+            "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+            "license": "MIT",
+            "dependencies": {
+                "forwarded": "0.2.0",
+                "ipaddr.js": "1.9.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/proxy-agent": {
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz",
+            "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==",
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^7.0.2",
+                "debug": "^4.3.4",
+                "http-proxy-agent": "^7.0.0",
+                "https-proxy-agent": "^7.0.2",
+                "lru-cache": "^7.14.1",
+                "pac-proxy-agent": "^7.0.1",
+                "proxy-from-env": "^1.1.0",
+                "socks-proxy-agent": "^8.0.2"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/proxy-agent/node_modules/lru-cache": {
+            "version": "7.18.3",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+            "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+            "license": "ISC",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/proxy-from-env": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+            "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+            "license": "MIT"
+        },
+        "node_modules/pstree.remy": {
+            "version": "1.1.8",
+            "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+            "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/public-encrypt": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+            "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bn.js": "^4.1.0",
+                "browserify-rsa": "^4.0.0",
+                "create-hash": "^1.1.0",
+                "parse-asn1": "^5.0.0",
+                "randombytes": "^2.0.1",
+                "safe-buffer": "^5.1.2"
+            }
+        },
+        "node_modules/public-encrypt/node_modules/bn.js": {
+            "version": "4.12.2",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
+            "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/pump": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+            "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+            "license": "MIT",
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/punycode": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+            "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/qs": {
+            "version": "6.13.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+            "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+            "license": "BSD-3-Clause",
+            "dependencies": {
+                "side-channel": "^1.0.6"
+            },
+            "engines": {
+                "node": ">=0.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/querystring-es3": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+            "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.4.x"
+            }
+        },
+        "node_modules/queue": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
+            "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "~2.0.3"
+            }
+        },
+        "node_modules/quick-lru": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+            "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/randombytes": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+            "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "^5.1.0"
+            }
+        },
+        "node_modules/randomfill": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+            "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "randombytes": "^2.0.5",
+                "safe-buffer": "^5.1.0"
+            }
+        },
+        "node_modules/range-parser": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+            "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/raw-body": {
+            "version": "2.5.2",
+            "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+            "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+            "license": "MIT",
+            "dependencies": {
+                "bytes": "3.1.2",
+                "http-errors": "2.0.0",
+                "iconv-lite": "0.4.24",
+                "unpipe": "1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/raw-body/node_modules/iconv-lite": {
+            "version": "0.4.24",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+            "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/rc": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+            "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+            "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+            "dependencies": {
+                "deep-extend": "^0.6.0",
+                "ini": "~1.3.0",
+                "minimist": "^1.2.0",
+                "strip-json-comments": "~2.0.1"
+            },
+            "bin": {
+                "rc": "cli.js"
+            }
+        },
+        "node_modules/rcedit": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-3.1.0.tgz",
+            "integrity": "sha512-WRlRdY1qZbu1L11DklT07KuHfRk42l0NFFJdaExELEu4fEQ982bP5Z6OWGPj/wLLIuKRQDCxZJGAwoFsxhZhNA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "cross-spawn-windows-exe": "^1.1.0"
+            },
+            "engines": {
+                "node": ">= 10.0.0"
+            }
+        },
+        "node_modules/read": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+            "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
+            "license": "ISC",
+            "dependencies": {
+                "mute-stream": "~0.0.4"
+            },
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/read-chunk": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz",
+            "integrity": "sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ==",
+            "license": "MIT",
+            "dependencies": {
+                "pify": "^4.0.1",
+                "with-open-file": "^0.1.6"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/read-only-stream": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+            "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/read-pkg": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+            "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "load-json-file": "^2.0.0",
+                "normalize-package-data": "^2.3.2",
+                "path-type": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+            "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "find-up": "^2.0.0",
+                "read-pkg": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/find-up": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+            "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "locate-path": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/locate-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+            "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-locate": "^2.0.0",
+                "path-exists": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/p-limit": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+            "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-try": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/p-locate": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+            "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-limit": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/p-try": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+            "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/path-exists": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+            "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/readable-stream": {
+            "version": "2.3.8",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+            "license": "MIT",
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.3",
+                "isarray": "~1.0.0",
+                "process-nextick-args": "~2.0.0",
+                "safe-buffer": "~5.1.1",
+                "string_decoder": "~1.1.1",
+                "util-deprecate": "~1.0.1"
+            }
+        },
+        "node_modules/readable-stream/node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+            "license": "MIT"
+        },
+        "node_modules/readable-stream/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/readable-web-to-node-stream": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz",
+            "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==",
+            "license": "MIT",
+            "dependencies": {
+                "readable-stream": "^4.7.0"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/Borewit"
+            }
+        },
+        "node_modules/readable-web-to-node-stream/node_modules/buffer": {
+            "version": "6.0.3",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+            "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "base64-js": "^1.3.1",
+                "ieee754": "^1.2.1"
+            }
+        },
+        "node_modules/readable-web-to-node-stream/node_modules/readable-stream": {
+            "version": "4.7.0",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+            "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+            "license": "MIT",
+            "dependencies": {
+                "abort-controller": "^3.0.0",
+                "buffer": "^6.0.3",
+                "events": "^3.3.0",
+                "process": "^0.11.10",
+                "string_decoder": "^1.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/readdirp": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+            "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+            "license": "MIT",
+            "dependencies": {
+                "picomatch": "^2.2.1"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/rebuild": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/rebuild/-/rebuild-0.1.2.tgz",
+            "integrity": "sha512-EtDZ5IapND57htCrOOcfH7MzXCQKivzSZUIZIuc8H0xDHfmi9HDBZIyjT7Neh5GcUoxQ6hfsXluC+UrYLgGbZg==",
+            "dependencies": {
+                "optimist": "0.3.x"
+            },
+            "bin": {
+                "rebuild": "cli.js"
+            },
+            "engines": {
+                "node": ">=0.8.8"
+            }
+        },
+        "node_modules/rechoir": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+            "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "resolve": "^1.20.0"
+            },
+            "engines": {
+                "node": ">= 10.13.0"
+            }
+        },
+        "node_modules/regenerate": {
+            "version": "1.4.2",
+            "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+            "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/regenerate-unicode-properties": {
+            "version": "10.2.0",
+            "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+            "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "regenerate": "^1.4.2"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/regexpu-core": {
+            "version": "6.2.0",
+            "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+            "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "regenerate": "^1.4.2",
+                "regenerate-unicode-properties": "^10.2.0",
+                "regjsgen": "^0.8.0",
+                "regjsparser": "^0.12.0",
+                "unicode-match-property-ecmascript": "^2.0.0",
+                "unicode-match-property-value-ecmascript": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/regjsgen": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+            "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/regjsparser": {
+            "version": "0.12.0",
+            "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+            "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "jsesc": "~3.0.2"
+            },
+            "bin": {
+                "regjsparser": "bin/parser"
+            }
+        },
+        "node_modules/regjsparser/node_modules/jsesc": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+            "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "jsesc": "bin/jsesc"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/relateurl": {
+            "version": "0.2.7",
+            "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+            "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/renderkid": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
+            "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "css-select": "^4.1.3",
+                "dom-converter": "^0.2.0",
+                "htmlparser2": "^6.1.0",
+                "lodash": "^4.17.21",
+                "strip-ansi": "^6.0.1"
+            }
+        },
+        "node_modules/require-from-string": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+            "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/require-in-the-middle": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz",
+            "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "^4.1.1",
+                "module-details-from-path": "^1.0.3",
+                "resolve": "^1.22.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/resolve": {
+            "version": "1.22.10",
+            "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+            "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+            "license": "MIT",
+            "dependencies": {
+                "is-core-module": "^2.16.0",
+                "path-parse": "^1.0.7",
+                "supports-preserve-symlinks-flag": "^1.0.0"
+            },
+            "bin": {
+                "resolve": "bin/resolve"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/resolve-alpn": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+            "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/resolve-cwd": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+            "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "resolve-from": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/resolve-from": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+            "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/responselike": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
+            "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "lowercase-keys": "^2.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/retry": {
+            "version": "0.12.0",
+            "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+            "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/rfdc": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+            "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+            "license": "MIT"
+        },
+        "node_modules/rimraf": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+            "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+            "deprecated": "Rimraf versions prior to v4 are no longer supported",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/ripemd160": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+            "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "hash-base": "^3.0.0",
+                "inherits": "^2.0.1"
+            }
+        },
+        "node_modules/roarr": {
+            "version": "2.15.4",
+            "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+            "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "optional": true,
+            "dependencies": {
+                "boolean": "^3.0.1",
+                "detect-node": "^2.0.4",
+                "globalthis": "^1.0.1",
+                "json-stringify-safe": "^5.0.1",
+                "semver-compare": "^1.0.0",
+                "sprintf-js": "^1.1.2"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/run-series": {
+            "version": "1.1.9",
+            "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz",
+            "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT"
+        },
+        "node_modules/safe-buffer": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT"
+        },
+        "node_modules/safe-regex-test": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+            "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "es-errors": "^1.3.0",
+                "is-regex": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+            "license": "MIT"
+        },
+        "node_modules/sax": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
+            "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
+            "license": "ISC"
+        },
+        "node_modules/schema-utils": {
+            "version": "4.3.2",
+            "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
+            "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/json-schema": "^7.0.9",
+                "ajv": "^8.9.0",
+                "ajv-formats": "^2.1.1",
+                "ajv-keywords": "^5.1.0"
+            },
+            "engines": {
+                "node": ">= 10.13.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/webpack"
+            }
+        },
+        "node_modules/semver": {
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+            "dev": true,
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/semver-compare": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+            "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/send": {
+            "version": "0.19.0",
+            "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+            "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "2.6.9",
+                "depd": "2.0.0",
+                "destroy": "1.2.0",
+                "encodeurl": "~1.0.2",
+                "escape-html": "~1.0.3",
+                "etag": "~1.8.1",
+                "fresh": "0.5.2",
+                "http-errors": "2.0.0",
+                "mime": "1.6.0",
+                "ms": "2.1.3",
+                "on-finished": "2.4.1",
+                "range-parser": "~1.2.1",
+                "statuses": "2.0.1"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/send/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/send/node_modules/debug/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/send/node_modules/encodeurl": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+            "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/send/node_modules/mime": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+            "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+            "license": "MIT",
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/serialize-error": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+            "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "type-fest": "^0.13.1"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/serialize-javascript": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+            "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "dependencies": {
+                "randombytes": "^2.1.0"
+            }
+        },
+        "node_modules/serve-index": {
+            "version": "1.9.1",
+            "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+            "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+            "license": "MIT",
+            "dependencies": {
+                "accepts": "~1.3.4",
+                "batch": "0.6.1",
+                "debug": "2.6.9",
+                "escape-html": "~1.0.3",
+                "http-errors": "~1.6.2",
+                "mime-types": "~2.1.17",
+                "parseurl": "~1.3.2"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/serve-index/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/serve-index/node_modules/depd": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+            "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/serve-index/node_modules/http-errors": {
+            "version": "1.6.3",
+            "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+            "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+            "license": "MIT",
+            "dependencies": {
+                "depd": "~1.1.2",
+                "inherits": "2.0.3",
+                "setprototypeof": "1.1.0",
+                "statuses": ">= 1.4.0 < 2"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/serve-index/node_modules/inherits": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+            "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+            "license": "ISC"
+        },
+        "node_modules/serve-index/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/serve-index/node_modules/setprototypeof": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+            "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+            "license": "ISC"
+        },
+        "node_modules/serve-index/node_modules/statuses": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+            "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/serve-static": {
+            "version": "1.16.2",
+            "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+            "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+            "license": "MIT",
+            "dependencies": {
+                "encodeurl": "~2.0.0",
+                "escape-html": "~1.0.3",
+                "parseurl": "~1.3.3",
+                "send": "0.19.0"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/set-blocking": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+            "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/set-function-length": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+            "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "define-data-property": "^1.1.4",
+                "es-errors": "^1.3.0",
+                "function-bind": "^1.1.2",
+                "get-intrinsic": "^1.2.4",
+                "gopd": "^1.0.1",
+                "has-property-descriptors": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/setprototypeof": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+            "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+            "license": "ISC"
+        },
+        "node_modules/sha.js": {
+            "version": "2.4.11",
+            "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+            "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+            "dev": true,
+            "license": "(MIT AND BSD-3-Clause)",
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.0.1"
+            },
+            "bin": {
+                "sha.js": "bin.js"
+            }
+        },
+        "node_modules/shallow-clone": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+            "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "kind-of": "^6.0.2"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/shasum-object": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz",
+            "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "fast-safe-stringify": "^2.0.7"
+            }
+        },
+        "node_modules/shebang-command": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+            "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+            "license": "MIT",
+            "dependencies": {
+                "shebang-regex": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/shebang-regex": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+            "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/shell-quote": {
+            "version": "1.8.3",
+            "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
+            "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/shimmer": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
+            "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==",
+            "license": "BSD-2-Clause"
+        },
+        "node_modules/side-channel": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+            "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0",
+                "object-inspect": "^1.13.3",
+                "side-channel-list": "^1.0.0",
+                "side-channel-map": "^1.0.1",
+                "side-channel-weakmap": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/side-channel-list": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+            "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0",
+                "object-inspect": "^1.13.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/side-channel-map": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+            "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.5",
+                "object-inspect": "^1.13.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/side-channel-weakmap": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+            "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.5",
+                "object-inspect": "^1.13.3",
+                "side-channel-map": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/signal-exit": {
+            "version": "3.0.7",
+            "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+            "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+            "license": "ISC"
+        },
+        "node_modules/silly-datetime": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/silly-datetime/-/silly-datetime-0.1.2.tgz",
+            "integrity": "sha512-q8hnO91rRvQsYTYaZCJc6UpljzfdmWD3bNljDLKGVBT2ukj7snE+ENkVVkXfo529ABLEBeN6PHoEaT1ONEq81w==",
+            "license": "MIT"
+        },
+        "node_modules/simple-concat": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+            "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT"
+        },
+        "node_modules/simple-get": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+            "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "decompress-response": "^6.0.0",
+                "once": "^1.3.1",
+                "simple-concat": "^1.0.0"
+            }
+        },
+        "node_modules/simple-update-notifier": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
+            "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "semver": "~7.0.0"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/simple-update-notifier/node_modules/semver": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+            "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+            "dev": true,
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/smart-buffer": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+            "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 6.0.0",
+                "npm": ">= 3.0.0"
+            }
+        },
+        "node_modules/socket.io": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.1.tgz",
+            "integrity": "sha512-eaTE4tBKRD6RFoetquMbxgvcpvoDtRyIlkIMI/SMK2bsKvbENTsDeeu4GJ/z9c90yOWxB7b/eC+yKLPbHnH6bA==",
+            "license": "MIT",
+            "dependencies": {
+                "debug": "~4.1.0",
+                "engine.io": "~3.6.0",
+                "has-binary2": "~1.0.2",
+                "socket.io-adapter": "~1.1.0",
+                "socket.io-client": "2.5.0",
+                "socket.io-parser": "~3.4.0"
+            }
+        },
+        "node_modules/socket.io-adapter": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
+            "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==",
+            "license": "MIT"
+        },
+        "node_modules/socket.io-client": {
+            "version": "2.5.0",
+            "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
+            "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
+            "license": "MIT",
+            "dependencies": {
+                "backo2": "1.0.2",
+                "component-bind": "1.0.0",
+                "component-emitter": "~1.3.0",
+                "debug": "~3.1.0",
+                "engine.io-client": "~3.5.0",
+                "has-binary2": "~1.0.2",
+                "indexof": "0.0.1",
+                "parseqs": "0.0.6",
+                "parseuri": "0.0.6",
+                "socket.io-parser": "~3.3.0",
+                "to-array": "0.1.4"
+            }
+        },
+        "node_modules/socket.io-client/node_modules/debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/socket.io-client/node_modules/isarray": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+            "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
+            "license": "MIT"
+        },
+        "node_modules/socket.io-client/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+            "license": "MIT"
+        },
+        "node_modules/socket.io-client/node_modules/socket.io-parser": {
+            "version": "3.3.4",
+            "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.4.tgz",
+            "integrity": "sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==",
+            "license": "MIT",
+            "dependencies": {
+                "component-emitter": "~1.3.0",
+                "debug": "~3.1.0",
+                "isarray": "2.0.1"
+            }
+        },
+        "node_modules/socket.io-parser": {
+            "version": "3.4.3",
+            "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.3.tgz",
+            "integrity": "sha512-1rE4dZN3kCI/E5wixd393hmbqa78vVpkKmnEJhLeWoS/C5hbFYAbcSfnWoaVH43u9ToUVtzKjguxEZq+1XZfCQ==",
+            "license": "MIT",
+            "dependencies": {
+                "component-emitter": "1.2.1",
+                "debug": "~4.1.0",
+                "isarray": "2.0.1"
+            },
+            "engines": {
+                "node": ">=10.0.0"
+            }
+        },
+        "node_modules/socket.io-parser/node_modules/component-emitter": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+            "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==",
+            "license": "MIT"
+        },
+        "node_modules/socket.io-parser/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/socket.io-parser/node_modules/isarray": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+            "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
+            "license": "MIT"
+        },
+        "node_modules/socket.io/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/socks": {
+            "version": "2.8.5",
+            "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz",
+            "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==",
+            "license": "MIT",
+            "dependencies": {
+                "ip-address": "^9.0.5",
+                "smart-buffer": "^4.2.0"
+            },
+            "engines": {
+                "node": ">= 10.0.0",
+                "npm": ">= 3.0.0"
+            }
+        },
+        "node_modules/socks-proxy-agent": {
+            "version": "8.0.5",
+            "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+            "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^7.1.2",
+                "debug": "^4.3.4",
+                "socks": "^2.8.3"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/source-map": {
+            "version": "0.5.7",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+            "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+            "dev": true,
+            "license": "BSD-3-Clause",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/source-map-support": {
+            "version": "0.5.21",
+            "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+            "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+            "license": "MIT",
+            "dependencies": {
+                "buffer-from": "^1.0.0",
+                "source-map": "^0.6.0"
+            }
+        },
+        "node_modules/source-map-support/node_modules/source-map": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+            "license": "BSD-3-Clause",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/spdx-correct": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+            "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "spdx-expression-parse": "^3.0.0",
+                "spdx-license-ids": "^3.0.0"
+            }
+        },
+        "node_modules/spdx-exceptions": {
+            "version": "2.5.0",
+            "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+            "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+            "dev": true,
+            "license": "CC-BY-3.0"
+        },
+        "node_modules/spdx-expression-parse": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+            "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "spdx-exceptions": "^2.1.0",
+                "spdx-license-ids": "^3.0.0"
+            }
+        },
+        "node_modules/spdx-license-ids": {
+            "version": "3.0.21",
+            "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
+            "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
+            "dev": true,
+            "license": "CC0-1.0"
+        },
+        "node_modules/sprintf-js": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+            "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+            "license": "BSD-3-Clause"
+        },
+        "node_modules/sqlite3": {
+            "version": "5.1.7",
+            "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz",
+            "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==",
+            "hasInstallScript": true,
+            "license": "BSD-3-Clause",
+            "dependencies": {
+                "bindings": "^1.5.0",
+                "node-addon-api": "^7.0.0",
+                "prebuild-install": "^7.1.1",
+                "tar": "^6.1.11"
+            },
+            "optionalDependencies": {
+                "node-gyp": "8.x"
+            },
+            "peerDependencies": {
+                "node-gyp": "8.x"
+            },
+            "peerDependenciesMeta": {
+                "node-gyp": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/ssri": {
+            "version": "8.0.1",
+            "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+            "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^3.1.1"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/statuses": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+            "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/stream-browserify": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+            "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "~2.0.4",
+                "readable-stream": "^3.5.0"
+            }
+        },
+        "node_modules/stream-browserify/node_modules/readable-stream": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/stream-combiner2": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+            "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "duplexer2": "~0.1.0",
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/stream-http": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz",
+            "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "builtin-status-codes": "^3.0.0",
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.6.0",
+                "xtend": "^4.0.2"
+            }
+        },
+        "node_modules/stream-http/node_modules/readable-stream": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/stream-splicer": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz",
+            "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/streamifier": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz",
+            "integrity": "sha512-zDgl+muIlWzXNsXeyUfOk9dChMjlpkq0DRsxujtYPgyJ676yQ8jEm6zzaaWHFDg5BNcLuif0eD2MTyJdZqXpdg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/streamroller": {
+            "version": "3.1.5",
+            "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz",
+            "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==",
+            "license": "MIT",
+            "dependencies": {
+                "date-format": "^4.0.14",
+                "debug": "^4.3.4",
+                "fs-extra": "^8.1.0"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/streamroller/node_modules/fs-extra": {
+            "version": "8.1.0",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+            "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+            "license": "MIT",
+            "dependencies": {
+                "graceful-fs": "^4.2.0",
+                "jsonfile": "^4.0.0",
+                "universalify": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=6 <7 || >=8"
+            }
+        },
+        "node_modules/streamroller/node_modules/jsonfile": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+            "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+            "license": "MIT",
+            "optionalDependencies": {
+                "graceful-fs": "^4.1.6"
+            }
+        },
+        "node_modules/streamroller/node_modules/universalify": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+            "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/streamsearch": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+            "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/string_decoder": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+            "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.2.0"
+            }
+        },
+        "node_modules/string-width": {
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+            "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "emoji-regex": "^8.0.0",
+                "is-fullwidth-code-point": "^3.0.0",
+                "strip-ansi": "^6.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/strip-ansi": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+            "devOptional": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/strip-bom": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+            "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/strip-json-comments": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+            "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/strip-outer": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+            "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "escape-string-regexp": "^1.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/strip-outer/node_modules/escape-string-regexp": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+            "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/strtok3": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
+            "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
+            "license": "MIT",
+            "dependencies": {
+                "@tokenizer/token": "^0.3.0",
+                "peek-readable": "^4.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/Borewit"
+            }
+        },
+        "node_modules/subarg": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+            "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "minimist": "^1.1.0"
+            }
+        },
+        "node_modules/sumchecker": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+            "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "debug": "^4.1.0"
+            },
+            "engines": {
+                "node": ">= 8.0"
+            }
+        },
+        "node_modules/supports-color": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+            "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+            "license": "MIT",
+            "dependencies": {
+                "has-flag": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/supports-preserve-symlinks-flag": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+            "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/syntax-error": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+            "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "acorn-node": "^1.2.0"
+            }
+        },
+        "node_modules/systeminformation": {
+            "version": "5.27.3",
+            "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.27.3.tgz",
+            "integrity": "sha512-SFgXCnmO/z0Nvln3aQ3fQRjbVVP5ybUPifyInJU6pIs6PpCjm/HuMGl3UenEd03tpeZLk44nxEikT/LON4UDrA==",
+            "license": "MIT",
+            "optional": true,
+            "os": [
+                "darwin",
+                "linux",
+                "win32",
+                "freebsd",
+                "openbsd",
+                "netbsd",
+                "sunos",
+                "android"
+            ],
+            "bin": {
+                "systeminformation": "lib/cli.js"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            },
+            "funding": {
+                "type": "Buy me a coffee",
+                "url": "https://www.buymeacoffee.com/systeminfo"
+            }
+        },
+        "node_modules/tapable": {
+            "version": "2.2.2",
+            "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
+            "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/tar": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+            "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+            "license": "ISC",
+            "dependencies": {
+                "chownr": "^2.0.0",
+                "fs-minipass": "^2.0.0",
+                "minipass": "^5.0.0",
+                "minizlib": "^2.1.1",
+                "mkdirp": "^1.0.3",
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/tar-fs": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
+            "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
+            "license": "MIT",
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "mkdirp-classic": "^0.5.2",
+                "pump": "^3.0.0",
+                "tar-stream": "^2.1.4"
+            }
+        },
+        "node_modules/tar-fs/node_modules/bl": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+            "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+            "license": "MIT",
+            "dependencies": {
+                "buffer": "^5.5.0",
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.4.0"
+            }
+        },
+        "node_modules/tar-fs/node_modules/buffer": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+            "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "base64-js": "^1.3.1",
+                "ieee754": "^1.1.13"
+            }
+        },
+        "node_modules/tar-fs/node_modules/chownr": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+            "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+            "license": "ISC"
+        },
+        "node_modules/tar-fs/node_modules/readable-stream": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/tar-fs/node_modules/tar-stream": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+            "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+            "license": "MIT",
+            "dependencies": {
+                "bl": "^4.0.3",
+                "end-of-stream": "^1.4.1",
+                "fs-constants": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^3.1.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/tar-stream": {
+            "version": "1.6.2",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+            "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+            "license": "MIT",
+            "dependencies": {
+                "bl": "^1.0.0",
+                "buffer-alloc": "^1.2.0",
+                "end-of-stream": "^1.0.0",
+                "fs-constants": "^1.0.0",
+                "readable-stream": "^2.3.0",
+                "to-buffer": "^1.1.1",
+                "xtend": "^4.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/tar/node_modules/minipass": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+            "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+            "license": "ISC",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/tar/node_modules/mkdirp": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+            "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+            "license": "MIT",
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/tar/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "license": "ISC"
+        },
+        "node_modules/terser": {
+            "version": "5.43.0",
+            "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.0.tgz",
+            "integrity": "sha512-CqNNxKSGKSZCunSvwKLTs8u8sGGlp27sxNZ4quGh0QeNuyHM0JSEM/clM9Mf4zUp6J+tO2gUXhgXT2YMMkwfKQ==",
+            "dev": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "@jridgewell/source-map": "^0.3.3",
+                "acorn": "^8.14.0",
+                "commander": "^2.20.0",
+                "source-map-support": "~0.5.20"
+            },
+            "bin": {
+                "terser": "bin/terser"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/terser-webpack-plugin": {
+            "version": "5.3.14",
+            "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
+            "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@jridgewell/trace-mapping": "^0.3.25",
+                "jest-worker": "^27.4.5",
+                "schema-utils": "^4.3.0",
+                "serialize-javascript": "^6.0.2",
+                "terser": "^5.31.1"
+            },
+            "engines": {
+                "node": ">= 10.13.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/webpack"
+            },
+            "peerDependencies": {
+                "webpack": "^5.1.0"
+            },
+            "peerDependenciesMeta": {
+                "@swc/core": {
+                    "optional": true
+                },
+                "esbuild": {
+                    "optional": true
+                },
+                "uglify-js": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/terser/node_modules/acorn": {
+            "version": "8.15.0",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+            "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/terser/node_modules/commander": {
+            "version": "2.20.3",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+            "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/through": {
+            "version": "2.3.8",
+            "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+            "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/through2": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+            "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "readable-stream": "~2.3.6",
+                "xtend": "~4.0.1"
+            }
+        },
+        "node_modules/time-zone": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz",
+            "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/timers-browserify": {
+            "version": "1.4.2",
+            "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+            "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==",
+            "dev": true,
+            "dependencies": {
+                "process": "~0.11.0"
+            },
+            "engines": {
+                "node": ">=0.6.0"
+            }
+        },
+        "node_modules/to-array": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+            "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A=="
+        },
+        "node_modules/to-buffer": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.0.tgz",
+            "integrity": "sha512-uM2Zapt+GfaxYhCxKtUn7ktNOjAHL8nthQIQVhvNCjGLe8t+ULQ5i5hyFpMzuRxHkg2nrKNFTQpYDLhzxC3Jew==",
+            "license": "MIT",
+            "dependencies": {
+                "isarray": "^2.0.5",
+                "safe-buffer": "^5.2.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/to-buffer/node_modules/isarray": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+            "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+            "license": "MIT"
+        },
+        "node_modules/to-regex-range": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+            "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+            "license": "MIT",
+            "dependencies": {
+                "is-number": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/toidentifier": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+            "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/token-types": {
+            "version": "4.2.1",
+            "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
+            "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
+            "license": "MIT",
+            "dependencies": {
+                "@tokenizer/token": "^0.3.0",
+                "ieee754": "^1.2.1"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/Borewit"
+            }
+        },
+        "node_modules/touch": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
+            "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+            "dev": true,
+            "license": "ISC",
+            "bin": {
+                "nodetouch": "bin/nodetouch.js"
+            }
+        },
+        "node_modules/trim-repeated": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+            "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "escape-string-regexp": "^1.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/trim-repeated/node_modules/escape-string-regexp": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+            "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/tslib": {
+            "version": "2.8.1",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+            "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+            "license": "0BSD"
+        },
+        "node_modules/tty-browserify": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+            "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/tunnel-agent": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+            "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+            "license": "Apache-2.0",
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/tv4": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz",
+            "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==",
+            "license": [
+                {
+                    "type": "Public Domain",
+                    "url": "http://geraintluff.github.io/tv4/LICENSE.txt"
+                },
+                {
+                    "type": "MIT",
+                    "url": "http://jsonary.com/LICENSE.txt"
+                }
+            ],
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/tx2": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz",
+            "integrity": "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==",
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "json-stringify-safe": "^5.0.1"
+            }
+        },
+        "node_modules/type-fest": {
+            "version": "0.13.1",
+            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+            "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+            "dev": true,
+            "license": "(MIT OR CC0-1.0)",
+            "optional": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/type-is": {
+            "version": "1.6.18",
+            "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+            "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+            "license": "MIT",
+            "dependencies": {
+                "media-typer": "0.3.0",
+                "mime-types": "~2.1.24"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/typedarray": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+            "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+            "license": "MIT"
+        },
+        "node_modules/umd": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+            "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "umd": "bin/cli.js"
+            }
+        },
+        "node_modules/undeclared-identifiers": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz",
+            "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "acorn-node": "^1.3.0",
+                "dash-ast": "^1.0.0",
+                "get-assigned-identifiers": "^1.2.0",
+                "simple-concat": "^1.0.0",
+                "xtend": "^4.0.1"
+            },
+            "bin": {
+                "undeclared-identifiers": "bin.js"
+            }
+        },
+        "node_modules/undefsafe": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+            "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/undici-types": {
+            "version": "7.8.0",
+            "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+            "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/unicode-canonical-property-names-ecmascript": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+            "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/unicode-match-property-ecmascript": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+            "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "unicode-canonical-property-names-ecmascript": "^2.0.0",
+                "unicode-property-aliases-ecmascript": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/unicode-match-property-value-ecmascript": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+            "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/unicode-property-aliases-ecmascript": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+            "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/unique-filename": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+            "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "unique-slug": "^2.0.0"
+            }
+        },
+        "node_modules/unique-slug": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+            "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "imurmurhash": "^0.1.4"
+            }
+        },
+        "node_modules/universalify": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+            "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 10.0.0"
+            }
+        },
+        "node_modules/unpipe": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+            "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/update-browserslist-db": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+            "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/browserslist"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/browserslist"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ],
+            "license": "MIT",
+            "dependencies": {
+                "escalade": "^3.2.0",
+                "picocolors": "^1.1.1"
+            },
+            "bin": {
+                "update-browserslist-db": "cli.js"
+            },
+            "peerDependencies": {
+                "browserslist": ">= 4.21.0"
+            }
+        },
+        "node_modules/url": {
+            "version": "0.11.4",
+            "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
+            "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "punycode": "^1.4.1",
+                "qs": "^6.12.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/util": {
+            "version": "0.12.5",
+            "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+            "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "is-arguments": "^1.0.4",
+                "is-generator-function": "^1.0.7",
+                "is-typed-array": "^1.1.3",
+                "which-typed-array": "^1.1.2"
+            }
+        },
+        "node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+            "license": "MIT"
+        },
+        "node_modules/utila": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+            "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/utils-merge": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+            "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/uuid": {
+            "version": "8.3.2",
+            "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+            "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+            "license": "MIT",
+            "bin": {
+                "uuid": "dist/bin/uuid"
+            }
+        },
+        "node_modules/validate-npm-package-license": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+            "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "spdx-correct": "^3.0.0",
+                "spdx-expression-parse": "^3.0.0"
+            }
+        },
+        "node_modules/vary": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+            "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/vizion": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz",
+            "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==",
+            "license": "Apache-2.0",
+            "dependencies": {
+                "async": "^2.6.3",
+                "git-node-fs": "^1.0.0",
+                "ini": "^1.3.5",
+                "js-git": "^0.7.8"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/vizion/node_modules/async": {
+            "version": "2.6.4",
+            "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+            "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+            "license": "MIT",
+            "dependencies": {
+                "lodash": "^4.17.14"
+            }
+        },
+        "node_modules/vm-browserify": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+            "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/watchpack": {
+            "version": "2.4.4",
+            "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
+            "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "glob-to-regexp": "^0.4.1",
+                "graceful-fs": "^4.1.2"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/webpack": {
+            "version": "5.99.9",
+            "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz",
+            "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@types/eslint-scope": "^3.7.7",
+                "@types/estree": "^1.0.6",
+                "@types/json-schema": "^7.0.15",
+                "@webassemblyjs/ast": "^1.14.1",
+                "@webassemblyjs/wasm-edit": "^1.14.1",
+                "@webassemblyjs/wasm-parser": "^1.14.1",
+                "acorn": "^8.14.0",
+                "browserslist": "^4.24.0",
+                "chrome-trace-event": "^1.0.2",
+                "enhanced-resolve": "^5.17.1",
+                "es-module-lexer": "^1.2.1",
+                "eslint-scope": "5.1.1",
+                "events": "^3.2.0",
+                "glob-to-regexp": "^0.4.1",
+                "graceful-fs": "^4.2.11",
+                "json-parse-even-better-errors": "^2.3.1",
+                "loader-runner": "^4.2.0",
+                "mime-types": "^2.1.27",
+                "neo-async": "^2.6.2",
+                "schema-utils": "^4.3.2",
+                "tapable": "^2.1.1",
+                "terser-webpack-plugin": "^5.3.11",
+                "watchpack": "^2.4.1",
+                "webpack-sources": "^3.2.3"
+            },
+            "bin": {
+                "webpack": "bin/webpack.js"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/webpack"
+            },
+            "peerDependenciesMeta": {
+                "webpack-cli": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/webpack-cli": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz",
+            "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@discoveryjs/json-ext": "^0.6.1",
+                "@webpack-cli/configtest": "^3.0.1",
+                "@webpack-cli/info": "^3.0.1",
+                "@webpack-cli/serve": "^3.0.1",
+                "colorette": "^2.0.14",
+                "commander": "^12.1.0",
+                "cross-spawn": "^7.0.3",
+                "envinfo": "^7.14.0",
+                "fastest-levenshtein": "^1.0.12",
+                "import-local": "^3.0.2",
+                "interpret": "^3.1.1",
+                "rechoir": "^0.8.0",
+                "webpack-merge": "^6.0.1"
+            },
+            "bin": {
+                "webpack-cli": "bin/cli.js"
+            },
+            "engines": {
+                "node": ">=18.12.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/webpack"
+            },
+            "peerDependencies": {
+                "webpack": "^5.82.0"
+            },
+            "peerDependenciesMeta": {
+                "webpack-bundle-analyzer": {
+                    "optional": true
+                },
+                "webpack-dev-server": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/webpack-cli/node_modules/commander": {
+            "version": "12.1.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+            "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18"
+            }
+        },
+        "node_modules/webpack-merge": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz",
+            "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "clone-deep": "^4.0.1",
+                "flat": "^5.0.2",
+                "wildcard": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=18.0.0"
+            }
+        },
+        "node_modules/webpack-sources": {
+            "version": "3.3.2",
+            "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.2.tgz",
+            "integrity": "sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/webpack/node_modules/acorn": {
+            "version": "8.15.0",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+            "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+            "dev": true,
+            "license": "MIT",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/which": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+            "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+            "license": "ISC",
+            "dependencies": {
+                "isexe": "^2.0.0"
+            },
+            "bin": {
+                "node-which": "bin/node-which"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/which-typed-array": {
+            "version": "1.1.19",
+            "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+            "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+            "dev": true,
+            "license": "MIT",
+            "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"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/wide-align": {
+            "version": "1.1.5",
+            "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+            "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "string-width": "^1.0.2 || 2 || 3 || 4"
+            }
+        },
+        "node_modules/wildcard": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+            "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/with-open-file": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.7.tgz",
+            "integrity": "sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA==",
+            "license": "MIT",
+            "dependencies": {
+                "p-finally": "^1.0.0",
+                "p-try": "^2.1.0",
+                "pify": "^4.0.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/wordwrap": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+            "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/wrappy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+            "license": "ISC"
+        },
+        "node_modules/ws": {
+            "version": "7.5.10",
+            "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+            "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8.3.0"
+            },
+            "peerDependencies": {
+                "bufferutil": "^4.0.1",
+                "utf-8-validate": "^5.0.2"
+            },
+            "peerDependenciesMeta": {
+                "bufferutil": {
+                    "optional": true
+                },
+                "utf-8-validate": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/xmlbuilder": {
+            "version": "15.1.1",
+            "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+            "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/xmlhttprequest-ssl": {
+            "version": "1.6.3",
+            "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
+            "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/xtend": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+            "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4"
+            }
+        },
+        "node_modules/yallist": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+            "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+            "dev": true,
+            "license": "ISC"
+        },
+        "node_modules/yargs-parser": {
+            "version": "21.1.1",
+            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+            "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+            "dev": true,
+            "license": "ISC",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/yauzl": {
+            "version": "2.10.0",
+            "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+            "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "buffer-crc32": "~0.2.3",
+                "fd-slicer": "~1.1.0"
+            }
+        },
+        "node_modules/yazl": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+            "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+            "license": "MIT",
+            "dependencies": {
+                "buffer-crc32": "~0.2.3"
+            }
+        },
+        "node_modules/yeast": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+            "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==",
+            "license": "MIT"
+        },
+        "node_modules/yocto-queue": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+            "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        }
+    }
+}

+ 70 - 0
exe/package.json

@@ -0,0 +1,70 @@
+{
+    "name": "electronmain",
+    "version": "1.0.0",
+    "description": "",
+    "main": "src/main/index.js",
+    "scripts": {
+        "test": "echo \"Error: no test specified\" && exit 1",
+        "build:main": "webpack --mode production --config webpack.main.config.js",
+        "dev": "electron .",
+        "build": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./logo.ico",
+        "build_app_main": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./logo.ico --ignore=\"myFile/*\" --ignore=\"new_src/*\" --ignore=\"outApp/*\" ",
+        "clean_app_src" : "node clean_app_src_folder.js",
+        "build_app_src": "webpack --mode production --config webpack.main.build.config.js",
+        "build_app_asar": "asar pack outApp/HelloWorld-win32-x64/resources/app outApp/HelloWorld-win32-x64/resources/app.asar",
+        "clean_app" : "node clean_app_folder.js",
+        "build_app_ok": "echo \"########## build ok ##########\" && exit 1",
+        "build_app_start" : "npm run build_app_main && npm run clean_app_src && npm run build_app_src && npm run build_app_asar && npm run clean_app && npm run build_app_ok"
+    },
+    "type": "commonjs",
+    "keywords": [],
+    "author": "",
+    "license": "ISC",
+    "devDependencies": {
+        "@babel/core": "^7.26.10",
+        "@babel/preset-env": "^7.26.9",
+        "asar": "^3.2.0",
+        "babel-loader": "^10.0.0",
+        "browserify": "^17.0.0",
+        "electron": "^35.1.4",
+        "electron-packager": "^17.1.2",
+        "html-webpack-plugin": "^5.6.3",
+        "nodemon": "^2.0.12",
+        "webpack": "^5.99.5",
+        "webpack-cli": "^6.0.1",
+        "webpack-merge": "^6.0.1"
+    },
+    "dependencies": {
+        "axios": "^0.21.1",
+        "body-parser": "^1.19.0",
+        "compressing": "^1.5.1",
+        "cookie-parser": "^1.4.5",
+        "cors": "^2.8.5",
+        "date-fns": "^2.22.1",
+        "electron-reloader": "^1.2.3",
+        "express": "^4.17.1",
+        "express-static": "^1.2.6",
+        "file-type": "^16.5.2",
+        "fs-extra": "^10.0.0",
+        "gm": "^1.23.1",
+        "iconv-lite": "^0.6.3",
+        "image-size": "^1.0.0",
+        "log4js": "^6.7.1",
+        "mime": "^2.5.2",
+        "moment": "^2.29.1",
+        "multer": "^1.4.2",
+        "node-cmd": "^4.0.0",
+        "nprogress": "^0.2.0",
+        "pm2": "^5.2.2",
+        "print-js": "^1.6.0",
+        "Printer": "^1.0.0",
+        "read-chunk": "^3.2.0",
+        "rebuild": "^0.1.2",
+        "serve-index": "^1.9.1",
+        "silly-datetime": "^0.1.2",
+        "socket.io": "^2.0.4",
+        "sqlite3": "^5.0.11",
+        "uuid": "^8.3.2",
+        "ws": "^7.5.3"
+    }
+}

+ 580 - 0
exe/src/common/moudles/CommonVar.js

@@ -0,0 +1,580 @@
+var MySqllite = require('../../common/moudles/MySqllite.js');
+var SystemInformation = require('../../common/moudles/SystemInformation.js');
+var MyFile = require('../../common/moudles/MyFile.js');
+// 时间模块
+var modelsSillyDatetime = require('silly-datetime');
+var modelsMoment = require('moment');
+
+// 通用的全局变量和方法
+class CommonVar {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+        // 判断web服务是否启动成功
+        this.webServerStartBool = false
+        // 全局常量
+        this.constVal = {
+            "userObj" : {
+                "state" : {
+                    0 : "未分析",
+                    1 : "完成",
+                }
+            },
+            "userObjUrl" : {
+                "state" : {
+                    0 : "未分析",
+                    1 : "完成",
+                }
+            },
+            "userObjUrlVideo" : {
+                "state" : {
+                    0 : "未分析",
+                    1 : "完成",
+                }
+            }
+        }
+
+        // 机器码
+        this.machineCode = null;
+        // 到期时间
+        this.timeEnd = null;
+        // 激活码
+        this.activation = null;
+        // 获取根目录
+        this.commonPath = MyFile.find().pathStart() + "new_src/";
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+    /**
+     * 返回接口正确结果格式
+     * res  objRouter.post('/userObjAdd', function (req, res) { 的  res 参数
+     * data  返回的数据,可以是字符串,也可以是数组,或者 json
+     */
+    retOk(res, data) {
+
+        return res.send({
+            "success": true,
+            "code": 200,
+            "data": data,
+            "message": "OK"
+
+        })
+
+    }
+
+    /**
+     * 返回接口错误格式
+     * res  objRouter.post('/userObjAdd', function (req, res) { 的  res 参数
+     * data  返回的数据,可以是字符串,也可以是数组,或者 json
+     */
+    retError(res, data) {
+
+        return res.send({
+            "success": false,
+            "code": 500,
+            "data": {
+                "name": "报错了",
+                "message": data,
+                "code": 0,
+                "status": 500,
+                "type": "报错了"
+            },
+            "message": "报错了"
+        })
+
+    }
+
+    /**
+     * 通用分页查询结果
+     * sql          sql语句前缀 例如 Select * from users order by id desc  千万,不要有 ;  结尾 【 注意 from 也一定是要小写  , 排序  order by 一定用小写】
+     * limitPage    第几页
+     * limitSum     每页显示几条数据
+     * callback     成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+    sqlitePage(sql, limitPage, limitSum, callback) {
+
+        // 查询数据
+        var selectSql = sql + " LIMIT " + ((limitPage - 1) * limitSum) + ", " + limitSum;
+
+        // 分割数组
+        var selectSqlArray = selectSql.split("order by");
+        // 找到 from所在下标
+        var fromIndex = selectSqlArray[0].indexOf('from');
+        // 返回总数量
+        var countSql = "Select count(*) as sumMax " + selectSqlArray[0].substring(fromIndex, selectSqlArray[0].length - 1);
+        
+        // 返回查询返回的所有数据
+        var pageDb = [];
+        // 总数量
+        var sumMax = 0;
+
+        // 查询总数据
+        MySqllite.find().query(selectSql, 'all', function (err, selectSqlRes) {
+
+            if (selectSqlRes != undefined && selectSqlRes != null) {
+                pageDb = selectSqlRes;
+            }
+
+            // 查询总数量
+            MySqllite.find().query(countSql, 'get', function (err, countSqlRes) {
+
+                
+                if (countSqlRes != undefined && countSqlRes != null) {
+                    sumMax = countSqlRes['sumMax'];
+                }
+
+                var sumPage = Number(sumMax / limitSum).toString();
+                if (sumPage.indexOf('.') >= 0) {
+                    var sumPageArray = sumPage.split(".");
+                    sumPage = Number(sumPageArray[0]) + 1;
+                }
+
+                var ret = {
+                    'page' : pageDb,
+                    '_meta' : {
+                        // 总共页数
+                        'sum_page' : sumPage,
+                        // 每页显示数据数量
+                        'all_sum' : limitSum,
+                        // 当前页显示数据数量
+                        'this_sum' : pageDb.length,
+                        // 总数量
+                        'sum' : sumMax,
+                    },
+                }
+        
+                return callback(ret)
+
+
+            });
+
+    
+        });
+
+    }
+
+
+    /**
+     * 公共操作文件缓存
+     * type     get - 获取内容, set - 设置
+     * name     缓存的名字
+     * val      type = get 可以不传, = set 传 null 则为删除 否则为更新
+     */
+    cacheGetOrUpdate(type, name, val) {
+
+        var objPath = this.commonPath + name + ".txt";
+
+        if (type === 'get') {
+            var data = MyFile.find().fileRead(objPath);
+            return data === false ? null : data;
+        }
+
+        // 删除缓存
+        if (val === undefined || val === null) {
+            MyFile.find().fileDel(objPath);
+            return null;
+        }
+
+        MyFile.find().fileCreate(objPath, val, 'w');
+
+        return val;
+
+    }
+
+    /**
+     * 获取激活信息
+     */
+    getMain () {
+
+        // 机器码
+        if (this.machineCode === null || this.machineCode === undefined) {
+            // 获取硬盘序列号,每台电脑都是唯一值
+            this.machineCode = SystemInformation.find().getDiskdriveSerialnumber();
+            this.machineCode = Buffer.from(this.machineCode).toString('base64');
+        }
+
+
+        // 到期时间
+        this.timeEnd = this.cacheGetOrUpdate("get", "timeEnd");
+        // 激活码
+        this.activation = this.cacheGetOrUpdate("get", "activation");
+
+
+        return {
+            "machineCode": this.machineCode,
+            "timeEnd": this.timeEnd,
+            "activation": this.activation
+        }
+        
+    }
+
+    /**
+     * 根据到期时间生成密钥
+     * machineCode  机器码
+     * timeEnd      到期时间
+     */
+    activationCode(machineCode, timeEnd) {
+
+        // 必须是16位
+        var pwd = "abcdefghijklmnop";
+        var txtAdd = SystemInformation.find().aseEncode(machineCode + timeEnd, pwd);
+        
+        return txtAdd;
+
+    }
+
+
+    /**
+     * 判断激活是否成功
+     */
+    stateBool() {
+
+        var getActivationCode = this.activationCode(this.machineCode, this.timeEnd);
+        if (getActivationCode !== this.activation) {
+            return false;
+        }
+
+        // 获取当前的时间戳
+        var thisTime = Date.now();
+        // 转换成时间戳
+        var timeEndNum = new Date(this.timeEnd + " 23:59:59").getTime();
+        
+        if (timeEndNum < thisTime) {
+            console.log(thisTime, timeEndNum);
+            return false;
+        }
+
+        return true;
+
+    }
+
+    /**
+     * 根据项目ID创建对应的目录,返回对应ID的目录
+     * id   传项目ID
+     */
+    projectPath(id) {
+
+        let pathMyResCom = 'myRes/'
+        let pathMyRes = this.commonPath + pathMyResCom
+        MyFile.find().pathCreate(pathMyRes)
+
+        let path3dCom = '3d/'
+        let path3d = this.commonPath + path3dCom
+        MyFile.find().pathCreate(path3d)
+
+        let pathId = path3dCom + id + "/"
+        let path = this.commonPath + pathId
+        MyFile.find().pathCreate(path)
+
+        // 模型存放的目录
+        let pathIdModel = pathId +  "model/"
+        let pathModel = this.commonPath + pathIdModel
+        MyFile.find().pathCreate(pathModel)
+
+        // 得到对应最后完成时间的文件的时间戳结果
+        let updateOkTimeFileName = "updateOkTime.txt";
+        let updateOkTimePath = pathModel + "updateOkTime.txt";
+
+        // 记录最后操作完成的文件列表
+        let okFileListFileName = "okFileList.txt";
+        let okFileListPath = pathModel + okFileListFileName;
+
+        let json = {
+            // 项目根目录
+            'commonPath' : this.commonPath,
+            'pathMyResCom' : pathMyResCom,
+            'pathMyRes' : pathMyRes,
+            'path3dCom' : path3dCom,
+            'path3d' : path3d,
+            'pathId' : pathId,
+            'path' : path,
+            'pathIdModel' : pathIdModel,
+            'pathModel' : pathModel,
+            'updateOkTimeFileName' : updateOkTimeFileName,
+            'updateOkTimePath' : updateOkTimePath,
+            'okFileListFileName' : okFileListFileName,
+            'okFileListPath' : okFileListPath,
+        }
+
+        return json;
+    }
+
+    /**
+     * 保存项目ID配置的 configJson 的配置文件
+     * 还是读取内容
+     * id       项目id
+     * type     set 保存, get 读取
+     * txt      如果是保存,则该参数要传
+     * 无论保存,还是读取,都返回目标id的配置文件内容结果
+     */
+    projectPathConfigJson(id, type, txt) {
+        // 创建项目单独的存储目录
+        let path = CommonVar.find().projectPath(id);
+        // 文件存储目录
+        let pathSave = path['pathModel'];
+        // 配置文件名
+        let fileName = 'config.json';
+
+        if (type == 'set') {
+            MyFile.find().fileCreate(pathSave + fileName, txt, 'w');
+            return txt;
+        }
+
+        let json = MyFile.find().fileRead(pathSave + fileName);
+        if (json === false) {
+            return '{}';
+        }
+
+        return json;
+
+    }
+
+
+    /**
+     * 传入json对象,得到所有的字段,无论嵌套多少层都变成不是嵌套的字段
+     * json     json 对象
+     * array    默认传 []  即可,这个数组会自动不断追加到最后的结果
+     * 返回数组结果
+     */
+    jsonGetArray(json, array) {
+
+
+        if (array == null || array == undefined) {
+            array = [];
+        }
+
+        for (var key in json) {
+
+            var thisJson = json[key];
+            // console.log(typeof thisJson);
+
+            if (typeof thisJson == 'object') {
+
+                // console.log("object", thisJson);
+
+                // 如果是数组
+                if (thisJson instanceof Array) {
+                    
+                    for (var thisJsonI = 0; thisJsonI < thisJson.length; thisJsonI++) {
+
+                        var thisJsonArray = thisJson[thisJsonI];
+                        // console.log("数组 thisJsonArray", typeof thisJsonArray);
+
+                        if (typeof thisJsonArray == 'object') {
+
+                            // 如果是数组
+                            if (thisJsonArray instanceof Array) {
+
+                                // console.log("数组 thisJsonArray", thisJsonArray);
+
+                                for (var thisJsonArrayI = 0; thisJsonArrayI < thisJsonArray.length; thisJsonArrayI++) {
+
+                                    array.push({
+                                        'key' : thisJsonArrayI,
+                                        'val' : thisJsonArray[thisJsonArrayI]
+                                    });
+
+                                }
+
+                            } else {
+                                // console.log("对象 thisJsonArray", thisJsonArray);
+
+                                for (var thisJsonArrayKey in thisJsonArray) {
+
+                                    array.push({
+                                        'key' : thisJsonArrayKey,
+                                        'val' : thisJsonArray
+                                    });
+
+                                }
+
+                            }
+
+                        } else {
+
+                            array.push({
+                                'key' : thisJsonI,
+                                'val' : thisJsonArray
+                            });
+
+                        }
+
+
+                    }
+
+                } else {
+
+                    var thisJsonGetArray = CommonVar.find().jsonGetArray(thisJson);
+                    for (var thisJsonGetArrayI = 0; thisJsonGetArrayI < thisJsonGetArray.length; thisJsonGetArrayI++) {
+                        array.push(thisJsonGetArray[thisJsonGetArrayI]);
+                    }
+
+                }
+                
+            } else if (typeof thisJson == 'string') {
+
+                // console.log("string", thisJson);
+                array.push({
+                    'key' : key,
+                    'val' : thisJson
+                });
+
+            }
+            
+        }
+        
+
+        return array;
+
+    }
+
+
+    /**
+     * 获取 webserver 的端口号
+     */
+    getServerPort = function() {
+
+        var thisClass = this;
+
+        // 获取自定义端口
+        var port = thisClass.cacheGetOrUpdate('get', 'ServerPort');
+        // 不存在,则自动创建写入端口号
+        if (port == null) {
+            port = "6789";
+            thisClass.cacheGetOrUpdate('set', 'ServerPort', port);
+        }
+
+        return port;
+
+    }
+
+    /**
+     * 获取 WebSocket 的端口号
+     */
+    getWebSocketPort = function() {
+
+        var thisClass = this;
+
+        // 获取自定义端口
+        var port = thisClass.cacheGetOrUpdate('get', 'WebSocketPort');
+        // 不存在,则自动创建写入端口号
+        if (port == null) {
+            port = "6788";
+            thisClass.cacheGetOrUpdate('set', 'WebSocketPort', port);
+        }
+
+        return port;
+
+    }
+
+
+
+}
+
+module.exports = CommonVar;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 317 - 0
exe/src/common/moudles/MigrateSqllite.js

@@ -0,0 +1,317 @@
+// 引入封装好的类
+var MySqllite = require('../../common/moudles/MySqllite.js');
+// 时间模块
+var modelsSillyDatetime = require('silly-datetime');
+var modelsMoment = require('moment');
+
+/**
+ * 用于自动化同步数据表结构
+ * 只适用于 SQLLite 数据库
+ * 
+ * 使用说明,首先配置
+ * this.sqlUpdate  你要执行的sql语句
+ * 
+ * // 引入该模块
+ * var MigrateSqllite = require('../common/moudles/MigrateSqllite.js');
+ * 
+ * 然后在你要同步表结构调用
+ * MigrateSqllite.find().start();
+ * 
+ */
+class MigrateSqllite {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+        /**
+         * 定义要同步的表结构
+         */
+        this.sqlUpdate = [
+            // {
+            //     // 格式为时间戳,时间戳不要出现重复
+            //     "key" : "202205011055",
+            //     // 要执行的sql语句
+            //     "sql" : "CREATE TABLE users(id varchar(255) PRIMARY KEY NOT NULL, name TEXT NOT NULL, age integer(11) NOT NULL, address varchar(255) );",
+            // },
+            // {
+            //     "key" : "202205011056",
+            //     "sql" : "INSERT INTO users (id, name, age) VALUES ('1', '姓名', 3);",
+            // },
+            // {
+            //     "key" : "202205011057",
+            //     "sql" : "INSERT INTO users (id, name, age) VALUES ('2', '姓名', 3);",
+            // },
+            {
+                "key" : "202205050800",
+                "sql" : "CREATE TABLE user_obj(id varchar(255) PRIMARY KEY NOT NULL, del integer(11), time VARCHAR(255), user_name varchar(255), state integer(11), sum integer(11) );",
+            },
+            // {
+            //     "key" : "202205050801",
+            //     "sql" : "CREATE TABLE user_obj_url(user_obj_id varchar(255) PRIMARY KEY NOT NULL, del integer(11), time VARCHAR(255), sec_uid varchar(255), state integer(11) );",
+            // },
+            // {
+            //     "key" : "202205050802",
+            //     "sql" : "CREATE TABLE user_obj_url_video(user_obj_id varchar(255), del integer(11), time VARCHAR(255), aweme_id varchar(255), state integer(11) );",
+            // },
+            // {
+            //     "key" : "202205050803",
+            //     "sql" : "CREATE TABLE user_obj_url_video_comment(id varchar(255) PRIMARY KEY NOT NULL, aweme_id varchar(255), del integer(11), time VARCHAR(255), create_time varchar(255), text text, nickname varchar(255), uid varchar(255), short_id varchar(255), sec_uid varchar(255), unique_id varchar(255) );",
+            // },
+            {
+                "key" : "202209030909",
+                "sql" : "CREATE TABLE project(id varchar(255) PRIMARY KEY NOT NULL, del integer(11), time VARCHAR(255), name varchar(255), model_main varchar(255) );",
+            },
+            {
+                "key" : "202307032139",
+                "sql" : "CREATE TABLE name_only(id varchar(255) PRIMARY KEY NOT NULL, del integer(11), time VARCHAR(255), name varchar(255), type integer(11) );",
+            },
+        ];
+
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+
+    /**
+     * 开始同步数据
+     */
+    start() {
+
+        this.migrateCreateBool(function(result) {
+            
+            MigrateSqllite.find().sqlStart(0, function(migrateSqlliteRes) {
+                console.log("数据表同步数据完成");
+            });
+
+        });
+
+    }
+
+    /**
+     * 判断 migrate 表是否存在
+     * callback 成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+    migrateCreateBool(callback) {
+
+        var sql = 'SELECT name FROM sqlite_master WHERE type="table"';
+        // 因为操作数据库是异步的
+        MySqllite.find().query(sql, 'all', function (err, result) {
+
+            // 判断 migrate表是否存在
+            var migrateTabelBool = false;
+
+            if (result.length > 0) {
+
+                for (var key in result) {
+
+                    if (result[key].name === 'migrate') {
+                        migrateTabelBool = true;
+                    }
+
+                }
+
+            }
+
+            // 如果不存在
+            if (migrateTabelBool === false) {
+                // 创建表
+                var createTable = 'CREATE TABLE migrate(name varchar(255), time VARCHAR(255));';
+                MySqllite.find().query(createTable, null, function (err, result) {
+                    callback(result)
+                });
+
+            } else {
+                callback("migrate 已经存在了")
+            }
+
+        });
+
+
+    }
+
+    /**
+     * 开始执行sql语句
+     * sum      当前执行的是第几个数组下标,当数组下标是最后一个,并且执行完成后,则改方法调用结束
+     * callback 成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+    sqlStart(sum, callback) {
+
+        if (this.sqlUpdate.length <= 0) {
+            return callback("同步完成")
+        }
+
+        var thisSqlUpdate = this.sqlUpdate[sum];
+        
+
+        this.sqlMigrate(thisSqlUpdate, function(sqlMigrateErr, sqlMigrateRes) {
+
+
+            console.log(sqlMigrateRes)
+
+
+            if (sum >= (MigrateSqllite.find().sqlUpdate.length - 1)) {
+                return callback("表结构同步完成")
+            }
+    
+            return MigrateSqllite.find().sqlStart(sum +=1, callback)
+
+
+        })
+
+
+    }
+
+    /**
+     * 执行sql语句,更新到 migrate 里
+     * thisSqlUpdate    当前执行的sql语句
+     * callback 成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (err, result) {}
+     */
+    sqlMigrate(thisSqlUpdate, callback) {
+
+        // 转换成你要的时间格式
+        var date = modelsSillyDatetime.format(new Date(), 'YYYY-MM-DD HH:mm:ss');
+
+        // 判断是否执行过记录了
+        // 查询单条数据,只会返回一条数据
+        // var sql = "SELECT * FROM users WHERE id = '38c7e90c-39d8-4c6b-bc70-a3d837f60c42';";
+        var sql = "SELECT * FROM migrate WHERE name = '" + thisSqlUpdate['key'] + "';";
+
+        // 因为操作数据库是异步的
+        MySqllite.find().query(sql, 'get', function (err, result) {
+
+
+            // 此时说明是不存在的
+            if (result === undefined || result === null) {
+
+
+                // 所以我们采用回调的方法,来实现同步
+                MySqllite.find().query(thisSqlUpdate['sql'], null, function (err, result) {
+
+                    
+                    // 新增执行过的记录
+                    var sqlAddMigrate = "INSERT INTO migrate (name, time) VALUES ('" + thisSqlUpdate['key'] + "', '" + date + "');";
+                    MySqllite.find().query(sqlAddMigrate, null, function (err, result) {
+                        callback(null, "表结构同步 = " + thisSqlUpdate['key'] + " 执行完成")
+                    });
+                });
+
+                return true;
+            }
+
+            // 已经执行过了,则就不需要执行了
+            callback(null, thisSqlUpdate['key'] + " 已经执行过了")
+
+
+        });
+
+    }
+
+
+}
+
+module.exports = MigrateSqllite;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 955 - 0
exe/src/common/moudles/MyFile.js

@@ -0,0 +1,955 @@
+/**
+ * 注意,该类一定要放在 common/moudles
+ * 否则 获取根目录 pathStart() 的方法会不准
+ * 如果不是,那么请修改 pathStart() 的方法逻辑
+ */
+class MyFile {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+        /**
+         * 对应文件后缀找到对应的 Content-Type
+         */
+        this.mime = {
+            ".": "application/x-",
+            ".*": "application/octet-stream",
+            ".pdf": "application/pdf",
+            ".ai": "application/postscript",
+            ".xml": "application/xop+xml",
+            ".js": "application/x-javascript",
+            ".edi": "application/EDIFACT",
+            ".json": "application/json",
+            ".ogg": "application/ogg",
+            ".rdf": "application/rdf+xml",
+            ".woff": "application/font-woff",
+            ".xhtml": "application/xhtml+xml",
+            ".dtd": "application/xml-dtd",
+            ".zip": "application/zip",
+            ".gzip": "application/gzip",
+            ".xls": "application/vnd.ms-excel",
+            ".001": "application/x-001",
+            ".301": "application/x-301",
+            ".906": "application/x-906",
+            ".a11": "application/x-a11",
+            ".awf": "application/vnd.adobe.workflow",
+            ".bmp": "application/x-bmp",
+            ".c4t": "application/x-c4t",
+            ".cal": "application/x-cals",
+            ".cdf": "application/x-netcdf",
+            ".cel": "application/x-cel",
+            ".cg4": "application/x-g4",
+            ".cit": "application/x-cit",
+            ".bot": "application/x-bot",
+            ".c90": "application/x-c90",
+            ".cat": "application/vnd.ms-pki.seccat",
+            ".cdr": "application/x-cdr",
+            ".cer": "application/x-x509-ca-cert",
+            ".cgm": "application/x-cgm",
+            ".cmx": "application/x-cmx",
+            ".crl": "application/pkix-crl",
+            ".csi": "application/x-csi",
+            ".cut": "application/x-cut",
+            ".dbm": "application/x-dbm",
+            ".cmp": "application/x-cmp",
+            ".cot": "application/x-cot",
+            ".crt": "application/x-x509-ca-cert",
+            ".dbf": "application/x-dbf",
+            ".dbx": "application/x-dbx",
+            ".dcx": "application/x-dcx",
+            ".dgn": "application/x-dgn",
+            ".dll": "application/x-msdownload",
+            ".dot": "application/msword",
+            ".der": "application/x-x509-ca-cert",
+            ".dib": "application/x-dib",
+            ".doc": "application/msword",
+            ".drw": "application/x-drw",
+            ".dwf": "application/x-dwf",
+            ".dxb": "application/x-dxb",
+            ".edn": "application/vnd.adobe.edn",
+            ".dwg": "application/x-dwg",
+            ".dxf": "application/x-dxf",
+            ".emf": "application/x-emf",
+            ".epi": "application/x-epi",
+            ".eps": "application/x-ps",
+            ".exe": "application/x-msdownload",
+            ".fdf": "application/vnd.fdf",
+            ".etd": "application/x-ebx",
+            ".fif": "application/fractals",
+            ".frm": "application/x-frm",
+            ".gbr": "application/x-gbr",
+            ".g4": "application/x-g4",
+            ".gl2": "application/x-gl2",
+            ".hgl": "application/x-hgl",
+            ".hpg": "application/x-hpgl",
+            ".hqx": "application/mac-binhex40",
+            ".hta": "application/hta",
+            ".gp4": "application/x-gp4",
+            ".hmr": "application/x-hmr",
+            ".hpl": "application/x-hpl",
+            ".hrf": "application/x-hrf",
+            ".icb": "application/x-icb",
+            ".ico": "application/x-ico",
+            ".ig4": "application/x-g4",
+            ".iii": "application/x-iphone",
+            ".ins": "application/x-internet-signup",
+            ".iff": "application/x-iff",
+            ".igs": "application/x-igs",
+            ".img": "application/x-img",
+            ".isp": "application/x-internet-signup",
+            ".jpe": "application/x-jpe",
+            ".jpg": "application/x-jpg",
+            ".lar": "application/x-laplayer-reg",
+            ".latex": "application/x-latex",
+            ".lbm": "application/x-lbm",
+            ".ls": "application/x-javascript",
+            ".ltr": "application/x-ltr",
+            ".man": "application/x-troff-man",
+            ".mdb": "application/x-mdb",
+            ".mac": "application/x-mac",
+            ".mfp": "application/x-shockwave-flash",
+            ".mi": "application/x-mi",
+            ".mil": "application/x-mil",
+            ".mocha": "application/x-javascript",
+            ".mpd": "application/vnd.ms-project",
+            ".mpp": "application/vnd.ms-project",
+            ".mpt": "application/vnd.ms-project",
+            ".mpw": "application/vnd.ms-project",
+            ".mpx": "application/vnd.ms-project",
+            ".mxp": "application/x-mmxp",
+            ".nrf": "application/x-nrf",
+            ".out": "application/x-out",
+            ".p12": "application/x-pkcs12",
+            ".p7c": "application/pkcs7-mime",
+            ".p7r": "application/x-pkcs7-certreqresp",
+            ".pc5": "application/x-pc5",
+            ".pcl": "application/x-pcl",
+            ".pdx": "application/vnd.adobe.pdx",
+            ".pgl": "application/x-pgl",
+            ".pko": "application/vnd.ms-pki.pko",
+            ".p10": "application/pkcs10",
+            ".p7b": "application/x-pkcs7-certificates",
+            ".p7m": "application/pkcs7-mime",
+            ".p7s": "application/pkcs7-signature",
+            ".pci": "application/x-pci",
+            ".pcx": "application/x-pcx",
+            ".pfx": "application/x-pkcs12",
+            ".pic": "application/x-pic",
+            ".pl": "application/x-perl",
+            ".plt": "application/x-plt",
+            ".png": "application/x-png",
+            ".ppa": "application/vnd.ms-powerpoint",
+            ".pps": "application/vnd.ms-powerpoint",
+            ".ppt": "application/vnd.ms-powerpoint",
+            ".prf": "application/pics-rules",
+            ".prt": "application/x-prt",
+            ".ps": "application/x-ps",
+            ".pwz": "application/vnd.ms-powerpoint",
+            ".ra": "audio/vnd.rn-realaudio",
+            ".ras": "application/x-ras",
+            ".pot": "application/vnd.ms-powerpoint",
+            ".ppm": "application/x-ppm",
+            ".pr": "application/x-pr",
+            ".prn": "application/x-prn",
+            ".ptn": "application/x-ptn",
+            ".red": "application/x-red",
+            ".rjs": "application/vnd.rn-realsystem-rjs",
+            ".rlc": "application/x-rlc",
+            ".rm": "application/vnd.rn-realmedia",
+            ".rat": "application/rat-file",
+            ".rec": "application/vnd.rn-recording",
+            ".rgb": "application/x-rgb",
+            ".rjt": "application/vnd.rn-realsystem-rjt",
+            ".rle": "application/x-rle",
+            ".rmf": "application/vnd.adobe.rmf",
+            ".rmj": "application/vnd.rn-realsystem-rmj",
+            ".rmp": "application/vnd.rn-rn_music_package",
+            ".rmvb": "application/vnd.rn-realmedia-vbr",
+            ".rnx": "application/vnd.rn-realplayer",
+            ".rpm": "audio/x-pn-realaudio-plugin",
+            ".rms": "application/vnd.rn-realmedia-secure",
+            ".rmx": "application/vnd.rn-realsystem-rmx",
+            ".rsml": "application/vnd.rn-rsml",
+            ".rtf": "application/x-rtf",
+            ".rv": "video/vnd.rn-realvideo",
+            ".sat": "application/x-sat",
+            ".sdw": "application/x-sdw",
+            ".slb": "application/x-slb",
+            ".sam": "application/x-sam",
+            ".sdp": "application/sdp",
+            ".sit": "application/x-stuffit",
+            ".sld": "application/x-sld",
+            ".smi": "application/smil",
+            ".smk": "application/x-smk",
+            ".smil": "application/smil",
+            ".spc": "application/x-pkcs7-certificates",
+            ".spl": "application/futuresplash",
+            ".ssm": "application/streamingmedia",
+            ".stl": "application/vnd.ms-pki.stl",
+            ".sst": "application/vnd.ms-pki.certstore",
+            ".tdf": "application/x-tdf",
+            ".tga": "application/x-tga",
+            ".sty": "application/x-sty",
+            ".swf": "application/x-shockwave-flash",
+            ".tg4": "application/x-tg4",
+            ".tif": "application/x-tif",
+            ".vdx": "application/vnd.visio",
+            ".vpg": "application/x-vpeg005",
+            ".vsd": "application/vnd.visio",
+            ".vst": "application/x-vst",
+            ".vsw": "application/vnd.visio",
+            ".vtx": "application/vnd.visio",
+            ".torrent": "application/x-bittorrent",
+            ".vda": "application/x-vda",
+            ".vss": "application/vnd.visio",
+            ".vsx": "application/vnd.visio",
+            ".wb1": "application/x-wb1",
+            ".wb3": "application/x-wb3",
+            ".wiz": "application/msword",
+            ".wk4": "application/x-wk4",
+            ".wks": "application/x-wks",
+            ".wb2": "application/x-wb2",
+            ".wk3": "application/x-wk3",
+            ".wkq": "application/x-wkq",
+            ".wmf": "application/x-wmf",
+            ".wmd": "application/x-ms-wmd",
+            ".wp6": "application/x-wp6",
+            ".wpg": "application/x-wpg",
+            ".wq1": "application/x-wq1",
+            ".wri": "application/x-wri",
+            ".ws": "application/x-ws",
+            ".wmz": "application/x-ms-wmz",
+            ".wpd": "application/x-wpd",
+            ".wpl": "application/vnd.ms-wpl",
+            ".wr1": "application/x-wr1",
+            ".wrk": "application/x-wrk",
+            ".ws2": "application/x-ws",
+            ".xdp": "application/vnd.adobe.xdp",
+            ".xfd": "application/vnd.adobe.xfd",
+            ".xfdf": "application/vnd.adobe.xfdf",
+            ".xwd": "application/x-xwd",
+            ".sis": "application/vnd.symbian.install",
+            ".x_t": "application/x-x_t",
+            ".apk": "application/vnd.android.package-archive",
+            ".x_b": "application/x-x_b",
+            ".sisx": "application/vnd.symbian.install",
+            ".ipa": "application/vnd.iphone",
+            ".xap": "application/x-silverlight-app",
+            ".xlw": "application/x-xlw",
+            ".xpl": "audio/scpls",
+            ".anv": "application/x-anv",
+            ".uin": "application/x-icq",
+            ".323": "text/h323",
+            ".biz": "text/xml",
+            ".cml": "text/xml",
+            ".asa": "text/asa",
+            ".asp": "text/asp",
+            ".css": "text/css",
+            ".csv": "text/csv",
+            ".dcd": "text/xml",
+            ".dtd": "text/xml",
+            ".ent": "text/xml",
+            ".fo": "text/xml",
+            ".htc": "text/x-component",
+            ".html": "text/html",
+            ".htx": "text/html",
+            ".htm": "text/html",
+            ".htt": "text/webviewhtml",
+            ".jsp": "text/html",
+            ".math": "text/xml",
+            ".mml": "text/xml",
+            ".mtx": "text/xml",
+            ".plg": "text/html",
+            ".rdf": "text/xml",
+            ".rt": "text/vnd.rn-realtext",
+            ".sol": "text/plain",
+            ".spp": "text/xml",
+            ".stm": "text/html",
+            ".svg": "text/xml",
+            ".tld": "text/xml",
+            ".txt": "text/plain",
+            ".uls": "text/iuls",
+            ".vml": "text/xml",
+            ".tsd": "text/xml",
+            ".vcf": "text/x-vcard",
+            ".vxml": "text/xml",
+            ".wml": "text/vnd.wap.wml",
+            ".wsdl": "text/xml",
+            ".wsc": "text/scriptlet",
+            ".xdr": "text/xml",
+            ".xql": "text/xml",
+            ".xsd": "text/xml",
+            ".xslt": "text/xml",
+            ".xml": "text/xml",
+            ".xq": "text/xml",
+            ".xquery": "text/xml",
+            ".xsl": "text/xml",
+            ".xhtml": "text/html",
+            ".odc": "text/x-ms-odc",
+            ".r3t": "text/vnd.rn-realtext3d",
+            ".sor": "text/plain",
+            ".acp": "audio/x-mei-aac",
+            ".aif": "audio/aiff",
+            ".aiff": "audio/aiff",
+            ".aifc": "audio/aiff",
+            ".au": "audio/basic",
+            ".la1": "audio/x-liquid-file",
+            ".lavs": "audio/x-liquid-secure",
+            ".lmsff": "audio/x-la-lms",
+            ".m3u": "audio/mpegurl",
+            ".midi": "audio/mid",
+            ".mid": "audio/mid",
+            ".mp2": "audio/mp2",
+            ".mp3": "audio/mp3",
+            ".mp4": "audio/mp4",
+            ".mnd": "audio/x-musicnet-download",
+            ".mp1": "audio/mp1",
+            ".mns": "audio/x-musicnet-stream",
+            ".mpga": "audio/rn-mpeg",
+            ".pls": "audio/scpls",
+            ".ram": "audio/x-pn-realaudio",
+            ".rmi": "audio/mid",
+            ".rmm": "audio/x-pn-realaudio",
+            ".snd": "audio/basic",
+            ".wav": "audio/wav",
+            ".wax": "audio/x-ms-wax",
+            ".wma": "audio/x-ms-wma",
+            ".asf": "video/x-ms-asf",
+            ".asx": "video/x-ms-asf",
+            ".avi": "video/avi",
+            ".IVF": "video/x-ivf",
+            ".m1v": "video/x-mpeg",
+            ".m2v": "video/x-mpeg",
+            ".m4e": "video/mpeg4",
+            ".movie": "video/x-sgi-movie",
+            ".mp2v": "video/mpeg",
+            ".mp4": "video/mpeg4",
+            ".mpa": "video/x-mpg",
+            ".mpe": "video/x-mpeg",
+            ".mpg": "video/mpg",
+            ".mpeg": "video/mpg",
+            ".mps": "video/x-mpeg",
+            ".mpv": "video/mpg",
+            ".mpv2": "video/mpeg",
+            ".wm": "video/x-ms-wm",
+            ".wmv": "video/x-ms-wmv",
+            ".wmx": "video/x-ms-wmx",
+            ".wvx": "video/x-ms-wvx",
+            ".tif": "image/tiff",
+            ".fax": "image/fax",
+            ".gif": "image/gif",
+            ".ico": "image/x-icon",
+            ".jfif": "image/jpeg",
+            ".jpe": "image/jpeg",
+            ".jpeg": "image/jpeg",
+            ".jpg": "image/jpeg",
+            ".net": "image/pnetvue",
+            ".png": "image/png",
+            ".rp": "image/vnd.rn-realpix",
+            ".tiff": "image/tiff",
+            ".wbmp": "image/vnd.wap.wbmp",
+            ".eml": "message/rfc822",
+            ".mht": "message/rfc822",
+            ".mhtml": "message/rfc822",
+            ".nws": "message/rfc822",
+            ".907": "drawing/907",
+            ".slk": "drawing/x-slk",
+            ".top": "drawing/x-top",
+            ".class": "java/*",
+            ".java": "java/*",
+            ".dwf": "Model/vnd.dwf",
+            ".babylon" : "application/octet-stream",
+            ".glb" : "model/gltf-binary",
+            ".txt" : "text/plain",
+            ".bin" : "application/octet-stream",
+            ".gltf" : "model/gltf+json",
+            ".fbx" : "application/octet-stream",
+            ".mp3" : "audio/mpeg",
+            ".webp" : "image/webp",
+            ".dds" : "application/octet-stream",
+            ".env" : "application/octet-stream",
+            ".mtl" : "application/octet-stream",
+            ".obj" : "application/x-tgif",
+            ".hdr" : "application/octet-stream",
+            ".sdf" : "application/octet-stream",
+            // 自定义的一个文件格式
+            ".chengguangyuanjing" : "model/gltf+json",
+            ".cg" : "model/gltf+json",
+            ".babylonbinarymeshdata" : "application/octet-stream",
+        }
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+     static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+    /**
+     * 统一格式化目录
+     * path  传具体目录,例如 C:\a\b\c\
+     * 返回字符串 , 例如 C:/a/b/c/
+     */
+    pathFormat(path) {
+
+        path = path.replace("\\", "/");
+        path = path.replace("//", "/");
+
+        if (
+            path.indexOf("\\") > 0
+            || path.indexOf("//") > 0
+        ) {
+            return this.pathFormat(path);
+        }
+
+        return path;
+    }
+
+    /**
+     * 获取根目录
+     * 返回字符串
+     */
+    pathStart() {
+        
+        var path = __dirname;
+
+        path = this.pathFormat(path);
+
+        var pathNew = path;
+
+        // // // 如果你的代码目录结构改了,这里打包后,则需要单独写入文件,调试,来修改这里的代码,得到真正新的根目录的逻辑
+        // // var pathNew = path;
+        // // this.fileCreate(pathNew + '/path.txt', '' + pathNew, 'w');
+        // // 测试调试用
+        // this.fileCreate('E:/path.txt', '' + pathNew, 'w');
+
+        /**
+         * 如果打包的结果是 app.asar 的方式
+         * E:/2022-08-08_work/code/demo_t/ExeMainApp/outApp/HelloWorld-win32-x64/resources/app.asar/src/common/moudles
+         * 得到的根目录是这样的,需要特殊处理
+         */
+        if (path.indexOf("/resources/app.asar") >= 0) {
+            var pathArray = path.split("/resources/app.asar");
+            pathNew = pathArray[0] + "/";
+        }
+        /**
+         * E:/2022-08-08_work/code/demo_t/ExeMainApp/outApp/HelloWorld-win32-x64/resources/app/src/main
+         * 此时说明是发布后的项目,获取根目录则需要这里处理
+         */
+        else if (path.indexOf("/resources/app/src") >= 0) {
+            pathNew = path.substr(0, path.indexOf("/resources/app/src")) + "/";
+        }
+        /**
+         * 【打包后,会生成入口文件放到了 dist 里】
+         * E:/2022-08-08_work/code/demo_t/ExeMainApp/outApp/HelloWorld-win32-x64/resources/app/dist/main
+         * 此时说明是发布后的项目,获取根目录则需要这里处理
+         */
+        else if (path.indexOf("/resources/app/dist") >= 0) {
+            pathNew = path.substr(0, path.indexOf("/resources/app/dist")) + "/";
+        } else {
+
+            /**
+             * E:/2022-08-08_work/code/demo_t/ExeMainApp/src/common/moudles
+             * 此时说明是开发模式
+             */
+            if (path.indexOf("src/common/moudles") >= 0) {
+                pathNew = path.substr(0, path.length - ("src/common/moudles").length) + "/";
+            }
+            // 如果得到的结果不是win系统的目录。而此时可能是 mac 或者  linux 系统的, 或者是用了 electron 运行的程序
+            else if (pathNew.indexOf(":") < 0) {
+                pathNew = "./";
+            }
+            
+        }
+
+        // // 测试调试用
+        // this.fileCreate('E:/path.txt', '' + pathNew, 'w');
+
+        // // 去除 common/moudles,来得到真正的项目根目录【 此时得到的是适合 win系统的】
+        // var pathNew = path.substr(0, path.length - ("/common/moudles").length) + "/";
+
+       
+        // // 如果是 electron 打包后的安装应用, 而且是win系统运行  D:/Electron_EXE_OPEN/electron-vue-template/build/win-unpacked/resources/app.asa/
+        // if (path.indexOf("/resources/app") >= 0) {
+        //     pathNew = path;
+        //     pathNew = path.substr(0, path.length - ("/resources/app.asar/dist/electron").length) + "/";
+        // }
+        // // 如果得到的结果不是win系统的目录。而此时可能是 mac 或者  linux 系统的, 或者是用了 electron 运行的程序
+        // else if (pathNew.indexOf(":") < 0) {
+        //     pathNew = "./";
+        // }
+
+        return this.pathFormat(pathNew);
+
+    }
+
+    /**
+     * 创建目录
+     * path 传具体创建的目录,例如 C:/abc
+     * 成功返回 true , 失败返回字符串具体原因
+     */
+    pathCreate(path) {
+
+        var objFs = require("fs");
+        path = this.pathFormat(path);
+
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(path);
+        if (pathBool == true) {
+            return "目录已存在";
+        }
+        
+        try {
+            objFs.mkdirSync(path);
+        } catch (e) {
+            return "没有操作权限";
+        }
+
+        return true;
+
+    }
+
+    /**
+     * 删除目录
+     * path 传具体目录,例如 C:/abc
+     * 成功返回 true , 失败返回字符串具体原因
+     */
+    pathDel(path) {
+
+        var objFs = require("fs");
+        path = this.pathFormat(path);
+
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(path);
+        if (pathBool == false) {
+            return "目录已经不存在";
+        }
+        
+        try {
+            objFs.rmdirSync(path);
+        } catch (e) {
+            return "没有操作权限";
+        }
+
+        return true;
+
+    }
+
+    /**
+     * 遍历指定目录下的,所有目录 和 文件
+     * path     传具体目录,例如 C:/abc
+     * forBol   是否递归遍历子目录 true - 是, false - 否
+     * ret      被累加的 json 结果,第一次调用该方法传null,或者不传,当被递归循环遍历的时候传结果
+     * 成功返回 json, 失败返回 使用原因的字符串
+     */
+    pathOrFileAll(path, forBol, ret) {
+
+        path = this.pathFormat(path);
+
+        var objFs = require('fs');
+        var objPath = require('path');
+
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(path);
+        if (pathBool == false) {
+            return "目录已经不存在";
+        }
+
+        if (ret == null || ret =="") {
+
+            // 最终返回遍历结果
+            ret = {
+
+                // 文件集合
+                "file" : [],
+                // 遍历的目录集合
+                "path" : [],
+                
+            };
+
+        }
+        
+        // 循环遍历目录里的文件 和 文件夹
+        objFs.readdirSync(path).forEach(function (
+            // 得到的是文件夹 还是 文件
+            fileOrPath
+        ) {
+
+            // 获取当前文件的目录,例如 C:/a
+            var filePath = objPath.join(path, fileOrPath);
+            filePath = MyFile.find().pathFormat(filePath);
+
+            // 获取文件的相关信息,例如文件大小,等信息
+            var objFsStat = objFs.statSync(filePath);
+
+
+            // 如果是文件的话
+            if (objFsStat.isFile()) {
+
+                ret["file"].push({
+                    "name" : fileOrPath,
+                    "filePath" : filePath
+                });
+
+            } else {
+
+                // 否则就是目录
+                ret["path"].push({
+                    "name" : fileOrPath,
+                    "filePath" : filePath
+                });
+
+                // 继续递推
+                if (forBol == true) {
+                    
+                    MyFile.find().pathOrFileAll(filePath, forBol, ret);
+
+                }
+
+            }
+
+        });
+
+        return ret;
+
+    }
+
+    /**
+     * 创建文件并且写入文件
+     * 如果文件已经存在,则覆盖文件,或者是追加写入文件
+     * filePath     具体文件的目录,例如 C:/abc.txt
+     * txt          写入内容
+     * type         w - 覆盖写入 , a - 追加写入
+     * 成功返回 true, 失败返回具体字符串原因
+     */
+    fileCreate(filePath, txt, type) {
+
+        filePath = this.pathFormat(filePath);
+        var objFs = require("fs");
+
+        // 配置生成的参数
+        var options = {
+            // 编码
+            encoding : "utf8",
+            /**
+             * 'a': 打开文件进行追加。 如果文件不存在,则创建该文件。
+             * 'ax': 类似于 'a' 但如果路径存在则失败。
+             * 'a+': 打开文件进行读取和追加。 如果文件不存在,则创建该文件。
+             * 'ax+': 类似于 'a+' 但如果路径存在则失败。
+             * 'as': 以同步模式打开文件进行追加。 如果文件不存在,则创建该文件。
+             * 'as+': 以同步模式打开文件进行读取和追加。 如果文件不存在,则创建该文件。
+             * 'r': 打开文件进行读取。 如果文件不存在,则会发生异常。
+             * 'r+': 打开文件进行读写。 如果文件不存在,则会发生异常。
+             * 'rs+': 以同步模式打开文件进行读写。 指示操作系统绕过本地文件系统缓存。
+             * 这主要用于在 NFS 挂载上打开文件,因为它允许跳过可能过时的本地缓存。 它对 I/O 性能有非常实际的影响,因此除非需要,否则不建议使用此标志。
+             * 这不会将 fs.open() 或 fsPromises.open() 变成同步阻塞调用。 如果需要同步操作,应该使用类似 fs.openSync() 的东西。
+             * 'w': 打开文件进行写入。 创建(如果它不存在)或截断(如果它存在)该文件。
+             * 'wx': 类似于 'w' 但如果路径存在则失败。
+             * 'w+': 打开文件进行读写。 创建(如果它不存在)或截断(如果它存在)该文件。
+             * 'wx+': 类似于 'w+' 但如果路径存在则失败。
+             * 
+             */
+            flag : type
+        };
+
+        // 生成或覆盖写入
+        objFs.writeFileSync(filePath, txt, options, function(err) {
+           if (err) {
+               return "没有操作权限";
+           }
+           
+        });
+
+        return true;
+        
+    }
+
+    /**
+     * 读取目录文件的内容
+     * filePath     具体文件的目录,例如 C:/abc.txt
+     * 成功返回字符串结果, 失败返回 false
+     */
+    fileRead(filePath) {
+
+        filePath = this.pathFormat(filePath);
+        
+        var objFs = require("fs");
+        
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(filePath);
+        if (pathBool == false) {
+            return false;
+        }
+        
+        var filePathStr = objFs.readFileSync(filePath);
+
+        return filePathStr.toString();
+
+    }
+
+
+    /**
+     * 删除文件
+     * filePath     具体文件的目录,例如 C:/abc.txt
+     * 删除成功返回 true , false 文件已经不存在 ,失败返回字符串的原因
+     */
+    fileDel(filePath) {
+
+        filePath = this.pathFormat(filePath);
+        var objFs = require("fs");
+
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(filePath);
+        if (pathBool == false) {
+            return false;
+        }
+
+        objFs.unlinkSync(filePath);
+
+        return true;
+
+    }
+
+
+    /**
+     * 将文件转换成base64编码
+     * filePath     具体文件的目录,例如 C:/abc.png
+     * 成功返回base64字符串编码
+     * 失败返回 false 说明文件不存在
+     */
+    fileToBase64(filePath) {
+
+        filePath = this.pathFormat(filePath);
+        var objFs = require("fs");
+
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(filePath);
+        if (pathBool == false) {
+            return false;
+        }
+
+        var data = objFs.readFileSync(filePath);
+        var objBuffer = Buffer.from(data, "utf8");
+        return objBuffer.toString('base64');
+
+    }
+
+    /**
+     * 将base64编码转换成文件
+     * base64Str    base64字符串编码
+     * filePath     具体文件的目录,例如 C:/abc.png
+     * 成功返回 true
+     * 失败返回 字符串的原因
+     */
+    base64ToFile(base64Str, filePath) {
+
+        var objFs = require("fs");
+        //把base64码转成buffer对象,
+        // var dataBuffer = new Buffer(base64Str, 'base64');
+        var dataBuffer = Buffer.from(base64Str, 'base64');
+        objFs.writeFileSync(filePath, dataBuffer);
+
+        return true;
+
+    }
+
+    /**
+     * 将网络文件下载下来
+     * url          文件地址,例如 http://xxxxxxxxx.com/a.png
+     * filePath     具体文件的目录,例如 C:/abc.png
+     * 成功返回 true , 失败返回 false
+     */
+    urlDown(url, filePath) {
+
+        try {
+            
+            if (url.indexOf('https') >= 0) {
+                
+                var objHttp = require('https');
+                var objFs = require('fs');
+                var file = objFs.createWriteStream(filePath);
+                var request = objHttp.get(url, function(response) {
+                    response.setHeader
+                    response.pipe(file);
+                });
+
+                return objHttp;
+
+            } else {
+
+                var objHttp = require('http');
+                var objFs = require('fs');
+                var file = objFs.createWriteStream(filePath);
+                var request = objHttp.get(url, function(response) {
+                    response.setHeader
+                    response.pipe(file);
+                });
+
+                return objHttp;
+
+            }
+
+        } catch (e) {
+
+        }
+
+    
+        return null;
+
+    }
+
+
+    /**
+     * 将网络文件下载下来
+     * url          文件地址,例如 http://xxxxxxxxx.com/a.png
+     * filePath     具体文件的目录,例如 C:/abc.png
+     * callback     回调函数,文件下载操作完成后,会自动回调 callback(res)
+     */
+     urlDownCallback(url, filePath, callback) {
+
+        try {
+            
+            if (url.indexOf('https') >= 0) {
+                
+                var objHttp = require('https');
+                var objFs = require('fs');
+                var file = objFs.createWriteStream(filePath);
+                var request = objHttp.get(url, function(response) {
+                    response.setHeader
+                    response.pipe(file);
+                    callback("ok");
+                });
+
+                return objHttp;
+
+            } else {
+
+                var objHttp = require('http');
+                var objFs = require('fs');
+                var file = objFs.createWriteStream(filePath);
+                var request = objHttp.get(url, function(response) {
+                    response.setHeader
+                    response.pipe(file);
+                    callback("ok");
+                });
+
+                return objHttp;
+
+            }
+
+        } catch (e) {
+            callback("error");
+            return null;
+        }
+
+        callback("error");
+        return null;
+
+    }
+
+
+}
+
+module.exports = MyFile;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 422 - 0
exe/src/common/moudles/MyHttp.js

@@ -0,0 +1,422 @@
+
+class MyHttp {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+     static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+    /**
+     * 提交请求
+     * type         http 还是 https 请求
+     * options      具体的请求参数,例如
+     * {
+     *      // 域名或者ip
+     *      hostname : 'www.baidu.com',
+     *      // 端口
+     *      port : 80,
+     *      // 请求方式 GET、POST 等
+     *      method : "GET"
+     * }
+     * 
+     * 这三个参数是必传的,后续可以传其他参数,具体有哪些参数,可以看官方文档
+     * http://nodejs.cn/api/http.html#http_class_http_incomingmessage 的 http.request(url[, options][, callback])
+     * 
+     * submitParams 请求参数(  )。如果没有,则传 null
+     * 
+     * callback 成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function demo(ret) {}
+     * 
+     * 返回json结果
+     * 
+     */
+    submit(type, options, submitParams, callback) {
+
+        // 最后的返回结果
+        var ret = {
+            // wait - 等待请求结果, success - 成功, error - 请求失败报错
+            status : "wait",
+            // 具体返回的请求结果
+            ret : null,
+        };
+
+        var objHttp = type == "http" ? require('http') : require('https');
+
+        /**
+         * 【 注意,平时的这种方式请求,是 异步的,所有这里定义了 callback 回调函数 】
+         */
+
+        // 请求
+        var objHttpReq = objHttp.request(options, function(res) {
+
+            // 设置编码
+            res.setEncoding("utf-8");
+
+            // 成功返回
+            res.on('data', function(chunk) {
+                
+                try {
+
+                    ret = {
+                        // wait - 等待请求结果, success - 成功, error - 请求失败报错
+                        status : "success",
+                        // 具体返回的请求结果
+                        ret : chunk.toString(),
+                    };
+
+                    /**
+                     * 回调函数,
+                     * result   如果没有报错,则会返回执行结果,否则返回null
+                     */
+                    callback(ret);
+                    
+                } catch (e) {
+
+
+                }
+                
+
+            });
+        
+        });
+        
+        // 返回失败
+        objHttpReq.on("error", function(err) {
+
+            ret = {
+                // wait - 等待请求结果, success - 成功, error - 请求失败报错
+                status : "error",
+                // 具体返回的请求结果
+                ret : err.message,
+            };
+
+            /**
+             * 回调函数,
+             * result   如果没有报错,则会返回执行结果,否则返回null
+             */
+            callback(ret);
+
+        });
+
+        if (submitParams != null && submitParams != "undefined") {
+            // 写入请求的参数
+            objHttpReq.write(submitParams);
+        }
+        
+        // 结束请求
+        objHttpReq.end();
+
+        // 注意回调函数,放到 请求里的事件,如果放到外部,就没办法实现 同步操作了
+
+        return ret;
+
+    }
+
+    /**
+     * 统一格式化目录
+     * path  传具体目录,例如 C:\a\b\c\
+     * 返回字符串 , 例如 C:/a/b/c/
+     */
+     pathFormat(path) {
+
+        path = path.replace("\\", "/");
+        path = path.replace("//", "/");
+
+        if (
+            path.indexOf("\\") > 0
+            || path.indexOf("//") > 0
+        ) {
+            return this.pathFormat(path);
+        }
+
+        return path;
+    }
+
+
+    /**
+     * 提交请求【 专门用于 上传文件使用 】
+     * type         http 还是 https 请求
+     * options      具体的请求参数,例如
+     * {
+     *      // 域名或者ip
+     *      hostname : 'www.baidu.com',
+     *      // 端口
+     *      port : 80,
+     *      // 请求方式 GET、POST 等
+     *      method : "GET"
+     * }
+     * 
+     * 这三个参数是必传的,后续可以传其他参数,具体有哪些参数,可以看官方文档
+     * http://nodejs.cn/api/http.html#http_class_http_incomingmessage 的 http.request(url[, options][, callback])
+     * 
+     * path         上传的具体文件,例如 D:/abc.png
+     * 
+     * callback 成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function demo(ret) {}
+     * 
+     * 返回json结果
+     * 
+     */
+    upload(type, options, path, callback) {
+
+        // 格式化目录
+        path = this.pathFormat(path);
+        var objFs = require('fs');
+        
+        // 判断目录或者文件是否存在
+        var pathBool = objFs.existsSync(path);
+
+        if (pathBool == false) {
+            
+            try {
+
+                ret = {
+                    // wait - 等待请求结果, success - 成功, error - 请求失败报错
+                    status : "error",
+                    // 具体返回的请求结果
+                    ret : "文件:" + path + " 不存在",
+                };
+
+                /**
+                 * 回调函数,
+                 * result   如果没有报错,则会返回执行结果,否则返回null
+                 */
+                callback(ret);
+
+                return false;
+                
+            } catch (e) {
+
+            }
+
+        }
+
+        // 读取文件流
+        var fileStream = objFs.createReadStream(path, { bufferSize: 4 * 1024 });
+
+        // 获取文件的相关信息,例如文件大小,等信息
+        var objFsStat = objFs.statSync(path);
+
+        // 获取文件类型
+        var objMime = require('mime');
+        var mimeType = objMime.getType(path);
+
+        // 获取文件名
+        var fileName = "";
+        if (path.lastIndexOf("/") >= 0) {
+            var pathArray = path.split("/");
+            fileName = pathArray[pathArray.length - 1];
+        }
+
+        // 最后的返回结果
+        var ret = {
+            // wait - 等待请求结果, success - 成功, error - 请求失败报错
+            status : "wait",
+            // 具体返回的请求结果
+            ret : null,
+        };
+
+        var objHttp = type == "http" ? require('http') : require('https');
+
+        /**
+         * 【 注意,平时的这种方式请求,是 异步的,所有这里定义了 callback 回调函数 】
+         */
+
+        // 请求
+        var objHttpReq = objHttp.request(options, function(res) {
+
+            // 设置编码
+            res.setEncoding("utf-8");
+
+            // 成功返回
+            res.on('data', function(chunk) {
+                
+                try {
+
+                    ret = {
+                        // wait - 等待请求结果, success - 成功, error - 请求失败报错
+                        status : "success",
+                        // 具体返回的请求结果
+                        ret : chunk.toString(),
+                    };
+
+                    /**
+                     * 回调函数,
+                     * result   如果没有报错,则会返回执行结果,否则返回null
+                     */
+                    callback(ret);
+                    
+                } catch (e) {
+
+
+                }
+                
+
+            });
+        
+        });
+        
+        // 返回失败
+        objHttpReq.on("error", function(err) {
+
+            ret = {
+                // wait - 等待请求结果, success - 成功, error - 请求失败报错
+                status : "error",
+                // 具体返回的请求结果
+                ret : err.message,
+            };
+
+            /**
+             * 回调函数,
+             * result   如果没有报错,则会返回执行结果,否则返回null
+             */
+            callback(ret);
+
+        });
+
+
+        // 随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置
+        var boundaryKey = Math.random().toString(16);
+
+        var payload = '--' + boundaryKey + '\r\n'
+            // use your file's mime type here, if known
+            + 'Content-Type: ' + mimeType + '\r\n' 
+            // "name" is the name of the form field
+            // "filename" is the name of the original file
+            + 'Content-Disposition: form-data; name="media"; filename="' + fileName + '"\r\n'
+            + 'Content-Transfer-Encoding: binary\r\n\r\n';
+
+        var enddata  = '\r\n--' + boundaryKey + '--';
+        
+        objHttpReq.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundaryKey + '');
+        objHttpReq.setHeader('Content-Length', Buffer.byteLength(payload) + Buffer.byteLength(enddata) + objFsStat.size);
+        
+        objHttpReq.write(payload);
+        
+        fileStream.pipe( objHttpReq, {end: false} );
+
+        fileStream.on('end', function() {
+
+            // mark the end of the one and only part
+            // 结束请求【 注意,此时是在这里结束请求】并且标记结尾,否则没办法上传结束
+            objHttpReq.end(enddata);
+            
+        });
+        
+        // 注意回调函数,放到 请求里的事件,如果放到外部,就没办法实现 同步操作了
+
+        return ret;
+
+
+     }
+     
+
+
+}
+
+module.exports = MyHttp;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 197 - 0
exe/src/common/moudles/MyImg.js

@@ -0,0 +1,197 @@
+
+/**
+ * 图像处理
+ * */ 
+var gm = require("gm");
+// 提供生成node子进程的方法
+var spawn = require('child_process').spawn;
+
+class MyImg {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+        var config = {};
+        config.position = {
+            NorthWest : "NorthWest",
+            North : "North",
+            NorthEast : "NorthEast",
+            West : "West",
+            Center : "Center",
+            East : "East",
+            South : "South",
+            SouthWest : "SouthWest",
+            SouthEast : "SouthEast",
+        };
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+
+    }
+
+    /**
+     * 裁剪图片
+     * srcImg       待裁剪的图片路径
+     * srcImgNew    裁剪后图片路径
+     * width        宽度
+     * height       高度
+     * x            x坐标
+     * y            y坐标
+     * callback     回调函数
+     */
+    cropCurrentImg(srcImg, srcImgNew, width, height, x, y, callback) {
+
+        // 注意了,这个是异步处理的,所以我们要使用回调函数
+        gm(srcImg).crop(width, height, x, y).write(srcImgNew, function (err) {
+            if (err) {
+                
+                callback('error', err);
+                return false;
+            }
+
+            callback('ok', '裁剪成功');
+
+        });
+
+    }
+
+
+    /**
+     * 缩放图片
+     * srcImg    待缩放的图片路径
+     * destImg   缩放后的图片输出路径
+     * quality   缩放的图片质量,0~100(质量最优)
+     * width     缩放后的图片宽度
+     * height    缩放后的图片高度
+     * imgFormat 缩放后的图片格式
+     * callback     回调函数
+     */
+    resizeImgWithFullArgs(srcImg, destImg, quality, width, height, imgFormat, callback) {
+
+        // 注意了,这个是异步处理的,所以我们要使用回调函数
+        gm(srcImg).resize(width, height).quality(quality).setFormat(imgFormat).write(destImg, function (err) {
+
+            if (err) {
+                
+                callback('error', err);
+                return false;
+            }
+
+            callback('ok', '压缩完成');
+
+        });
+        
+    }
+
+
+
+
+    
+}
+
+module.exports = MyImg;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 290 - 0
exe/src/common/moudles/MySqllite.js

@@ -0,0 +1,290 @@
+const MyFile = require('./MyFile');
+
+var objSqlite3 = require('sqlite3').verbose();
+
+class MySqllite {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+
+    }
+
+
+    /**
+     * 执行sql语句
+     * sql      sql的语句
+     * type     执行类型,get - 单条语句查询,并且只返回一条数据结果,all - 查询的数据很多,返回全部数据结果,null - 用于平时的 创建表,修改表,更新数据,删除数据使用
+     * callback 成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (err, result) {}
+     */
+    query(sql, type, callback) {
+
+        if (!sql) {
+            // 回调函数
+            callback('请填写执行的SQL语句', null);
+            return;
+        }
+
+        var path = MyFile.find().pathStart();
+
+        /**
+         * 链接数据库,如果目标 数据库不存在,则会自动(项目运行根目录)创建该数据库文件
+         * 后续操作的数据库的名字如果有所变动,则修改这里的 new objSqlite3.Database 第一个参数
+         * 可以是具体的文件目录 D:/mainSqllite.db , 如果该文件不存在,则会自动创建该文件
+         */
+        var objDatabase = new objSqlite3.Database(path + "mainSqllite.db", function(err) {
+
+            if (err) {
+
+                /**
+                 * 回调函数,
+                 * err  如果有报错返回报错原因,否则返回null
+                 * result   如果没有报错,则会返回执行结果,否则返回null
+                 */
+                callback(err, null);
+                
+                // 关闭数据库
+                objDatabase.close(function(err) { console.log(err); });
+
+                return true;
+            };
+
+            // 用于平时的 创建表,修改表,更新数据,删除数据使用
+            if (type == null || type == "undefined") {
+
+                objDatabase.exec(sql, function(err, result) {
+
+                    if (err) {
+
+                        /**
+                         * 回调函数,
+                         * err  如果有报错返回报错原因,否则返回null
+                         * result   如果没有报错,则会返回执行结果,否则返回null
+                         */
+                        callback(err, null);
+
+                        // 关闭数据库
+                        objDatabase.close(function(err) { console.log(err); });
+
+                        return true;
+
+                    } else {
+
+                        /**
+                         * 回调函数,
+                         * err  如果有报错返回报错原因,否则返回null
+                         * result   如果没有报错,则会返回执行结果,否则返回null
+                         */
+                        callback(null, result);
+
+                        // 关闭数据库
+                        objDatabase.close(function(err) { console.log(err); });
+
+                        return true;
+
+                    }
+
+    
+                });
+
+            }
+            // 专门用于查询数据,返回所有结果使用
+            else if (type == 'get') {
+
+                objDatabase.get(sql, function(err, result) {
+
+                    if (err) {
+
+                        /**
+                         * 回调函数,
+                         * err  如果有报错返回报错原因,否则返回null
+                         * result   如果没有报错,则会返回执行结果,否则返回null
+                         */
+                        callback(err, null);
+
+                        // 关闭数据库
+                        objDatabase.close(function(err) { console.log(err); });
+
+                        return true;
+
+                    } else {
+
+                        /**
+                         * 回调函数,
+                         * err  如果有报错返回报错原因,否则返回null
+                         * result   如果没有报错,则会返回执行结果,否则返回null
+                         */
+                        callback(null, result);
+
+                        // 关闭数据库
+                        objDatabase.close(function(err) { console.log(err); });
+
+                        return true;
+
+                    }
+
+                });
+
+            }
+            // 专门用于查询数据,返回所有结果使用
+            else if (type == 'all') {
+
+                objDatabase.all(sql, function(err, result) {
+
+                    if (err) {
+
+                        /**
+                         * 回调函数,
+                         * err  如果有报错返回报错原因,否则返回null
+                         * result   如果没有报错,则会返回执行结果,否则返回null
+                         */
+                        callback(err, null);
+
+                        // 关闭数据库
+                        objDatabase.close(function(err) { console.log(err); });
+
+                        return true;
+
+                    } else {
+
+                        /**
+                         * 回调函数,
+                         * err  如果有报错返回报错原因,否则返回null
+                         * result   如果没有报错,则会返回执行结果,否则返回null
+                         */
+                        callback(null, result);
+
+                        // 关闭数据库
+                        objDatabase.close(function(err) { console.log(err); });
+
+                        return true;
+
+                    }
+
+                });
+
+
+            }
+
+            
+            // 关闭数据库
+            objDatabase.close(function(err) { console.log(err); });
+
+        });
+
+
+        return true;
+
+    }
+
+    
+}
+
+module.exports = MySqllite;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 499 - 0
exe/src/common/moudles/SystemInformation.js

@@ -0,0 +1,499 @@
+
+class SystemInformation {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+    /**
+     * 获取所有网卡信息,ip、mac等
+     * {
+            "WLAN": [{
+                "address": "fe80::e081:7ea3:c3b8:ed56",
+                "netmask": "ffff:ffff:ffff:ffff::",
+                "family": "IPv6",
+                "mac": "3c:9c:0f:70:d4:3d",
+                "internal": false,
+                "cidr": "fe80::e081:7ea3:c3b8:ed56/64",
+                "scopeid": 7
+            }, {
+                "address": "192.168.1.109",
+                "netmask": "255.255.255.0",
+                "family": "IPv4",
+                "mac": "3c:9c:0f:70:d4:3d",
+                "internal": false,
+                "cidr": "192.168.1.109/24"
+            }],
+            "Loopback Pseudo-Interface 1": [{
+                "address": "::1",
+                "netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+                "family": "IPv6",
+                "mac": "00:00:00:00:00:00",
+                "internal": true,
+                "cidr": "::1/128",
+                "scopeid": 0
+            }, {
+                "address": "127.0.0.1",
+                "netmask": "255.0.0.0",
+                "family": "IPv4",
+                "mac": "00:00:00:00:00:00",
+                "internal": true,
+                "cidr": "127.0.0.1/8"
+            }]
+        }
+
+        console.log(`地址:${obj.address}`);
+        console.log(`掩码:${obj.netmask}`);
+        console.log(`物理地址:${obj.mac}`);
+        console.log(`协议族:${obj.family}`);
+     */
+    getNetworkInterfaces() {
+
+        var os = require("os");
+        var networkInterfaces = os.networkInterfaces();
+        return networkInterfaces;
+
+    }
+
+    /**
+     * 获取局域网的所有ip
+     */
+    getLANIpList() {
+
+        var ret = [];
+        var getNetworkInterfaces = this.getNetworkInterfaces();
+
+        for (var key in getNetworkInterfaces) {
+            
+            var getNetworkInterfacesKey = getNetworkInterfaces[key];
+
+            if (typeof getNetworkInterfacesKey == 'object') {
+
+                if (getNetworkInterfacesKey.length > 0) {
+
+                    for ( var i = 0; i < getNetworkInterfacesKey.length; i++ ) {
+
+                        if (getNetworkInterfacesKey[i]['address'] != null && getNetworkInterfacesKey[i]['address'] != 'undefined') {
+
+                            if (getNetworkInterfacesKey[i]['address'].indexOf("192.") >= 0) {
+
+                                ret.push(getNetworkInterfacesKey[i]['address']);
+
+                            }
+
+                        }
+
+                    }
+
+                }
+
+            }
+
+        }
+
+        return ret;
+
+    }
+
+    /**
+     * 获取所有cpu信息
+     */
+    getCpu() {
+
+        var os = require("os");
+        var cpus = os.cpus();
+
+        // console.log('*****cpu信息*******');
+        // cpus.forEach((cpu,idx,arr)=>{
+        //     var times = cpu.times;
+        //     console.log(`cpu${idx}:`);
+        //     console.log(`型号:${cpu.model}`);
+        //     console.log(`频率:${cpu.speed}MHz`);
+        //     console.log(`使用率:${((1-times.idle/(times.idle+times.user+times.nice+times.sys+times.irq))*100).toFixed(2)}%`);
+        // });
+
+        return cpus;
+
+    }
+
+    /**
+     * 获取主机名
+     */
+    getHostname() {
+
+        // var os = require("os");
+        // var hostname = os.hostname();
+        // 以上方式获取,会导致获取的中文名字是乱码
+
+        // 操作cmd模块
+        var childProcess = require('child_process');
+        // 进行编码解码使用
+        var iconvLite = require('iconv-lite');
+        
+        // 同步执行 cmd
+        var execSync = childProcess.execSync('hostname', { encoding: 'binary' });
+        // 解决中文乱码返回问题
+        var hostname = iconvLite.decode(execSync, 'cp936');
+
+        // 去除特殊符号
+        if (hostname.indexOf("\n") >= 0) {
+
+            hostname = hostname.split("\n")[0];
+
+        }
+
+        return hostname;
+
+    }
+
+    /**
+     * 获取主目录
+     */
+    getHomedir() {
+
+        var os = require("os");
+        var homedir = os.homedir();
+        return homedir;
+
+    }
+
+    /**
+     * 获取系统的其他信息
+     */
+    getSystemInfomation() {
+
+        var os = require("os");
+        return {
+            // 操作系统平台
+            platform : os.platform(),
+            // 开机时间
+            uptime : os.uptime(),
+            // 内核
+            type : os.type(),
+            // CPU架构
+            arch : os.arch(),
+            // 内存大小
+            totalmem : os.totalmem(),
+            // 空闲内存
+            freemem : os.freemem(),
+        };
+
+    }
+
+
+    /**
+     * 获取cpu的处理器id【经过测试,并没有真正的唯一,遇到同牌子的电脑会出现一模一样的值】
+     */
+    getCpuProcessorId() {
+
+        // 操作cmd模块
+        var childProcess = require('child_process');
+        // 进行编码解码使用
+        var iconvLite = require('iconv-lite');
+        // 同步执行 cmd
+        var execSync = childProcess.execSync('wmic cpu list full', { encoding: 'binary' });
+        // 解决中文乱码返回问题
+        var execSyncTxt = iconvLite.decode(execSync, 'cp936');
+
+        // 分割换行
+        var execSyncTxtArray = execSyncTxt.split("\n");
+
+        var processorId = "";
+
+        if (typeof execSyncTxtArray == "object") {
+
+            for (var key in execSyncTxtArray) {
+                
+                var execSyncTxtArrayKey = execSyncTxtArray[key];
+
+                // 统一转小写
+                var execSyncTxtArrayKeyMin = execSyncTxtArrayKey.toLowerCase();
+
+                // 找到处理器id
+                if (execSyncTxtArrayKeyMin.indexOf("processorid=") >= 0) {
+
+                    var execSyncTxtArrayKeyMinArray = execSyncTxtArrayKeyMin.split("=");
+                    processorId = execSyncTxtArrayKeyMinArray[1];
+
+                    // 去除特殊符号
+                    if (processorId.indexOf("\r") >= 0) {
+
+                        processorId = processorId.split("\r")[0];
+
+                    }
+
+                }
+                
+
+            }
+
+        }
+        
+
+        return processorId;
+    }
+
+
+    /**
+     * 异步执行cmd命令
+     * str          执行cmd命令字符串
+     * callback     回调函数
+     * 返回执行结果
+     */
+    cmd(str, callback) {
+
+        // 操作cmd模块
+        var childProcess = require('child_process');
+        var iconvLite = require('iconv-lite');
+
+        // 对于程序不想要等待cmd结果,导致卡住我们就使用异步执行cmd命令。 这样既不影响平时程序的正常继续操作,也可以在异步处理要的结果
+        childProcess.exec(
+            str,
+            { encoding: 'binary' },
+            function (err, data) {
+                try {
+
+                    if (data) {
+                        data = iconvLite.decode(data, 'cp936');
+                    }
+
+                } catch (e) {
+
+                }
+
+                // 回调
+                callback(err, data);
+
+            }
+        );
+
+
+    }
+
+
+    /**
+     * 同步执行cmd命令
+     * str          执行cmd命令字符串
+     * 返回执行结果
+     */
+    cmdSync(str) {
+
+        // 操作cmd模块
+        var childProcess = require('child_process');
+        var iconvLite = require('iconv-lite');
+        var execSync = null;
+        // 同步执行 cmd
+        // var execSync = childProcess.execSync(str, { encoding: 'binary' });
+
+        try {
+            execSync = childProcess.execSync(str, { encoding: 'binary' });
+            if (execSync) {
+
+                // 解决中文乱码返回问题
+                execSync = iconvLite.decode(execSync, 'cp936');
+    
+            }
+
+        } catch (e) {
+
+        }
+        
+        return execSync;
+
+    }
+
+
+    /** 
+     * 将文字通过密码 加密
+     * data     文字
+     * password 密码【 必须是 16位 】
+     * 返回加密后的字符串结果
+     */
+     aseEncode(data, password) {
+
+        var objCrypto = require("crypto");
+
+        // ase-128-cbc 加密算法要求key和iv长度都为16
+        const key = Buffer.from(password, 'utf8');
+        const iv = Buffer.from(password, 'utf8');
+
+        let sign = '';
+        const cipher = objCrypto.createCipheriv('aes-128-cbc', key, iv);
+        sign += cipher.update(data, 'utf8', 'hex');
+        sign += cipher.final('hex');
+        return sign;
+
+    };
+
+    /** 
+     * 将文字通过密码 解密
+     * data     已经被加密的文字
+     * password 密码【 必须是 16位 】
+     * 返回加密后的字符串结果
+     */
+    aseDecode(data, password) {
+
+        var objCrypto = require("crypto");
+
+        // ase-128-cbc 加密算法要求key和iv长度都为16
+        const key = Buffer.from(password, 'utf8');
+        const iv = Buffer.from(password, 'utf8');
+
+        let src = '';
+        const cipher = objCrypto.createDecipheriv('aes-128-cbc', key, iv);
+        src += cipher.update(data, 'hex', 'utf8');
+        src += cipher.final('utf8');
+        return src;
+
+    };
+
+
+    /**
+     * 获取硬盘序列号,每台电脑都是唯一值
+     */
+     getDiskdriveSerialnumber() {
+
+        // 操作cmd模块
+        var childProcess = require('child_process');
+        // 进行编码解码使用
+        var iconvLite = require('iconv-lite');
+        // 同步执行 cmd【得到多个硬盘序列号】
+        var execSync = childProcess.execSync('wmic diskdrive get serialnumber', { encoding: 'binary' });
+        // 解决中文乱码返回问题
+        var execSyncTxt = iconvLite.decode(execSync, 'cp936');
+
+        // 分割换行
+        var execSyncTxtArray = execSyncTxt.split("\n");
+
+        var diskdriveSerialnumber = "";
+
+        if (typeof execSyncTxtArray == "object") {
+
+            // 获取第一个硬盘的序列号。每台电脑肯定只少有一个硬盘
+            diskdriveSerialnumber = execSyncTxtArray.length <= 1 ? execSyncTxtArray[0] : execSyncTxtArray[1];
+
+            // 去除特殊符号
+            if (diskdriveSerialnumber.indexOf("\r") >= 0) {
+                diskdriveSerialnumber = diskdriveSerialnumber.split("\r")[0];
+            }
+
+            diskdriveSerialnumber = diskdriveSerialnumber.trim();
+
+        }
+        
+
+        return diskdriveSerialnumber;
+    }
+
+
+}
+
+module.exports = SystemInformation;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 234 - 0
exe/src/common/moudles/TechnologicalProcess.js

@@ -0,0 +1,234 @@
+var MySqllite = require('../../common/moudles/MySqllite.js');
+
+// 通用的全局变量和方法
+class TechnologicalProcess {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+
+    /**
+     * 获取步骤
+     * callback     成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+    getStep(callback) {
+
+        var ret = {
+            // no - 代表没有可操作, userObj - 用户
+            'setp' : 'no',
+            // 操作的参数
+            'db' : null,
+        }
+
+        // 获取当前要操作的用户获取视频
+        TechnologicalProcess.find().getUserObjUrlOne(function(getUserObjUrlOneRes) {
+
+            if (getUserObjUrlOneRes !== undefined && getUserObjUrlOneRes !== null) {
+
+                ret = {
+                    'setp' : 'userObjUrl',
+                    'db' : getUserObjUrlOneRes
+                }
+                return callback(ret)
+
+            }
+
+
+            TechnologicalProcess.find().userObjUrlVideoOne(function(userObjUrlVideoOneRes) {
+
+                if (userObjUrlVideoOneRes !== undefined && userObjUrlVideoOneRes !== null) {
+
+                    ret = {
+                        'setp' : 'userObjVideo',
+                        'db' : userObjUrlVideoOneRes
+                    }
+                    return callback(ret)
+    
+                }
+
+                // 获取当前要操作的用户
+                TechnologicalProcess.find().getUserObjOne(function(getUserObjOneRes) {
+
+                    if (getUserObjOneRes !== undefined && getUserObjOneRes !== null) {
+
+
+                        ret = {
+                            'setp' : 'userObj',
+                            'db' : getUserObjOneRes
+                        }
+                        return callback(ret)
+
+                    }
+
+                    return callback(ret)
+
+                });
+
+            });
+
+        });
+
+    }
+
+    /**
+     * 获取当前要操作的用户
+     * callback     成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+    getUserObjOne(callback) {
+
+        var sql = "SELECT * FROM user_obj where del = 0 and state = 0 order by time desc;";
+        MySqllite.find().query(sql, 'get', function (err, result) {
+
+            callback(result)
+
+        });
+
+
+    }
+
+    /**
+     * 获取当前要操作的用户获取播放视频
+     * callback     成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+     getUserObjUrlOne(callback) {
+
+        var sql = "SELECT * FROM user_obj_url where del = 0 and state = 0 order by time desc;";
+        MySqllite.find().query(sql, 'get', function (err, result) {
+
+            callback(result)
+
+        });
+
+
+    }
+
+    /**
+     * 获取当前要操作的视频读取评论
+     * callback     成功返回后的回调方法,比如我执行完语句后,要返回的指定方法,例如 function (result) {}
+     */
+     userObjUrlVideoOne(callback) {
+
+        var sql = "SELECT * FROM user_obj_url_video where del = 0 and state = 0 order by time asc;";
+        MySqllite.find().query(sql, 'get', function (err, result) {
+
+            callback(result)
+
+        });
+
+
+    }
+
+
+
+}
+
+module.exports = TechnologicalProcess;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 628 - 0
exe/src/main/index.js

@@ -0,0 +1,628 @@
+// import {
+//     app,
+//     BrowserWindow,
+//     Menu,
+//     // 主进程与渲染进程通讯
+//     ipcMain,
+//     shell
+//   } from 'electron'
+
+const {
+    app,
+    BrowserWindow,
+    Menu,
+    // 主进程与渲染进程通讯
+    ipcMain,
+    shell
+} = require('electron');
+
+var MyHttp = require('../common/moudles/MyHttp.js');
+var CommonVar = require('../common/moudles/CommonVar.js');
+
+var os = require('os');
+const axios = require('axios');
+
+// 有用 共享内存
+app.commandLine.appendSwitch('enable-features','SharedArrayBuffer');
+// 滑动更流畅
+app.commandLine.appendSwitch('enable-gpu-rasterization');   
+// 快速 UDP 互联网连接
+app.commandLine.appendSwitch('enable-quic');
+app.commandLine.appendSwitch('enable-zero-copy');
+// 有用
+app.commandLine.appendSwitch('enable-features', "Vulkan");
+// 有用
+app.commandLine.appendSwitch('enable-unsafe-webgpu');
+
+/**
+ * 加载窗口,加载完成后,会自动关闭。
+ * 【 后续开发在考虑,先不管这个逻辑 】但,如果是唯一存在的,则不关闭,而是移动到别人看不到的地方
+ * */ 
+var loadingWindow = null;
+
+// 主程序窗口
+var mainWindow = null;
+
+// 获取webserver端口
+var ServerPort = CommonVar.find().getServerPort();
+var WebSocketPort = CommonVar.find().getWebSocketPort();
+
+/**
+ * 【 有时候,窗口黑屏或者白屏的问题 】
+ * 禁用当前应用程序的硬件加速。
+ * 这个方法只能在应用程序准备就绪(ready)之前调用。
+ */
+// app.disableHardwareAcceleration();
+
+// 引入类
+var SystemInformation = require('../common/moudles/SystemInformation.js');
+var CommonVar = require('../common/moudles/CommonVar.js');
+var MigrateSqllite = require('../common/moudles/MigrateSqllite.js');
+var MyFile = require('../common/moudles/MyFile.js');
+
+// 根目录
+var pathStart = MyFile.find().pathStart();
+
+// 引用封装好的websocket通讯的类
+var WebSocketEvent = require('../myWebSocket/WebSocketEvent.js');
+
+/**
+ * 该启动的程序是否主动启动了 http服务
+ * 如果启动的话,则初始开启的窗口不是关闭
+ * 还是放在某个看不到的地方隐藏
+ */
+var mainStartWebServerBool = false;
+
+/**
+ * 记录当前启动服务时候的版本号
+ */
+var version = null;
+
+// 加载窗口
+function createLoadingWindow() {
+  
+    // 创建窗口
+    loadingWindow = new BrowserWindow({
+        width : 300,
+        height : 300,
+    
+        // // 是否全屏
+        // fullscreen: true,
+        // 创建一个无边框窗口,后续自定义菜单会用到。此时所有菜单都会隐藏起来
+        frame : false,
+    
+        // 是否全屏
+        fullscreen: false,
+        // // 创建一个无边框窗口,后续自定义菜单会用到。此时所有菜单都会隐藏起来
+        // frame : true,
+    
+        // 平时如果html 文件要引入使用 node 模块,就一定要加入该配置,否则就不需要,详细参数见 http://www.electronjs.org/docs/api/browser-window
+        webPreferences : {
+            // 高版本的 Electron 必须加上这个配置,否则 webPreferences 配置没反应
+            contextIsolation : false,
+            // 开启node模块
+            nodeIntegration : false,
+            // 确保启用 WebGPU 支持
+            enableWebGPU: true,
+            // 开启remote模块
+            enableRemoteModule : false,
+    
+            /**
+             * 解决 jq 等引用 其他js 失败的方法
+             * 
+             * <!-- Insert this line above script imports置于引入jQuery 等其他 外部js文件 之前--> 
+             * <script>if (typeof module === 'object') {window.module = module;module = undefined;}</script> 
+             * 
+             * 【 中间这部分是你平时引入 外部的 js文件的 】
+             * 
+             *  <!-- Insert this line above script imports置于引入jQuery 等其他 外部js文件 之后(本人测试可以不加下面这句) --> 
+             * <script>if (window.module) module = window.module;</script>
+             * 
+             */
+    
+            // 都开启之后,我们在平时些的js 可以通过 const { remote : {  } } = require('electron');具体见案例 electronDemo\src\js\index.js
+        },
+    });
+  
+    // mainWindow.maximize();
+
+    // 设置窗口不在任务栏显示
+    loadingWindow.setSkipTaskbar(true);
+
+    // // 设置窗口的位置
+    // loadingWindow.setPosition(200, 200);
+    // // 设置窗口的大小
+    // loadingWindow.setSize(1000, 800);
+  
+    // ########## 定义菜单 ##########
+    // 定义菜单模板【 如果要隐藏所有菜单,直接设置 [] 空数组即可 】
+    const templateMenu = [
+    ];
+  
+    // 编辑模板
+    const objMenu = Menu.buildFromTemplate(templateMenu);
+    // 设置菜单
+    Menu.setApplicationMenu(objMenu);
+  
+    /** 
+     * 加载文件【 自定义菜单见该加载的文件 】
+     * 【 注意了,这里只是案例 】
+     * 我们可以通过静态文件的方式,js里面来操作 nodejs 的代码
+     * 但是呢,放在静态 new_src 文件里是保留出来的,不安全
+     * 所以,后续,我们会启动一个 web 服务,这个web服务 来启动 index.html 文件
+     * 
+     * 例如 http:127.0.0.1:9080/index.html
+     * 然后这个 index.html 是由 vue 开发的结果
+     * 然后我们通过 启动一个 后台 web服务,来数据交互
+     * 由 web服务 来触发各种 nodejs 的代码逻辑
+     * 
+     * 【 注意的是 】 打包成安装包后 new_src 要放到 安装的应用里
+     * 因为默认打包后后是在 build 的 文件夹里
+     * build 的里有个 exe 的安装包。 其实也是可以不用到这个安装包的
+     * 可以直接将 build\win-unpacked 的这个整个文件, 将 new_src 放入该文件,然后可以通过其他工具,例如 Inno Setup 编译器 来重新弄个安装包,发给用户安装使用
+     */
+    // mainWindow.loadFile('../../new_src/index.html');
+    loadingWindow.loadFile(pathStart + 'new_src/loading.html');
+
+    // 设置为总是在最前面
+    loadingWindow.setAlwaysOnTop(true, 'floating');
+    
+}
+
+
+// 创建窗口
+function createMainWindow() {
+  
+    // 创建窗口
+    mainWindow = new BrowserWindow({
+        width : 600,
+        height : 500,
+    
+        // // 是否全屏
+        // fullscreen: true,
+        // 创建一个无边框窗口,后续自定义菜单会用到。此时所有菜单都会隐藏起来
+        frame : true,
+    
+        // 是否全屏
+        fullscreen: false,
+        // // 创建一个无边框窗口,后续自定义菜单会用到。此时所有菜单都会隐藏起来
+        // frame : true,
+    
+        // 平时如果html 文件要引入使用 node 模块,就一定要加入该配置,否则就不需要,详细参数见 http://www.electronjs.org/docs/api/browser-window
+        webPreferences : {
+            // 高版本的 Electron 必须加上这个配置,否则 webPreferences 配置没反应
+            contextIsolation : false,
+            // 开启node模块
+            nodeIntegration : false,
+            // 确保启用 WebGPU 支持
+            enableWebGPU: true,
+            // 开启remote模块
+            enableRemoteModule : false,
+    
+            /**
+             * 解决 jq 等引用 其他js 失败的方法
+             * 
+             * <!-- Insert this line above script imports置于引入jQuery 等其他 外部js文件 之前--> 
+             * <script>if (typeof module === 'object') {window.module = module;module = undefined;}</script> 
+             * 
+             * 【 中间这部分是你平时引入 外部的 js文件的 】
+             * 
+             *  <!-- Insert this line above script imports置于引入jQuery 等其他 外部js文件 之后(本人测试可以不加下面这句) --> 
+             * <script>if (window.module) module = window.module;</script>
+             * 
+             */
+    
+            // 都开启之后,我们在平时些的js 可以通过 const { remote : {  } } = require('electron');具体见案例 electronDemo\src\js\index.js
+        },
+    });
+  
+    // mainWindow.maximize();
+  
+    // ########## 定义菜单 ##########
+    // 定义菜单模板【 如果要隐藏所有菜单,直接设置 [] 空数组即可 】
+    const templateMenu = [
+    ];
+  
+    // 编辑模板
+    const objMenu = Menu.buildFromTemplate(templateMenu);
+    // 设置菜单
+    Menu.setApplicationMenu(objMenu);
+  
+    /** 
+     * 加载文件【 自定义菜单见该加载的文件 】
+     * 【 注意了,这里只是案例 】
+     * 我们可以通过静态文件的方式,js里面来操作 nodejs 的代码
+     * 但是呢,放在静态 new_src 文件里是保留出来的,不安全
+     * 所以,后续,我们会启动一个 web 服务,这个web服务 来启动 index.html 文件
+     * 
+     * 例如 http:127.0.0.1:9080/index.html
+     * 然后这个 index.html 是由 vue 开发的结果
+     * 然后我们通过 启动一个 后台 web服务,来数据交互
+     * 由 web服务 来触发各种 nodejs 的代码逻辑
+     * 
+     * 【 注意的是 】 打包成安装包后 new_src 要放到 安装的应用里
+     * 因为默认打包后后是在 build 的 文件夹里
+     * build 的里有个 exe 的安装包。 其实也是可以不用到这个安装包的
+     * 可以直接将 build\win-unpacked 的这个整个文件, 将 new_src 放入该文件,然后可以通过其他工具,例如 Inno Setup 编译器 来重新弄个安装包,发给用户安装使用
+     */
+    // mainWindow.loadFile('../../new_src/index.html');
+  
+    /**
+     * 这里修改为浏览地址
+     * 浏览的地址,是我们启动的内置 web服务
+     * 【 此时你会发现,网址里,也是一样可以操作 nodejs 的 】
+     */
+    // mainWindow.loadURL('http://127.0.0.1:6789/dist/index.html');
+  
+    // 开发的时候
+    // mainWindow.loadURL('http://127.0.0.1:8088/index.html#/login');
+  
+    // // 打包的时候
+    mainWindow.loadURL('http://127.0.0.1:' + ServerPort + '/index.html');
+  
+  
+    // 也可以直接通过该代码打开调试工具
+    // mainWindow.webContents.openDevTools();
+    
+    mainLoadUrl();
+    mainLoadUrlBrowser();
+    
+}
+  
+// 监听弹出新窗口
+function mainLoadUrl() {
+  
+    setInterval(function() {
+      
+        let createBrowserWindowUrl = CommonVar.find().cacheGetOrUpdate('get', 'createBrowserWindowUrl');
+    
+        if (createBrowserWindowUrl === null) {
+            return;
+        }
+    
+        CommonVar.find().cacheGetOrUpdate('set', 'createBrowserWindowUrl', null);
+        createBrowserWindowUrlMain(createBrowserWindowUrl);
+    
+        // 修改成弹出网址的方式
+        // shell.openExternal(createBrowserWindowUrl);
+  
+    }, 1000)
+  
+}
+  
+/**
+ * 弹出新的窗口
+ * url  
+ */
+function createBrowserWindowUrlMain(url) {
+  
+    // 创建窗口
+    let objBrowserWindow = new BrowserWindow({
+        width : 600,
+        height : 500,
+    
+        // // 是否全屏
+        // fullscreen: true,
+        // 创建一个无边框窗口,后续自定义菜单会用到。此时所有菜单都会隐藏起来
+        frame : true,
+    
+        // 是否全屏
+        fullscreen: false,
+        // // 创建一个无边框窗口,后续自定义菜单会用到。此时所有菜单都会隐藏起来
+        // frame : true,
+    
+        // 平时如果html 文件要引入使用 node 模块,就一定要加入该配置,否则就不需要,详细参数见 http://www.electronjs.org/docs/api/browser-window
+        webPreferences : {
+            // 高版本的 Electron 必须加上这个配置,否则 webPreferences 配置没反应
+            contextIsolation : false,
+            // 开启node模块
+            nodeIntegration : false,
+            // 确保启用 WebGPU 支持
+            enableWebGPU: true,
+            // 开启remote模块
+            enableRemoteModule : false,
+    
+            /**
+             * 解决 jq 等引用 其他js 失败的方法
+             * 
+             * <!-- Insert this line above script imports置于引入jQuery 等其他 外部js文件 之前--> 
+             * <script>if (typeof module === 'object') {window.module = module;module = undefined;}</script> 
+             * 
+             * 【 中间这部分是你平时引入 外部的 js文件的 】
+             * 
+             *  <!-- Insert this line above script imports置于引入jQuery 等其他 外部js文件 之后(本人测试可以不加下面这句) --> 
+             * <script>if (window.module) module = window.module;</script>
+             * 
+             */
+    
+            // 都开启之后,我们在平时些的js 可以通过 const { remote : {  } } = require('electron');具体见案例 electronDemo\src\js\index.js
+        },
+    });
+  
+    objBrowserWindow.maximize()
+  
+    objBrowserWindow.loadURL(url)
+  
+    objBrowserWindow.on('closed', () => {
+        objBrowserWindow = null
+    })
+  
+    // // 也可以直接通过该代码打开调试工具
+    // objBrowserWindow.webContents.openDevTools();
+  
+}
+  
+// 监听弹出新窗口【到浏览器】
+function mainLoadUrlBrowser() {
+  
+    setInterval(function() {
+      
+        let createBrowserWindowUrlBrowser = CommonVar.find().cacheGetOrUpdate('get', 'createBrowserWindowUrlBrowser');
+    
+        if (createBrowserWindowUrlBrowser === null) {
+            return;
+        }
+    
+        // 修改成弹出网址的方式
+        shell.openExternal(createBrowserWindowUrlBrowser);
+    
+        CommonVar.find().cacheGetOrUpdate('set', 'createBrowserWindowUrlBrowser', null);
+  
+    }, 1000)
+  
+}
+
+function initWindow () {
+
+    // 优先加载加载窗口
+    createLoadingWindow();
+
+    // 初始化基本数据
+    CommonVar.find().getMain()
+    // 开始同步数据
+    MigrateSqllite.find().start();
+
+    return boolStartServerOrWindow();
+    
+}
+
+// 当前运行的程序 web 或者 websocket 服务是否启动过了
+var serverStartOpen = false;
+var serverStartOpenTime = null;
+// 当前是否可以继续请求
+var httpBool = true;
+
+/**
+ * 判断是否需要启动web服务,之后在启动 主程序窗口
+ */
+function boolStartServerOrWindow() {
+
+    if (serverStartOpenTime != null && serverStartOpenTime != undefined) {
+        return;
+    }
+
+    serverStartOpenTime = setInterval(function() {
+
+        // 如果启动过了
+        if (serverStartOpen == true) {
+
+            clearInterval(serverStartOpenTime);
+            serverStartOpenTime = null;
+            startMainWindowEvent();
+            return;
+
+        }
+
+        if (httpBool == false) {
+            return;
+        }
+        httpBool = false;
+
+        // 说明窗口已经运行了
+        if (mainWindow != null && mainWindow != undefined) {
+            httpBool = true;
+            return;
+        }
+
+        /**
+         * 注意 http 网络请求 虽然开发过程中你使用 fetch 是可以正常运行的
+         * 但是打包后,不进行代码混肴也可以正常运行
+         * 但是代码混肴后,却无法运行了,解决办法就是还是用
+         * node.js 自带的 http 的方式去进行请求,才可以兼容各种平台
+         */
+        var options = {
+            // 域名或者ip
+            hostname : '127.0.0.1',
+            // 追加的请求地址
+            path : '/loading.html',
+            // 端口
+            port : ServerPort,
+            // 请求方式 GET、POST 等
+            method : "GET"
+        };
+
+        // 由于请求的异步操作的
+        MyHttp.find().submit("http", options, null, function (result) {
+            
+            console.log(
+                "MyHttp.find().submit", result
+            );
+
+            // 是否服务启动成功了
+            var httpStartOpen = false;
+
+            // 没启动
+            if (result == null || result == undefined) {
+                
+            } else if (result["status"] != null && result["status"] != undefined) {
+                var status = result["status"];
+                console.log(
+                    "MyHttp.find().submit status === >", status
+                );
+
+                // 只有这个的时候才是启动成功
+                if (status == "success") {
+                    httpStartOpen = true;
+                }
+                
+            }
+
+            // 启动成功了
+            if (httpStartOpen == true) {
+                console.log("服务启动过了");
+                httpBool = true;
+                startMainWindowEvent();
+                return;
+            }
+
+            console.log(
+                "说明服务是没有启动的"
+            );
+            // 没有启动成功,则触发启动服务逻辑
+
+            // ##############################  【 启动 web 服务】 ##############################
+            require('../myWebServerRote/WebServer.js');
+            // ##############################  【 启动 webSocket 服务】 ##############################
+            WebSocketEvent.find().start();
+
+            serverStartOpen = true;
+            httpBool = true;
+
+            versionUpdate();
+            mainStartWebServerBool = true;
+            
+        });
+
+        // // 发起请求,看看服务是否启动,保证不重复启动同服务
+        // var apiUrl = "http://127.0.0.1:" + ServerPort + "/loading.html";
+        // fetch(apiUrl, {
+        //     method: 'GET',
+        //     headers: {
+        //         // 'Content-Type': 'application/json',
+        //         'Content-Type' : 'application/x-www-form-urlencoded',
+        //     },
+        // }).then(res => {
+
+        //     console.log("服务启动过了", res);
+
+        //     httpBool = true;
+        //     startMainWindowEvent();
+
+        // }).catch(error => {
+
+        //     console.log(
+        //         "说明服务是没有启动的", error
+        //     );
+
+        //     // ##############################  【 启动 web 服务】 ##############################
+        //     require('../myWebServerRote/WebServer.js');
+        //     // ##############################  【 启动 webSocket 服务】 ##############################
+        //     WebSocketEvent.find().start();
+
+        //     serverStartOpen = true;
+        //     httpBool = true;
+            
+        // });
+        
+    }, 1000);
+    
+}
+
+
+// 是否启动主窗口,以及同时关闭加载窗口
+function startMainWindowEvent() {
+
+    if (loadingWindow != null && loadingWindow != undefined) {
+
+        console.log(
+            "mainStartWebServerBool === >", mainStartWebServerBool
+        );
+
+        /**
+         * 如果是主动启动服务,则窗口不关闭,隐藏到一个别人看不到的地方
+         * 方便后续不需要重复启动服务,以及后续如果关闭主程序
+         * 不会导致其他程序因为没有web服务而无法正常使用
+         */
+        if (mainStartWebServerBool == true) {
+            // // 设置窗口的位置
+            // loadingWindow.setPosition(200, 200);
+
+            // 窗口最小化
+            loadingWindow.minimize();
+            versionBoolExitEvent();
+
+        } else {
+
+            // 关闭加载窗口
+            loadingWindow.close();
+            loadingWindow = null;
+            
+        }
+        
+    }
+
+    if (mainWindow != null && mainWindow != undefined) {
+        return;
+    }
+
+    createMainWindow();
+
+}
+
+/**
+ * 记录当前启动服务的版本号
+ */
+function versionUpdate() {
+    version = CommonVar.find().cacheGetOrUpdate("get", "version");
+    console.log("version ===>", version);
+}
+
+/**
+ * 如果是当前程序主动运行的web服务
+ * 则启动这个逻辑,当记录的 version 版本号, 跟获取最新 new_src\version.txt 版本号内容不一致
+ * 则整个应用程序关闭退出
+ */
+function versionBoolExitEvent() {
+
+    var objInterval = setInterval(function() {
+
+        var newVersion = CommonVar.find().cacheGetOrUpdate("get", "version");
+        // console.log("newVersion ===>", newVersion);
+        if (newVersion != version) {
+            
+            clearInterval(objInterval);
+            objInterval = null;
+            // 整个应用关闭退出
+            app.quit();
+
+        }
+
+    }, 2000);
+
+}
+
+// // 当 app 准备好时创建窗口
+// app.whenReady().then(() => {
+//   createMainWindow();
+
+//     app.on('activate', function () {
+//         // 在 macOS 上,当点击 dock 图标并且没有其他窗口打开时,
+//         // 通常在应用程序中重新创建一个窗口。
+//         if (BrowserWindow.getAllWindows().length === 0) createMainWindow();
+//     });
+
+// });
+
+// 一定是要在 当 app 准备好时创建窗口 的事件处理,来创建 窗口,否则会报错
+app.isReady() ? onAppReady() : app.on('ready', onAppReady)
+// 解决9.x跨域异常问题
+app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
+
+// 在 Windows 和 Linux 上,当所有窗口关闭时退出应用程序。
+app.on('window-all-closed', function () {
+    app.quit();
+});
+
+function onAppReady () {
+    initWindow();
+}

+ 270 - 0
exe/src/myWebServerRote/WebServer.js

@@ -0,0 +1,270 @@
+// 让字符串实现占位符
+String.prototype.format = function() {
+  if(arguments.length == 0) return this;
+  var param = arguments[0];
+  var s = this;
+  if(typeof(param) == 'object') {
+      for(var key in param)
+          s = s.replace(new RegExp("\\{" + key + "\\}", "g"), param[key]);
+      return s;
+  } else {
+      for(var i = 0; i < arguments.length; i++)
+          s = s.replace(new RegExp("\\{" + i + "\\}", "g"), arguments[i]);
+      return s;
+  }
+}
+
+var CommonVar = require('../common/moudles/CommonVar.js');
+var MyFile = require('../common/moudles/MyFile.js');
+
+// 引入框架
+var express = require('express');
+// 应用对象
+var app = express();
+
+/**
+ * 解决【 开发的时候打开,编译成桌面文件的时候,注释掉,否则 html页面会变成 代码显示
+ * 当然,如果你作为服务的话,那么就可以打开。 可以重新开启一个 express 新的服务,开启新的端口, 然后不要有整个代码,用来展示页面也可以 】
+ * NodeJS+Express解决跨域问题:Access-Control-Allow-Origin
+ * 注意,一定要在 app.use 之前引入才有用
+ */
+app.all('*', function(req, res, next) {
+    res.header("Access-Control-Allow-Origin", "*");
+    // 经过测试,以下的就不要设置了,否则返回的html 还是 png 等各种资源文件都会变成 代码,乱码的结果显示
+    // res.header("Access-Control-Allow-Headers", "X-Requested-With");
+    // res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
+    // res.header("X-Powered-By",' 3.2.1')
+    // res.header("Content-Type", "application/json;charset=utf-8");
+    // res.header('Access-Control-Allow-Headers','Content-Type');
+    next();
+});
+
+// 通过这个方式,解决跨域问题
+// cnpm install cors@2.8.5 --save --registry=https://registry.npm.taobao.org
+// app.use(require('cors')())  // 需要安装 cors 依赖
+
+// // cnpm install express-static@1.2.6 --save --registry=https://registry.npm.taobao.org
+// const exStatic = require("express-static");
+// app.use(exStatic('./new_src'));
+
+var pathStart = MyFile.find().pathStart();
+MyFile.find().pathCreate(pathStart + "new_src");
+
+/**
+ * 设置静态文件目录,此时也就是入口文件 下的 static 文件夹,作为我们的静态文件目录
+ */ 
+var objStatic = express.static('new_src');
+// 通过如下代码就可以将 static 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了
+app.use(objStatic);
+
+// 接收POST请求,一定必须加入该代码,同时设置限制容量,解决 413 (Payload Too Large)
+app.use(express.urlencoded({limit: '3072mb' }));
+
+// 设置接收的参数大小,否则上传的文件,还是POST参数容量太大则会出现 413 (Payload Too Large)
+app.use(express.json({limit: '3072mb'}));
+
+// 引入body-parser中间件,用来处理post请求体body中的数据
+var bodyParser = require('body-parser');
+// app.use(bodyParser)
+
+// 引入multer中间件,用于处理上传的文件数据
+var multer = require('multer');
+
+// express 接收上传文件数据
+app.use(multer(
+   { 
+      // 该配置一定要配置的,这样才能接收到临时上传的文件,临时存放的目录
+      dest: './tmp/',
+      // 文件上传的容量限制
+      limits : {
+        /** Maximum size of each form field name in bytes. (Default: 100) */
+        fieldNameSize : 1024 * 1024 * 3072,
+        /** Maximum size of each form field value in bytes. (Default: 1048576) */
+        fieldSize : 1024 * 1024 * 3072,
+        /** Maximum number of non-file form fields. (Default: Infinity) */
+        fields : 1024 * 1024 * 3072,
+        /** Maximum size of each file in bytes. (Default: Infinity) */
+        fileSize : 1024 * 1024 * 3072,
+        /** Maximum number of file fields. (Default: Infinity) */
+        files : 1024 * 1024 * 3072,
+        /** Maximum number of parts (non-file fields + files). (Default: Infinity) */
+        parts : 1024 * 1024 * 3072,
+        /** Maximum number of headers. (Default: 2000) */
+        headerPairs : 1024 * 1024 * 3072,
+    }
+   }
+).any());
+
+// ########## 【 定义一个统一的路由 】 ##########
+/**
+ * next()权限控制转移
+ * express的路由控制有个next()功能,在定义了多个路由的时候,使用next对匹配的url会按顺序执行,
+ * 如果不使用next进行权限转移,只会执行第一个满足的路由规则。
+ * next() 函数用于将当前控制权转交给下一步处理,如果给 next() 传递一个参数时,表示出错信息
+ * 例如:
+ * app.get('/test/*',function(req,res,next) {
+ *    //res.send("userid:");//要进行转移,不要响应客户端
+ *    req.temp="给你控制权";
+ *    next();//把权限转移到下一个路由
+ * });
+ * 
+ * app.get('/test/next',function(req,res) {
+ *    res.send("content: "+req.temp);
+ * })
+ * 
+ * 访问URL:http://localhost:3000/test/next满足这两个路由规则
+ * 
+ * next()一般用来编写中间件
+ * 中间件一般不直接对客户端进行响应,而是对请求进行一些预处理,再传递下去;
+ * 中间件一般会在路由处理之前执行;
+ * 比如:
+ *    // 检查用户是否登录中间件,所有需要登录权限的页面都使用此中间件 function checkLogin (req, res, next) {
+ *    if (req.session.user) {
+ *       next();//检验到用户已登入,转移权限阁下一个路由
+ *    } else {
+ *       res.redirect('/');//否则,页面重定位,不执行下面路由
+ *    } 
+ * 
+ */
+
+/** 
+ * 此时,我们请求的所有的路由,都会优先执行该路由
+ * 这里我们可以在每次的地址都增加get后缀参数 ?token=123456789 ,来进行一次理解
+ * 例如
+ * http://127.0.0.1:6789/?token=123456789
+ * 
+ * http://127.0.0.1:6789/del_user?token=123456789
+ * 
+ * http://127.0.0.1:6789/list_user?token=123456789
+ * 
+ **/
+app.get('/*',function( req, res, next) {
+   
+    return next();
+
+    // 得到的结果是 /del_user?token=123456789  活着  /del_user 【 后续我们可以通过这样来进行控制,哪些路由是不需要安全验证的 】
+    console.log(req.url);
+
+    // 不需要进行安全验证
+    if (
+        req.url === "/mainSelect"
+        || req.url.indexOf("/mainGetCode") >= 0
+    ) {
+        return next();
+    }
+
+    // // 获取 get 参数 得到一个 json格式 { name: 'zhangsan', age: '20' }
+    // console.log(req.query);
+
+    // // 接收post参数 得到一个json结构 { aaaa: 'aaa', bb: 'bb' }
+    // console.log(req.body);
+
+    // console.log("我是被统一优先执行的路由");
+
+    //  // 开始进行一个 token 的安全验证
+    //  if (req.query.token == null || req.query.token == "undefined") {
+
+    //     res.send("token不正确");
+    //     return false;
+    //  }
+
+    //  if (req.query.token != "123456789") {
+
+    //     res.send("token不正确");
+    //     return false;
+
+    //  }
+
+    // 验证失败
+    if (CommonVar.find().stateBool() === false) {
+        return CommonVar.find().retError(res, '使用已到期,联系管理员重新激活!');
+    }
+
+    return next();
+   // 安全验证成功只会
+   // 把权限转移到下一个路由。如果不执行该方法,则不会到真正到对应路由里执行代码逻辑
+   next();
+
+});
+
+app.post('/*',function( req, res, next) {
+   
+    return next();
+
+    // 得到的结果是 /del_user?token=123456789  活着  /del_user 【 后续我们可以通过这样来进行控制,哪些路由是不需要安全验证的 】
+    console.log(req.url);
+ 
+    // 不需要进行安全验证
+    if (
+        req.url === "/mainUpdate"
+    ) {
+        return next();
+    }
+
+    // 验证失败
+    if (CommonVar.find().stateBool() === false) {
+        return CommonVar.find().retError(res, '使用已到期,联系管理员重新激活!');
+    }
+
+    return next();
+ 
+});
+/**
+ * 此时我们可以访问如下地址,来理解静态文件的引用
+ * http://127.0.0.1:6789/main.html
+ * http://127.0.0.1:6789/js/indexMain.js
+ * http://127.0.0.1:6789/img/a.png
+ */
+
+// 接下来,引入路由模块
+// var objRouteIndex = require('./route/index.js');
+// 引入应用里
+// app.use(objRouteIndex);
+
+// ########## 【 后续开发,引入新的路由,就采用这样的方式 】 ##########
+
+// 引入路由模块
+app.use('/', require('../myWebServerRote/file.js'));
+// 引入路由模块
+app.use('/', require('../myWebServerRote/time.js'));
+// 引入路由模块
+app.use('/', require('../myWebServerRote/upload.js'));
+// 引入路由模块
+app.use('/', require('../myWebServerRote/http.js'));
+// 引入路由模块
+app.use('/', require('../myWebServerRote/sqllite.js'));
+// 引入路由模块
+app.use('/', require('../myWebServerRote/systemDemo.js'));
+// 用户管理
+app.use('/', require('../myWebServerRote/userObj.js'));
+// 首页,公共接口
+app.use('/', require('../myWebServerRote/main.js'));
+// 项目列表
+app.use('/', require('../myWebServerRote/project.js'));
+
+
+// 获取自定义端口
+var ServerPort = CommonVar.find().getServerPort();
+
+// 监听服务
+// var server = app.listen(6789, function () {
+var server = app.listen(parseInt(ServerPort), function () {
+
+    CommonVar.find().webServerStartBool = true
+    var host = server.address().address;
+    var port = server.address().port;
+
+   console.log("应用实例,访问地址为 http://%s:%s", host, port);
+
+})
+
+
+
+
+
+
+
+
+
+
+

Diff do ficheiro suprimidas por serem muito extensas
+ 118 - 0
exe/src/myWebServerRote/file.js


+ 298 - 0
exe/src/myWebServerRote/http.js

@@ -0,0 +1,298 @@
+// 引入框架
+var express = require('express');
+const { exit } = require('process');
+// 路由对象
+var objRouter = express.Router();
+
+var querystring = require("querystring");
+
+// 引入封装好的类
+var MyHttp = require('../common/moudles/MyHttp');
+
+// ########## 定义如下路由 ##########
+
+/**
+ * get 请求案例
+ * 地址:http://127.0.0.1:6789/http
+ */
+objRouter.get('/http', function (req, res) {
+
+    // var options = {
+    //     // 域名或者ip
+    //     hostname : '127.0.0.1',
+    //     // 端口
+    //     port : 6789,
+    //     // 请求方式 GET、POST 等
+    //     method : "GET"
+    // };
+
+    var options = {
+        // 域名或者ip
+        hostname : 'www.baidu.com',
+        // 端口
+        port : 80,
+        // 请求方式 GET、POST 等
+        method : "GET"
+    };
+
+    // 由于请求的异步操作的
+    MyHttp.find().submit("http", options, null, function (result) {
+        
+        // 所以要实现同步,就要在回调的函数里面写逻辑,这样就保证了同步效果
+
+        // 返回页面
+        res.send(result);
+
+    });
+
+
+});
+
+/**
+ * POST 请求案例
+ * 地址:http://127.0.0.1:6789/httpPostDemo
+ */
+ objRouter.get('/httpPostDemo', function (req, res) {
+
+    var submitParams = querystring.stringify({
+        username : "admin",
+        password_hash : "123456",
+    });
+
+    var options = {
+        // 域名或者ip
+        hostname : '127.0.0.1',
+        // 追加的请求地址
+        path : '/common-admin/backend/web/api1/user-verification/login',
+        // 端口
+        port : 80,
+        // 请求方式 GET、POST 等
+        method : "POST",
+        // 设置header
+        headers: {
+            'Content-Type':'application/x-www-form-urlencoded',
+            // 请求参数的长度
+            'Content-Length': submitParams.length,
+        }
+    };
+
+    // 由于请求的异步操作的
+    MyHttp.find().submit("http", options, submitParams, function (result) {
+        
+        // 所以要实现同步,就要在回调的函数里面写逻辑,这样就保证了同步效果
+
+        // 返回页面
+        res.send(result);
+
+    });
+
+
+});
+
+
+/**
+ * headers 请求案例
+ * 地址:http://127.0.0.1:6789/httpGetHeadersDemo
+ */
+ objRouter.get('/httpGetHeadersDemo', function (req, res) {
+
+    var options = {
+        // 域名或者ip
+        hostname : '127.0.0.1',
+        // 追加的请求地址
+        path : '/common-admin/backend/web/api1/apiGet',
+        // 端口
+        port : 80,
+        // 请求方式 GET、POST 等
+        method : "GET",
+        // 设置header
+        headers: {
+            'Content-Type':'application/x-www-form-urlencoded',
+            'Authorization': 'Basic UGJhZGhDYlA2bldjX0lTX2VXMEowbGVWMTdTVFdoZ0Q6',
+            'VerificationToken': 'R0poWkdoRFk=MTYxNzA4Nzg=',
+            'VerificationTime': '161708785103',
+        }
+    };
+
+    // 由于请求的异步操作的
+    MyHttp.find().submit("http", options, null, function (result) {
+        
+        // 所以要实现同步,就要在回调的函数里面写逻辑,这样就保证了同步效果
+
+        // 返回页面
+        res.send(result);
+
+    });
+
+});
+
+/**
+ * 上传文件 请求案例
+ * 地址:http://127.0.0.1:6789/httpUpload
+ */
+ objRouter.get('/httpUpload', function (req, res) {
+
+    var options = {
+        // 域名或者ip
+        hostname : '127.0.0.1',
+        // 追加的请求地址
+        path : '/upload',
+        // 端口
+        port : 6789,
+        // 请求方式 GET、POST 等
+        method : "POST",
+    };
+
+    // var options = {
+    //     // 域名或者ip
+    //     hostname : '127.0.0.1',
+    //     // 追加的请求地址
+    //     path : '/common-admin/backend/web/api1/common-upload/upload',
+    //     // 端口
+    //     port : 80,
+    //     // 请求方式 GET、POST 等
+    //     method : "POST",
+    //     // 设置header
+    //     headers: {
+    //         'Content-Type':'application/x-www-form-urlencoded',
+    //         'Authorization': 'Basic UGJhZGhDYlA2bldjX0lTX2VXMEowbGVWMTdTVFdoZ0Q6',
+    //         'VerificationToken': 'R0poWkdoRFk=MTYxNzA4Nzg=',
+    //         'VerificationTime': '161708785102',
+    //     }
+    // };
+
+    /**
+     * 注意了,有的电脑很奇葩
+     * 文件在d盘 根目录 还是桌面,是无法识别该文件的 例如 D:/a.jpg
+     * 但是新建一个文件夹,放到里面就可以正常识别和上传了 例如 D:/Output/a.jpg
+     */
+    // var fileNamePath = 'D:/Output/abc.png';
+    // var fileNamePath = 'D:/Output/exeHttpWebsocketDemo.exe';
+    var fileNamePath = 'D:/Output/a.jpg';
+    
+    // 由于请求的异步操作的
+    MyHttp.find().upload("http", options, fileNamePath, function (result) {
+        
+        // 所以要实现同步,就要在回调的函数里面写逻辑,这样就保证了同步效果
+
+        // 返回页面
+        res.send(result);
+
+    });
+
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 398 - 0
exe/src/myWebServerRote/main.js

@@ -0,0 +1,398 @@
+// 引入框架
+var express = require('express');
+// 路由对象
+var objRouter = express.Router();
+
+var CommonVar = require('../common/moudles/CommonVar.js');
+
+// 引入 uuid模块,用于自动生成唯一客户cid使用的
+const { v4: uuidv4 } = require('uuid');
+// 时间模块
+var modelsSillyDatetime = require('silly-datetime');
+var modelsMoment = require('moment');
+var MySqllite = require('../common/moudles/MySqllite.js');
+
+
+// ########## 定义如下路由 ##########
+
+/**
+ * 首页-查询
+ * 地址:http://127.0.0.1:6789/mainSelect
+ */
+objRouter.get('/mainSelect', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+    
+    return CommonVar.find().retOk(res, CommonVar.find().getMain());
+
+
+});
+
+/**
+ * 首页-激活
+ * 地址:http://127.0.0.1:6789/mainUpdate
+ */
+objRouter.post('/mainUpdate', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['timeEnd'] === undefined || post['timeEnd'] === null || post['activation'] === "") {
+        return CommonVar.find().retError(res, '到期时间,参数不正确!');
+    }
+
+    if (post['activation'] === undefined || post['activation'] === null || post['activation'] === "") {
+        return CommonVar.find().retError(res, '密钥,参数不正确!');
+    }
+
+    CommonVar.find().cacheGetOrUpdate("set", "timeEnd", post['timeEnd']);
+    CommonVar.find().cacheGetOrUpdate("set", "activation", post['activation']);
+
+    // 重新获取最新的激活情况
+    CommonVar.find().getMain();
+    // 进行验证
+    if (CommonVar.find().stateBool() === false) {
+        return CommonVar.find().retError(res, '使用已到期,请关闭软件后,联系管理员重新激活!');
+    }
+
+    return CommonVar.find().retOk(res, "更新成功")
+
+});
+
+/**
+ * 首页-获取
+ * 地址:http://127.0.0.1:6789/mainGetCode?machineCode=MDAwMF8wMDAwXzAxMDBfMDAwMF9FNEQyXzVDMzFfNDBCNF80RDAxLg==&timeEnd=2022-03-15
+ */
+objRouter.get('/mainGetCode', function (req, res) {
+
+    var get = req.query;
+
+    if (get['machineCode'] === undefined || get['machineCode'] === null || get['machineCode'] === "") {
+        return CommonVar.find().retError(res, '机器码,参数不正确!');
+    }
+
+    if (get['timeEnd'] === undefined || get['timeEnd'] === null || get['timeEnd'] === "") {
+        return CommonVar.find().retError(res, '到期时间,参数不正确!');
+    }
+
+    return CommonVar.find().retOk(res, CommonVar.find().activationCode(get['machineCode'], get['timeEnd']));
+
+});
+
+/**
+ * 首页-弹出指定的地址,创建新的窗口
+ * 地址:http://127.0.0.1:6789/mainLoadUrl
+ */
+objRouter.post('/mainLoadUrl', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+    
+    CommonVar.find().cacheGetOrUpdate('set', 'createBrowserWindowUrl', post['url']);
+
+    return CommonVar.find().retOk(res, "正在弹出")
+
+});
+
+/**
+ * 首页-弹出指定的地址,创建新的窗口【到浏览器】
+ * 地址:http://127.0.0.1:6789/mainLoadUrlBrowser
+ */
+objRouter.post('/mainLoadUrlBrowser', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+    
+    CommonVar.find().cacheGetOrUpdate('set', 'createBrowserWindowUrlBrowser', post['url']);
+
+    return CommonVar.find().retOk(res, "正在弹出")
+
+});
+
+/**
+ * 唯一name值参数记录
+ * 地址:http://127.0.0.1:6789/nameOnlyAdd
+ */
+objRouter.post('/nameOnlyAdd', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    // console.log({
+    //     "GET" : get,
+    //     "POST" : post
+    // });
+
+    if (post['json'] === undefined || post['json'] === null) {
+        return CommonVar.find().retError(res, 'json 必须填写');
+    }
+
+
+    var sqlTimeObj = null;
+    try {
+
+        var json = post["json"];
+        json = JSON.parse(json);
+        
+        var jsonStr = json["JSON"];
+        jsonStr = JSON.parse(jsonStr);
+        
+        var results = jsonStr["results"];
+        
+        // 当前数据库成功查询返回的数据次数
+        var sqlGetSum = 0;
+        // 批量新增的数据
+        var sqlAdd = "";
+
+
+        // 当前执行查询操作的语句是否完成
+        var sqlEnd = true;
+
+        var sqlTimeObj = setInterval(function() {
+
+            if (sqlEnd == true) {
+                sqlEnd = false;
+
+                if (sqlGetSum >= results.length) {
+
+                    clearInterval(sqlTimeObj);
+                    sqlTimeObj = null;
+
+                    // console.log(
+                    //     "增加的数据",
+                    //     sqlAdd
+                    // );
+
+                    // // 因为操作数据库是异步的
+                    // MySqllite.find().query(sqlAdd, null, function (err, result) {
+
+                    //     // 所以我们采用回调的方法,来实现同步
+                    //     return CommonVar.find().retOk(res, "数据写入完成");
+
+                    // });
+
+                    // 所以我们采用回调的方法,来实现同步
+                    return CommonVar.find().retOk(res, "数据写入完成 " + new Date());
+                    
+                } else {
+
+                    var thisResults = results[sqlGetSum];
+                    // console.log("thisResults", thisResults);
+
+                    // console.log("thisResultsName", thisResults["name"]);
+                    
+                    // 查询单条数据,只会返回一条数据
+                    var sql = "SELECT * FROM name_only WHERE name = '" + thisResults["name"] + "';";
+
+                    // 因为操作数据库是异步的
+                    MySqllite.find().query(sql, 'get', function (err, result) {
+                        
+                        // sqlGetSum += 1;
+                        // sqlEnd = true;
+
+                        // console.log("查询结果", result, thisResults["name"]);
+
+                        if (result == null || result == undefined) {
+                            // sqlAdd += "INSERT INTO name_only (id, name, type) VALUES ('" + uuidv4() + "', '" + thisResults["name"] + "', 0);";
+                            
+                            sqlAdd = "INSERT INTO name_only (id, name, type) VALUES ('" + uuidv4() + "', '" + thisResults["name"] + "', 0);";
+                            // 因为操作数据库是异步的
+                            MySqllite.find().query(sqlAdd, null, function (err, result) {
+
+                                console.log("数据增加了", thisResults["name"], sqlGetSum, results.length);
+                                
+                                sqlGetSum += 1;
+                                sqlEnd = true;
+
+                            });
+
+                        } else {
+
+                            sqlGetSum += 1;
+                            sqlEnd = true;
+                            
+                        }
+                        
+                    });
+
+                }
+                
+            }
+            
+        }, 100);
+        
+        // for (var i = 0; i < results.length; i++) {
+
+        //     var thisResults = results[i];
+        //     // console.log("thisResults", thisResults);
+
+
+        //     // 查询单条数据,只会返回一条数据
+        //     var sql = "SELECT * FROM name_only WHERE name = '" + thisResults["name"] + "';";
+
+        //     // 因为操作数据库是异步的
+        //     MySqllite.find().query(sql, 'get', function (err, result) {
+                
+        //         sqlGetSum += 1;
+
+        //         if (err == null || err == undefined || result == null || result == undefined) {
+        //             sqlAdd += "INSERT INTO name_only (id, name, type) VALUES ('" + uuidv4() + "', '" + thisResults["name"] + "', 0);";
+        //         }
+                
+        //         if (sqlGetSum >= results.length) {
+
+        //             // console.log(
+        //             //     "增加的数据",
+        //             //     sqlAdd
+        //             // );
+
+        //             // 因为操作数据库是异步的
+        //             MySqllite.find().query(sqlAdd, null, function (err, result) {
+
+        //                 // 所以我们采用回调的方法,来实现同步
+        //                 return CommonVar.find().retOk(res, "数据写入完成");
+
+        //             });
+                    
+        //         }
+                
+        //     });
+            
+        // }
+
+        return;
+
+    } catch (e) {
+        clearInterval(sqlTimeObj);
+        sqlTimeObj = null;
+        return CommonVar.find().retError(res, 'json 参数不符合条件');
+    }
+
+    
+    clearInterval(sqlTimeObj);
+    sqlTimeObj = null;
+    return CommonVar.find().retOk(res, "正在写入");
+
+});
+
+
+/**
+ * 唯一name 查询第一个数据,并且重新更新 type
+ * 地址:http://127.0.0.1:6789/nameOnlyGetOne
+ */
+objRouter.get('/nameOnlyGetOne', function (req, res) {
+
+    // 查询单条数据,只会返回一条数据
+    var sql = "SELECT * FROM name_only where type = 0 order by name asc limit 1;";
+
+    // 因为操作数据库是异步的
+    MySqllite.find().query(sql, 'get', function (err, result) {
+
+        if (result != null && result != undefined) {
+
+            // 更新type
+            var sqlUpdate = "UPDATE name_only SET type = 1 WHERE id = '" + result.id + "';";
+            // 因为操作数据库是异步的
+            MySqllite.find().query(sqlUpdate, null, function (errUpdate, resultUpdate) {
+                
+                // return CommonVar.find().retOk(res, result);
+                res.send(result.name);
+
+            });
+            
+        } else {
+
+            return CommonVar.find().retError(res, '没有可操作的数据');
+
+        }
+        
+    });
+    
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 1949 - 0
exe/src/myWebServerRote/project.js

@@ -0,0 +1,1949 @@
+// 引入框架
+var express = require('express');
+// 路由对象
+var objRouter = express.Router();
+
+var CommonVar = require('../common/moudles/CommonVar.js');
+var MyFile = require('../common/moudles/MyFile.js');
+
+// 引入 uuid模块,用于自动生成唯一客户cid使用的
+const { v4: uuidv4 } = require('uuid');
+// 时间模块
+var modelsSillyDatetime = require('silly-datetime');
+var modelsMoment = require('moment');
+var MySqllite = require('../common/moudles/MySqllite.js');
+let SystemInformation = require('../common/moudles/SystemInformation.js');
+
+
+// ########## 定义如下路由 ##########
+
+/**
+ * 项目列表-创建【 需要上传文件 】
+ * 地址:http://127.0.0.1:6789/projectAdd
+ */
+objRouter.post('/projectAdd', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    // 是否压缩模型
+    var compress = 'no';
+    if (post['compress'] !== undefined && post['compress'] !== null) {
+        compress = post['compress'];
+    }
+
+    // 转换成你要的时间格式
+    var date = modelsSillyDatetime.format(new Date(), 'YYYY-MM-DD HH:mm:ss');
+
+    post['name'] = '新项目_' + date;
+
+    var uuid = uuidv4();
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(uuid);
+    // 项目根目录
+    let commonPath = path['commonPath'];
+
+    // ########## 接收上传的文件 ##########
+
+    // 获取当前的地址
+    var url = "http://" + req.headers.host + "/";
+
+    // 文件存储目录
+    var pathSave = path['pathModel'];
+
+    var objFs = require('fs');
+    var objCrypto = require('crypto');
+    var ret = [];
+
+    // 不压缩的时候保存的文件名
+    var fileNameSave = "";
+    // 不压缩文件的目录 + 文件名
+    var pathFileNameSave = "";
+    // 如果压缩,则用这个文件名保存,之后压缩完成后,自动变成 fileNameSave 文件名,最后删除这个文件
+    var fileNameSaveCompress = "";
+    // 压缩文件的目录 + 文件名
+    var pathFileNameSaveCompress = "";
+
+    // 循环遍历要上传的文件,支持多文件同时上传
+    req.files.forEach(function(value, key, iterable) {
+
+        // 获取文件的md5
+        // 读取文件
+        var stream = objFs.readFileSync(value.path);
+        // 得到md5
+        var md5 = objCrypto.createHash('md5').update(stream).digest('hex');
+
+        // 获取文件名后缀
+        var suffix = "";
+        if (value.originalname.lastIndexOf(".") >= 0) {
+            var suffixArray = value.originalname.split(".");
+            suffix = "." + suffixArray[suffixArray.length - 1];
+        }
+
+        // 上传的文件在req.files中
+        // fileNameSave = value.filename + suffix;
+        fileNameSave = 'main' + suffix;
+        pathFileNameSave = pathSave + fileNameSave;
+
+        fileNameSaveCompress = 'main_compress' + suffix;
+        pathFileNameSaveCompress = pathSave + fileNameSaveCompress;
+
+        var filenamePath = pathSave + fileNameSave;
+        // 如果是压缩
+        if (compress == 'yes') {
+            filenamePath = pathSave + fileNameSaveCompress;
+        }
+
+        // 通过重命名的方式,将临时上传的文件放到指定的存储目录
+        // objFs.renameSync(req.files[0].path, filename);
+        objFs.renameSync(value.path, filenamePath);
+
+        // 处理完成之后,临时的文件是会消失的
+        
+        var thisFileJson = {
+            // 字段名
+            fieldname : value.fieldname,
+            // 上传的原始文件名
+            originalname : value.originalname,
+            // 编码类型
+            encoding : value.encoding,
+            // 模型类
+            mimetype : value.mimetype,
+            // 临时存储目录
+            destination : value.destination,
+            // 临时存储的文件名
+            filename : value.filename,
+            // 临时存储目录和文件名
+            path : value.path,
+            // 文件大小
+            size : value.size,
+            // md5
+            md5 : md5,
+            // 后缀
+            suffix : suffix,
+            // 文件地址
+            url : url + pathSave + fileNameSave,
+        };
+
+        // 增加返回的结果
+        ret.push(thisFileJson);
+
+    });
+
+    // //替换路径 去除 /new_src
+    // let modelUrl = pathSave.replaceAll("/new_src", '');
+
+    // //cd到new_src目录 执行glb压缩命令,生成压缩文件,名称为mainCom.glb
+    // //如果comLog返回信息则说明压缩失败,成功时不返回信息
+    // let comLog = SystemInformation.find().cmd(`cd new_src && compress.exe -i ${modelUrl}main.glb -o ${modelUrl}mainCom.glb -tc -vp 16 -vt 16 -vn 16 -kn`);
+
+    var compressExePath = commonPath + 'compress.exe';
+
+    // 如果确定压缩
+    if (compress == 'yes') {
+
+        // 获取根目录
+        var rootPath = MyFile.find().pathStart();
+
+        let modelUrl = pathSave.replaceAll("/new_src", '');
+        // // 执行的cmd命令【开发的时候,使用这个】
+        // let cmdCompressStr = `cd ${rootPath} && cd new_src && compress.exe -i ${modelUrl}${fileNameSaveCompress} -o ${modelUrl}${fileNameSave} -tc -vp 16 -vt 16 -vn 16`;
+
+        // 执行的cmd命令【发布的时候,使用这个】
+        let cmdCompressStr = `cd ${rootPath} && ${compressExePath} -i ${pathFileNameSaveCompress} -o ${pathFileNameSave} -tc -vp 16 -vt 16 -vn 16`;
+
+        // // 写入日志看下情况
+        // MyFile.find().fileCreate(commonPath + "cmd.txt", cmdCompressStr, 'w');
+
+        //cd到new_src目录 执行glb压缩命令,生成压缩文件,名称为mainCom.glb
+        //如果comLog返回信息则说明压缩失败,成功时不返回信息
+        SystemInformation.find().cmd(cmdCompressStr, function (err, data) {
+
+            // console.log([
+            //     "异步cmd命令执行结果",
+            //     err,
+            //     data
+            // ]);
+
+            // 删除没有压缩文件
+            MyFile.find().fileDel(pathFileNameSaveCompress);
+
+            // 写入默认的配置项目文件
+            var jsonInit = {
+                "id" : uuid,
+                "model_name" : fileNameSave,
+                "name" : uuid,
+            };
+
+            CommonVar.find().projectPathConfigJson(uuid, 'set', JSON.stringify(jsonInit));
+
+            // 创建成功后返回唯一的 uuid 的值
+            return CommonVar.find().retOk(res, { 'str' : uuid, 'fileNameSave' : fileNameSave });
+
+
+        });
+        
+        return;
+
+    }
+
+    // // ########## 新增数据 ##########
+    // var sql = "INSERT INTO project (id, del, time, name, model_main) VALUES ('" + uuid + "', 0, '" + date + "', '" + post['name'] + "', '" + fileNameSave + "');";
+
+    // MySqllite.find().query(sql, null, function (err, result) {
+
+    //     return CommonVar.find().retOk(res, { 'str' : '创建成功' });
+
+    // });
+
+    // 写入默认的配置项目文件
+    var jsonInit = {
+        "id" : uuid,
+        "model_name" : fileNameSave,
+        "name" : uuid,
+    };
+
+    CommonVar.find().projectPathConfigJson(uuid, 'set', JSON.stringify(jsonInit));
+
+    // 创建成功后返回唯一的 uuid 的值
+    return CommonVar.find().retOk(res, { 'str' : uuid, 'fileNameSave' : fileNameSave });
+    
+});
+
+
+/**
+ * 项目列表-创建【 不需要上传文件上传 】
+ * 地址:http://127.0.0.1:6789/projectAddNew
+ */
+objRouter.post('/projectAddNew', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+    
+    // 转换成你要的时间格式
+    var date = modelsSillyDatetime.format(new Date(), 'YYYY-MM-DD HH:mm:ss');
+
+    var name = '新项目_' + date;
+    
+    if (post['name'] !== undefined && post['name'] !== null) {
+        name = post['name'];
+    }
+
+    var uuid = uuidv4();
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(uuid);
+
+    // 写入默认的配置项目文件
+    var jsonInit = {
+        "id" : uuid,
+        "model_name" : null,
+        "name" : name,
+    };
+
+    CommonVar.find().projectPathConfigJson(uuid, 'set', JSON.stringify(jsonInit));
+
+    // 创建成功后返回唯一的 uuid 的值
+    return CommonVar.find().retOk(res, { 'str' : uuid, 'fileNameSave' : null, 'jsonInit' : jsonInit });
+    
+});
+
+/**
+ * 项目列表-查询
+ * 地址:http://127.0.0.1:6789/projectSelect
+ */
+objRouter.post('/projectSelect', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(post['id']);
+    var url = "http://" + req.headers.host + "/";
+
+    // var sql = "SELECT * FROM project WHERE id = '" + post['id'] + "';";
+    // MySqllite.find().query(sql, 'get', function (err, result) {
+
+    //     // 新增返回字段
+    //     // 存储的模型地址
+    //     result['modelUrl'] = url + path['pathIdModel'];
+
+    //     // 得到配置文件
+    //     let configJson = CommonVar.find().projectPathConfigJson(post['id'], 'get');
+    //     result['configJson'] = configJson;
+
+    //     return CommonVar.find().retOk(res, result);
+
+    // });
+
+    var result = {};
+    // 得到配置文件
+    let configJson = CommonVar.find().projectPathConfigJson(post['id'], 'get');
+
+    try {
+        configJson = JSON.parse(configJson);
+    } catch (e) {
+        configJson = null;
+    }
+
+    
+    result['configJson'] = configJson;
+    result['modelUrl'] = url + path['pathIdModel'];
+
+    return CommonVar.find().retOk(res, result);
+
+
+});
+
+/**
+ * 项目列表-更新
+ * 地址:http://127.0.0.1:6789/projectUpdate
+ */
+objRouter.post('/projectUpdate', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    if (post['name'] === undefined || post['name'] === null) {
+        return CommonVar.find().retError(res, "项目名称 不能为空")
+    }
+
+    let uuid = post['id'];
+
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(uuid);
+    // 得到对应项目id下的目录
+    let pathModel = path['pathModel'];
+
+    if (post['configJson'] !== undefined && post['configJson'] !== null) {
+        // 存储 json 配置
+        let configJson = post['configJson'];
+        
+        var objConfigJson = null;
+        try {
+            objConfigJson = JSON.parse(configJson);
+        } catch (e) {
+
+        }
+
+        // 帅选出所有会用到的文件
+        var configFileList = {};
+
+        if (objConfigJson != null) {
+
+            var jsonGetArray = CommonVar.find().jsonGetArray(objConfigJson);
+            try {
+
+                for (var i = 0; i < jsonGetArray.length; i++) {
+                    var thisJsonGetArray = jsonGetArray[i];
+                    if (typeof thisJsonGetArray.val == 'object') {
+
+                        for (var key in thisJsonGetArray.val) {
+
+                            var thisJsonGetArrayValKey = thisJsonGetArray.val[key];
+                            
+                            if (typeof thisJsonGetArrayValKey == 'string') {
+                                
+
+                                if (
+                                    thisJsonGetArrayValKey.indexOf(".") >= 0
+                                    && thisJsonGetArrayValKey.indexOf("http") < 0
+                                    && thisJsonGetArrayValKey.indexOf("../../") < 0
+                                ) {
+                                    // console.log(thisJsonGetArrayValKey);
+                                    configFileList[thisJsonGetArrayValKey] = thisJsonGetArrayValKey;
+                                }
+
+                            }
+
+                        }
+
+                    } else if (typeof thisJsonGetArray.val == 'string') {
+
+                        var thisJsonGetArrayVal = thisJsonGetArray.val;
+
+                        if (
+                            thisJsonGetArrayVal.indexOf(".") >= 0
+                            && thisJsonGetArrayVal.indexOf("http") < 0
+                            && thisJsonGetArrayVal.indexOf("../../") < 0
+                        ) {
+                            // console.log(thisJsonGetArrayVal);
+                            configFileList[thisJsonGetArrayVal] = thisJsonGetArrayVal;
+                        }
+                        
+
+                    }
+
+                }
+
+            } catch (e) {
+
+            }
+
+            // console.log(
+            //     "确定要删除的文件列表",
+            //     configFileList
+            // );
+
+
+
+            
+            // 开始遍历要删除的文件
+            if (
+                configFileList != {}
+            ) {
+                
+                // 是否允许触发删除不需要的文件逻辑,默认触发
+                let delEventBool = true;
+                for (let key in configFileList) {
+
+                    let configFileListKey = configFileList[key];
+                    // console.log(
+                    //     "configFileListKey", configFileListKey
+                    // );
+
+                    if (
+                        configFileListKey.indexOf(".gltf") >= 0
+                        || configFileListKey.indexOf(".bin") >= 0
+                        || configFileListKey.indexOf(".babylon") >= 0
+                    ) {
+                        // 不触发删除逻辑
+                        delEventBool = false;
+                    }
+
+                }
+                
+                if (delEventBool == true) {
+                    
+                    // console.log("筛选出的文件列表", configFileList);
+
+                    // 遍历目录【通过目录知道该项目是否需要下载】
+                    let pathOrFileAll = MyFile.find().pathOrFileAll(pathModel);
+                    let pathModelFileArray = pathOrFileAll['file'];
+
+                    try {
+
+                        for (var i = 0; i < pathModelFileArray.length; i++) {
+
+                            var thisPathModelFileArray = pathModelFileArray[i];
+                            var name = thisPathModelFileArray.name;
+                            var filePath = thisPathModelFileArray.filePath;
+        
+                            // 必须保留的文件
+                            if (
+                                name != 'config.json'
+                                && name != 'okFileList.txt'
+                                && name != 'main.glb'
+                            ) {
+        
+                                if (configFileList[name] != null && configFileList[name] != undefined) {
+        
+                                } else {
+                                    // 要删除的文件
+                                    console.log("要删除的文件", name);
+                                    // MyFile.find().fileDel(filePath);
+                                }
+                                
+                            }
+                            
+                        }
+
+                    } catch (e) {
+
+                    }
+
+                }
+
+            }
+
+        }
+        
+        CommonVar.find().projectPathConfigJson(uuid, 'set', configJson);
+
+        return CommonVar.find().retOk(res, {
+            "str" : "更新成功",
+            "configFileList" : configFileList,
+        });
+
+    }
+
+    return CommonVar.find().retOk(res, "更新成功");
+
+    var sql = "UPDATE project SET name = '" + post['name'] + "' ";
+
+    sql += " WHERE id = '" + post['id'] + "';";
+
+    MySqllite.find().query(sql, null, function (err, result) {
+
+        return CommonVar.find().retOk(res, "更新成功")
+        
+    });
+
+
+
+});
+
+/**
+ * 项目列表-删除
+ * 地址:http://127.0.0.1:6789/projectDel
+ */
+objRouter.post('/projectDel', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    var sql = "UPDATE project SET del = 1 ";
+
+    sql += " WHERE id = '" + post['id'] + "';";
+
+    MySqllite.find().query(sql, null, function (err, result) {
+
+        return CommonVar.find().retOk(res, "删除成功")
+        
+    });
+
+});
+
+/**
+ * 项目列表-分页
+ * 地址:http://127.0.0.1:6789/projectPage
+ */
+objRouter.get('/projectPage', function (req, res) {
+
+
+    var get = req.query;
+    var post = req.body;
+
+    var sql = "Select * from project where del = 0";
+
+    if (get['search'] !== undefined && get['search'] !== null && get['search'] !== '') {
+        sql += " and name like'%" + get['search'] + "%'";
+    }
+
+    // var constState = CommonVar.find().constVal['userObj']['state'];
+
+    sql += " order by time desc";
+    CommonVar.find().sqlitePage(sql, get['page'], get['pagesize'], function(sqlitePageRes) {
+
+        // 存在分页数据的话
+        if (sqlitePageRes['page'].length >= 1) {
+
+            for (var key in sqlitePageRes['page']) {
+
+                var thisState = sqlitePageRes['page'][key]['state'];
+                // // 新增字段数据返回
+                // sqlitePageRes['page'][key]['stateCz'] = constState[thisState];
+
+
+            }
+
+        }
+
+
+        return CommonVar.find().retOk(res, sqlitePageRes)
+
+    });
+
+
+});
+
+/**
+ * 项目列表-文件上传
+ * 地址:http://127.0.0.1:6789/projectFileUpload
+ */
+objRouter.post('/projectFileUpload', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    // 如果文件名字前缀存在,则会以文字前缀来命名,同时根据上传文件的顺序自动追加顺序的数值
+    var fileNamePrefix = null;
+    if (post['fileNamePrefix'] !== undefined && post['fileNamePrefix'] !== null) {
+        fileNamePrefix = post['fileNamePrefix'];
+    }
+
+
+    /**
+     * 是否自定义文件名进行上传。自定义名字,记得带上后缀,例如 123.png 或者 123.jpg
+     * 【【【【【【【【【【这个逻辑后续在继续开发】】】】】】】】】】
+     */
+    var fileNameMyCustom = null;
+    if (post['fileNameMyCustom'] !== undefined && post['fileNameMyCustom'] !== null) {
+        fileNameMyCustom = post['fileNameMyCustom'];
+    }
+
+    console.log(
+        "【【【【【【【【【【这个逻辑后续在继续开发】】】】】】】】】】",
+        "上传的文件自定义文件名 fileNameMyCustom = ",
+        fileNameMyCustom
+    );
+
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(post['id']);
+
+    // ########## 接收上传的文件 ##########
+
+    // 获取当前的地址
+    var url = "http://" + req.headers.host + "/";
+
+    // 文件存储目录
+    var pathSave = path['pathModel'];
+
+    var objFs = require('fs');
+    var objCrypto = require('crypto');
+    var ret = [];
+
+    var fileNameSave = ""
+    // 记录最后一次存储的 文件 json
+    var thisFileJson = {}
+
+    // 记录当前第几个循环
+    var forI = 0;
+
+    // 循环遍历要上传的文件,支持多文件同时上传
+    req.files.forEach(function(value, key, iterable) {
+
+        // 获取文件的md5
+        // 读取文件
+        var stream = objFs.readFileSync(value.path);
+        // 得到md5
+        var md5 = objCrypto.createHash('md5').update(stream).digest('hex');
+
+        // 获取文件名后缀
+        var suffix = "";
+        if (value.originalname.lastIndexOf(".") >= 0) {
+            var suffixArray = value.originalname.split(".");
+            suffix = "." + suffixArray[suffixArray.length - 1];
+        }
+
+        // 上传的文件在req.files中
+        // fileNameSave = value.filename + suffix;
+
+        // 如果文件名字前缀存在,则会以文字前缀来命名,同时根据上传文件的顺序自动追加顺序的数值
+        if (fileNamePrefix != null && fileNamePrefix != undefined) {
+            md5 = fileNamePrefix + forI;
+        }
+
+        fileNameSave = md5 + suffix;
+        var filenamePath = pathSave + fileNameSave;
+
+        // 通过重命名的方式,将临时上传的文件放到指定的存储目录
+        // objFs.renameSync(req.files[0].path, filename);
+        objFs.renameSync(value.path, filenamePath);
+
+        // 处理完成之后,临时的文件是会消失的
+        
+        thisFileJson = {
+            // 字段名
+            fieldname : value.fieldname,
+            // 上传的原始文件名
+            originalname : value.originalname,
+            // 编码类型
+            encoding : value.encoding,
+            // 模型类
+            mimetype : value.mimetype,
+            // 临时存储目录
+            destination : value.destination,
+            // 临时存储的文件名
+            filename : value.filename,
+            // 临时存储目录和文件名
+            path : value.path,
+            // 文件大小
+            size : value.size,
+            // md5
+            md5 : md5,
+            // 后缀
+            suffix : suffix,
+            // 文件地址
+            url : url + fileNameSave,
+            // 存储后的名字
+            fileNameSave : fileNameSave,
+        };
+
+        // 增加返回的结果
+        ret.push(thisFileJson);
+
+        forI += 1;
+
+    });
+    
+    return CommonVar.find().retOk(
+        res,
+        {
+            // 最后一次上传的文件
+            'fileJson' : thisFileJson,
+            // 批量上传结果
+            'fileList' : ret,
+        }
+    );
+
+    
+});
+
+
+
+/**
+ * 项目列表-删除指定ID下的文件
+ * 地址:http://127.0.0.1:6789/projectFileDel
+ */
+objRouter.post('/projectFileDel', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    // if (post['fileName'] === undefined || post['fileName'] === null) {
+    //     return CommonVar.find().retError(res, "fileName 不能为空")
+    // }
+
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(post['id']);
+    let delFile = path['pathModel'] + (post['fileName'] || '无' );
+    MyFile.find().fileDel(delFile);
+
+    return CommonVar.find().retOk(res, { 'str' : '删除成功' });
+
+});
+
+/**
+ * 项目列表-通过数组项目列表得到哪些项目是需要更新的
+ * 地址:http://127.0.0.1:6789/projectArrayUpdate
+ */
+objRouter.post('/projectArrayUpdate', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['array'] === undefined || post['array'] === null) {
+        return CommonVar.find().retOk(res, { 'str' : [] });
+    }
+
+    let objFs = require('fs');
+
+    // 返回对应字段 项目id,是否需要更新
+    let ret = {};
+    let array = [];
+
+    try {
+        array = JSON.parse(post['array']);
+    } catch (e) {
+        return CommonVar.find().retOk(res, { 'ret' : ret });
+    }
+
+    if (array.length <= 0) {
+        return CommonVar.find().retOk(res, { 'ret' : ret });
+    }
+
+    for (let i = 0; i < array.length; i++) {
+
+        var thisArray = array[i];
+        var uuid = thisArray['sceneUuid'];
+
+        // 得到配置文件,通过版本号判断是否要更新
+        let projectPathConfigJson = CommonVar.find().projectPathConfigJson(uuid, 'get');
+        let projectPathConfigJsonToJson = {};
+        try {
+            projectPathConfigJsonToJson = JSON.parse(projectPathConfigJson);
+        } catch (e) {
+
+        }
+
+        /**
+         * 当前项目是否需要更新
+         * no       不需要更新
+         * down     必须下载项目
+         * update  版本可以更新
+         * */
+        let updateBool = 'no';
+
+        // 创建项目单独的存储目录
+        let path = CommonVar.find().projectPath(uuid);
+        // 得到对应项目id下的目录
+        let pathModel = path['pathModel'];
+
+        // 遍历目录【通过目录知道该项目是否需要下载】
+        let pathOrFileAll = MyFile.find().pathOrFileAll(pathModel);
+        let pathModelFileArray = pathOrFileAll['file'];
+
+        // 判断配置的文件是否存在
+        let configJsonPath = pathModel + 'config.json';
+        
+        // 判断目录或者文件是否存在
+        var pathBoolConfigJsonPath = objFs.existsSync(configJsonPath);
+        // 没有配置文件的话就肯定是必须要更新的了
+        if (
+            pathBoolConfigJsonPath == false
+            // 2个文件,说明既要有配置文件,也要有模型文件
+            // || pathModelFileArray.length <= 1
+            // 此时只要有配置文件就说明不用下载
+            || pathModelFileArray.length <= 0
+        ) {
+            updateBool = 'down';
+        } else {
+            // 通过版本号进行判断
+            var thisVersion = 
+            projectPathConfigJsonToJson['version'] != null
+            && projectPathConfigJsonToJson['version'] != undefined ? projectPathConfigJsonToJson['version'] : '1.0';
+
+            var listVersion = thisArray['version'] != null
+            && thisArray['version'] != undefined ? thisArray['version'] : '1.0';
+
+            if (thisVersion != listVersion) {
+                updateBool = 'update';
+            }
+
+        }
+
+        ret[uuid] = updateBool;
+
+    }
+
+    return CommonVar.find().retOk(res, { 'ret' : ret });
+
+});
+
+/**
+ * 项目列表-触发下载
+ * 地址:http://127.0.0.1:6789/projectDown
+ */
+objRouter.post('/projectDown', function (req, res) {
+
+    // 判断是否已经有正在下载的内容了
+    var downList = CommonVar.find().cacheGetOrUpdate('get', 'downList', null);
+    if (downList != null && downList != undefined) {
+        return CommonVar.find().retError(res, "已有正在下载的文件,等下载完成后再尝试!")
+    }
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    if (post['downList'] === undefined || post['downList'] === null) {
+        return CommonVar.find().retError(res, "没有可下载的列表")
+    }
+
+    if (post['downListConfigJson'] === undefined || post['downListConfigJson'] === null) {
+        return CommonVar.find().retError(res, "没有可下载的配置文件")
+    }
+
+
+    var uuid = post['id'];
+    var downList = post['downList'];
+    var downListConfigJson = post['downListConfigJson'];
+    
+    var downListArray = [];
+    try {
+        downListArray = JSON.parse(downList);
+        for (var i = 0; i < downListArray.length; i++) {
+            // 是否下载完成,成功 yes,未下载 no
+            downListArray[i]['state'] = 'no';
+
+        }
+
+    } catch (e) {
+
+    }
+
+    if (downListArray.length <= 0) {
+        return CommonVar.find().retError(res, "没有可下载的列表")
+    }
+    
+    try {
+        downListConfigJson = JSON.parse(downListConfigJson);
+    } catch (e) {
+        downListConfigJson = null;
+    }
+
+    if (typeof downListConfigJson != 'object') {
+        return CommonVar.find().retError(res, "没有可下载的列表")
+    }
+
+
+    // console.log("downListArray", downListConfigJson, downListArray);
+
+    // 帅选出所有会用到的文件
+    var configFileList = {};
+
+    var jsonGetArray = CommonVar.find().jsonGetArray(downListConfigJson);
+    try {
+
+        for (var i = 0; i < jsonGetArray.length; i++) {
+            var thisJsonGetArray = jsonGetArray[i];
+            if (typeof thisJsonGetArray.val == 'object') {
+
+                for (var key in thisJsonGetArray.val) {
+
+                    var thisJsonGetArrayValKey = thisJsonGetArray.val[key];
+                    
+                    if (typeof thisJsonGetArrayValKey == 'string') {
+                        
+
+                        if (
+                            thisJsonGetArrayValKey.indexOf(".") >= 0
+                            && thisJsonGetArrayValKey.indexOf("http") < 0
+                            && thisJsonGetArrayValKey.indexOf("../../") < 0
+                        ) {
+                            // console.log(thisJsonGetArrayValKey);
+                            configFileList[thisJsonGetArrayValKey] = thisJsonGetArrayValKey;
+                        }
+
+                    }
+
+                }
+
+            } else if (typeof thisJsonGetArray.val == 'string') {
+
+                var thisJsonGetArrayVal = thisJsonGetArray.val;
+
+                if (
+                    thisJsonGetArrayVal.indexOf(".") >= 0
+                    && thisJsonGetArrayVal.indexOf("http") < 0
+                    && thisJsonGetArrayVal.indexOf("../../") < 0
+                ) {
+                    // console.log(thisJsonGetArrayVal);
+                    configFileList[thisJsonGetArrayVal] = thisJsonGetArrayVal;
+                }
+                
+
+            }
+
+        }
+
+    } catch (e) {
+
+    }
+    
+
+    // console.log("可下载的文件", configFileList, downListArray);
+
+    // // 重新遍历得到可以下载的文件[ 由于新增了 babylon 格式的文件 , 就不判断是否下载逻辑了]
+    // var downListArrayNew = [];
+    // for (var i = 0; i < downListArray.length; i++) {
+    //     var thisDownListArray = downListArray[i];
+    //     // console.log("thisDownListArray", thisDownListArray);
+
+    //     var downName = thisDownListArray["name"];
+
+    //     if (
+    //         // 一些固定的文件是必须下载的
+    //         downName == "config.json"
+    //         // || downName == "config.json"
+    //         ||
+    //         (
+    //             configFileList[downName] != null && configFileList[downName] != undefined
+    //         )
+    //     ) {
+    //         downListArrayNew.push(thisDownListArray);
+    //     }
+        
+
+    // }
+
+    // [暂时修改为,所有文件可下载]
+    downListArrayNew = downListArray;
+    
+    var downListJson = {
+        'uuid' : uuid,
+        'pathList' : downListArrayNew
+    }
+
+    // console.log("downListJson", downListJson);
+
+    // return CommonVar.find().retOk(res, { 'ret' : "开始下载了" });
+
+    CommonVar.find().cacheGetOrUpdate('set', 'downList', JSON.stringify(downListJson));
+
+    return CommonVar.find().retOk(res, { 'ret' : "开始下载了" });
+
+});
+
+/**
+ * 项目列表-触发上传[发布]
+ * 地址:http://127.0.0.1:6789/projectUploadWeb
+ */
+objRouter.post('/projectUploadWeb', function (req, res) {
+    
+    // 判断是否已经有正在上传的内容了
+    var uploadList = CommonVar.find().cacheGetOrUpdate('get', 'uploadList', null);
+    if (uploadList != null && uploadList != undefined) {
+        return CommonVar.find().retError(res, "已有正在上传的文件,等上传完成后再尝试!")
+    }
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    if (post['userId'] === undefined || post['userId'] === null) {
+        return CommonVar.find().retError(res, "userId 不能为空")
+    }
+
+    var uuid = post['id'];
+    var userId = post['userId'];
+
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(uuid);
+    // 得到对应项目id下的目录
+    let pathModel = path['pathModel'];
+
+    // 上传列表
+    var pathList = [];
+    var pathOrFileAll = MyFile.find().pathOrFileAll(pathModel, false);
+    // 所有上传的文件列表
+    var file = pathOrFileAll['file'];
+
+    try {
+
+        if (file.length > 0) {
+            // 追加可上传的列表
+            for (let i = 0; i < file.length; i++) {
+                var thisFile = file[i];
+                // 是否上传完成,成功 yes,未上传为 no
+                thisFile['state'] = 'no';
+                pathList.push(thisFile);
+            }
+        }
+
+    } catch (e) {
+
+    }
+
+    if (pathList.length <= 0) {
+        CommonVar.find().cacheGetOrUpdate('set', 'uploadList', null);
+        return CommonVar.find().retError(res, "该项目没有可上传的文件!")
+    }
+
+    var uploadJson = {
+        'uuid' : uuid,
+        'userId' : userId,
+        'pathList' : pathList
+    }
+
+    CommonVar.find().cacheGetOrUpdate('set', 'uploadList', JSON.stringify(uploadJson));
+    return CommonVar.find().retOk(res, { 'ret' : "正在发布中" });
+
+});
+
+/**
+ * 项目列表-当前是否存在上传或者下载的任务
+ * 地址:http://127.0.0.1:6789/projectUploadOrDown
+ */
+objRouter.post('/projectUploadOrDown', function (req, res) {
+    var uploadListBool = false;
+    var downListBool = false;
+
+    // 得到上传百分比
+    var progressUpload = 0;
+    // 得到下载百分比
+    var progressDown = 0;
+
+    var uploadList = CommonVar.find().cacheGetOrUpdate('get', 'uploadList', null);
+    if (uploadList != null && uploadList != undefined) {
+
+        try {
+            var uploadListJson = JSON.parse(uploadList);
+            uploadListBool = uploadListJson['uuid'];
+            var pathList = uploadListJson.pathList;
+            try {
+                // 总进度
+                var progressUploadMax = pathList.length;
+                // 已完成的进度
+                var progressUploadOk = 0;
+                for (var i = 0; i < pathList.length; i++) {
+                    var thisPathList = pathList[i];
+                    // console.log(thisPathList);
+                    if (thisPathList.state == 'yes') {
+                        progressUploadOk += 1;
+                    }
+                }
+
+                progressUpload = (progressUploadOk / progressUploadMax * 100).toFixed(3);
+
+
+            } catch(e) {
+
+            }
+        } catch (e) {
+
+        }
+        
+    }
+
+    var downList = CommonVar.find().cacheGetOrUpdate('get', 'downList', null);
+    if (downList != null && downList != undefined) {
+        downListBool = true;
+
+        try {
+            var downListJson = JSON.parse(downList);
+            downListBool = downListJson['uuid'];
+
+            try {
+
+                var pathList = downListJson.pathList;
+                // 总进度
+                var progressDownMax = pathList.length;
+                // 已完成的进度
+                var progressDownOk = 0;
+                for (var i = 0; i < pathList.length; i++) {
+                    var thisPathList = pathList[i];
+                    // console.log(thisPathList);
+                    if (thisPathList.state == 'yes') {
+                        progressDownOk += 1;
+                    }
+                }
+
+                progressDown = (progressDownOk / progressDownMax * 100).toFixed(3);
+
+            } catch(e) {
+
+            }
+
+
+        } catch (e) {
+
+        }
+
+    }
+
+    return CommonVar.find().retOk(res, { 
+        'uploadListBool' : uploadListBool,
+        'downListBool' : downListBool,
+        'progressUpload' : progressUpload,
+        'progressDown' : progressDown,
+    });
+
+});
+
+/**
+ * 项目列表-将base64位图片转图片文件存储
+ * 地址:http://127.0.0.1:6789/base64ToPng
+ */
+objRouter.post('/base64ToPng', function (req, res) {
+    
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    if (post['base64'] === undefined || post['base64'] === null) {
+        return CommonVar.find().retError(res, "base64 不能为空")
+    }
+
+    if (post['base64Suffix'] === undefined || post['base64Suffix'] === null) {
+        return CommonVar.find().retError(res, "base64Suffix 不能为空")
+    }
+
+    var uuid = post['id'];
+    var base64 = post['base64'];
+    // 例如 data:image/png;base64,
+    var base64Suffix = post['base64Suffix'];
+    
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(uuid);
+    // 得到对应项目id下的目录
+    let pathModel = path['pathModel'];
+
+    var base64Str = "";
+    try {
+        base64Str = base64.split(base64Suffix)[1];
+    } catch (e) {
+
+    }
+
+    var time = new Date().getTime();
+    var fileName = time + ".png";
+    var pathSave = pathModel + fileName;
+    var base64ToFile = MyFile.find().base64ToFile(base64Str, pathSave);
+    return CommonVar.find().retOk(res, { 'fileName' : fileName, 'pathSave' : pathSave });
+
+
+});
+
+
+/**
+ * 项目列表-通过文件地址自动下载到本地仓库之后再复制到目标项目id的目录下
+ * 地址:http://127.0.0.1:6789/urlDownToUuid
+ */
+objRouter.post('/urlDownToUuid', function (req, res) {
+    
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    if (post['url'] === undefined || post['url'] === null) {
+        return CommonVar.find().retError(res, "url 不能为空")
+    }
+
+    var uuid = post['id'];
+    var url = post['url'];
+
+    if (url.indexOf('.') < 0) {
+        return CommonVar.find().retError(res, "文件格式不正确 不能为空")
+    }
+
+    
+    // 创建项目单独的存储目录
+    let path = CommonVar.find().projectPath(uuid);
+    // 得到对应项目id下的目录
+    let pathModel = path['pathModel'];
+    // 得到对应本地仓库的目录
+    let pathMyRes = path['pathMyRes'];
+    
+    var rulArray = url.split('/');
+    // 存储的文件名
+    let fileName = rulArray[rulArray.length - 1];
+
+    // 存储本地仓库的目录 + 文件名
+    let pathSaveMyRes = pathMyRes + fileName;
+    // 存储本地项目的目录 + 文件名
+    let pathSaveModel = pathModel + fileName;
+
+    // 返回结果的 json
+    let resJson = {
+        'pathSaveMyRes' : pathSaveMyRes,
+        'pathSaveModel' : pathSaveModel,
+        'url' : url,
+        'fileName' : fileName,
+        // 是否是重新下载的
+        'down' : false,
+    };
+
+    let objFs = require('fs');
+    
+    // 记录最后一次文件容量的变化[ 当容量一致说明文件是真正的写入完成 ]
+    var fileSize = 0;
+    // 记录出现了多少次容量没有变化,一直没变化说明网络异常
+    var fileSizeSum = 0;
+    // 出现了多少次后网络异常
+    var fileSizeSumMax = 6;
+    // 用于判断文件是否下载完成定时器
+    var setIntervalObj = null;
+    
+    // 文件不存在
+    if (objFs.existsSync(pathSaveMyRes) == false) {
+
+        // 开始下载文件
+        MyFile.find().urlDownCallback(url, pathSaveMyRes, function() {
+
+            // 重新判断文件是否下载成功了
+            if (objFs.existsSync(pathSaveMyRes) == false) {
+                return CommonVar.find().retError(res, "文件不存在操作失败");
+            }
+
+            // 判断下载的文件是否成功写入磁盘
+            setIntervalObj = setInterval(function() {
+
+                // 得到物体的容量是否存在变化
+                var pathSaveMyResDb = objFs.statSync(pathSaveMyRes);
+
+                if (fileSizeSum >= fileSizeSumMax) {
+                    // 此时删除文件
+                    MyFile.find().fileDel(pathSaveMyRes);
+                    return CommonVar.find().retError(res, "网络异常文件不存在操作失败");
+                }
+
+                if (fileSize != pathSaveMyResDb.size) {
+                    fileSize = pathSaveMyResDb.size;
+                    return false;
+                }
+
+                // 此时说明文件还没下载完成
+                if (fileSize <= 0) {
+                    fileSizeSum += 1;
+                    return false;
+                }
+
+                clearInterval(setIntervalObj);
+                setIntervalObj = null;
+                
+                // ########## 开始走复制文件的逻辑
+                // 初始化参数
+                fileSize = 0;
+                fileSizeSum = 0;
+
+                // 直接复制文件
+                objFs.copyFileSync(pathSaveMyRes, pathSaveModel);
+
+                // 判断项目文件是否存在【 不存在 】
+                if (objFs.existsSync(pathSaveModel) == false) {
+                    return CommonVar.find().retError(res, "文件不存在操作失败");
+                }
+
+                // 是重新下载的
+                resJson['down'] = true;
+                
+                setIntervalObj = setInterval(function() {
+                    // 得到物体的容量是否存在变化
+                    var pathSaveModelDb = objFs.statSync(pathSaveModel);
+
+                    if (fileSizeSum >= fileSizeSumMax) {
+                        // 此时删除文件
+                        MyFile.find().fileDel(pathSaveModel);
+                        return CommonVar.find().retError(res, "网络异常文件不存在操作失败");
+                    }
+    
+                    if (fileSize != pathSaveModelDb.size) {
+                        fileSize = pathSaveModelDb.size;
+                        return false;
+                    }
+
+                    // 此时说明文件还没下载完成
+                    if (fileSize <= 0) {
+                        fileSizeSum += 1;
+                        return false;
+                    }
+
+                    clearInterval(setIntervalObj);
+                    setIntervalObj = null;
+                    return CommonVar.find().retOk(res, resJson);
+    
+                }, 1000);
+                
+            }, 1000);
+
+            return true;
+
+            
+            // // 判断项目文件是否存在【 不存在 】
+            // if (objFs.existsSync(pathSaveModel) == false) {
+                
+            //     // 开始下载文件[ 实现复制,nodejs自带的复制文件有问题 ]
+            //     MyFile.find().urlDownCallback(url, pathSaveModel, function() {
+                    
+            //         // 判断项目文件是否存在【 不存在 】
+            //         if (objFs.existsSync(pathSaveModel) == false) {
+            //             return CommonVar.find().retError(res, "文件不存在操作失败");
+            //         }
+
+            //         // 是重新下载的
+            //         resJson['down'] = true;
+                    
+            //         setIntervalObj = setInterval(function() {
+            //             // 得到物体的容量是否存在变化
+            //             var pathSaveModelDb = objFs.statSync(pathSaveModel);
+
+            //             if (fileSizeSum >= fileSizeSumMax) {
+            //                 // 此时删除文件
+            //                 MyFile.find().fileDel(pathSaveModel);
+            //                 return CommonVar.find().retError(res, "网络异常文件不存在操作失败");
+            //             }
+        
+            //             if (fileSize != pathSaveModelDb.size) {
+            //                 fileSize = pathSaveModelDb.size;
+            //                 return false;
+            //             }
+
+            //             // 此时说明文件还没下载完成
+            //             if (fileSize <= 0) {
+            //                 fileSizeSum += 1;
+            //                 return false;
+            //             }
+
+            //             clearInterval(setIntervalObj);
+            //             setIntervalObj = null;
+            //             return CommonVar.find().retOk(res, resJson);
+        
+            //         }, 1000);
+
+            //     });
+
+
+            //     return true;
+
+            // }
+
+            return CommonVar.find().retOk(res, resJson);
+
+        });
+
+        return true;
+
+    }
+
+    // 判断项目文件是否存在【 不存在 】
+    if (objFs.existsSync(pathSaveModel) == false) {
+
+        // console.log("被复制的文件", pathSaveMyRes, "复制后的文件", pathSaveModel);
+
+        // 直接复制文件
+        objFs.copyFileSync(pathSaveMyRes, pathSaveModel);
+        // 判断项目文件是否存在【 不存在 】
+        if (objFs.existsSync(pathSaveModel) == false) {
+            return CommonVar.find().retError(res, "文件不存在操作失败");
+        }
+
+        // 是重新下载的
+        resJson['down'] = true;
+        
+        setIntervalObj = setInterval(function() {
+            // 得到物体的容量是否存在变化
+            var pathSaveModelDb = objFs.statSync(pathSaveModel);
+
+            if (fileSizeSum >= fileSizeSumMax) {
+                // 此时删除文件
+                MyFile.find().fileDel(pathSaveModel);
+                return CommonVar.find().retError(res, "网络异常文件不存在操作失败");
+            }
+
+            if (fileSize != pathSaveModelDb.size) {
+                fileSize = pathSaveModelDb.size;
+                return false;
+            }
+
+            // 此时说明文件还没下载完成
+            if (fileSize <= 0) {
+                fileSizeSum += 1;
+                return false;
+            }
+
+            clearInterval(setIntervalObj);
+            setIntervalObj = null;
+            return CommonVar.find().retOk(res, resJson);
+
+        }, 1000);
+                
+        // // 开始下载文件[ 实现复制,nodejs自带的复制文件有问题 ]
+        // MyFile.find().urlDownCallback(url, pathSaveModel, function() {
+            
+        //     // 判断项目文件是否存在【 不存在 】
+        //     if (objFs.existsSync(pathSaveModel) == false) {
+        //         return CommonVar.find().retError(res, "文件不存在操作失败");
+        //     }
+
+        //     // 是重新下载的
+        //     resJson['down'] = true;
+            
+        //     setIntervalObj = setInterval(function() {
+        //         // 得到物体的容量是否存在变化
+        //         var pathSaveModelDb = objFs.statSync(pathSaveModel);
+
+        //         if (fileSizeSum >= fileSizeSumMax) {
+        //             // 此时删除文件
+        //             MyFile.find().fileDel(pathSaveModel);
+        //             return CommonVar.find().retError(res, "网络异常文件不存在操作失败");
+        //         }
+
+        //         if (fileSize != pathSaveModelDb.size) {
+        //             fileSize = pathSaveModelDb.size;
+        //             return false;
+        //         }
+
+        //         // 此时说明文件还没下载完成
+        //         if (fileSize <= 0) {
+        //             fileSizeSum += 1;
+        //             return false;
+        //         }
+
+        //         clearInterval(setIntervalObj);
+        //         setIntervalObj = null;
+        //         return CommonVar.find().retOk(res, resJson);
+
+        //     }, 1000);
+
+        // });
+
+        return true;
+
+    }
+    
+    return CommonVar.find().retOk(res, resJson);
+
+});
+
+/**
+ * 项目列表-删除本地项目
+ * 地址:http://127.0.0.1:6789/projectUuidDel
+ */
+objRouter.post('/projectUuidDel', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    var uuid = post['id'];
+
+    // 创建项目单独的存储目录
+    var path = CommonVar.find().projectPath(uuid);
+
+    // 项目id目录
+    var pathFile = path['path'];
+
+    // 得到对应项目id下的【模型】目录
+    var pathModel = path['pathModel'];
+    // 得到目录下的文件
+    var pathOrFileAll = MyFile.find().pathOrFileAll(pathModel);
+
+    // 目录文件列表
+    var fileList = pathOrFileAll['file'];
+    for (var i = 0; i < fileList.length; i++) {
+
+        var thisFileList = fileList[i];
+        // 删除文件
+        MyFile.find().fileDel(thisFileList['filePath']);
+
+    }
+
+    // 删除目录
+    MyFile.find().pathDel(pathModel);
+    MyFile.find().pathDel(pathFile);
+
+    return CommonVar.find().retOk(res, "删除成功");
+
+});
+
+
+
+/**
+ * 项目列表-将目标项目uuid的文件,复制到目标项目的uuid下
+ * 地址:http://127.0.0.1:6789/uuidToObjUuidPathCopy
+ */
+objRouter.post('/uuidToObjUuidPathCopy', function (req, res) {
+    
+    var get = req.query;
+    var post = req.body;
+
+    if (post['uuid'] === undefined || post['uuid'] === null) {
+        return CommonVar.find().retError(res, "uuid 不能为空");
+    }
+
+    if (post['objUuid'] === undefined || post['objUuid'] === null) {
+        return CommonVar.find().retError(res, "objUuid 不能为空");
+    }
+
+    // 是否允许直接复制。如果允许直接复制,那么就不需要判断是否是资产库的逻辑了
+    var copyBool = 'no';
+    if (post['copyBool'] !== undefined && post['copyBool'] !== null) {
+        copyBool = post['copyBool'];
+    }
+    
+    var uuid = post['uuid'];
+    var objUuid = post['objUuid'];
+
+    // 创建项目单独的存储目录
+    var uuidPath = CommonVar.find().projectPath(uuid);
+    // 得到对应项目id下的目录
+    var uuidPathModel = uuidPath['pathModel'];
+    // 得到对应本地仓库的目录
+    var uuidPathMyRes = uuidPath['pathMyRes'];
+
+    // 创建项目单独的存储目录
+    var objUuidPath = CommonVar.find().projectPath(objUuid);
+    // 得到对应项目id下的目录
+    var objUuidPathModel = objUuidPath['pathModel'];
+    // 得到对应本地仓库的目录
+    var objUuidPathMyRes = objUuidPath['pathMyRes'];
+    
+    // console.log(
+    //     {
+    //         "uuid" : uuid,
+    //         "uuidPath" : uuidPath,
+    //         "uuidPathModel" : uuidPathModel,
+    //         "uuidPathMyRes" : uuidPathMyRes,
+    //         "objUuid" : objUuid,
+    //         "objUuidPath" : objUuidPath,
+    //         "objUuidPathModel" : objUuidPathModel,
+    //         "objUuidPathMyRes" : objUuidPathMyRes,
+    //     }
+    // );
+    
+    // 判断被复制目录的配置文件是否存在
+    var uuidConfig = uuidPathModel + "config.json";
+    var uuidConfigTxt = MyFile.find().fileRead(uuidConfig);
+
+    if (uuidConfigTxt == false) {
+        return CommonVar.find().retError(res, "目标【资产库】不存在可用文件,可在编辑器里重新下载后进行操作。");
+    }
+    
+    var uuidConfigTxtJson = null;
+    try {
+        uuidConfigTxtJson = JSON.parse(uuidConfigTxt);
+    } catch (e) {
+
+    }
+    
+    if (uuidConfigTxtJson == null) {
+        return CommonVar.find().retError(res, "目标【资产库】不存在可用文件,可在编辑器里重新下载后进行操作。");
+    }
+
+    // 此时不是动态图库的情况下
+    if (uuidConfigTxtJson["animationImgList"] == null || uuidConfigTxtJson["animationImgList"] == undefined) {
+
+        // 此时要判断资产库的逻辑
+        if (copyBool != 'yes') {
+            
+            if (uuidConfigTxtJson["configJson"] == null || uuidConfigTxtJson["configJson"] == undefined) {
+                return CommonVar.find().retError(res, "该【资产库】必须存在文件才可以进行操作。");
+            }
+            
+            if (uuidConfigTxtJson["configJson"]["loadUrlAppendArrays"] == null || uuidConfigTxtJson["configJson"]["loadUrlAppendArrays"] == undefined) {
+                return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+            }
+        
+            var loadUrlAppendArrays = uuidConfigTxtJson["configJson"]["loadUrlAppendArrays"];
+        
+            if (typeof loadUrlAppendArrays != "object") {
+                return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+            }
+        
+            if (loadUrlAppendArrays.length <= 0) {
+                return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+            }
+        
+            if (loadUrlAppendArrays.length > 1) {
+                return CommonVar.find().retError(res, "该【资产库】只能存在一个模型,才可以进行此操作");
+            }
+
+        }
+
+    }
+    
+    // 遍历所有目录下的文件
+    var pathOrFileAll = MyFile.find().pathOrFileAll(uuidPathModel);
+    if (pathOrFileAll["file"].length <= 1) {
+        return CommonVar.find().retError(res, "该【资产库】没有可操作的文件");
+    }
+
+    var fileList = pathOrFileAll["file"];
+
+    // console.log("复制的列表", fileList);
+
+    var objFs = require('fs');
+
+    for (var i = 0; i < fileList.length; i++) {
+
+        var thisFileList = fileList[i];
+        var thisFileListName = thisFileList["name"];
+        var thisFileListFilePath = thisFileList["filePath"];
+
+        // 过滤掉不被复制的文件
+        if (
+            thisFileListName == "config.json"
+            || thisFileListName == "okFileList.txt"
+        ) {
+            continue;
+        }
+
+        // 被复制的文件
+        var uuidCopyFile = uuidPathModel + thisFileListName;
+        // 复制后的文件目录
+        var objUuidSaveFile = objUuidPathModel + thisFileListName;
+
+        // console.log([
+        //     "thisFileList", uuidCopyFile, objUuidSaveFile
+        // ]);
+        
+        // 直接复制文件
+        objFs.copyFileSync(uuidCopyFile, objUuidSaveFile);
+        // 判断项目文件是否存在【 不存在 】
+        if (objFs.existsSync(objUuidSaveFile) == false) {
+            console.log("文件没有复制过去", objUuidSaveFile);
+        }
+        
+    }
+    // console.log("得到目录下的所有文件", fileList);
+    
+    // console.log("读取的文件内容", uuidConfigTxtJson);
+    // console.log("追加模型的逻辑 loadUrlAppendArrays = ", loadUrlAppendArrays);
+    
+    var resJson = {
+        "loadUrlAppendArrays" : loadUrlAppendArrays,
+        "uuidConfigTxtJson" : uuidConfigTxtJson,
+    }
+
+    return CommonVar.find().retOk(res, resJson);
+    
+});
+
+
+/**
+ * 项目列表-目标项目uuid是否允许转换成资产库
+ * 地址:http://127.0.0.1:6789/uuidToAssetsBool
+ */
+objRouter.post('/uuidToAssetsBool', function (req, res) {
+    
+    var get = req.query;
+    var post = req.body;
+
+    if (post['uuid'] === undefined || post['uuid'] === null) {
+        return CommonVar.find().retError(res, "uuid 不能为空");
+    }
+
+    var uuid = post['uuid'];
+
+    // 创建项目单独的存储目录
+    var uuidPath = CommonVar.find().projectPath(uuid);
+    // 得到对应项目id下的目录
+    var uuidPathModel = uuidPath['pathModel'];
+    // 得到对应本地仓库的目录
+    var uuidPathMyRes = uuidPath['pathMyRes'];
+
+    // 判断被复制目录的配置文件是否存在
+    var uuidConfig = uuidPathModel + "config.json";
+    var uuidConfigTxt = MyFile.find().fileRead(uuidConfig);
+
+    if (uuidConfigTxt == false) {
+        return CommonVar.find().retError(res, "目标【资产库】不存在可用文件,可在编辑器里重新下载后进行操作。");
+    }
+    
+    var uuidConfigTxtJson = null;
+    try {
+        uuidConfigTxtJson = JSON.parse(uuidConfigTxt);
+    } catch (e) {
+
+    }
+
+    if (uuidConfigTxtJson == null) {
+        return CommonVar.find().retError(res, "目标【资产库】不存在可用文件,可在编辑器里重新下载后进行操作。");
+    }
+    
+    if (uuidConfigTxtJson["configJson"] == null || uuidConfigTxtJson["configJson"] == undefined) {
+        return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+    }
+
+    if (uuidConfigTxtJson["configJson"]["loadUrlAppendArrays"] == null || uuidConfigTxtJson["configJson"]["loadUrlAppendArrays"] == undefined) {
+        return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+    }
+
+    var loadUrlAppendArrays = uuidConfigTxtJson["configJson"]["loadUrlAppendArrays"];
+
+    if (typeof loadUrlAppendArrays != "object") {
+        return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+    }
+
+    if (loadUrlAppendArrays.length <= 0) {
+        return CommonVar.find().retError(res, "该【资产库】需上传一个模型后才可进行操作。");
+    }
+
+    if (loadUrlAppendArrays.length > 1) {
+        return CommonVar.find().retError(res, "该【资产库】只能存在一个模型,才可以进行此操作");
+    }
+
+    // 遍历所有目录下的文件
+    var pathOrFileAll = MyFile.find().pathOrFileAll(uuidPathModel);
+    if (pathOrFileAll["file"].length <= 0) {
+        return CommonVar.find().retError(res, "该【资产库】没有可操作的文件,发现继续操作");
+    }
+
+    return CommonVar.find().retOk(res, "ok");
+    
+});
+
+
+/**
+ * 项目列表uuid 返回对应的配置文件的所有数据-查询
+ * 地址:http://127.0.0.1:6789/projectSelectIdList
+ */
+objRouter.post('/projectSelectIdList', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['uuidList'] === undefined || post['uuidList'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    var uuidList = post['uuidList'];
+    var uuidListArray = [];
+    var ret = {};
+    try {
+        uuidListArray = JSON.parse(uuidList);
+    } catch (e) {
+        return CommonVar.find().retOk(res, JSON.stringify(ret));
+    }
+
+    for (var i = 0; i < uuidListArray.length; i++) {
+        var thisUuidListArray = uuidListArray[i];
+        
+        // 创建项目单独的存储目录
+        let path = CommonVar.find().projectPath(thisUuidListArray);
+        var url = "http://" + req.headers.host + "/";
+        
+        var result = {};
+        // 得到配置文件
+        let configJson = CommonVar.find().projectPathConfigJson(thisUuidListArray, 'get');
+
+        try {
+            var configJsonNew = JSON.parse(configJson);
+            var configConfigJson = configJsonNew["configJson"] == null || configJsonNew["configJson"] == undefined ? {} : configJsonNew["configJson"];
+
+            // 更新只返回的字段数据,要不然有的字段数据太多了
+            configJson = {
+                "id": configJsonNew["id"],
+                "model_name": configJsonNew["model_name"],
+                "name": configJsonNew["name"],
+                "animationImgDelayTime": configJsonNew["animationImgDelayTime"],
+                "animationImgList": configJsonNew["animationImgList"],
+                "configJson" : {
+                    "MyMergeProjectList" : configConfigJson["MyMergeProjectList"],
+                    "mainImg" : configConfigJson["mainImg"],
+                }
+            };
+
+        } catch (e) {
+            configJson = null;
+        }
+
+        var retJson = {
+            "configJson" : configJson,
+            "modelUrl" : url + path['pathIdModel']
+        }
+
+        ret[thisUuidListArray] = retJson;
+        
+    }
+    
+    return CommonVar.find().retOk(res, JSON.stringify(ret));
+    
+});
+
+
+/**
+ * 项目列表-打开目标项目uuid的文件夹
+ * 地址:http://127.0.0.1:6789/uuidOpenPath
+ */
+objRouter.post('/uuidOpenPath', function (req, res) {
+    
+    var get = req.query;
+    var post = req.body;
+
+    if (post['uuid'] === undefined || post['uuid'] === null) {
+        return CommonVar.find().retError(res, "uuid 不能为空");
+    }
+
+    var pathStart = MyFile.find().pathStart();
+    var uuidFile = pathStart + "new_src\\3d\\" + post['uuid'];
+    
+    // 执行cmd命令来打开文件夹
+    var cmdStr = "start " + uuidFile;
+
+    // 异步执行
+    SystemInformation.find().cmd(cmdStr, function (err, data) {
+
+        console.log([
+            "异步cmd命令执行结果",
+            err,
+            data
+        ]);
+        
+    });
+    
+    return CommonVar.find().retOk(res, "打开成功");
+    
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 285 - 0
exe/src/myWebServerRote/sqllite.js

@@ -0,0 +1,285 @@
+// 引入框架
+var express = require('express');
+// 路由对象
+var objRouter = express.Router();
+
+// 引入 uuid模块,用于自动生成唯一客户cid使用的
+const { v4: uuidv4 } = require('uuid');
+
+// 引入封装好的类
+var MySqllite = require('../common/moudles/MySqllite.js');
+
+// ########## 定义如下路由 ##########
+
+/**
+ * 操作Sqllite数据的各种语句操作
+ * 地址:http://127.0.0.1:6789/sqllite
+ */
+objRouter.get('/sqllite', function (req, res) {
+
+    // // 创建表 id 改为字符串,并且后续存储都以uuid为主
+    // var sql = "CREATE TABLE users(id varchar(255) PRIMARY KEY NOT NULL, name TEXT NOT NULL, age integer(11) NOT NULL, address varchar(255) );";
+    // // 因为操作数据库是异步的
+    // MySqllite.find().query(sql, null, function (err, result) {
+
+    //     // 所以我们采用回调的方法,来实现同步
+    //     res.send({
+    //         err,
+    //         result
+    //     });
+
+    // });
+    
+
+    // // 增加数据
+    // // 【 注意了,由于 增加数据的时候,操作 sqllite 数据库是不会直接返回增加成功数据的id结果,所以这里采用生成uuid的方式,来记录id值 】
+    // var uuid = uuidv4();
+    // // 可以一次性执行多条语句,实现批量增加数据
+    // var sql = "INSERT INTO users (id, name, age, address) VALUES ('" + uuid + "', '姓名', 1, '地址');";
+    // sql += "INSERT INTO users (id, name, age) VALUES ('" + uuidv4() + "', '姓名', 2);";
+    // sql += "INSERT INTO users (id, name, age) VALUES ('" + uuidv4() + "', '姓名', 3);";
+
+    // // 因为操作数据库是异步的
+    // MySqllite.find().query(sql, null, function (err, result) {
+
+    //     // 所以我们采用回调的方法,来实现同步
+    //     res.send({
+    //         err,
+    //         result
+    //     });
+
+    // });
+    
+    // // 更新数据
+    // var sql = "UPDATE users SET address = 'updateDemo' WHERE id = '6b7305e1-a839-41c7-aab5-7d9844e75710';";
+
+    // // 因为操作数据库是异步的
+    // MySqllite.find().query(sql, null, function (err, result) {
+
+    //     // 所以我们采用回调的方法,来实现同步
+    //     res.send({
+    //         err,
+    //         result
+    //     });
+
+    // });
+
+    // // 删除数据
+    // var sql = "DELETE FROM users WHERE id = '88cb90b1-5c71-41e7-99f2-402fa1e81610';";
+
+    // // 因为操作数据库是异步的
+    // MySqllite.find().query(sql, null, function (err, result) {
+
+    //     // 所以我们采用回调的方法,来实现同步
+    //     res.send({
+    //         err,
+    //         result
+    //     });
+
+    // });
+
+
+    // // 查询单条数据,只会返回一条数据
+    // // var sql = "SELECT * FROM users WHERE id = '38c7e90c-39d8-4c6b-bc70-a3d837f60c42';";
+    // var sql = "SELECT * FROM users;";
+
+    // // 因为操作数据库是异步的
+    // MySqllite.find().query(sql, 'get', function (err, result) {
+
+    //     // 所以我们采用回调的方法,来实现同步
+    //     res.send({
+    //         err,
+    //         result
+    //     });
+
+    // });
+
+    // 查询所有数据
+    // var sql = "SELECT * FROM users WHERE id = '38c7e90c-39d8-4c6b-bc70-a3d837f60c42';";
+    var sql = "SELECT * FROM users;";
+
+    // 因为操作数据库是异步的
+    MySqllite.find().query(sql, 'all', function (err, result) {
+
+        // 所以我们采用回调的方法,来实现同步
+        res.send({
+            err,
+            result
+        });
+
+    });
+
+    /**
+     * 浅谈SQL注入
+     * 本来想把这篇文章写在 Nodejs(访问mysql)里 但是查了一下SQL注入 引起了我的兴趣 可能学习完前端这一套 我会抽时间 学习网络安全 这种课程
+     * 什么是SQL注入 就是 大家写SQL的时候 不管方法也好 还是 直接从界面取得控件内容 都或多或少拼接字符串方式
+     * var name=txt_name.text;
+     * var password=txt_pass.text;
+     * select * from 表 where name = '"+name+"' and pass = '"+password+"' ;
+     * 那么 假如 一个人 在登录的时候 输入了 admin' or '1
+     * select * from 表 where username= 'admin' or '1' and password='admin' or '1'
+     * 根据SQL中逻辑运算的优先级,or低于and,最后的or ‘1’永远成立,所以该条件表达式结果为True,此语句同等于下面的这条语句
+     * select * from [users]
+     * 那就进入了界面 
+     * 那么前台做特殊字符的防御 也可以达到防止的目的 但是 高人也会有高人的手段 就看他想不想~
+     * 还有很多进攻手段
+     * https://blog.51cto.com/13444271/2126594(老君) 看一下这篇文章
+     * nodejs占位符 转义查询
+     * 防止SQL注入  使用占位符 也是很好的选择
+     * 那么为什么 占位符可以防止 SQL注入那
+     * 简单的说 使用占位符 在mysql 传入的就是被转义后的sql
+     * 
+     * 被数据库厂商方便的解决了
+     * select * from 表 where username= admin\' or '\1\ and password=admin\' or '\1\
+     * 详细可以看这篇
+     * https://www.cnblogs.com/greatfish/p/6067849.html
+     * nodejs 使用占位符
+     * var  mysql  = require('mysql');
+     * //连接信息
+     * var connection = mysql.createConnection({
+     * host     : 'localhost',
+     * port:3306,
+     * ser     : 'root',
+     * password : 'root',
+     * database : 'db'
+     * });
+     * //建立连接
+     * connection.connect();
+     * var age = '2'
+     * var id='1'
+     * //执行语句
+     * connection.query('select *from prople where age=? and id=?',[age,id],function(err,results, fields)
+     * {
+     * if (err) {
+     *      console.log(err);
+     * }else
+     * {
+     *      console.log(results);
+     *      console.log(fields); 
+     * }
+     * });
+     * connection.end();
+     * 占位符是很重要的一个知识点!get get
+     */
+
+    // // var sqlDemoJson = { id : '38c7e90c-39d8-4c6b-bc70-a3d837f60c42' };
+    // var sqlDemoJson = { id : '2 or id=1' };
+    // var sqlDemo = "SELECT * FROM users WHERE id = '{id}' or id = '{id}';".format(sqlDemoJson);
+    // console.log(sqlDemo);
+
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 360 - 0
exe/src/myWebServerRote/systemDemo.js

@@ -0,0 +1,360 @@
+// 引入框架
+var express = require('express');
+const { exit } = require('process');
+// 路由对象
+var objRouter = express.Router();
+
+// 引入封装好的类
+var SystemInformation = require('../common/moudles/SystemInformation.js');
+
+// 引入封装好的类
+var MyFile = require('../common/moudles/MyFile.js');
+var MyImg = require('../common/moudles/MyImg.js');
+
+// ########## 定义如下路由 ##########
+
+/**
+ * 操作cmd命令
+ * 地址:http://127.0.0.1:6789/systemDemo
+ */
+objRouter.get('/systemDemo', function (req, res) {
+
+    /**
+     * iconv-lite 支持的编码
+     * 所有的node原生的编码:utf8, ucs2 / utf15-le, ascii , binary, base64, hex
+     * 附加的unicode编码: utf16, utf16-be, utf-7, utf7-imap, utf32, utf32-le, utf32-be
+     * 所有广泛使用的单字节编码: windows 125x family, IOS-8859, IBM/DOS codepages, Maciontosh family, KO18 family, 
+     * 所有受支持的 iconv 库。 latin1 , us-ascii 别名的编码也支持
+     * 所有广泛使用的多字节编码: CP932, CP936, CP949, GB2312, GBK , GB18030, Big5, Shift_JIS, EUC-JP
+     */
+    
+    // 操作cmd模块
+    var childProcess = require('child_process');
+    // 进行编码解码使用
+    var iconvLite = require('iconv-lite');
+
+    // 同步执行 cmd
+    var execSync = childProcess.execSync('ipconfig /all', { encoding: 'binary' });
+    // 解决中文乱码返回问题
+    var txt = iconvLite.decode(execSync, 'cp936');
+
+    // 对于程序不想要等待cmd结果,导致卡住我们就使用异步执行cmd命令。 这样既不影响平时程序的正常继续操作,也可以在异步处理要的结果
+    childProcess.exec(
+        'rundll32 printui.dll,PrintUIEntry /e /n"EPSON L310 Series"',
+        { encoding: 'binary' },
+        function (err, data) {
+            console.log(data);
+        }
+    );
+
+    res.send(txt);
+
+});
+
+
+/**
+ * 操作cmd命令封装
+ * 地址:http://127.0.0.1:6789/systemFunDemo
+ */
+ objRouter.get('/systemFunDemo', function (req, res) {
+
+    // 被执行的cmd命令
+    var cmdStr = "ipconfig /all";
+
+    // 异步执行
+    SystemInformation.find().cmd(cmdStr, function (err, data) {
+
+        console.log([
+            "异步cmd命令执行结果",
+            err,
+            data
+        ]);
+        
+    });
+
+    // 同步执行
+    var cmdSync = SystemInformation.find().cmdSync(cmdStr);
+    res.send({ "操作cmd命令封装" : cmdSync });
+
+});
+
+
+
+/**
+ * 编码解码
+ * 地址:http://127.0.0.1:6789/systemDemoIconvLite
+ */
+objRouter.get('/systemDemoIconvLite', function (req, res) {
+
+    /** 
+     * node.js当中的Buffer对象支持的编码格式的种类有限,大概有ascii、utf8、utf16le、ucs2、base64、binary、hex。
+     * 不支持GBK的编码形式。对于windows系统来说,由于历史原因,许多文件默认的编码格式均为GBK。
+     */
+    var txt = "我是用来被编码解码的内容";
+
+    // 编码
+    var txtBase64Encode = Buffer.from(txt).toString('base64');
+    // 解码
+    var txtBase64Decode = Buffer.from(txtBase64Encode, 'base64').toString();
+
+    // 编码
+    var txtHexEncode = Buffer.from(txt).toString('hex');
+    // 解码
+    var txtHexDecode = Buffer.from(txtHexEncode, 'hex').toString();
+
+    // md5编码
+    var crypto = require('crypto');
+    var content = '123456';
+    var resultMd5 = crypto.createHash('md5').update(content).digest("hex");
+
+    var json = {
+        "原本内容" : txt,
+        "编码base64" : txtBase64Encode,
+        "解码base64" : txtBase64Decode,
+        "编码utf-8" : txtHexEncode,
+        "解码utf-8" : txtHexDecode,
+        "md5加密的内容" : resultMd5,
+    };
+
+    res.send(json);
+
+});
+
+
+/**
+ * 获取一些系统的信息,例如本地ip,cpu等
+ * 地址:http://127.0.0.1:6789/systemDemoInformation
+ */
+objRouter.get('/systemDemoInformation', function (req, res) {
+
+    // 获取所有网卡信息
+    var getNetworkInterfaces = SystemInformation.find().getNetworkInterfaces();
+
+    // 获取局域网的所有ip
+    var getLANIpList = SystemInformation.find().getLANIpList();
+    
+    // 获取cpu信息
+    var getCpu = SystemInformation.find().getCpu();
+
+    // 获取主机名
+    var getHostname = SystemInformation.find().getHostname();
+
+    // 获取主目录
+    var getHomedir = SystemInformation.find().getHomedir();
+
+    // 获取系统的其他信息
+    var getSystemInfomation = SystemInformation.find().getSystemInfomation();
+
+    // 获取cpu的处理器id
+    var getCpuProcessorId = SystemInformation.find().getCpuProcessorId();
+
+    // 获取硬盘序列号,每台电脑都是唯一值
+    var getDiskdriveSerialnumber = SystemInformation.find().getDiskdriveSerialnumber();
+
+    res.send({
+        "所有网卡信息" : getNetworkInterfaces,
+        "获取局域网的所有ip" : getLANIpList,
+        "获取cpu信息" : getCpu,
+        "获取主机名" : getHostname,
+        "获取主目录" : getHomedir,
+        "获取系统的其他信息" : getSystemInfomation,
+        "获取cpu的处理器id" : getCpuProcessorId,
+        "获取硬盘序列号,每台电脑都是唯一值" : getDiskdriveSerialnumber,
+    });
+
+});
+
+
+/**
+ * 图片操作,例如裁剪,压缩等
+ * 地址:http://127.0.0.1:6789/imgDemo
+ */
+ objRouter.get('/imgDemo', function (req, res) {
+
+    /**
+     * 这个其实可以 web  前端 js 来实现
+     * 后续不一定需要这样实现了
+     * 因为之前这个方法,需要安装电脑插件
+     * 电脑没有这个插件,反而无法正常的去使用,就比较麻烦
+     * 
+     */
+
+    var path = MyFile.find().pathStart();
+    // 被操作的图片
+    var objImg = path + "imgdemo/demo.jpg";
+    // 裁剪之后的图片
+    var objImgNew = path + "imgdemo/demoNew.jpg";
+    // 压缩之后的图片
+    var objImgResize = path + "imgdemo/demoNewResize.jpg";
+
+    // 获取图片信息模块
+    var imageSize = require('image-size');
+    // 获取图片的信息,宽度,高度,类型
+    var imageSize = imageSize(objImg);
+
+    // 图片裁剪
+    MyImg.find().cropCurrentImg(objImg, objImgNew, imageSize.width / 2, imageSize.height / 2, 50, 50, function (type, ret) {
+        
+        console.log([
+            type, ret
+        ]);
+
+    });
+
+
+    // 图片压缩
+    MyImg.find().resizeImgWithFullArgs(objImg, objImgResize, 10, imageSize.width / 2, imageSize.height / 2, "jpg", function (type, ret) {
+        
+        console.log([
+            type, ret
+        ]);
+
+    });
+
+
+    res.send({
+        "根目录" : path,
+        "被操作的图片" : objImg,
+        "裁剪后的图片" : objImgNew,
+        "获取图片的信息" : imageSize,
+    });
+
+});
+
+/**
+ * 文字通过密码加密和解密
+ * 地址:http://127.0.0.1:6789/txtPwd
+ */
+objRouter.get('/txtPwd', function (req, res) {
+    
+
+    var txt = "我是被加密的文字";
+    // 必须是16位
+    var pwd = "abcdefghijklmnop";
+
+    var txtAdd = SystemInformation.find().aseEncode(txt, pwd);
+    var txtUn = SystemInformation.find().aseDecode(txtAdd, pwd);
+
+    res.send({
+        "加密前的文字" : txt,
+        "加密的密码" : pwd,
+        "加密后的文字" : txtAdd,
+        "解密后的文字" : txtUn,
+    });
+
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 141 - 0
exe/src/myWebServerRote/time.js

@@ -0,0 +1,141 @@
+// 引入框架
+var express = require('express');
+// 路由对象
+var objRouter = express.Router();
+
+// 时间模块
+var modelsSillyDatetime = require('silly-datetime');
+var modelsMoment = require('moment');
+
+// 引入封装好的类
+
+// ########## 定义如下路由 ##########
+
+/**
+ * new 出对象,设置属性等
+ * 地址:http://127.0.0.1:6789/time
+ */
+objRouter.get('/time', function (req, res) {
+
+    // 获取13位时间戳
+    var timeStamp13 = Date.now();
+
+    // 获取10位时间戳
+    var timeStamp10 = parseInt(Date.now() / 1000);
+
+    // 获取当前时间
+    var time = new Date();
+
+    // 转换成你要的时间格式
+    var date = modelsSillyDatetime.format(time, 'YYYY-MM-DD HH:mm:ss');
+
+    // 时间戳(13位)转日期格式
+    var timeStamp13ToDate = modelsSillyDatetime.format(new Date(timeStamp13), 'YYYY-MM-DD HH:mm:ss');
+    // 时间戳(10位)转日期格式【 注意了 10位时间戳 这里 成 1000 变成了 13位 】
+    var timeStamp10ToDate = modelsSillyDatetime.format(new Date(timeStamp10 * 1000), 'YYYY-MM-DD HH:mm:ss');
+
+    // 将日期格式,转换成时间戳
+    var dateToTimeStamp = new Date("2021-07-20 18:00:00").getTime();
+    // 在 13位时间戳 转换成日期格式
+    var dateToTimeStampToDate = modelsSillyDatetime.format(dateToTimeStamp, 'YYYY-MM-DD HH:mm:ss');
+
+    // 返回页面
+    res.send({
+        timeStamp13 : timeStamp13,
+        timeStamp10 : timeStamp10,
+        time : time,
+        date : date,
+        timeStamp13ToDate : timeStamp13ToDate,
+        timeStamp10ToDate : timeStamp10ToDate,
+        dateToTimeStamp : dateToTimeStamp,
+        dateToTimeStampToDate : dateToTimeStampToDate,
+
+    });
+
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 222 - 0
exe/src/myWebServerRote/upload.js

@@ -0,0 +1,222 @@
+// 引入框架
+var express = require('express');
+// 路由对象
+var objRouter = express.Router();
+
+
+// 引入封装好的类
+var MyFile = require('../common/moudles/MyFile.js');
+
+// ########## 定义如下路由 ##########
+
+/**
+ * 上传文件
+ * 地址:http://127.0.0.1:6789/upload
+ */
+objRouter.post('/upload', function (req, res) {
+
+    // // 得到 body 的参数
+    // console.log(req.body);
+    // // 得到上传文件的参数
+    // console.log(req.files);
+
+    // 获取当前的地址
+    var url = "http://" + req.headers.host + "/";
+
+    // 获取项目根目录
+    var path = MyFile.find().pathStart();
+
+    // 以根目录下的哪个目录进行上传文件存储
+    var pathUpload = "upload/";
+
+    // 文件存储目录
+    var pathSave = path + "new_src/" + pathUpload;
+
+    console.log([
+        "文件存储的目录:",
+        pathSave
+    ]);
+
+    MyFile.find().pathCreate(pathSave);
+
+    var objFs = require('fs');
+    var objCrypto = require('crypto');
+    var ret = [];
+
+    // 循环遍历要上传的文件,支持多文件同时上传
+    req.files.forEach(function(value, key, iterable) {
+
+        // 获取文件的md5
+        // 读取文件
+        var stream = objFs.readFileSync(value.path);
+        // 得到md5
+        var md5 = objCrypto.createHash('md5').update(stream).digest('hex');
+
+        // 获取文件名后缀
+        var suffix = "";
+        if (value.originalname.lastIndexOf(".") >= 0) {
+            var suffixArray = value.originalname.split(".");
+            suffix = "." + suffixArray[suffixArray.length - 1];
+        }
+
+        // 上传的文件在req.files中
+        // var fileNameSave = value.filename + suffix;
+        var fileNameSave = md5 + suffix;
+        var filenamePath = pathSave + fileNameSave;
+
+        // 通过重命名的方式,将临时上传的文件放到指定的存储目录
+        // objFs.renameSync(req.files[0].path, filename);
+        objFs.renameSync(value.path, filenamePath);
+
+        // 处理完成之后,临时的文件是会消失的
+        
+        var thisFileJson = {
+            // 字段名
+            fieldname : value.fieldname,
+            // 上传的原始文件名
+            originalname : value.originalname,
+            // 编码类型
+            encoding : value.encoding,
+            // 模型类
+            mimetype : value.mimetype,
+            // 临时存储目录
+            destination : value.destination,
+            // 临时存储的文件名
+            filename : value.filename,
+            // 临时存储目录和文件名
+            path : value.path,
+            // 文件大小
+            size : value.size,
+            // md5
+            md5 : md5,
+            // 后缀
+            suffix : suffix,
+            // 文件地址
+            url : url + pathUpload + fileNameSave,
+        };
+
+        // 增加返回的结果
+        ret.push(thisFileJson);
+
+    });
+    
+    // 返回页面
+    res.send(ret);
+
+
+});
+
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 251 - 0
exe/src/myWebServerRote/userObj.js

@@ -0,0 +1,251 @@
+// 引入框架
+var express = require('express');
+// 路由对象
+var objRouter = express.Router();
+
+var CommonVar = require('../common/moudles/CommonVar.js');
+
+// 引入 uuid模块,用于自动生成唯一客户cid使用的
+const { v4: uuidv4 } = require('uuid');
+// 时间模块
+var modelsSillyDatetime = require('silly-datetime');
+var modelsMoment = require('moment');
+var MySqllite = require('../common/moudles/MySqllite.js');
+
+
+// ########## 定义如下路由 ##########
+
+/**
+ * 用户管理-创建
+ * 地址:http://127.0.0.1:6789/userObjAdd
+ */
+objRouter.post('/userObjAdd', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    // 转换成你要的时间格式
+    var date = modelsSillyDatetime.format(new Date(), 'YYYY-MM-DD HH:mm:ss');
+    var uuid = uuidv4();
+    var sql = "INSERT INTO user_obj (id, del, time, user_name, state, sum) VALUES ('" + uuid + "', 0, '" + date + "', '" + post['user_name'] + "', 0, " + post['sum'] + ");";
+
+    MySqllite.find().query(sql, null, function (err, result) {
+
+        return CommonVar.find().retOk(res, { 'str' : '创建成功' });
+
+    });
+
+    
+});
+
+/**
+ * 用户管理-查询
+ * 地址:http://127.0.0.1:6789/userObjSelect
+ */
+objRouter.post('/userObjSelect', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    var sql = "SELECT * FROM user_obj WHERE id = '" + post['id'] + "';";
+    MySqllite.find().query(sql, 'get', function (err, result) {
+
+        return CommonVar.find().retOk(res, result)
+
+    });
+
+
+});
+
+/**
+ * 用户管理-更新
+ * 地址:http://127.0.0.1:6789/userObjUpdate
+ */
+objRouter.post('/userObjUpdate', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    if (post['user_name'] === undefined || post['user_name'] === null) {
+        return CommonVar.find().retError(res, "用户 不能为空")
+    }
+
+    var sql = "UPDATE user_obj SET user_name = '" + post['user_name'] + "' ";
+
+    if (post['sum'] !== undefined && post['sum'] !== null) {
+        sql += " , sum = " + post['sum'];
+    }
+
+
+    sql += " WHERE id = '" + post['id'] + "';";
+
+    MySqllite.find().query(sql, null, function (err, result) {
+
+        return CommonVar.find().retOk(res, "更新成功")
+        
+    });
+
+
+
+});
+
+/**
+ * 用户管理-删除
+ * 地址:http://127.0.0.1:6789/userObjDel
+ */
+objRouter.post('/userObjDel', function (req, res) {
+
+    var get = req.query;
+    var post = req.body;
+
+    if (post['id'] === undefined || post['id'] === null) {
+        return CommonVar.find().retError(res, "id 不能为空")
+    }
+
+    var sql = "UPDATE user_obj SET del = 1 ";
+
+    sql += " WHERE id = '" + post['id'] + "';";
+
+    MySqllite.find().query(sql, null, function (err, result) {
+
+        return CommonVar.find().retOk(res, "删除成功")
+        
+    });
+
+});
+
+/**
+ * 用户管理-分页
+ * 地址:http://127.0.0.1:6789/userObjPage
+ */
+objRouter.get('/userObjPage', function (req, res) {
+
+
+    var get = req.query;
+    var post = req.body;
+
+    var sql = "Select * from user_obj where del = 0";
+
+    if (get['search'] !== undefined && get['search'] !== null && get['search'] !== '') {
+        sql += " and user_name like'%" + get['search'] + "%'";
+    }
+
+    var constState = CommonVar.find().constVal['userObj']['state'];
+
+    sql += " order by time desc";
+    CommonVar.find().sqlitePage(sql, get['page'], get['pagesize'], function(sqlitePageRes) {
+
+        // 存在分页数据的话
+        if (sqlitePageRes['page'].length >= 1) {
+
+            for (var key in sqlitePageRes['page']) {
+
+                var thisState = sqlitePageRes['page'][key]['state'];
+                // 新增字段数据返回
+                sqlitePageRes['page'][key]['stateCz'] = constState[thisState];
+
+
+            }
+
+        }
+
+
+        return CommonVar.find().retOk(res, sqlitePageRes)
+
+    });
+
+
+});
+
+// 【注意】必须导出模块
+module.exports = objRouter;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 975 - 0
exe/src/myWebSocket/WebSocketEvent.js

@@ -0,0 +1,975 @@
+// 引入 websocket模块
+const WebSocket = require('ws');
+const WebSocketServer = WebSocket.Server;
+
+// 引入 uuid模块,用于自动生成唯一客户cid使用的
+const { v4: uuidv4 } = require('uuid');
+// 时间模块
+var sd = require('silly-datetime');
+
+var CommonVar = require('../common/moudles/CommonVar.js');
+var WebSocketPort = CommonVar.find().getWebSocketPort();
+
+class WebSocketEvent {
+
+    // 记录当前被new 出来的类
+    static thisObjModel = null;
+
+    // 类被实例化的时候立即被调用
+    constructor() {
+
+        // 变量定义
+
+        // 端口号
+        // this.prot = 3000;
+        this.prot = WebSocketPort;
+        
+        // 记录所有房间
+        this.roomList = {
+            
+            // 【 每个房间号对应的初始化数据见 function roomAdd( 】
+            // "房间号1" : roomInit,
+            // "房间号2" : roomInit
+
+        };
+
+        // 记录客户端列表相关数据
+        this.clientList = {
+
+            // "客户id" : {
+            //     // 昵称
+            //     "name" : "昵称1",
+            //     // 登录时间
+            //     "timeLogin" : "2021-07-15 10:29:30",
+            //     // 这里是记录客户端连接成功的 ws 对象的,该对象是服务端这里的对象,如果后续要将一些数据返回给客户端,该对象的数据不要返回
+            //     "objWs" : null,
+            // },
+            // "客户id2" : {
+            //     // 昵称
+            //     "name" : "昵称2",
+            //     // 登录时间
+            //     "timeLogin" : "2021-07-15 10:29:30",
+            //     // 这里是记录客户端连接成功的 ws 对象的,该对象是服务端这里的对象,如果后续要将一些数据返回给客户端,该对象的数据不要返回
+            //     "objWs" : null,
+            // },
+
+        };
+
+        // // 记录总人数
+        // this.clientSum = 0;
+
+        /**
+         * 记录当前运行的 websocket服务对象
+         */
+        this.objWebSocketServer = null;
+
+        /**
+         * 心跳包 ping pong
+         * 多少秒执行一次,遍历每个cid多少秒内没有在接收到过消息
+         * 则在后端强制触发退出逻辑,释放内存
+         */
+        this.heartbeatTime = 5;
+        /**
+         * 多少秒执行一次对所有cid发起ping的指令
+         * 客户端cid接收到,需要马上回复pong的消息
+         */
+        this.pingTime = 25;
+        /**
+         * 当前心跳包的类型
+         * 0 - 按照 this.pingTime 逻辑触发,触发完成该状态变成 1
+         * 1 - 按照 this.heartbeatTime 逻辑触发,触发完成该状态变成 0
+         */
+        this.heartbeatType = 0;
+        /**
+         * 心跳包计时器对象
+         */
+        this.objPingPong = null;
+        
+    }
+
+    /**
+     * 单例模式的核心在于该方法
+     * 单例模式的调用案例
+     */
+    static find() {
+
+        // 当前对象不存在的时候
+        if (this.thisObjModel == null) {
+            // new 出自己本身对象
+            this.thisObjModel = new this();
+        }
+
+        // 返回自己本身对象
+        return this.thisObjModel;
+    }
+
+    /**
+     * 自动服务
+     */
+    start = function() {
+        
+        let thisClass = this;
+        if (thisClass.objWebSocketServer != null && thisClass.objWebSocketServer != undefined) {
+            return this;
+        }
+
+        // 创建 websocket 服务器
+        thisClass.objWebSocketServer = new WebSocketServer({
+            port: thisClass.prot
+        });
+        // 服务器启动成功的时候,触发
+        thisClass.objWebSocketServer.on("listening", function () {
+
+            console.log('websocket start http://127.0.0.1:' + thisClass.prot);
+            thisClass.eventInit();
+
+        });
+
+        thisClass.heartbeatTimeEvent();
+        
+    }
+
+    /**
+     * 心跳包事件逻辑
+     */
+    heartbeatTimeEvent = function() {
+
+        let thisClass = this;
+
+        if (thisClass.objPingPong != null && thisClass.objPingPong != undefined) {
+            return thisClass;
+        }
+
+        // 根据不同类型,决定多少秒执行一次
+        let objTime = thisClass.heartbeatType == 0 ? thisClass.pingTime : thisClass.heartbeatTime;
+        thisClass.objPingPong = setInterval(function() {
+
+            clearInterval(thisClass.objPingPong);
+            thisClass.objPingPong = null;
+
+            if (thisClass.heartbeatType == 0) {
+                thisClass.allPingEvent();
+                thisClass.heartbeatType = 1;
+            } else if (thisClass.heartbeatType == 1) {
+                thisClass.allPongExitEvent();
+                thisClass.heartbeatType = 0;
+            }
+
+            thisClass.heartbeatTimeEvent();
+            
+        }, objTime * 1000);
+
+
+        return thisClass;
+
+    }
+
+
+    /**
+     * 给所有cid用户发送 ping 的消息
+     * 接收到ping消息的用户,必须回复一个 pong
+     * 然后更新最后cid接收的时间戳
+     */
+    allPingEvent = function() {
+
+        let thisClass = this;
+        // console.log("执行ping逻辑");
+
+        for (let key in thisClass.clientList) {
+
+            let obj = thisClass.clientList[key];
+            // let objWs = obj["objWs"];
+            let objCid = obj["cid"];
+            // console.log(
+            //     "allPingEvent objCid", objCid
+            // );
+
+            let submit = { "type" : "ping", "message" : "", };
+            thisClass.sendCid(objCid, submit);
+
+        }
+
+        return thisClass;
+
+    }
+
+    /**
+     * 所有用户pong后的时间逻辑
+     * 来将指定不符合的用户强制退出通讯
+     */
+    allPongExitEvent = function() {
+
+        let thisClass = this;
+        // console.log("执行用户强制退出逻辑");
+
+        let thisTime = new Date().getTime();
+
+        for (let key in thisClass.clientList) {
+
+            let obj = thisClass.clientList[key];
+            let objCid = obj["cid"];
+            let objWs = obj["objWs"];
+            let pongTime = obj["pongTime"];
+
+            // 得到时间戳的插值
+            let timeDistance = thisTime - pongTime;
+
+            // console.log(
+            //     "allPongExitEvent timeDistance",
+            //     // obj, objCid
+            //     timeDistance
+            // );
+
+            // 如果目标cid进行pong 的时间戳很久到一定范围,说明用户没有连接了,强制退出
+            if (
+                // timeDistance >= (thisClass.heartbeatTime * 1000 * 0.5)
+                timeDistance >= (thisClass.heartbeatTime * 1000 * 1.5)
+            ) {
+                // 让服务端的cid对象,强制退出
+                objWs.close();
+            }
+
+        }
+
+        return thisClass;
+
+    }
+
+
+    /**
+     * 初始化通讯的事件
+     */
+    eventInit = function() {
+
+        let thisClass = this;
+        if (thisClass.objWebSocketServer == null || thisClass.objWebSocketServer == undefined) {
+            return this;
+        }
+        
+        // 服务器被客户端连接
+        thisClass.objWebSocketServer.on('connection', (ws) => {
+            
+            // 给当前连接的客户端,生成一个唯一的 cid
+            const cid = uuidv4();
+            // 给当前的客户端对象,设置生成唯一的cid的值,这么一来后续断开连接之后,就可以很直接的找到是哪个cid断开连接,然后删除一些对应的数据
+            ws.cid = cid;
+
+            let thisTime = new Date().getTime();
+
+            // 更新客户列表的相关cid的数据
+            thisClass.clientList[cid] = {
+                // 当前用户客户端的cid
+                "cid" : cid,
+                // 昵称
+                "name" : null,
+                // 登录时间
+                "timeLogin" : sd.format(new Date(), 'YYYY-MM-DD HH:mm:ss'),
+                // 登陆的时间戳
+                "timeLoginMain" : thisTime,
+                // 这里是记录客户端连接成功的 ws 对象的,该对象是服务端这里的对象,如果后续要将一些数据返回给客户端,该对象的数据不要返回
+                "objWs" : ws,
+            };
+
+            // 用户第一次登陆,服务端主动发送消息给客户端,告诉客户端当前自己的参数
+            let getCidConfig = thisClass.getCidConfig(cid);
+            thisClass.sendCid(
+                cid,
+                {
+                    "type" : "login",
+                    "message" : {
+                        "userDb" : getCidConfig,
+                    },
+                }
+            );
+            
+            // 接收客户端信息并把信息返回发送
+            ws.on('message', (message) => {
+                
+                thisClass.commonMessage(ws.cid, message);
+                
+            });
+
+            /**
+             * 当服务器关闭时发送。此事件仅取决于HTTP服务器在内部创建时的“关闭”事件。
+             * 在所有其他情况下,例如服务端将目标客户端 thisClass.clientList[cid]["objWs"].close(); 进行强制退出。
+             * 获取客户端,与服务器断开连接的时候
+             * */ 
+            ws.on("close", () => {
+
+                // 获取客户离开的房间号
+                // const roomId = clientList[ws.cid]['roomId'];
+                // console.log("用户 客户端 或者 服务器 进行退出 close ws.cid", ws.cid);
+                thisClass.wsCidClose(ws.cid);
+                
+            });
+
+        });
+        
+    }
+
+    /**
+     * 目标cid 因为网页端网络断开,或者主动调用退出的时候出发该方法,或者其他情况
+     * 退出对应房间,已经 删除对应客户端id的相关数据
+     * cid          退出的 客户端id
+     */
+    wsCidClose = function(cid) {
+
+        // console.log(
+        //     "wsCidClose cid", cid
+        // );
+
+        let thisClass = this;
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return this;
+        }
+
+        let objUser = thisClass.clientList[cid];
+        if (objUser["roomId"] != null && objUser["roomId"] != undefined) {
+            let roomId = objUser["roomId"];
+            // console.log(
+            //     "哪个cid退出", roomId
+            // );
+            thisClass.roomExitCid(roomId, cid);
+            
+        }
+
+        // console.log(
+        //     "wsCidClose objUser", objUser
+        // );
+
+        // 删除用户记录
+        thisClass.clientList[cid] = null;
+        delete thisClass.clientList[cid];
+
+        // console.log(
+        //     "thisClass.clientList", thisClass.clientList
+        // );
+
+        return thisClass;
+
+    }
+    
+    /**
+     * 统一给对应的 cid 目标客户端发送消息的方法
+     * cid          目标客户端cid值 也就是 this.clientList 的 key 值
+     * message      发送的具体消息,可以是字符串,也可以是json对象
+     */
+    sendCid = function(cid, message) {
+
+        let thisClass = this;
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return this;
+        }
+        let objUser = thisClass.clientList[cid];
+        let objWs = objUser["objWs"];
+        objWs.send(
+            JSON.stringify(
+                {
+                    "cid" : cid,
+                    "data" : message
+                }
+            )
+        );
+        return this;
+
+    }
+
+    /**
+     * 获取目标cid的配置参数
+     * cid          目标客户端cid值 也就是 this.clientList 的 key 值
+     * 这里会过滤掉一些不需要的参数
+     * 如果返回null,说明该用户已经不存在了
+     */
+    getCidConfig = function(cid) {
+
+        let thisClass = this;
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return null;
+        }
+        let objUser = thisClass.clientList[cid];
+        let retJson = {};
+        for (let key in objUser) {
+            // 过滤一些不需要返回的字段数据
+            if (
+                key == "objWs"
+            ) {
+            } else {
+                retJson[key] = objUser[key];
+            }
+        }
+        return retJson;
+    }
+
+    /**
+     * 统一处理接收到的消息
+     * cid              哪个客户端发来的消息
+     * userData         接收客户端的消息
+     */
+    commonMessage = function(cid, userData) {
+
+        let thisClass = this;
+
+        let json = {};
+        try {
+            json = JSON.parse(userData);
+        } catch(e) {
+            return thisClass;
+        }
+
+        let type = json["type"];
+
+        console.log("commonMessage", cid, type, json);
+
+        if (typeof type == "string") {
+
+            switch (type) {
+
+                // 心跳包pong,更新pong的时间戳,用于后续是否强制在服务端进行退出逻辑
+                case "pong":
+                    thisClass.objUserPongEvent(cid);
+                    break;
+
+                // 更新用户的参数数据
+                case "upUser":
+                    thisClass.upUserEvent(cid, json);
+                    break;
+
+                // 用户进入房间或者切换到另外一个房间
+                case "joinRoom":
+                    thisClass.joinRoomEvent(cid, json);
+                    break;
+
+                /**
+                 * 房间里群发消息,房间里所有用户可以接收到消息,是一个通用的传输数据
+                 * 这里只做实时通讯消息发送,具体最后前端进行逻辑处理
+                 * 
+                 */
+                case "roomSendAll":
+                    thisClass.roomSendAllEvent(cid, json);
+                    break;
+
+                /**
+                 * 给指定用户发送消息
+                 */
+                case "cidSend":
+                    thisClass.cidSendEvent(cid, json);
+                    break;
+
+            }
+
+        }
+        
+        
+        return thisClass;
+
+    }
+
+    /**
+     * 更新目标用户的 pong 数据
+     * cid          目标用户cid
+     */
+    objUserPongEvent = function(cid) {
+
+        let thisClass = this;
+
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return thisClass;
+        }
+
+        let thisTime = new Date().getTime();
+        thisClass.clientList[cid]["pongTime"] = thisTime;
+        
+        return thisClass;
+
+    }
+
+    /**
+     * 更新目标用户的数据参数
+     * cid          目标用户cid
+     * json         接收的参数
+     */
+    upUserEvent = function(cid, json) {
+
+        let thisClass = this;
+
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return thisClass;
+        }
+
+        let objUser = thisClass.clientList[cid];
+
+        let message = json["message"];
+
+        // console.log(
+        //     "upUserEvent", cid, json, message
+        // );
+
+        /**
+         * 记录只有发生变化的数据,后续这些数据会进行特殊处理
+         * 例如改变后,则通知整个房间里面的人消息
+         */
+        let updateJson = {};
+        // 是否触发过,更新数据字段
+        let updateJsonBool = false;
+        
+        // 遍历只更新对应的数据
+        for (let key in message) {
+            let val = message[key];
+            
+            // 是否更新数据字段
+            let boolUpdate = false;
+
+            // 存在的时候
+            if (
+                typeof objUser[key] != 'undefined' && objUser[key] != val
+            ) {
+                boolUpdate = true;
+            } else {
+                // 不存在的时候
+                boolUpdate = true;
+            }
+
+            // 更新对应用户字段数据
+            if (boolUpdate == true) {
+                updateJson[key] = val;
+                thisClass.clientList[cid][key] = val;
+                updateJsonBool = true;
+            }
+
+        }
+        
+        /**
+         * 有数据更新
+         */
+        if (updateJsonBool == true) {
+
+            /**
+             * 这里有个特殊的字段,单独处理
+             * userId           后续用户统一用该字段来判断
+             * 因为每次用户重连的时候,cid是会变化的
+             * 但是该字段记录后,就永远是这个数据,不会变化了
+             */
+            if (
+                thisClass.clientList[cid]["userId"] != null
+                && thisClass.clientList[cid]["userId"] != undefined
+            ) {
+
+                let userId = thisClass.clientList[cid]["userId"];
+                // console.log(
+                //     "userId 触发更新字段了", userId, updateJson
+                // );
+
+                // 新增固定返回字段数据
+                updateJson["userId"] = userId;
+
+            }
+
+            // 告诉用户自己,在服务器成功更新了哪些数据字段的数据
+            thisClass.sendCid(
+                cid,
+                {
+                    "type" : "myDbUpdate",
+                    "message" : {
+                        "updateJson" : updateJson,
+                    },
+                }
+            );
+
+            // 判断用户是否有在房间里
+            if (
+                thisClass.clientList[cid]["roomId"] != null
+                && thisClass.clientList[cid]["roomId"] != undefined
+            ) {
+
+                let roomId = thisClass.clientList[cid]["roomId"];
+                // console.log(
+                //     "当前用户数据更新了,所在房间号 roomId", roomId
+                // );
+
+                // 通知房间里所有用户,更新了哪些字段了
+                thisClass.roomAllSend(roomId, cid, "roomUserDbUpdate", updateJson);
+
+            }
+
+
+        }
+        
+        return thisClass;
+
+    }
+
+
+    /**
+     * 用户进入房间或者切换到另外一个房间
+     * cid          目标用户cid
+     * json         接收的参数
+     */
+    joinRoomEvent = function(cid, json) {
+
+        let thisClass = this;
+
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return thisClass;
+        }
+
+        let objUser = thisClass.clientList[cid];
+        let message = json["message"];
+
+        // 得到当前用户要进入的房间号
+        let roomId = message["roomId"];
+
+        // 当前用户已经进入的房间号
+        let userRoomId = null;
+        if (objUser["roomId"] != null && objUser["roomId"] != undefined) {
+            userRoomId = objUser["roomId"];
+        }
+
+        // 如果切换的房间号,跟已经所在房间号一致,则不触发后面的逻辑
+        if (userRoomId == roomId) {
+            return;
+        }
+
+        // 此时如果之前是进入过别的房间号
+        if (userRoomId != null && userRoomId != undefined) {
+            // 优先退出当前所在的房间号
+            thisClass.objCidExitRoom(cid);
+        }
+
+        // 房间号如果不存在的情况
+        if (thisClass.roomList[roomId] == null || thisClass.roomList[roomId] == undefined) {
+            thisClass.roomList[roomId] = {};
+        }
+
+        // 进入对应的房间
+        thisClass.roomList[roomId][cid] = cid;
+
+        // 更新用户,当前进入的房间号
+        thisClass.clientList[cid]["roomId"] = roomId;
+        // 告诉用户自己,在服务器成功更新了哪些数据字段的数据
+        thisClass.sendCid(
+            cid,
+            {
+                "type" : "myDbUpdate",
+                "message" : {
+                    "updateJson" : {
+                        "roomId" : roomId,
+                    },
+                },
+            }
+        );
+
+        // 告诉房间里,哪个用户加入,并且所有用户列表消息更新发送
+        let roomUserListDb = thisClass.getRoomUserListDb(roomId);
+        thisClass.roomAllSend(roomId, cid, "roomUserJoin", roomUserListDb);
+
+        return thisClass;
+
+    }
+    
+    /**
+     * 将目标房间号 的 用户 cid退出房间号
+     * roomId       房间号 也就是 this.roomList 的 key 值
+     * cid          目标cid
+     */
+    roomExitCid = function(roomId, cid) {
+
+        let thisClass = this;
+        // console.log("roomExitCid", roomId, cid);
+
+        // 房间号已不存在,则不触发
+        if (thisClass.roomList[roomId] == null || thisClass.roomList[roomId] == undefined) {
+            return;
+        }
+
+        // 用户本身也不存在房间里
+        if (thisClass.roomList[roomId][cid] == null || thisClass.roomList[roomId][cid] == undefined) {
+            return;
+        }
+
+        // 将目标用户题出群里
+        thisClass.roomList[roomId][cid] = null;
+        delete thisClass.roomList[roomId][cid];
+
+        // 发送整个房间,告诉房间所有用户,谁离开房间了,以及当前房间号还剩余哪些用户
+        let roomUserListDb = thisClass.getRoomUserListDb(roomId);
+        thisClass.roomAllSend(roomId, cid, "roomUserExit", roomUserListDb);
+
+        return thisClass;
+        
+    }
+
+    /**
+     * 目标cid 退出房间号
+     * cid          目标cid
+     */
+    objCidExitRoom = function(cid) {
+
+        let thisClass = this;
+
+        if (thisClass.clientList[cid] == null || thisClass.clientList[cid] == undefined) {
+            return thisClass;
+        }
+
+        let objUser = thisClass.clientList[cid];
+        if (objUser["roomId"] != null && objUser["roomId"] != undefined) {
+            let userRoomId = objUser["roomId"];
+            return thisClass.roomExitCid(userRoomId, cid);
+        }
+        
+        return thisClass;
+
+    }
+    
+    /**
+     * 给整个房间里的所有用户,发送消息
+     * roomId       房间号 也就是 this.roomList 的 key 值
+     * cid          当前群发消息的 cid , 如果是 commonSysServer  说明是服务端统一发起的, 否则就是用户发起的
+     * type         群发的类型
+     *              roomUserExit        有用户退出房间了
+     *              roomUserJoin        有用户加入房间了
+     *              roomChatAll         用户发起的群聊消息
+     *              roomUserDbUpdate    房间里的用户更新了具体哪些字段,后续例如同步用户昵称,坐标等数据使用
+     * 
+     * message      发送的具体消息,可以是字符串,也可以是json对象
+     */
+    roomAllSend = function(roomId, cid, type, message) {
+
+        let thisClass = this;
+
+        // 房间号已不存在,则不触发
+        if (thisClass.roomList[roomId] == null || thisClass.roomList[roomId] == undefined) {
+            return;
+        }
+        
+        let roomCidAll = thisClass.roomList[roomId];
+
+        // 拼接统一发送消息的格式
+        let sendJson = {
+            "type" : type,
+            "message" : {
+                // 哪一个cid主动发送消息的
+                "sendCid" : cid,
+                // 具体的内容
+                "message" : message,
+            },
+        }
+
+        // 循环所有用户
+        for (let forCid in roomCidAll) {
+            
+            // 给指定的用户发送消息
+            thisClass.sendCid(forCid, sendJson);
+
+        }
+        
+        return thisClass;
+
+    }
+
+
+    /**
+     * 获取目标房间号里所有房间的用户数据列表
+     * roomId       房间号 也就是 this.roomList 的 key 值
+     */
+    getRoomUserListDb = function(roomId) {
+
+        let thisClass = this;
+        let retArray = [];
+
+        // 房间号已不存在,则不触发
+        if (thisClass.roomList[roomId] == null || thisClass.roomList[roomId] == undefined) {
+            return retArray;
+        }
+
+        let roomCidAll = thisClass.roomList[roomId];
+        // 循环所有用户
+        for (let forCid in roomCidAll) {
+
+            let userConfig = thisClass.getCidConfig(forCid);
+            retArray.push(userConfig);
+
+        }
+        return retArray;
+
+    }
+
+    /**
+     * 在房间里群发消息
+     * cid          目标用户cid
+     * json         接收的参数
+     */
+    roomSendAllEvent = function(cid, json) {
+
+        let thisClass = this;
+
+        if (json == null || json == undefined) {
+            return thisClass;
+        }
+
+        if (json["message"] == null || json["message"] == undefined) {
+            return thisClass;
+        }
+
+        let message = json["message"];
+
+        if (message["roomId"] == null || message["roomId"] == undefined) {
+            return thisClass;
+        }
+
+        let roomId = message["roomId"];
+
+        // console.log(
+        //     "roomSendAllEvent", cid, json, roomId
+        // );
+
+        thisClass.roomAllSend(roomId, cid, "roomChatAll", json);
+
+        return thisClass;
+
+    }
+
+
+    /**
+     * 给指定的用户发送消息
+     * cid          目标用户cid
+     * json         接收的参数
+     */
+    cidSendEvent = function(cid, json) {
+
+        let thisClass = this;
+
+        if (json == null || json == undefined) {
+            return thisClass;
+        }
+
+        if (json["message"] == null || json["message"] == undefined) {
+            return thisClass;
+        }
+
+        let message = json["message"];
+
+        if (message["cid"] == null || message["cid"] == undefined) {
+            return thisClass;
+        }
+
+        // 跟目标cid用户对话
+        let objCid = message["cid"];
+
+        // console.log(
+        //     "cidSendEvent ===> ", cid, objCid, json
+        // );
+
+        let submit = {
+            "type" : "cidSend",
+            "message" : {
+                // 哪一个cid主动发送消息的
+                "sendCid" : cid,
+                // 接收消息的cid
+                "getCid" : objCid,
+                // 具体的内容
+                "submitJson" : json,
+            },
+        };
+        
+        thisClass.sendCid(objCid, submit);
+
+        // 如果不是发送给自己,则自己也要接收到消息
+        if (cid != objCid) {
+            thisClass.sendCid(cid, submit);
+        }
+
+        return thisClass;
+
+    }
+
+
+    
+}
+
+module.exports = WebSocketEvent;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 71 - 0
exe/webpack.main.build.config.js

@@ -0,0 +1,71 @@
+const path = require('path');
+const glob = require('glob');
+
+/**
+ * 动态获取 src 目录下的所有入口文件
+ * 使用 glob.sync() 来获取 src 目录下的所有 .js 文件。
+ * 遍历这些文件,将文件路径转换为入口名称,去掉 src/ 前缀和 .js 后缀。
+ * 将入口名称和对应的文件路径添加到 entries 对象中。
+ * */
+const getEntries = () => {
+    const entries = {};
+    const files = glob.sync('src/**/*.js');
+    files.forEach((file) => {
+        const entryName = file.replace(/^src\//, '').replace(/\.js$/, '');
+        entries[entryName] = `./${file}`;
+    });
+    return entries;
+};
+
+module.exports = {
+    // 指定打包目标为 Electron 的主进程环境,确保 Webpack 能针对 Electron 主进程的特性进行打包。
+    target: 'electron-main',
+    // 将 entry 设置为 getEntries() 的返回值,这样 Webpack 会根据动态获取的入口文件进行打包。
+    entry: getEntries(),
+    output: {
+        // path: path.resolve(__dirname, 'dist'),
+        path: path.resolve(__dirname, 'outApp/HelloWorld-win32-x64/resources/app/src'),
+        // filename: '[name].js' 表示输出的文件名会根据入口名称来生成,这样可以保证按照文件夹分类打包。
+        filename: '[name].js',
+        // 打包的库的模块类型,根据你写的代码,支持的写法有关,可以根据 ExeMainApp\package.json 的 "type": "commonjs", 配置来
+        // libraryTarget: 'umd',
+        libraryTarget: 'commonjs2',// 让 Webpack 以 CommonJS 模块格式输出打包后的代码,便于 Node.js 和 Electron 环境使用。
+        // libraryTarget: 'commonjs',
+    },
+    node: {
+        // __dirname: false 和 __filename: false 使 Webpack 不改变 Node.js 中 __dirname 和 __filename 的行为,保证在打包后的代码里这些变量可以正常使用。
+        __dirname: false,
+        __filename: false
+    },
+    /**
+     * 采用自定义函数来处理外部模块。正则表达式 /^[a-z\-0-9]+$/ 用于匹配 Node.js 核心模块和 node_modules 中的第三方模块,
+     * 并将它们排除在打包范围之外,以 commonjs 形式引入,避免将这些模块打包进最终文件。
+     */
+    externals: [
+        function ({ context, request }, callback) {
+            if (/^[a-z\-0-9]+$/.test(request)) {
+                return callback(null, `commonjs ${request}`);
+            }
+            callback();
+        }
+    ],
+    resolve: {
+        extensions: ['.js'],
+        modules: [path.resolve(__dirname, 'src'), 'node_modules']
+    },
+    module: {
+        // 使用 babel-loader 配合 @babel/preset-env 对 JavaScript 文件进行转译,确保代码能在目标环境中正常运行。
+        rules: [
+            {
+                test: /\.js$/,
+                exclude: /node_modules/,
+                use: {
+                    loader: 'babel-loader',
+                    options: {
+                        presets: ['@babel/preset-env']
+                    }
+                }
+            }
+        ]
+    }
+};    

+ 70 - 0
exe/webpack.main.config.js

@@ -0,0 +1,70 @@
+const path = require('path');
+const glob = require('glob');
+
+/**
+ * 动态获取 src 目录下的所有入口文件
+ * 使用 glob.sync() 来获取 src 目录下的所有 .js 文件。
+ * 遍历这些文件,将文件路径转换为入口名称,去掉 src/ 前缀和 .js 后缀。
+ * 将入口名称和对应的文件路径添加到 entries 对象中。
+ * */
+const getEntries = () => {
+    const entries = {};
+    const files = glob.sync('src/**/*.js');
+    files.forEach((file) => {
+        const entryName = file.replace(/^src\//, '').replace(/\.js$/, '');
+        entries[entryName] = `./${file}`;
+    });
+    return entries;
+};
+
+module.exports = {
+    // 指定打包目标为 Electron 的主进程环境,确保 Webpack 能针对 Electron 主进程的特性进行打包。
+    target: 'electron-main',
+    // 将 entry 设置为 getEntries() 的返回值,这样 Webpack 会根据动态获取的入口文件进行打包。
+    entry: getEntries(),
+    output: {
+        path: path.resolve(__dirname, 'dist'),
+        // filename: '[name].js' 表示输出的文件名会根据入口名称来生成,这样可以保证按照文件夹分类打包。
+        filename: '[name].js',
+        // 打包的库的模块类型,根据你写的代码,支持的写法有关,可以根据 ExeMainApp\package.json 的 "type": "commonjs", 配置来
+        // libraryTarget: 'umd',
+        libraryTarget: 'commonjs2',// 让 Webpack 以 CommonJS 模块格式输出打包后的代码,便于 Node.js 和 Electron 环境使用。
+        // libraryTarget: 'commonjs',
+    },
+    node: {
+        // __dirname: false 和 __filename: false 使 Webpack 不改变 Node.js 中 __dirname 和 __filename 的行为,保证在打包后的代码里这些变量可以正常使用。
+        __dirname: false,
+        __filename: false
+    },
+    /**
+     * 采用自定义函数来处理外部模块。正则表达式 /^[a-z\-0-9]+$/ 用于匹配 Node.js 核心模块和 node_modules 中的第三方模块,
+     * 并将它们排除在打包范围之外,以 commonjs 形式引入,避免将这些模块打包进最终文件。
+     */
+    externals: [
+        function ({ context, request }, callback) {
+            if (/^[a-z\-0-9]+$/.test(request)) {
+                return callback(null, `commonjs ${request}`);
+            }
+            callback();
+        }
+    ],
+    resolve: {
+        extensions: ['.js'],
+        modules: [path.resolve(__dirname, 'src'), 'node_modules']
+    },
+    module: {
+        // 使用 babel-loader 配合 @babel/preset-env 对 JavaScript 文件进行转译,确保代码能在目标环境中正常运行。
+        rules: [
+            {
+                test: /\.js$/,
+                exclude: /node_modules/,
+                use: {
+                    loader: 'babel-loader',
+                    options: {
+                        presets: ['@babel/preset-env']
+                    }
+                }
+            }
+        ]
+    }
+};    

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff