飛飛腳本台服版

飛飛腳本台服版,由在線版移植而來

目前為 2023-08-01 提交的版本,檢視 最新版本

// ==UserScript==
// @name              飞飞脚本台服版
// @name:zh-TW        飛飛腳本台服版
// @description       飞飞脚本台服版,由在线版移植而来
// @description:zh-TW 飛飛腳本台服版,由在線版移植而來
// @namespace         http://tampermonkey.net/
// @version           0.0.11
// @iconURL           http://res.yytou.cn/lunjian_tw/img/icon1.png
// @author            燕飞,東方鳴
// @match             http://swordman-s1.yytou.com/*
// @grant             unsafeWindow
// @grant             GM_xmlhttpRequest
// @connect           orchin.cn
// @run-at            document-end
// ==/UserScript==


//相容一下低版本瀏覽器flat函式
if (!Array.prototype.flat) {
    Array.prototype.flat = function(count) {
        let c = count || 1;
        let len = this.length;
        let exe = [];
        if (this.length == 0) return this;
        while (c--) {
            let _arr = [];
            let flag = false;
            if (exe.length == 0) {
                flag = true;
                for (let i = 0; i < len; i++) {
                    if (this[i] instanceof Array) {
                        exe.push(...this[i]);
                    } else {
                        exe.push(this[i]);
                    }
                }
            } else {
                for (let i = 0; i < exe.length; i++) {
                    if (exe[i] instanceof Array) {
                        flag = true;
                        _arr.push(...exe[i]);
                    } else {
                        _arr.push(exe[i]);
                    }
                }
                exe = _arr;
            }
            if (!flag && c == Infinity) {
                break;
            }
        }
        return exe;
    }
}

$(()=>{
    function init(){
        // 跨域
        GM_xmlhttpRequest({
            method: "GET",
            url: "http://orchin.cn/wujian/game/js/yfdata.json",
            responseType: "json",
            onload: function(res) {
                PLU.YFUI=YFUI;
                PLU.UTIL=UTIL;
                PLU.YFD=JSON.parse(res.responseText);
                PLU.YFD.cityList = ["雪亭鎮","洛陽","華山村","華山","揚州","丐幫","喬陰縣","峨眉山","恆山","武當山","晚月莊","水煙閣","少林寺","唐門",
                                    "青城山","逍遙林","開封","光明頂","全真教","古墓","白駝山","嵩山","梅莊","泰山","鐵血大旗門","大昭寺","黑木崖","星宿海",
                                    "茅山","桃花島","鐵雪山莊","慕容山莊","大理","斷劍山莊","冰火島","俠客島","絕情谷","碧海山莊","天山","苗疆","白帝城",
                                    "墨家機關城","掩月城","海雲閣","幽冥山莊","花街","西涼城","高昌迷宮","京城","越王劍宮","江陵","天龍寺","西夏","南詔國"];
                PLU.YFD.qlList = [{"n": "書房","v": "jh 1;e;n;e;e;e;e;n"},
                                  {"n": "打鐵鋪子","v": "jh 1;e;n;n;w"},
                                  {"n": "桑鄰藥鋪","v": "jh 1;e;n;n;n;w"},
                                  {"n": "南市","v": "jh 2;n;n;e"},
                                  {"n": "繡樓","v": "jh 2;n;n;n;n;w;s;w"},
                                  {"n": "北大街","v": "jh 2;n;n;n;n;n;n;n"},
                                  {"n": "錢莊","v": "jh 2;n;n;n;n;n;n;;n;e"},
                                  {"n": "雜貨鋪","v": "jh 3;s;s;e"},
                                  {"n": "祠堂大門","v": "jh 3;s;s;w"},
                                  {"n": "廳堂","v": "jh 3;s;s;w;n"}];
                PLU.YFD.mjList = [{"n": "山坳","v": "jh 1;e;n;n;n;n;n;"},
                                  {"n": "桃花泉","v": "jh 3;s;s;s;s;s;nw;n;n;e;"},
                                  {"n": "千尺幢","v": "jh 4;n;n;n;n"},
                                  {"n": "猢猻愁","v": "jh 4;n;n;n;n;n;n;e;n;n;"},
                                  {"n": "潭畔草地","v": "jh 4;n;n;n;n;n;n;n;event_1_91604710;s;s;s;"},
                                  {"n": "玉女峰","v": "jh 4;n;n;n;n;n;n;n;n;w;"},
                                  {"n": "長空棧道","v": "jh 4;n;n;n;n;n;n;n;n;n;e;"},
                                  {"n": "臨淵石台","v": "jh 4;n;n;n;n;n;n;n;n;n;e;n;"},
                                  {"n": "沙丘小洞","v": "jh 6;event_1_98623439;ne;n;ne;ne;ne;event_1_97428251;"},
                                  {"n": "九老洞","v": "jh 8;w;nw;n;n;n;n;e;e;n;n;e;kill emei_shoushan;;n;;n;n;n;w;n;n;n;n;n;n;n;n;n;nw;sw;w;nw;w;"},
                                  {"n": "懸根松","v": "jh 9;n;w;"},
                                  {"n": "夕陽嶺","v": "jh 9;n;n;e;"},
                                  {"n": "青雲坪","v": "jh 13;e;s;s;w;w;"},
                                  {"n": "玉壁瀑布","v": "jh 16;s;s;s;s;e;n;e;"},
                                  {"n": "湖邊","v": "jh 16;s;s;s;s;e;n;e;event_1_5221690;s;w;"},
                                  {"n": "碧水寒潭","v": "jh 18;n;nw;n;n;n;n;n;ne;n;n;n;n;n;e;e;se;se;e;"},
                                  {"n": "寒水潭","v": "jh 20;w;w;s;e;s;s;s;s;s;sw;sw;s;e;se;"},
                                  {"n": "懸崖","v": "jh 20;w;w;s;e;s;s;s;s;s;sw;sw;s;s;e;"},
                                  {"n": "戈壁","v": "jh 21;"},
                                  {"n": "盧崖瀑布","v": "jh 22;n;n;n;n;e;n"},
                                  {"n": "啟母石","v": "jh 22;n;n;w;w;"},
                                  {"n": "無極老姆洞","v": "jh 22;n;n;w;n;n;n;n;"},
                                  {"n": "山溪畔","v": "jh 22;n;n;w;n;n;n;n;event_1_88705407;s;s;"},
                                  {"n": "奇槐坡","v": "jh 23;n;n;n;n;n;n;n;n;"},
                                  {"n": "天梯","v": "jh 24;n;n;n;"},
                                  {"n": "小洞天","v": "jh 24;n;n;n;n;e;e;"},
                                  {"n": "雲步橋","v": "jh 24;n;n;n;n;n;n;n;n;n;"},
                                  {"n": "觀景台","v": "jh 24;n;n;n;n;n;n;n;n;n;n;n;n;e;e;n;"},
                                  {"n": "危崖前","v": "jh 25;w;"},
                                  {"n": "草原","v": "jh 26;w;"},
                                  {"n": "無名山峽谷","v": "jh 29;n;n;n;n;event_1_60035830;place?平台;event_1_65661209;place?無名山峽谷;"}];
                PLU.YFD.prizeList = [["明月鞋","月光寶甲衣","明月戒","明月帽","明月項鍊","明月手鐲","屠龍刀","倚天劍","冰魄銀針","墨玄掌套","碧磷鞭","烈日棍","西毒蛇杖","星月大斧","碧玉錘","霸王槍"],
                                     ["烈日寶靴","日光寶甲衣","烈日寶戒","烈日帽","烈日寶鏈","烈日寶鐲","斬神刀","誅仙劍","暴雨梨花針","龍象拳套","七星鞭","殘陽棍","伏虎杖","破冥斧","撼魂錘","赤焰槍"],
                                     ["斬龍寶靴","龍皮至尊甲衣","斬龍寶戒","斬龍帽","斬龍寶鏈","斬龍寶鐲","飛宇天怒刀","九天龍吟劍","小李飛刀","天罡掌套","烏金玄火鞭","開天寶棍","達摩杖","天雷斷龍斧","燭幽鬼煞錘","斬龍鎏金槍"],
                                     ["君影草","矢車菊","忘憂草","仙客來","雪英","朝開暮落花","夕霧草","鳳凰木","熙顏花","晚香玉","凌霄花","彼岸花","洛神花","百宜雪梅","胤天寶帽碎片","胤天項鍊碎片","胤天寶戒碎片","魚腸碎片","軒轅劍碎片","破嶽拳套碎片","胤天寶鐲碎片","胤天寶靴碎片","胤天紫金衣碎片","昊天龍旋鎧碎片","水羽雲裳碎片","奉天金帶碎片","鳳羽乾坤盾碎片","玄冰凝魄槍碎片","雷霆誅神刀碎片","天雨玄鏢碎片","天神杖碎片","轟天巨棍碎片","神龍怒火鞭碎片","胤武伏魔斧碎片","九天滅世錘碎片"]];
                PLU.YFD.masterList[3] = {n:"魔教", v:"jh 27;ne;nw;w;nw;w;w;kill heimuya_shaogong;get?船夫的屍體;yell;w;nw;n;n;n;n;n;n;n;w;n;n;n;n;n;n;n;n;n;n;yell;n;n;n;n;n;n;n;n;n;n;n;n;n;event_1_57107759;e;e;n;w"};
                PLU.YFD.masterList[24] = {n:"茅山", v:"jh 29;n;n;n;n;event_1_60035830;place?平台;event_1_65661209;place?無名山峽谷;n"};
                PLU.YFD.masterList.push({n:"风花",v:"jh 1;e;n;n;n;n;w;event_1_90287255 go 6;e;s;sw;se;ne;se;s;;;;;event_1_90371900;"});
                PLU.YFD.masterList.push({n:"天波",v:"jh 17;n;n;n;n;w;w;w;w"});
                PLU.YFD.masterList.push({n:"燕云",v:"jh 38;n;n;n;n;n;n;n;n;n"});
                PLU.YFD.masterList.push({n:"西夏",v:"jh 37;n;e;e;nw;nw;w;n;e;n;e;e;e;ne;nw;w;n;nw;n;ne;e;ne;se"});
                PLU.YFD.QuestAnsLibs["首次通过桥阴县不可以获得那种奖励?"] = "a";
                let waitGameSI = setInterval(()=>{
                    if(g_obj_map && g_obj_map.get("msg_attrs")) {
                        clearInterval(waitGameSI)
                        PLU.init();
                    }
                },500)
                }
        });
    }

    // 本地化
    function _(c, t){
        return navigator.language=="zh-CN" ? c : t;
    }

    function Base64(){
        var Encoder = new TextEncoder();
        var Decoder = new TextDecoder();
        this.encode = function(s){
            return btoa(Array.from(Encoder.encode(s), (x) => String.fromCodePoint(x)).join(""));
        };
        this.decode = function(s){
            return Decoder.decode(Uint8Array.from(atob(s), (m) => m.codePointAt(0)));
        };
    }
    //console.log(new Base64().decode("YSDEgCDwkICAIOaWhyDwn6aE"))

    //=================================================================================
    // UTIL模組
    //=================================================================================
    unsafeWindow.PLU={
        version: "0.0.11(v2.72.0622.01)",
        accId: null,
        nickName: null,
        battleData: null,
        MPFZ:{},
        TODO:[],//待辦列表
        STO:{},
        SIT:{},
        ONOFF:{},
        STATUS:{
            inBattle: 0,
            isBusy: 0,
        },
        CACHE:{
            autoDZ:1,
            autoHYC:1,
            autoLX:1,
            autoBF:1,
            autoB6:1,
            autoB5F:1,
        },
        FLK:null,
        TMP:{},
        logHtml:'',
        signInMaps:null,
        //================================================================================================
        init(){
            this.accId = UTIL.getAccId()
            this.initMenu()
            this.initTickTime()
            this.initStorage()
            this.initHistory()
            this.initSocketMsgEvent()
            this.initVersion()

            addEventListener("keydown", function(key) {
                if (key.altKey || key.ctrlKey || key.metaKey || key.shiftKey) return; // 不考慮組合鍵
                if (document.activeElement && document.activeElement.tagName == "INPUT") return;
                switch (key.keyCode) {
                    case 81: // q
                        clickButton("nw");
                        break;
                    case 87: // w
                        clickButton("n");
                        break;
                    case 69: // e
                        clickButton("ne");
                        break;
                    case 65: // a
                        clickButton("w");
                        break;
                    case 83: // s
                        clickButton("s");
                        break;
                    case 68: // d
                        clickButton("e");
                        break;
                    case 90: // z
                        clickButton("sw");
                        break;
                    case 67: // c
                        clickButton("se");
                        break;
                }
            })
        },
        //================================================================================================
        initVersion(){
            this.nickName=g_obj_map.get("msg_attrs").get("name");
            YFUI.writeToOut("<span style='color:yellow;'>+===========================+<br>"+
                            _("脚本名称: 无剑Mud辅助<br>",
                              "腳本名稱:無劍Mud輔助<br>")+
                            _("脚本开发","腳本開發")+":燕飞,<a onclick='clickButton(\"telluser u8429379(1)_U_東方鳴\", 1)'>東方鳴"+
                            _("(点击反馈)","(點擊反饋)")+"</a><br>"+
                            _("脚本版本:","腳本版本:")+this.version+"<br>"+
                            _("当前角色:","當前角色:")+this.nickName+"<br>"+
                            "角 色 ID :"+this.accId+"<br>"+
                            "+===========================+<br>"+
                            "</span>");
            YFUI.writeToOut("<span style='color:#FFF;'>"+_("监听设定","監聽設定")+":</span>")
            let autosets=''
            if(PLU.getCache("autoDZ")==1) autosets+=_("连续打坐,","連續打坐, ");
            if(PLU.getCache("autoHYC")==1) autosets+=_("连续睡床,","連續睡床, ");
            if(PLU.getCache("autoLX")==1) autosets+=_("连续练习,","連續練習, ");
            if(PLU.getCache("autoBF")==1) autosets+=_("加入帮四,","加入幫四, ");
            if(PLU.getCache("autoB6")==1) autosets+=_("加入帮六,","加入幫六, ");
            if(PLU.getCache("autoB5F")==1) autosets+=_("帮五跟杀,","幫五跟殺, ");
            YFUI.writeToOut("<span style='color:#CFF;'>"+autosets+"</span>")
            if(PLU.getCache('autoTP')==1){
                YFUI.writeToOut("<span style='color:#CFF;'>"+_("自动突破","自動突破")+": <span style='color:#FF9;'>"+PLU.getCache('autoTP_keys')+"</span></span>")
            }
            if(PLU.getCache('listenQL')==1){
                YFUI.writeToOut("<span style='color:#CFF;'>"+_("自动青龙","自動青龍")+": <span style='color:#FF9;'>"+PLU.getCache('listenQL_keys')+"</span></span>")
            }
            if(PLU.getCache('listenGCQL')==1){
                YFUI.writeToOut("<span style='color:#CFF;'>"+_("广场青龙","廣場青龍")+": <span style='color:#FF9;'>"+PLU.getCache('listenGCQL_keys')+"</span></span>")
            }
            if(PLU.getCache('listenTF')==1){
                YFUI.writeToOut("<span style='color:#CFF;'>"+_("自动逃犯","自動逃犯")+": <span style='color:#FF9;'>"+PLU.getCache('listenTF_keys')+"</span></span>")
            }
            if(!g_gmain.is_fighting){
                PLU.getSkillsList((allSkills, tupoSkills)=>{
                    if (tupoSkills.length > 0){
                        YFUI.writeToOut("<span style='color:white;'>突破中技能:</span>")
                        let topos = ""
                        tupoSkills.forEach((sk,i)=>{
                            topos+="<span style='color:#CCF;min-width:100px;display:inline-block;'>"+(i+1)+" : "+sk.name+"</span>"
                        })
                        YFUI.writeToOut("<span style='color:#CCF;'> "+topos+"</span>")
                        YFUI.writeToOut("<span style='color:yellow;'>+------------------------------+</span>")
                    }else{
                        YFUI.writeToOut("<span style='color:white;'>突破中技能: "+_("无","無")+"</span>")
                        YFUI.writeToOut("<span style='color:yellow;'>+------------------------------+</span>")
                    }
                    let lxSkill = g_obj_map.get('msg_attrs')?g_obj_map.get('msg_attrs').get('practice_skill'):0;
                    if(lxSkill){
                        let sk = allSkills.find(s=>s.key==lxSkill)
                        if(sk){
                            YFUI.writeToOut("<span style='color:white;'>"+_("练习中的技能","練習中技能")+": <span style='color:#F0F;'>"+sk.name+"</span> ("+sk.level+")</span>")
                            YFUI.writeToOut("<span style='color:yellow;'>+------------------------------+</span>")
                        }
                    }else{
                        YFUI.writeToOut("<span style='color:white;'>"+_("练习中的技能:无","練習中技能:無")+"</span>")
                        YFUI.writeToOut("<span style='color:yellow;'>+------------------------------+</span>")
                    }
                })
            }
        },
        //================================================================================================
        initSocketMsgEvent(){
            if (!gSocketMsg){
                console.log("%c%s","background:#C33;color:#FFF;",' ERROR:Not found gSocketMsg!! ');
                return
            }
            var YFBackupDispatchMsg = gSocketMsg.dispatchMessage;
            gSocketMsg.YFBackupDispatchMsg = YFBackupDispatchMsg;
            gSocketMsg.dispatchMessage = function(b){
                gSocketMsg.YFBackupDispatchMsg(b)
                let type = b.get("type")
                let subtype = b.get("subtype");
                let msg = b.get("msg");
                UTIL.sysDispatchMsg(b, type, subtype, msg);
            };
            PLU.initListeners()
            if(unsafeWindow.clickButton){
                PLU.Base64 = new Base64();
                var proxy_clickButton = unsafeWindow.clickButton;
                unsafeWindow.clickButton = function(){
                    let args = arguments
                    proxy_clickButton(...args)
                    if(PLU.TMP.leaderTeamSync){
                        PLU.commandTeam(args)
                    }
                }
            }
        },
        //================================================================================================
        initMenu(){
            YFUI.init();
            YFUI.addBtn({id:"ro",text:_("▲隐","▲隱"),style:{width:"30px",opacity:".6",background:"#333",color:"#FFF",border:"1px solid #CCC",borderRadius:"8px 0 0 0"},onclick($btn){
                $("#pluginMenus").toggle()
                $("#pluginMenus").is(':hidden') ? $btn.text(_("▼显","▼顯")) : $btn.text(_("▲隐","▲隱"))
                $(".menu").hide()
            }});
            YFUI.addBtnGroup({id:"pluginMenus"});
            //Home
            // YFUI.addBtn({
            //     id:"bt_home",
            //     groupId:"pluginMenus",
            //     text:"首頁",
            //     style:{"background":"#FFFF99","padding":"5px 2px","width":"40px"},
            //     onclick(e){
            //         $(".menu").hide()
            // 		PLU.STATUS.isBusy = false
            //         clickButton('home',1);
            //     }
            // })
            //Paths
            let PathsArray=[]
            PathsArray.push({
                id:"bt_home",
                groupId:"pluginMenus",
                text:_("首页","首頁"),
                style:{"background":"#FFFF99","padding":"5px 2px","width":"40px"},
                onclick(e){
                    $(".menu").hide()
                    PLU.STATUS.isBusy = false
                    clickButton('home',1);
                }
            })
            let citysArray= PLU.YFD.cityList.map((c,i)=>{
                return {id:"bt_jh_"+(i+1), text:c, extend:'jh '+(i+1)}
            })
            PathsArray.push({id:"bt_citys", text:_("地图","地圖"),
                             style:{background:"#FFE","width":"40px","padding":"5px 2px"},
                             menuStyle: {"width": "240px","margin-top":"-25px"},
                             children:citysArray})

            let qlArray= PLU.YFD.qlList.map((p,i)=>{
                return {id:"bt_ql_"+(i+1), text:p.n, extend:p.v, style:{"background-color":"#CFF"}}
            })
            PathsArray.push({id:"bt_qls", text:_("青龙","青龍"),
                             style:{background:"#DFF","width":"40px","padding":"5px 2px"},
                             menuStyle: {"width": "160px","margin-top":"-50px"},
                             children:qlArray})

            let mjArray= PLU.YFD.mjList.map((p,i)=>{
                return {id:"bt_mj_"+(i+1), text:p.n, extend:p.v, style:{"background-color":"#EFD"}}
            })
            // {id:"hr_qlmj", text:"", style:{width:"240px",opacity:0}},
            PathsArray.push({id:"bt_mjs", text:"秘境",
                             style:{background:"#EFD","width":"40px","padding":"5px 2px"},
                             menuStyle: {"width": "160px","margin-top":"-75px"},
                             children:mjArray})

            let masterArray= PLU.YFD.masterList.map((p,i)=>{
                let colr = i<10 ? '#FCF' : i<20 ? '#CFF' : '#FFC';
                return {id:"bt_master_"+(i+1), text:p.n, extend:p.v, style:{"background-color":colr}}
            })
            PathsArray.push({id:"bt_masters", text:_("出师","出師"),
                             style:{background:"#FCF","width":"40px","padding":"5px 2px"},
                             menuStyle: {"width": "160px","margin-top":"-100px"},
                             children:masterArray})

            let dailyArray= PLU.YFD.dailyList.map((p,i)=>{
                let colr = i<6 ? '#FFC' : i<20 ? '#FCF' : '#CFF';
                return {id:"bt_daily_"+(i+1), text:p.n, extend:p.v, style:{"background-color":colr}}
            })
            PathsArray.push({id:"bt_daily", text:"日常",
                             style:{background:"#FED","width":"40px","padding":"5px 2px"},
                             menuStyle: {"width": "160px","margin-top":"-125px"},
                             children:dailyArray})

            let usualArray= PLU.YFD.usualList.map((p,i)=>{
                let sty = p.style || {"background-color":"#CDF"}
                return {id:"bt_usual_"+(i+1), text:p.n, extend:p.v, style:sty}
            })
            PathsArray.push({id:"bt_usual", text:"常用",
                             style:{background:"#CDF","width":"40px","padding":"5px 2px"},
                             menuStyle: {"width": "160px","margin-top":"-150px"},
                             children:usualArray})

            let cts=[], libCity=PLU.YFD.mapsLib.Npc.filter(e=>{
                if(!cts.includes(e.jh)){
                    cts.push(e.jh)
                    return true;
                }
                return false
            }).map(e=>e.jh)
            let queryJHMenu=libCity.map((c,i)=>{
                return {id:"bt_queryjh_"+(i+1), text:c, style:{"width":"50px","whiteSpace": "nowrap","overflow":"hidden","fontSize":"12px"}, extend:{func:PLU.queryJHMenu, param:c}}
            })
            let queryArray= [
                {id:"bt_queryJHList", text:_("章节","章節"), children:queryJHMenu, style:{"width":"40px","background-color":"#9ED"} ,menuStyle: {width: "180px","margin-top":"-180px"},},
                {id:"bt_queryHistory", text:_("历史","歷史"), style:{"width":"40px","background-color":"#FDD"}, extend:{func:PLU.toQueryHistory}},
                {id:"bt_queryNpc", text:_("寻人","尋人"), style:{"width":"40px","background-color":"#FDD"}, extend:{func:PLU.toQueryNpc}},
                {id:"bt_pathNpc", text:_("扫图","掃圖"), style:{"width":"40px","background-color":"#FE9"}, extend:{func:PLU.toPathNpc}},
            ]
            PathsArray.push({id:"bt_query", text:"查找",
                             style:{background:"#9ED","width":"40px","padding":"5px 2px"},
                             menuStyle: {"margin-top":"-30px"},
                             children:queryArray})
            YFUI.addMenu({
                id: "m_paths",
                groupId: "pluginMenus",
                text: _("导航","導航"),
                style:{"width":"40px","padding":"5px 2px"},
                multiCol: true,
                menuStyle: {width: "80px","margin-top":"-25px"},
                children: PathsArray,
                onclick($btn,$box){
                    if($btn.$extend){
                        $(".menu").hide()
                        if($btn.$extend.func){
                            if($btn.$extend.param) $btn.$extend.func($btn, $btn.$extend.param)
                            else $btn.$extend.func($btn)
                            return
                        }
                        PLU.execActions($btn.$extend, ()=>{
                            if($btn.text()=='去哈日') PLU.goHaRi();
                            if($btn.text()=='杭界山') PLU.goHJS();
                        })
                        // clickButton($btn.$extend)
                    }
                }
            })
            //daily & usual
            // let dlusArray= PLU.YFD.dailyList.map((p,i)=>{
            //     return {id:"bt_daily_"+(i+1), text:p.n, extend:p.v, style:{"background-color":"#CFF"}}
            // })
            // dlusArray= dlusArray.concat(
            // 	{id:"hr_dlus", text:"", style:{width:"240px",opacity:0}},
            // 	PLU.YFD.usualList.map((p,i)=>{
            //     	return {id:"bt_usual_"+(i+1), text:p.n, extend:p.v, style:{"background-color":"#FFC"}}
            // 	})
            // )
            // dlusArray.push({id:"hr_dlus", text:"", style:{width:"240px",opacity:0}, boxStyle:{"font-size":0}})
            // let cts=[];let libCity=PLU.YFD.mapsLib.Npc.filter(e=>{
            //     if(!cts.includes(e.jh)){
            //         cts.push(e.jh)
            //         return true;
            //     }
            //     return false
            // }).map(e=>e.jh)

            // let queryJHMenu=libCity.map((c,i)=>{
            //     return {id:"bt_queryjh_"+(i+1), text:c, extend:{func:PLU.queryJHMenu, param:c}}
            // })
            // dlusArray.push({id:"bt_queryJHList", text:"章節目錄", children:queryJHMenu, style:{"background-color":"#FCF"} ,menuStyle: {width: "160px","margin-top":"-457px"},})
            // dlusArray.push({id:"bt_queryHistory", text:"導航歷史", style:{"background-color":"#FA8"}, extend:{func:PLU.toQueryHistory}})
            // dlusArray.push({id:"bt_queryNpc", text:"尋人導航", style:{"background-color":"#FA8"}, extend:{func:PLU.toQueryNpc}})
            // YFUI.addMenu({
            //     id: "m_dailyusuals",
            //     groupId: "pluginMenus",
            //     text: "日常",
            //     style:{"width":"40px"},
            //     multiCol: true,
            //     menuStyle: {width: "240px","margin-top":"-51px"},
            //     children: dlusArray,
            //     onclick($btn,$box){
            //         if($btn.$extend){
            //             $(".menu").hide()
            // 			if($btn.$extend.func){
            // 				if($btn.$extend.param) $btn.$extend.func($btn, $btn.$extend.param)
            // 				else $btn.$extend.func($btn)
            // 				return
            // 			}
            //             PLU.execActions($btn.$extend, ()=>{
            // 				if($btn.text()=='杭界山') PLU.goHJS();
            // 			})
            //         }
            //     }
            // })
            //auto do something
            let somethingArray=[]
            somethingArray.push({id:"bt_autoTeach", text:_("传授技能","傳授技能"), extend:{func:PLU.toAutoTeach}, style:{background:"#BFF"}})
            somethingArray.push({id:"bt_autoUpgrade", text:_("升级游侠","升級遊俠"), extend:{func:PLU.toAutoUpgrade}, style:{background:"#BFF"}})
            somethingArray.push({id:"hr_null2", text:"", style:{"display":"none"},boxStyle:{"display":"block","height":"5px"}})
            somethingArray.push({id:"bt_autoLearn", text:_("一键学习","一鍵學習"), extend:{func:PLU.toAutoLearn}, style:{background:"#FBF"}})
            somethingArray.push({id:"bt_autoChuaiMo", text:_("自动揣摩","自動揣摩"), extend:{func:PLU.toAutoChuaiMo}, style:{background:"#FBF"}})
            somethingArray.push({id:"hr_null2", text:"", style:{"display":"none"},boxStyle:{"display":"block","height":"5px"}})
            somethingArray.push({id:"bt_loopScript", text:_("循环执行","循環執行"), extend:{func:PLU.toLoopScript}, style:{background:"#FBB"}})
            somethingArray.push({id:"bt_loopKillByN", text:_("计时击杀","計數擊殺"), extend:{func:PLU.toLoopKillByN}, style:{background:"#FBB"}})
            somethingArray.push({id:"bt_waitCDKill", text:_("倒计时杀","倒計時殺"), extend:{func:PLU.toWaitCDKill}, style:{background:"#FBB"}})

            somethingArray.push({id:"bt_loopKillName", text:_("名字连杀","名字連殺"), extend:{func:PLU.toLoopKillName}, style:{background:"#FBB"}})
            somethingArray.push({id:"bt_loopClick", text:_("自动点击","自動點擊"), extend:{func:PLU.toLoopClick}, style:{background:"#FBB"}})
            somethingArray.push({id:"bt_loopSlowClick", text:_("慢速点击","慢速點擊"), extend:{func:PLU.toLoopSlowClick}, style:{background:"#FBB"}})
            somethingArray.push({id:"hr_null2", text:"", style:{"display":"none"},boxStyle:{"display":"block","height":"5px"}})
            somethingArray.push({id:"bt_sellLaji", text:"批量出售", extend:{func:PLU.toSellLaji}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_splitItem", text:"批量分解", extend:{func:PLU.toSplitItem}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_putStore", text:_("批量入库","批量入庫"), extend:{func:PLU.toPutStore}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_autoUse", text:"批量使用", extend:{func:PLU.toAutoUse}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_combineGem", text:_("合成宝石","合成寶石"), extend:{func:PLU.openCombineGem}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_autoMasterGem", text:_("一键合天神","一鍵合天神"), extend:{func:PLU.autoMasterGem}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_autoXTL1", text:"刷琅嬛玉洞", extend:{func:PLU.autoXTL1}, style:{background:"#FED"}})
            somethingArray.push({id:"bt_autoXTL2", text:"刷山崖", extend:{func:PLU.autoXTL2}, style:{background:"#FED"}})
            somethingArray.push({id:"bt_autoGetKey", text:_("自动捡钥匙","自動撿鑰匙"), extend:{func:PLU.toAutoGetKey}, style:{background:"#EBC"}})
            somethingArray.push({id:"bt_autoMoke", text:_("一键摹刻","一鍵摹刻"), extend:{func:PLU.toAutoMoke}, style:{background:"#EFD"}})
            somethingArray.push({id:"bt_autoKillZYY", text:"刷祝玉妍", extend:{func:PLU.toAutoKillZYY}, style:{background:"#FBF"}})
            somethingArray.push({id:"bt_checkYouxia", text:_("技能检查","技能檢查"), extend:{func:PLU.checkYouxia}, style:{background:"#DEF"}})
            somethingArray.push({id:"bt_loopReadBase", text:_("读技能书","讀技能書"), extend:{func:PLU.toLoopReadBase}, style:{background:"#FBB"}})
            somethingArray.push({id:"bt_searchBangQS", text:_("搜帮派任务","搜幫派任務"), extend:{func:PLU.toSearchBangQS}, style:{background:"#BBF"}})
            // somethingArray.push({id:"bt_autoFB11", text:"自動本11", extend:{func:PLU.toAutoFB11}, style:{background:"#FC9"}})
            YFUI.addMenu({
                id: "m_autoDoSomething",
                groupId: "pluginMenus",
                text: _("自动","自動"),
                style:{"width":"40px"},
                multiCol: true,
                menuStyle: {width: "160px","margin-top":"-61px"},
                children: somethingArray,
                onclick($btn,$box){
                    if($btn.$extend){
                        $(".menu").hide()
                        $btn.$extend.func($btn)
                    }
                }
            })
            //listens
            let listensArray=[]
            listensArray.push({id:"bt_autoBF", text:_("自动帮四","自動幫四"), extend:{key:"autoBF"}, style:{background:"#EDC"}})
            listensArray.push({id:"bt_autoB6", text:_("自动帮六","自動幫六"), extend:{key:"autoB6"}, style:{background:"#ECD"}})
            listensArray.push({id:"bt_autoB5F", text:_("帮五跟杀","幫五跟殺"), extend:{key:"autoB5F"}, style:{background:"#CEF"}})
            listensArray.push({id:"bt_autoDZ", text:_("持续打坐","持續打坐"), extend:{key:"autoDZ"}, style:{background:"#CEC"}})
            listensArray.push({id:"bt_autoHYC", text:_("持续睡床","持續睡床"), extend:{key:"autoHYC"}, style:{background:"#CEC"}})
            listensArray.push({id:"bt_autoLX", text:_("持续练习","持續練習"), extend:{key:"autoLX"}, style:{background:"#CEC"}})
            listensArray.push({id:"bt_autoTP", text:_("持续突破","持續突破"), extend:{key:"autoTP"}, style:{background:"#BEF"}})
            listensArray.push({id:"bt_autoQuitTeam", text:_("进塔离队","進塔離隊"), extend:{key:"autoQuitTeam"}, style:{background:"#EEF"}})
            listensArray.push({id:"bt_autoConnect", text:_("自动重连","自動重連"), extend:{key:"autoConnect"}, style:{background:"#FED"}})
            listensArray.push({id:"hr_listen", text:"", style:{width:"160px",opacity:0}, boxStyle:{"font-size":0}})
            listensArray.push({id:"bt_listenQL", text:_("本服青龙","本服青龍"), extend:{key:"listenQL"}})
            listensArray.push({id:"bt_listenGCQL", text:_("广场青龙","廣場青龍"), extend:{key:"listenGCQL"}})
            listensArray.push({id:"bt_listenYX", text:"遊俠", extend:{key:"listenYX"}})
            listensArray.push({id:"bt_listenTF", text:"夜魔逃犯", extend:{key:"listenTF"}})
            YFUI.addMenu({
                id: "m_listens",
                groupId: "pluginMenus",
                text: _("监听","監聽"),
                style:{"background":"#DDFFDD","width":"40px"},
                multiCol: true,
                menuStyle: {width: "160px","margin-top":"-25px"},
                children: listensArray,
                onclick($btn,$box){
                    if($btn.$extend){
                        //$(".menu").hide()
                        PLU.setListen($btn, $btn.$extend.key)
                    }
                }
            })
            //fightset
            let fightSetsArray=[]
            fightSetsArray.push({id:"bt_enableSkills", text:"技 能 組", style:{background:"#FBE"},menuStyle: {"margin-top":"-25px"}, children:[
                {id:"bt_enableSkill1",text:"技能組1", extend:{key:"enable1"}},
                {id:"bt_enableSkill2",text:"技能組2", extend:{key:"enable2"}},
                {id:"bt_enableSkill3",text:"技能組3", extend:{key:"enable3"}},
                {id:"bt_enableSkill4",text:"技能組4", extend:{key:"enable4"}},
            ]})
            fightSetsArray.push({id:"bt_wearEquip", text:_("装备切换","裝備切換"), style:{background:"#FEB"}, children:[
                {id:"bt_wearEquip1",text:_("装备组1","裝備組1"), extend:{key:"equip1"}, canSet:true},
                {id:"bt_wearEquip2",text:_("装备组2","裝備組2"), extend:{key:"equip2"}, canSet:true},
            ]})
            fightSetsArray.push({id:"bt_followKill", text:_("跟杀设置","跟殺設置"), extend:{key:"followKill"}, style:{background:"#FCC"}})
            fightSetsArray.push({id:"bt_autoCure", text:_("血蓝设置","血藍設置"), extend:{key:"autoCure"}, style:{background:"#CCF"}})
            fightSetsArray.push({id:"bt_autoPerform", text:_("技能设置","技能設置"), extend:{key:"autoPerform"}, style:{background:"#CFC"}})
            YFUI.addMenu({
                id: "m_fightsets",
                groupId: "pluginMenus",
                text: _("战斗","戰鬥"),
                style:{"background":"#FFDDDD","width":"40px"},
                //multiCol: true,
                menuStyle: {width: "80px","margin-top":"-50px"},
                children: fightSetsArray,
                onclick($btn,$box,BtnMode){
                    if($btn.$extend){
                        if($btn.$extend.key && PLU.getCache($btn.$extend.key)==0) $(".menu").hide()
                        if($btn.$extend.key.match('enable')) return PLU.setSkillGroup($btn.$extend.key.substr(-1));
                        if($btn.$extend.key.match('equip')) {
                            let equipKey = "equip_"+$btn.$extend.key.substr(-1)+"_keys";
                            let equipsStr=PLU.getCache(equipKey);
                            $(".menu").hide();
                            if(equipsStr && BtnMode!='setting'){
                                return PLU.wearEquip(equipsStr);
                            }
                            return PLU.setWearEquip($btn.$extend.key.substr(-1));
                        }
                        if($btn.$extend.key=='followKill') return PLU.setFightSets($btn, $btn.$extend.key);
                        if($btn.$extend.key=='autoCure') return PLU.setAutoCure($btn, $btn.$extend.key);
                        if($btn.$extend.key=='autoPerform') return PLU.setAutoPerform($btn, $btn.$extend.key);
                    }
                }
            })
            //Sign
            let signArray=[]
            // signArray.push({id:"bt_answerQues", text:"自動答題", extend:{func:PLU.answerQues}})
            signArray.push({id:"bt_autoAskQixia", text:_("自动问奇侠","自動問奇俠"), extend:{func:PLU.toAutoAskQixia}})
            signArray.push({id:"bt_autoVisitQixia", text:_("亲近奇侠","親近奇俠"), style:{background:"#CFC"}, extend:{func:PLU.toAutoVisitQixia}})
            signArray.push({id:"hr_dlus", text:"", style:{width:"240px",opacity:0}})
            signArray.push({id:"bt_sign", text:_("一键签到","一鍵簽到"), extend:{key:"signIn"}, style:{background:"#CCFFFF"}})
            YFUI.addMenu({
                id: "m_signs",
                groupId: "pluginMenus",
                text: _("签到","簽到"),
                style:{"background":"#DDFFFF","width":"40px"},
                menuStyle: {"margin-top":"-92px"},
                children: signArray,
                onclick($btn,$box){
                    if($btn.$extend){
                        if($btn.$extend.key=='signIn'){$(".menu").hide(); return PLU.toSignIn();}
                        else if($btn.$extend.key=='autoSignIn'){return PLU.setListen($btn, $btn.$extend.key);}
                        else {$(".menu").hide(); $btn.$extend.func($btn);}
                    }
                }
            })
            //sys
            let sysArray=[]
            sysArray.push({id:"bt_openTeam", text:"開隊伍", extend:"team"})
            sysArray.push({id:"bt_openFudi", text:"開府邸", extend:"fudi"})
            sysArray.push({id:"bt_openShop", text:"開商城", extend:"shop"})
            sysArray.push({id:"bt_openJFShop", text:"積分商城", extend:"shop xf_shop"})
            sysArray.push({id:"bt_openQixia", text:"奇俠列表", extend:"open jhqx"})
            sysArray.push({id:"bt_cleartask", text:"清謎題", extend:"auto_tasks cancel"})
            sysArray.push({id:"hr_sys", text:"", style:{width:"160px",opacity:0}, boxStyle:{"font-size":0}})
            sysArray.push({id:"bt_showMPFZ", text:"紛爭顯示", extend:{func:PLU.showMPFZ}, style:{background:"#EEEEFF"}})
            sysArray.push({id:"bt_log", text:"消息日誌", extend:{func:PLU.showLog}, style:{background:"#99CC00"}})
            sysArray.push({id:"bt_upset", text:"上傳設置", extend:{func:PLU.saveSetting}, style:{background:"#FFAAAA"}})
            sysArray.push({id:"bt_dlset", text:"下載設置", extend:{func:PLU.loadSetting}, style:{background:"#FFCC00"}})
            YFUI.addMenu({
                id: "m_sys",
                groupId:"pluginMenus",
                text: "工具",
                multiCol: true,
                style:{"background":"#FFFFDD","width":"40px"},
                menuStyle: {width: "160px","margin-top":"-117px"},
                children: sysArray,
                onclick($btn,$box){
                    if($btn.$extend && $btn.$extend.func){
                        $(".menu").hide()
                        $btn.$extend.func($btn)
                    }else if($btn.$extend){
                        $(".menu").hide()
                        PLU.execActions($btn.$extend)
                    }
                }
            })
            //================================================================================
            //  活動
            //================================================================================
            // let activeArray=[]
            // activeArray.push({id:"bt_goShop1", text:"去小二", extend:"jh 1;"})
            // activeArray.push({id:"bt_buyItem1", text:"買四樣", extend:"#21 buy_npc_item go 0;#21 buy_npc_item go 1;#21 buy_npc_item go 2;#21 buy_npc_item go 3;"})
            // activeArray.push({id:"bt_goShop2", text:"去掌櫃", extend:"jh 5;n;n;n;w;", style:{background:"#FDD"}})
            // activeArray.push({id:"bt_buyItem2", text:"買紅粉", extend:"#6 buy_npc_item go 0;", style:{background:"#FDD"}})
            // activeArray.push({id:"bt_goShop3", text:"去小販", extend:"jh 2;n;n;n;n;e;", style:{background:"#DEF"}})
            // activeArray.push({id:"bt_buyItem3", text:"買黃粉", extend:"#6 event_1_17045611 go 0;", style:{background:"#DEF"}})
            // activeArray.push({id:"bt_goShop4", text:"去峨眉", extend:"jh 8;w;nw;n;n;n;n;e;e;n;n;e;kill?看山弟子;n;n;n;n;w;", style:{background:"#EFE"}})
            // activeArray.push({id:"bt_buyItem4", text:"買藍粉", extend:"#6 event_1_39153184 go 0;", style:{background:"#EFE"}})
            // activeArray.push({id:"bt_goAll", text:"一鍵買材料", extend:"jh 1;#21 buy_npc_item go 0;#21 buy_npc_item go 1;#21 buy_npc_item go 2;#21 buy_npc_item go 3;jh 5;n;n;n;w;#6 buy_npc_item go 0;jh 2;n;n;n;n;e;#6 event_1_17045611 go 0;jh 8;w;nw;n;n;n;n;e;e;n;n;e;kill?看山弟子;n;n;n;n;w;#6 event_1_39153184 go 0;", style:{background:"#9F9"}})
            // activeArray.push({id:"bt_goShoot", text:"去放煙花", extend:"jh 2;n;n;n;", style:{background:"#FD9"}})
            // // activeArray.push({id:"bt_n", text:"", style:{opacity:0}})
            // // activeArray.push({id:"hr_sys", text:"", style:{width:"160px",opacity:0}, boxStyle:{"font-size":0}})
            // activeArray.push({id:"bt_goShoot1", text:"一鍵璀璨", extend:"#5 event_1_99582507;#15 event_1_48376442;", style:{background:"#F9D"}})
            // activeArray.push({id:"bt_goShoot2", text:"一鍵四款", extend:"#5 event_1_74166959;#5 event_1_10053782;#5 event_1_25918230;#5 event_1_48376442;", style:{background:"#D9F"}})

            // YFUI.addMenu({
            //     id: "m_active",
            //     groupId:"pluginMenus",
            //     text: "元宵",
            //     multiCol: true,
            //     style:{"background":"#FFFF55","width":"40px","margin-top":"25px"},
            //     menuStyle: {width: "160px","margin-top":"-22px"},
            //     children: activeArray,
            //     onclick($btn,$box){
            //         if($btn.$extend && $btn.$extend.func){
            //             //$(".menu").hide()
            //             $btn.$extend.func($btn)
            //         }else if($btn.$extend){
            //             //$(".menu").hide()
            // 			PLU.execActions($btn.$extend,()=>{
            // 				YFUI.writeToOut("<span style='color:#FFF;'>========== OK ==========</span>")
            // 			})
            // 		}
            //     }
            // })

            // 開發者帳號
            let dev = ["8429379(1)", "8432668(1)", "8432667(1)", "8432616(1)"];
            // 只對開發者開啓實驗功能
            if (dev.includes(this.accId)) {
                let flagArray = []
                flagArray.push({id:"bt_intervene", text:"介入戰鬥", extend:{func:PLU.intervene}});
                YFUI.addMenu({
                    id: "m_flag",
                    groupId:"pluginMenus",
                    text: _("实验","實驗"),
                    multiCol: true,
                    style:{"background":"#FBB","width":"40px"},
                    menuStyle: {width: "160px","margin-top":"-117px"},
                    children: flagArray,
                    onclick($btn,$box){
                        if($btn.$extend && $btn.$extend.func){
                            $(".menu").hide()
                            $btn.$extend.func($btn)
                        }else if($btn.$extend){
                            $(".menu").hide()
                            PLU.execActions($btn.$extend)
                        }
                    }
                })
            }
            //================================================================================
            //================================================================================

            let gh = parseInt($('#page').height()*$('#page').height()*0.00025)
            YFUI.addBtn({
                id:"bt_col_null",
                groupId:"pluginMenus",
                text:"",
                style:{"background":"transparent","height":gh+"px","width":"0px","visibility":"hidden"},
                boxStyle:{"pointer-events":"none"}
            })
            //戰鬥按鈕
            YFUI.addBtn({
                id:"bt_kg_loopKill",
                groupId:"pluginMenus",
                text:"循環殺",
                style:{"background":"#EECCCC","height":"20px","width":"40px"},
                // boxStyle:{"margin-bottom":"15px"},
                onclick($btn){
                    PLU.toLoopKill($btn);
                }
            })
            YFUI.addBtn({
                id:"bt_kg_teamSync",
                groupId:"pluginMenus",
                text:"同步",
                style:{"background":"#DDCCEE","height":"20px","width":"40px"},
                boxStyle:{"margin-bottom":"15px"},
                onclick($btn){
                    PLU.toggleTeamSync($btn);
                }
            })
            YFUI.addBtn({
                id:"bt_kg_followKill",
                groupId:"pluginMenus",
                text:_("跟杀","跟殺"),
                style:{"background":"#FFDDDD","height":"25px","width":"40px"},
                onclick($btn){
                    PLU.toggleFollowKill($btn, 'followKill');
                }
            })
            YFUI.addBtn({
                id:"bt_kg_autoCure",
                groupId:"pluginMenus",
                text:_("血蓝","血藍"),
                style:{"background":"#CCCCFF","height":"25px","width":"40px"},
                onclick($btn){
                    PLU.toggleAutoCure($btn, 'autoCure');
                }
            })
            YFUI.addBtn({
                id:"bt_kg_autoPerform",
                groupId:"pluginMenus",
                text:_("连招","連招"),
                style:{"background":"#FFCCFF","height":"25px","width":"40px"},
                onclick($btn){
                    PLU.toggleAutoPerform($btn, 'autoPerform');
                }
            })
            //monitor
            let momaxW = $('#page').width()-$('#out').width()>4 && $('#out').width()>634 ? 475 : Math.floor($('#out').width()*0.75);
            let leftSty = $('#page').width()-$('#out').width()>4 && $('#page').width()>634 ? '79px' : '12%';
            YFUI.addBtnGroup({id:"topMonitor", style:{position:'fixed',top:0,left:leftSty,width:'75%',height:'15px',maxWidth:momaxW+'px',lineHeight:'1.2',fontSize:'11px',textAlign:'left',color:'#FF9',background:'rgba(0,0,0,0)',display:'none'} });
        },
        //================================================================================================
        getCache(key){
            let res = PLU.CACHE[key]
            return (res==undefined||res==null)?'':res;
        },
        //================================================================================================
        setCache(key,val){
            PLU.CACHE[key] = val
            UTIL.setMem("CACHE",JSON.stringify(PLU.CACHE))
            return val
        },
        //================================================================================================
        initStorage(){
            if(!UTIL.getMem("CACHE")) UTIL.setMem("CACHE",JSON.stringify(PLU.CACHE))
            let caObj, ca = UTIL.getMem("CACHE")
            try {
                caObj = JSON.parse(ca)
            } catch (err) {}
            if(caObj){
                PLU.CACHE = caObj
                if(PLU.getCache("listenQL")==1) PLU.setListen($("#btn_bt_listenQL"), "listenQL", 1);
                if(PLU.getCache("listenTF")==1) PLU.setListen($("#btn_bt_listenTF"), "listenTF", 1);
                if(PLU.getCache("listenGCQL")==1) PLU.setListen($("#btn_bt_listenGCQL"), "listenGCQL", 1);
                if(PLU.getCache("listenYX")==1) PLU.setListen($("#btn_bt_listenYX"), "listenYX", 1);
                if(PLU.getCache("autoDZ")==1) PLU.setListen($("#btn_bt_autoDZ"), "autoDZ", 1);
                if(PLU.getCache("autoHYC")==1) PLU.setListen($("#btn_bt_autoHYC"), "autoHYC", 1);
                if(PLU.getCache("autoTP")==1) PLU.setListen($("#btn_bt_autoTP"), "autoTP", 1);
                if(PLU.getCache("autoLX")==1) PLU.setListen($("#btn_bt_autoLX"), "autoLX", 1);
                if(PLU.getCache("autoBF")==1) PLU.setListen($("#btn_bt_autoBF"), "autoBF", 1);
                if(PLU.getCache("autoB5F")==1) PLU.setListen($("#btn_bt_autoB5F"), "autoB5F", 1);
                if(PLU.getCache("autoB6")==1) PLU.setListen($("#btn_bt_autoB6"), "autoB6", 1);
                if(PLU.getCache("autoConnect")==1) PLU.setListen($("#btn_bt_autoConnect"), "autoConnect", 1);
                if(PLU.getCache("autoSignIn")==1) PLU.setListen($("#btn_bt_autoSignIn"), "autoSignIn", 1);
                if(PLU.getCache("autoQuitTeam")==1) PLU.setListen($("#btn_bt_autoQuitTeam"), "autoQuitTeam", 1);
                if(PLU.getCache("followKill")==1) {
                    PLU.toggleFollowKill($("#btn_bt_kg_followKill"), "followKill", 1);
                }
                if(PLU.getCache("autoCure")==1) {
                    PLU.toggleAutoCure($("#btn_bt_kg_autoCure"), "autoCure", 1);
                }
                if(PLU.getCache("autoPerform")>=1) {
                    PLU.toggleAutoPerform($("#btn_bt_kg_autoPerform"), "autoPerform", PLU.getCache("autoPerform"))
                }
                if(PLU.getCache("showTopMonitor")==1) {PLU.showMPFZ($("#btn_bt_showMPFZ"));}
            };
        },
        //================================================================================================
        initHistory(){
            //---------------------
            document.addEventListener('addLog',PLU.updateShowLog)
            //---------------------
            let hisArr=[],hstr=UTIL.getMem("HISTORY")
            if(hstr) try {
                hisArr = JSON.parse(hstr)
            } catch (err) {}
            if(hisArr && hisArr.length){
                let nowTs=new Date().getTime()
                let newArr = hisArr.filter(h=>{
                    UTIL.log(Object.assign({},h,{isHistory:true}))
                    if(nowTs-h.time > 43200000) return false;
                    return true;
                })
                UTIL.logHistory=newArr;
                UTIL.setMem("HISTORY",JSON.stringify(newArr))
            }
            PLU.MPFZ = UTIL.getMem('MPFZ') ? JSON.parse(UTIL.getMem('MPFZ')) : {};
        },
        //================================================================================================
        initListeners(){
            //監聽戰鬥消息
            UTIL.addSysListener("listenAllFight", function(b, type, subtype, msg) {
                if(type=="vs"){
                    switch (subtype) {
                        case "vs_info":
                            if (b.containsKey("is_watcher")) {
                                PLU.STATUS.inBattle = 2;
                                break
                            }
                            PLU.STATUS.inBattle = 1;
                            if(!PLU.battleData) PLU.battleData = {skills:{},xdz:0,myPos:0,mySide:'',performTime:0,cureTimes:0};

                            for (let i = b.elements.length - 1; i > -1; i--) {
                                let val = b.elements[i].value + "";
                                if (!val || val.indexOf(PLU.accId) < 0) continue;
                                PLU.battleData.myPos = b.elements[i].key.charAt(7);
                                PLU.battleData.mySide = b.elements[i].key.substring(0, 3);
                                break;
                            }
                            PLU.STATUS.isBusy = true;
                            break;
                        case "ready_skill":
                            if (b.get("uid").indexOf(PLU.accId) < 0 || b.get("skill")=="fight_item")  break;
                            if(!PLU.battleData) PLU.battleData = {skills:{},xdz:0,myPos:0,mySide:'',performTime:0,cureTimes:0};
                            PLU.battleData.skills[b.get("pos")-1] = {
                                name:UTIL.filterMsg(b.get("name")),
                                skill:b.get("skill"),
                                xdz:b.get("xdz"),
                                key:"playskill "+b.get("pos")
                            }
                            break;
                        case "add_xdz":
                            if (b.get("uid").indexOf(PLU.accId) < 0)  break;
                            if(!PLU.battleData) PLU.battleData = {skills:{},xdz:0,myPos:0,mySide:'',performTime:0,cureTimes:0};
                            PLU.battleData.xdz=parseInt(b.get("xdz"))
                            break;
                        case "playskill":
                            if (b.get("uid").indexOf(PLU.accId) < 0)  break;
                            if(!PLU.battleData) PLU.battleData = {skills:{},xdz:0,myPos:0,mySide:'',performTime:0,cureTimes:0};
                            let x = PLU.battleData.xdz - parseInt(b.get("lose_xdz"))
                            if(parseInt(b.get("lose_xdz"))) PLU.battleData.xdz = x>0 ? x : 0;
                            break;
                        case "out_watch":
                            PLU.STATUS.inBattle = 0;
                            PLU.STATUS.isBusy = false;
                            break;
                        case "combat_result":
                            PLU.STATUS.inBattle = 0;
                            PLU.battleData = null;

                            PLU.STATUS.isBusy = false;
                            if(PLU.TMP.loopUseSkill){
                                clearInterval(PLU.TMP.loopUseSkill)
                                PLU.TMP.loopUseSkill = null
                            }
                            break;
                        default:
                            break;
                    }
                    if(PLU.STATUS.inBattle==1 && !PLU.TMP.loopUseSkill){
                        PLU.TMP.loopUseSkill = setInterval(()=>{
                            if(PLU.STATUS.inBattle==1 && PLU.battleData && PLU.battleData.xdz>1){
                                PLU.checkUseSkills()
                            }
                        },300)
                    }
                }
                if(g_gmain.is_fighting && PLU.STATUS.inBattle==1){
                    if(type=="vs" || type=='attrs_changed'){
                        //自動療傷及自動技能
                        if(PLU.battleData && PLU.battleData.xdz>1 && PLU.STATUS.inBattle==1){
                            PLU.checkUseSkills()
                        }
                    }
                }
            });
            //監聽場景消息
            UTIL.addSysListener("listenNotice", function(b, type, subtype, msg) {
                if (type != "notice" && type != "main_msg") return;
                let msgTxt = UTIL.filterMsg(msg)
                if(msgTxt.match("你打坐完畢") && PLU.getCache("autoDZ")==1){
                    if(UTIL.inHome()) clickButton('exercise', 0);
                    else PLU.TODO.push({type:"cmds",cmds:"exercise",timeout:new Date().getTime()+8*60*60*1000});
                }
                if((msgTxt.match("你從寒玉床上爬起") || msgTxt.match("你從地髓石乳中出來")) && PLU.getCache("autoHYC")==1){
                    if(UTIL.inHome()) PLU.execActions("golook_room;sleep_hanyuchuang;home");
                    else PLU.TODO.push({type:"cmds",cmds:"golook_room;sleep_hanyuchuang;home",timeout:new Date().getTime()+8*60*60*1000});
                }
                if(msgTxt.match(/你的(.*)成功向前突破了/) && PLU.getCache("autoTP")==1){
                    if(UTIL.inHome()) PLU.toToPo();
                    else {
                        let checktp = PLU.TODO.find(e=>e.cmds=="toToPo")
                        if(!checktp) PLU.TODO.push({type:"func",cmds:"toToPo",timeout:new Date().getTime()+8*60*60*1000});
                    }
                }
                if((msgTxt.match("你現在正突破") && msgTxt.match("同時突破")) ||  msgTxt.match("此次突破需要")){//突破失敗
                    PLU.TMP.stopToPo = true
                }
                if(msgTxt.match("青龍會組織:")){//本服青龍
                    let l = msgTxt.match(/青龍會組織:(.*)正在\003href;0;([\w\d\s]+)\003(.*)\0030\003施展力量,本會願出(.*)的戰利品獎勵給本場戰鬥的最終獲勝者。/);
                    if(l && l.length>3){
                        UTIL.log({msg:'【青龍】'+l[3].padStart(5)+' - '+l[1].padEnd(4)+'  獎品:'+l[4], type:'QL', time:new Date().getTime()})
                        if(PLU.getCache("listenQL")==1){
                            let keysStr=PLU.getCache("listenQL_keys").split("|")[1].split(",").map(e=>(e=="*"?".*":e.replace("*","\\*"))).join("|")
                            let reg=new RegExp(keysStr)
                            if(l[4].match(reg) && UTIL.inHome()){
                                PLU.goQinglong(l[1],l[3],l[4],PLU.getCache("listenQL_keys").split("|")[0])
                            }
                        }
                    }
                }
                if(msgTxt.match("這是你今天完成的第")){//逃犯完成
                    let l = msgTxt.match(/這是你今天完成的第(\d)\/\d場逃犯任務/)
                    if(l && l.length>0 && l[1]==5){
                        YFUI.writeToOut('<span style="color:yellow;">逃犯任務已達到上限!取消逃犯監聽...</span>')
                        UTIL.log({msg:' 逃犯任務已達到上限!取消逃犯監聽...', type:'TIPS', time:new Date().getTime()})
                        PLU.setListen($("#btn_bt_listenTF"), "listenTF", 0)
                    }
                }
                if(msgTxt.match("對你悄聲道:你現在去") && !PLU.TMP.autoQixiaMijing){//奇俠說秘境
                    let l = msgTxt.match(/(.*)對你悄聲道:你現在去(.*),應當會有發現/);
                    if(l && l.length>2){
                        let placeData=PLU.YFD.mjList.find(e=>e.n==l[2])
                        if(placeData){
                            YFUI.writeToOut("<span>奇俠秘境: <a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.execActions(\""+placeData.v+"\")'>"+placeData.n+"</a></span>")
                            YFUI.showPop({
                                title:"奇俠秘境",
                                text:"秘境:"+placeData.n,
                                okText:"去秘境",
                                onOk(){
                                    PLU.execActions(placeData.v+';find_task_road secret;',()=>{
                                        YFUI.writeToOut("<span>:: <a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='clickButton(\"open jhqx\", 0)'>奇俠列表</a></span>")
                                    })
                                },
                                onNo(){}
                            })
                        }
                    }
                }
                if(msgTxt.match("開啟了幫派副本") && PLU.getCache("autoBF")==1){//幫四開啟
                    let ll = msg.match(/開啟了幫派副本.*十月圍城.*【(.*)】/)
                    if(ll){
                        let n = '一二三'.indexOf(ll[1])
                        UTIL.log({msg:'【幫四】幫四('+ll[1]+')開啟 ', type:'BF', time:new Date().getTime()})
                        if(n>=0){
                            if(!g_gmain.is_fighting && UTIL.inHome()){
                                PLU.toBangFour(n+1);
                            }else {
                                let checktodo = PLU.TODO.find(e=>e.cmds=="toBangFour")
                                if(!checktodo) PLU.TODO.push({type:"func",cmds:"toBangFour",param:n+1,timeout:new Date().getTime()+5*60*1000});
                            }
                        }
                    }
                }
                if(msgTxt.match("開啟了幫派副本") && PLU.getCache("autoB6")==1){//幫六開啟
                    let ls = msg.match(/開啟了幫派副本.*蠻荒七神寨.*/)
                    if(ls){
                        if(!g_gmain.is_fighting){
                            PLU.toBangSix();
                        }else {
                            let checktodo = PLU.TODO.find(e=>e.cmds=="toBangSix")
                            if(!checktodo) PLU.TODO.push({type:"func",cmds:"toBangSix",param:'',timeout:new Date().getTime()+5*60*1000});
                        }
                    }
                }
                if(msgTxt.match("十月圍城】幫派副本勝利")){//幫四完成
                    PLU.STO.bangFourTo && clearTimeout(PLU.STO.bangFourTo);
                    if(!g_gmain.is_fighting){
                        setTimeout(function(){
                            PLU.execActions('home;')
                        },2000)
                    }
                }
                if(msgTxt.match("蠻荒七神寨】幫派副本勝利")){//幫六完成
                    PLU.STO.bangSixTo && clearTimeout(PLU.STO.bangSixTo);
                    if(!g_gmain.is_fighting){
                        setTimeout(function(){
                            PLU.execActions('home;')
                        },2000)
                    }
                }

                if(msgTxt.match("你今天進入此副本的次數已達到上限了")){//幫四六無法進入
                    PLU.STO.bangFourTo && clearTimeout(PLU.STO.bangFourTo);
                    PLU.STO.bangSixTo && clearTimeout(PLU.STO.bangSixTo);
                    UTIL.log({msg:' !!副本超量!!', type:'TIPS', time:new Date().getTime()})
                }
                if(msgTxt.match(/你已進入幫派副本\*\*可汗金帳\*\*/) && PLU.getCache("autoB5F")==1){//幫五進入
                    PLU.inBangFiveEvent()
                }
                if(msgTxt.match("成功消滅了守將府內的所有敵人")){//幫二完成
                    let l = msgTxt.match(/守城成功】(.*)成功消滅了守將府內的所有敵人,幫派副本完成/);
                    if(l && l.length>1 && !g_gmain.is_fighting){
                        setTimeout(() => {
                            PLU.execActions('home;')
                        }, 3000);
                    }
                }
                if(msgTxt.match("你沒有精良魚餌,無法釣魚")){//釣魚完成
                    if(!UTIL.inHome() && !g_gmain.is_fighting){
                        setTimeout(() => {
                            PLU.execActions('home;')
                        }, 1000);
                    }
                }
            });

            //監聽頻道消息
            UTIL.addSysListener("listenChannel", function(b, type, subtype, msg) {
                if (type != "channel" || subtype != "sys") return;
                let msgTxt = UTIL.filterMsg(msg)
                //本服逃犯
                if(msgTxt.match("慌不擇路") && msgTxt.indexOf("跨服")<0){
                    var l = msgTxt.match(/系統】([\u4e00-\u9fa5|\*]+).*慌不擇路,逃往了(.*)-\003href;0;([\w\d\s]+)\003([\u4e00-\u9fa5]+)/);
                    if(l && l.length>4){
                        UTIL.log({msg:'【逃犯】'+l[2]+'-'+l[4]+' : '+l[1], type:'TF', time:new Date().getTime()})
                        //111
                        if(PLU.getCache("listenTF")==1 && UTIL.inHome()){
                            if(!PLU.TMP.lis_TF_list){
                                PLU.splitTFParam()
                            }
                            if(PLU.TMP.lis_TF_list.includes(l[1])){
                                let idx = PLU.TMP.lis_TF_list.findIndex(k=>k==l[1])
                                if(idx>=0){
                                    let gb = Number(PLU.getCache("listenTF_keys").split("|")[0])||0
                                    PLU.goTaofan(l[1], l[2], l[3], gb, PLU.TMP.lis_TF_force[idx]);
                                }
                            }
                        }
                    }
                }
                //廣場青龍
                if(msgTxt.match("跨服時空武林廣場")){
                    let l = msgTxt.match(/跨服:(.*)逃到了跨服時空(武林廣場.*)之中,青龍會組織懸賞(.*)懲治惡人,眾位英雄快來誅殺。/)
                    if(l && l.length>3){
                        UTIL.log({msg:'【廣場青龍】'+l[2]+' - '+l[1].padEnd(8)+'  獎品:'+l[3], type:'GCQL', time:new Date().getTime()})
                        if(PLU.getCache("listenGCQL")==1){
                            let keysStr=PLU.getCache("listenGCQL_keys").split("|")[1].split(",").map(e=>(e=="*"?".*":e.replace("*","\\*"))).join("|")
                            let reg=new RegExp(keysStr)
                            if(l[3].match(reg) && UTIL.inHome()){
                                PLU.goGCQinglong(l[1],l[2],l[3],PLU.getCache("listenGCQL_keys").split("|")[0])
                            }
                        }
                    }
                }
                //江湖紛爭
                if(msgTxt.match("江湖紛爭")){
                    let fz = msgTxt.match(/【江湖紛爭】:(.*)(門派|流派)的(.*)劍客傷害同門,欺師滅組,判師而出,卻有(.*)堅持此種另有別情而強行庇護,兩派紛爭在(.*)-(.*)一觸即發,江湖同門速速支援!/)
                    if (!fz) return;
                    let ro = fz[3]
                    let pl = fz[5]+"-"+fz[6]
                    let vs = fz[1]+" VS "+fz[4]
                    let tp = fz[2]
                    let logType = tp=='門派'?'MPFZ':'LPFZ';
                    UTIL.log({msg:'【'+tp+'之爭】 '+ro+'  地點:['+pl+']  '+vs, type:logType, time:new Date().getTime()})
                    if(tp=='門派'){
                        let nowTime = new Date().getTime()
                        for(let k in PLU.MPFZ){
                            if(k<nowTime) delete PLU.MPFZ[k];
                        }
                        let extime = new Date().getTime()+1560000
                        PLU.MPFZ[extime] = {n:ro,p:pl,v:vs,t:new Date().getTime()}
                        UTIL.setMem('MPFZ',JSON.stringify(PLU.MPFZ))
                    }
                }
                //遊俠
                if(msgTxt.match("出來闖蕩江湖了")){
                    let yx = msgTxt.match(/【系統】遊俠會:聽說(.*)出來闖蕩江湖了,目前正在前往(.*)的路上/);
                    if (!yx) return;
                    let yn = $.trim(yx[1])
                    let yp = yx[2]
                    let yr = ''
                    PLU.YFD.youxiaList.forEach(g=>{
                        if(g.v.includes(yn)) yr=g.n
                    })
                    UTIL.log({msg:'【遊俠-'+yr+'】 '+yn+'  地點:['+yp+']  ', type:'YX', time:new Date().getTime()})
                    if(PLU.getCache("listenYX")==1 && UTIL.inHome()){
                        if(!PLU.TMP.listenYX_list){
                            PLU.TMP.listenYX_list=PLU.getCache("listenYX_keys").split(",")
                        }
                        if(PLU.TMP.listenYX_list && PLU.TMP.listenYX_list.includes(yn)){
                            let jhName = PLU.fixJhName(yp)
                            let jhMap = PLU.YFD.mapsLib.Map.find(e=>e.name==jhName)
                            if(!jhMap){
                                return
                            }else{
                                let ways = jhMap.way.split(";")
                                PLU.goFindYouxia({paths:ways,idx:0,objectNPC:yn})
                            }
                        }
                    }
                }
            });
            //監聽場景
            UTIL.addSysListener("listenRoomInfo", function(b, type, subtype, msg) {
                if (type != "jh") return;
                //奇俠加按鈕
                $('#out .out>button.cmd_click3').each((i,e)=>{
                    if(PLU.YFD.qixiaList.includes(e.innerText)) {
                        let snpc = e.outerHTML.match(/clickButton\('look_npc (\w+)'/i)
                        if(snpc && snpc.length>=2){
                            $(e).css({'position':'relative'});
                            let $btnAsk = $('<span style="position:absolute;display:inline-block;left:0;top:0;padding:3% 5%;text-align:center;background:#39F;color:#fff;border-radius:3px;font-size:1.2em;">問<span>')
                            let $btnGold = $('<span style="position:absolute;display:inline-block;right:0;bottom:0;padding:3% 5%;text-align:center;background:#F93;color:#fff;border-radius:3px;font-size:1.2em;">金<span>')
                            $(e).append($btnAsk)
                            $(e).append($btnGold)
                            $btnAsk.click(e=>{
                                e.stopPropagation();
                                PLU.execActions('ask '+snpc[1]+';')
                            })
                            $btnGold.click(e=>{
                                e.stopPropagation();
                                let ename=snpc[1].split('_')[0]
                                PLU.execActions('auto_zsjd20_'+ename+';golook_room')
                            })
                        }
                    }
                })
                //監聽入隊靈鷲和塔
                if(type=="jh" && subtype=="info" && PLU.getCache("autoQuitTeam")==1){
                    let sn = g_obj_map.get("msg_room").get("short")
                    if(sn.match(/靈鷲宮(\D+)層/) ||
                       sn.match(/拱辰樓(\D+)層/) ||
                       sn.match(/陳異叔(\D+)層/) ||
                       sn.match(/無為寺(\D+)層/) ||
                       sn.match(/一品堂(\D+)層/) ||
                       sn.match(/名將堂(\D+)層/) ||
                       sn.match(/魔皇殿(\D+)層/) ||
                       sn.match(/藏典塔(\D+)層/) ||
                       sn.match(/無相樓(\D+)層/) ||
                       sn.match(/葬劍谷(\D+)層/) ||
                       sn.match(/霹靂堂(\D+)層/) ||
                       sn.match(/鑄劍洞(\D+)層/) ||
                       sn.match(/劍樓(\D+)層/) ||
                       sn.match(/紅螺寺(\D+)層/) ||
                       sn.match(/通天塔(\D+)層/)
                      ){
                        //退出隊伍
                        let quitTeamPrevTimeOut=setTimeout(()=>{
                            UTIL.delSysListener("quitTeamPrev");
                        },5000)
                        UTIL.addSysListener("quitTeamPrev", function(b, type, subtype, msg) {
                            if(type=="team" && subtype=="info"){
                                UTIL.delSysListener("quitTeamPrev");
                                clearTimeout(quitTeamPrevTimeOut);
                                clickButton('prev')
                            }
                        })
                        clickButton('team quit')
                    }
                }
                //刷新後恢復監聽幫五
                if(type=="jh" && subtype=="info" && PLU.TMP.listenBangFive==undefined){
                    let roomName = UTIL.filterMsg(g_obj_map.get("msg_room").get('short'))
                    if(roomName.match(/蒙古高原|成吉思汗的金帳/)){
                        PLU.inBangFiveEvent();
                    }else{
                        PLU.TMP.listenBangFive = false;
                    }
                }

                return;
            });
            //監聽練習
            UTIL.addSysListener("listenPractice", function(b, type, subtype, msg) {
                if (type == "practice" && subtype == "stop_practice" && PLU.getCache("autoLX")==1) {
                    let skillId = b.get("sid") , lxcmds='enable '+skillId+';practice '+skillId+';'
                    if(UTIL.inHome()) PLU.execActions(lxcmds);
                    else PLU.TODO.push({type:"cmds", cmds:lxcmds, timeout:new Date().getTime()+8*60*60*1000});
                }
            })
            //監聽劍陣
            UTIL.addSysListener("listenJianzhen", function(b, type, subtype, msg) {
                if (type != "notice") return;
                if (msg.indexOf("陣升級完畢!") < 0) return;
                let msgTxt = UTIL.filterMsg(msg)
                if(msgTxt.match(/(.*)陣升級完畢!成功升級到/)){
                    setTimeout(()=>{
                        let jzcmds='hhjz xiulian go;;;hhjz speedup go;'
                        if(UTIL.inHome()) PLU.execActions(jzcmds);
                        else PLU.TODO.push({type:"cmds", cmds:jzcmds, timeout:new Date().getTime()+8*60*60*1000});
                    },8000)
                }
            })
            //監聽跟殺
            UTIL.addSysListener("listenFightKill", function(b, type, subtype, msg) {
                if (type != "main_msg") return;
                if (!msg) return;
                if (msg.indexOf("對著") < 0) return;
                if (PLU.getCache("followKill")!=1) return;
                let msgTxt = UTIL.filterMsg(msg)
                var matchKill = msgTxt.match(/(.*)對著(.*)喝道:「(.*)!今日不是你死就是我活!」/);
                if (matchKill && $.trim(matchKill[1]) != "你" && $.trim(matchKill[2]) != "你" && !g_gmain.is_fighting) {
                    PLU.toCheckFollowKill($.trim(matchKill[1]), $.trim(matchKill[2]), "kill", msgTxt)
                    return
                }
                var matchFight = msgTxt.match(/(.*)對著(.*)說道:(.*),領教(.*)的高招!/);
                if (matchFight && $.trim(matchFight[1]) != "你" && $.trim(matchFight[2]) != "你" && !g_gmain.is_fighting) {
                    PLU.toCheckFollowKill($.trim(matchFight[1]), $.trim(matchFight[2]), "fight", msgTxt)
                    return;
                }
            })
            //test
            UTIL.addSysListener("testListener", function(b, type, subtype, msg) {
                // if(type != "channel" && type != "attrs_changed") console.log(b,"TYPE:",type," SUBTYPE:",subtype," MSG:",msg);
                //if(type=='g_login') console.log(b,"TYPE:",type," SUBTYPE:",subtype," MSG:",msg)
                if(type=='g_login' && subtype=='login_ret' && msg=='1'){
                    //console.log('%c%s','color:#FFF;background:#F00;','[ '+UTIL.getNow()+' ] ======掉線重連了!!!=====')
                    YFUI.writeToOut("<span style='color:#FFF;background:#F00;'>["+UTIL.getNow()+"] 斷線重連了 </span>")
                    PLU.TMP.reConnectTime = 0;
                }
            })
            unsafeWindow.sock.on("disconnect",()=>{
                console.log('%c%s','color:#F00','>>>>>>>sock disconnected')
                //sock && sock.close(); sock = 0
                if(PLU.getCache("autoConnect")==1){
                    let recTime = Number(PLU.getCache("autoConnect_keys"))
                    if(recTime) PLU.TMP.reConnectTime = recTime
                }
            })
            unsafeWindow.sock.on("telnet_connected",()=>{
                console.log('%c%s','color:#0F0','>>>>>>>sock connected')
            })
            UTIL.addSysListener("YXSkillsListener", function(b, type, subtype, msg) {
                if(type != "show_html_page") return;
                if(msg.indexOf("須傳授技能")<0) return;
                let list = msg.match(/\x1B\[1;36m(\d+)\/(\d+)[\s\S]{1,200}(fudi juxian up_skill .* 10)/g)
                let outList = null
                if(list && list.length){
                    outList = list.map(s=>{
                        let r=s.match(/\x1B\[1;36m(\d+)\/(\d+)[\s\S]{1,200}(fudi juxian up_skill .* 10)/);
                        return {lvl:r[1],max:r[2],cmd:r[3]+'0'}
                    })
                }
                PLU.TMP.CUR_YX_SKILLS = outList
                let matchNameLine=msg.match(/<span class="out2">([\s\S]+)<\/span><span class="out2">/)
                let npcNameLine = matchNameLine ? UTIL.filterMsg(matchNameLine[1]) : ''
                let dg = npcNameLine.match(/(\d+)級/)[1];
                PLU.TMP.CUR_YX_LEVEL = Number(dg)
                let nn = msg.match(/fudi juxian upgrade (\S+) 1/)[1];
                PLU.TMP.CUR_YX_ENG = nn
            });
            UTIL.addSysListener("masterSkillsListener", function(b, type, subtype, msg) {
                if(type != "master_skills" || subtype!="list") return;
                let masterSkills = PLU.parseSkills(b)

                PLU.TMP.MASTER_ID = b.get('id')
                PLU.TMP.MASTER_SKILLS = masterSkills

            })
        },
        //================================================================================================
        initTickTime(){
            setInterval(()=>{
                let nowDate = new Date()
                let nowTime = nowDate.getTime()
                if(PLU.TODO.length>0 && !PLU.STATUS.isBusy && UTIL.inHome()){//待辦
                    let ctd = PLU.TODO.shift()
                    if(nowDate.getTime()<ctd.timeout){
                        if(ctd.type=="cmds"){
                            PLU.execActions(ctd.cmds);
                        } else if(ctd.type=="func") {
                            if(ctd.param) PLU[ctd.cmds](ctd.param); else PLU[ctd.cmds]();
                        }
                    }
                };
                if($('#topMonitor').text()!="") $('#topMonitor').empty();
                let bi=0;
                for(let k in PLU.MPFZ){
                    if(k<nowTime) delete PLU.MPFZ[k];
                    else{
                        let f=PLU.MPFZ[k]
                        let dt = Math.floor((k-nowTime)/1000)
                        let flo = bi%2==1?'float:right;text-align:right;':''
                        $('#topMonitor').append(`<div title="${f.v}" style="display:inline-block;width:40%;${flo}">
                                                ${f.n.substr(0,1)} <span style="color:#9CF;">[${f.p}]</span> <span style="color:#DDD;">${dt}</span>
                                                </div>`)
                        bi++;
                    }
                }
                if(PLU.ONOFF["btn_bt_waitCDKill"] && PLU.TMP.DATA_MPFZ) PLU.toCheckAndWaitCDKill(nowTime)

                if(PLU.TMP.reConnectTime && PLU.getCache("autoConnect")==1 && PLU.TMP.reConnectTime>0){
                    PLU.TMP.reConnectTime--;
                    if(PLU.TMP.reConnectTime<=0){
                        location.reload()
                    }
                }
            },1000)
        },
        //================================================================================================
        toSignIn(){
            // this.signIn(0)
            // return;
            if(!this.signInMaps) this.initSignInMaps();
            let ckeds = PLU.getCache('signInArray') ? PLU.getCache('signInArray').split(',') : this.signInMaps.map((e,i)=>i);

            let htm='<div style="display:flex;flex-direction:row;flex-wrap: wrap;justify-content: space-between;width: 100%;align-content: flex-start;line-height:2;">'
            this.signInMaps.forEach((e,i)=>{
                if(!e.n) htm+='<span style="width:92px;">&nbsp;</span>';
                else htm+='<span><button class="signInBtn" data-sid="'+i+'" style="font-size:12px;padding:1px 2px;cursor:pointer;">GO</button>'+
                    '<label data-id="'+i+'" style="font-size:13px;margin:0 3px 5px 0;">'+e.n+
                    '<input type="checkbox" name="signInId" value="'+i+'" '+(ckeds.includes(i+'')||e.f?'checked':'')+' '+(e.f?'disabled':'')+'/>'+
                    '</label></span>'
            })
            htm+='</div>'
            htm+='<button class="signInAll" style="cursor:pointer;position:absolute;left:15px;bottom:10px;">全選</button>'
            YFUI.showPop({
                title:"簽到",
                text: htm,
                width:"360px",
                okText:"一鍵簽到",
                onOk(e){
                    let checkeds=[]
                    e.find('input[name="signInId"]:checked').each((i,b)=>{
                        checkeds.push(b.value)
                    })
                    PLU.setCache('signInArray',checkeds.join(','))
                    //console.log(checkeds)//--
                    PLU.goSign(checkeds)
                },
                onNo(){

                },
                afterOpen($el){
                    $el.find('.signInBtn').click(e=>{
                        let btnSid = $(e.currentTarget).attr('data-sid')
                        PLU.goSign(btnSid)
                    })
                    $el.find('.signInAll').click(e=>{
                        $el.find('input[name="signInId"]').each(function(){
                            $(this).prop("checked",true);
                        });
                    });
                }
            })
        },
        //================================================================================================
        autoGetVipReward(callback){
            let acts = '';
            let vipInfo = g_obj_map.get("msg_vip")
            if(vipInfo.get("get_vip_drops")==0) acts+='vip drops;';
            if(vipInfo.get("finish_sort")%1000 <5) acts+='#5 vip finish_sort;';
            if(vipInfo.get("finish_dig")%1000 <10) acts+='#10 vip finish_dig;';
            if(vipInfo.get("finish_diaoyu")%1000 <10) acts+='#10 vip finish_diaoyu;';
            if(vipInfo.get("do_task_num")%1000 <10) acts+='#10 vip finish_big_task;';
            if(vipInfo.get("family_quest_count")%1000 <25) acts+='#25 vip finish_family;';
            if(g_obj_map.get("msg_clan_view") && vipInfo.get("clan_quest_count")%1000 <20) acts+='#20 vip finish_clan;';
            if(vipInfo.get("saodang_fb_1") && vipInfo.get("saodang_fb_1").split(",")[2]%1000 <2) acts+='#2 vip finish_fb dulongzhai;';
            if(vipInfo.get("saodang_fb_2") && vipInfo.get("saodang_fb_2").split(",")[2]%1000 <2) acts+='#2 vip finish_fb junying;';
            if(vipInfo.get("saodang_fb_3") && vipInfo.get("saodang_fb_3").split(",")[2]%1000 <2) acts+='#2 vip finish_fb beidou;';
            if(vipInfo.get("saodang_fb_4") && vipInfo.get("saodang_fb_4").split(",")[2]%1000 <2) acts+='#2 vip finish_fb youling;';
            if(vipInfo.get("saodang_fb_5") && vipInfo.get("saodang_fb_5").split(",")[2]%1000 <1) acts+='vip finish_fb siyu;';
            if(vipInfo.get("saodang_fb_6") && vipInfo.get("saodang_fb_6").split(",")[2]%1000 <1) acts+='vip finish_fb changleweiyang;';
            if(vipInfo.get("saodang_fb_7") && vipInfo.get("saodang_fb_7").split(",")[2]%1000 <1) acts+='vip finish_fb heishuihuangling;';
            if(vipInfo.get("saodang_fb_8") && vipInfo.get("saodang_fb_8").split(",")[2]%1000 <1) acts+='vip finish_fb jiandangfenglingdu;';
            if(vipInfo.get("saodang_fb_9") && vipInfo.get("saodang_fb_9").split(",")[2]%1000 <1) acts+='vip finish_fb tianshanlongxue;';
            if(vipInfo.get("saodang_fb_10") && vipInfo.get("saodang_fb_10").split(",")[2]%1000 <1) acts+='vip finish_fb sizhanguangmingding;';
            acts +='home;'
            PLU.execActions(acts,()=>{
                callback && callback()
            })
        },
        autoVipShaodan(callback){
            let acts = '';
            let vipInfo = g_obj_map.get("msg_vip")
            if(vipInfo.get("saodang_fb_1") && vipInfo.get("saodang_fb_1").split(",")[2]%1000 <2) acts+='#2 vip finish_fb dulongzhai;';
            if(vipInfo.get("saodang_fb_2") && vipInfo.get("saodang_fb_2").split(",")[2]%1000 <2) acts+='#2 vip finish_fb junying;';
            if(vipInfo.get("saodang_fb_3") && vipInfo.get("saodang_fb_3").split(",")[2]%1000 <2) acts+='#2 vip finish_fb beidou;';
            if(vipInfo.get("saodang_fb_4") && vipInfo.get("saodang_fb_4").split(",")[2]%1000 <2) acts+='#2 vip finish_fb youling;';
            if(vipInfo.get("saodang_fb_5") && vipInfo.get("saodang_fb_5").split(",")[2]%1000 <1) acts+='vip finish_fb siyu;';
            if(vipInfo.get("saodang_fb_6") && vipInfo.get("saodang_fb_6").split(",")[2]%1000 <1) acts+='vip finish_fb changleweiyang;';
            if(vipInfo.get("saodang_fb_7") && vipInfo.get("saodang_fb_7").split(",")[2]%1000 <1) acts+='vip finish_fb heishuihuangling;';
            if(vipInfo.get("saodang_fb_8") && vipInfo.get("saodang_fb_8").split(",")[2]%1000 <1) acts+='vip finish_fb jiandangfenglingdu;';
            if(vipInfo.get("saodang_fb_9") && vipInfo.get("saodang_fb_9").split(",")[2]%1000 <1) acts+='vip finish_fb tianshanlongxue;';
            if(vipInfo.get("saodang_fb_10") && vipInfo.get("saodang_fb_10").split(",")[2]%1000 <1) acts+='vip finish_fb sizhanguangmingding;';
            acts +='home;'
            PLU.execActions(acts,()=>{
                callback && callback()
            })
        },
        //================================================================================================
        getClanInfo(callback){
            let openClanTimeout=setTimeout(()=>{
                UTIL.delSysListener("listenOpenClan");
                callback && callback(0)
            },5000)
            UTIL.addSysListener("listenOpenClan", function(b, type, subtype, msg) {
                if(type=="clan"){
                    UTIL.delSysListener("listenOpenClan");
                    clearTimeout(openClanTimeout);
                    clickButton("prev");
                    //console.log(g_obj_map.get("msg_clan_view"))
                    callback && callback(1)
                }
            })
            clickButton("clan");
        },
        getVipInfo(callback){
            let openVipTimeout=setTimeout(()=>{
                UTIL.delSysListener("listenOpenVip");
                callback && callback(0)
            },5000)
            UTIL.addSysListener("listenOpenVip", function(b, type, subtype, msg) {
                if(type=="vip"){
                    UTIL.delSysListener("listenOpenVip");
                    clearTimeout(openVipTimeout);
                    clickButton("prev");
                    //console.log(g_obj_map.get("msg_vip"))
                    callback && callback(1)
                }
            })
            clickButton("vip");
        },
        //================================================================================================
        goSign(param){
            if(!param){
                return YFUI.writeToOut("<span style='color:#FFF;'>--結束--</span>")
            }else if(param.length==0){
                return YFUI.writeToOut("<span style='color:#FFF;'>--簽到結束--</span>")
            }
            let sid=null
            if(typeof param == 'object'){
                sid = param.shift()
            }else{
                sid = param
                param = null
            }
            let signD = PLU.signInMaps[sid]
            if(signD.c != undefined){
                if(signD.c()){
                    if(signD.fn){
                        signD.fn(()=>{
                            PLU.goSign(param)
                        })
                    }else if(signD.go) {
                        PLU.execActions(signD.go, ()=>{
                            PLU.goSign(param)
                        })
                    }
                }else{
                    PLU.goSign(param)
                }
            }else{
                if(signD.fn){
                    signD.fn(()=>{
                        PLU.goSign(param)
                    })
                }else if(signD.go) {
                    PLU.execActions(signD.go, ()=>{
                        PLU.goSign(param)
                    })
                }
            }
        },
        //================================================================================================
        initSignInMaps(){
            let _this=this;
            this.getVipInfo(b=>{
                _this.getClanInfo(a=>{
                })
            })
            this.signInMaps = [
                {n:'揚州簽到',f:true,go:'jh 5;n;n;n;w;look_npc yangzhou_yangzhou4;sign7;home;'},
                {n:'每日禮包',f:true,go:'jh 1;event_1_48246976;event_1_85373703;home;'},
                {n:'潛龍禮包',go:'jh 1;w;event_1_76648488;event_1_21318613;home;'},
                {n:'續約會員',go:'jh 1;event_1_45018293;home;'},
                {n:'分享獎勵',go:'share_ok 1;share_ok 2;share_ok 3;share_ok 4;share_ok 5;share_ok 7;home;'},
                {n:'南詔投資',go:'jh 54;#4 nw;#2 w;#4 n;#2 e;n;#2 e;event_1_62143505 go;;;event_1_62143505 get;event_1_63750325 get;home;'},
                {n:'消費積分',go:'jh 1;e;n;e;e;event_1_44731074;event_1_8041045;event_1_8041045;event_1_29721519;home;'},
                {n:'吃九花丸',go:'items use obj_jiuhuayulouwan;home;'},
                {n:'打坐睡床',go:'home;exercise stop;exercise;golook_room;sleep_hanyuchuang;home;'},
                {n:'買引路蜂',go:'shop money_buy mny_shop2_N_10;home;'},
                {n:'領取工資',go:'home;work click maikuli;work click duancha;work click dalie;work click baobiao;work click maiyi;work click xuncheng;work click datufei;work click dalei;work click kangjijinbin;work click zhidaodiying;work click dantiaoqunmen;work click shenshanxiulian;work click jianmenlipai;work click dubawulin;work click youlijianghu;work click yibangmaoxiang;work click zhengzhanzhongyuan;work click taofamanyi;public_op3;home;'},
                {n:'爬樓獎勵',go:'home;cangjian get_all;xueyin_shenbinggu blade get_all;xueyin_shenbinggu unarmed get_all;xueyin_shenbinggu throwing get_all;xueyin_shenbinggu spear get_all;xueyin_shenbinggu hammer get_all;xueyin_shenbinggu axe get_all;xueyin_shenbinggu whip get_all;xueyin_shenbinggu stick get_all;xueyin_shenbinggu staff get_all;home;'},
                {n:_("自动答题","自動答題"),fn:PLU.loopAnswerQues},

                // {n:'VIP速領',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0},fn:PLU.autoGetVipReward},
                {n:'VIP 福利',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_vip").get("get_vip_drops")==0},go:'vip drops;home;'},
                {n:'VIP 排行',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_vip").get("finish_sort")%1000 <5},go:'#5 vip finish_sort;home;'},
                {n:'VIP 尋寶',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_vip").get("finish_dig")%1000 <10},go:'#10 vip finish_dig;home;'},
                {n:'VIP 釣魚',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_vip").get("finish_diaoyu")%1000 <10},go:'#10 vip finish_diaoyu;home;'},
                {n:'VIP 暴擊',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_vip").get("do_task_num")%1000 <10},go:'#10 vip finish_big_task;home;'},
                {n:'VIP 師門',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_vip").get("family_quest_count")%1000 <25},go:'#25 vip finish_family;home;'},
                {n:'VIP 幫派',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0&&g_obj_map.get("msg_clan_view")&&g_obj_map.get("msg_vip").get("clan_quest_count")%1000 <20},go:'#20 vip finish_clan;home;'},
                {n:'VIP 掃盪',c:function(){return g_obj_map.get("msg_vip")&&g_obj_map.get("msg_vip").get("vip_tm")>0},fn:PLU.autoVipShaodan},

                {n:'銀兩上香',c:function(){return !!g_obj_map.get("msg_clan_view")},go:'#20 clan incense yx;home;'},
                {n:'洛陽採蓮',go:'jh 2;#19 n;e;n;n;n;w;event_1_31320275;home;'},
                {n:'破陣採礦',go:'jh 26;w;w;n;e;e;event_1_18075497;w;w;n;event_1_14435995;home;'},
                {n:'冰火玄鐵',go:'jh 35;nw;nw;nw;n;ne;nw;w;nw;e;e;e;e;e;se;n;n;w;n;w;event_1_53278632;sousuo;sousuo;home;'},
                {n:'絕情鱷魚',go:'jh 37;n;e;e;nw;nw;w;n;e;n;e;e;e;ne;ne;ne;se;n;event_1_97487911;home;'},
                {n:'唐門冰月',fn:PLU.autoBingyue},
                // {n:'六一禮包',go:'jh 1;;event_1_62732294;;jh 5;n;n;e;event_1_7839160;;event_1_68123816;;jh 1;;w;w;n;event_1_33671699;;home;'},
                {n:'',go:'home'},
            ]
        },

        //================================================================================================
        autoBingyue(callback){
            PLU.execActions('jh 14;w;n;n;n;n;event_1_32682066;;;',()=>{
                setTimeout(()=>{
                    PLU.killBingYue(()=>{
                        YFUI.showPop({
                            title:"冰月完成",
                            text:"是否"+(callback?"繼續?":"回首頁?"),
                            autoOk:10,
                            onOk(){
                                if(callback) callback();
                                else clickButton("home")
                            },
                            onNo(){

                            }
                        })
                    })
                },1000)
            });
        },
        //================================================================================================
        killBingYue(endCallback){
            if(parseInt(PLU.getCache('autoPerform'))<1){
                PLU.toggleAutoPerform($("#btn_bt_kg_autoPerform"), "autoPerform", 1)
            }
            let tryKill=function(kname, cb, er){
                PLU.autoFight({
                    targetName: kname,
                    fightKind: 'kill',
                    onFail(){
                        er && er()
                    },
                    onEnd(){
                        cb && cb()
                    }
                })
            }
            PLU.execActions('event_1_48044005;;;;',()=>{
                tryKill('冰麟獸',()=>{
                    PLU.execActions('event_1_95129086;;;;',()=>{
                        tryKill('玄武機關獸',()=>{
                            PLU.execActions('event_1_17623983;event_1_41741346;;;;',()=>{
                                tryKill('九幽魔靈',()=>{
                                    PLU.execActions('s;;;;',()=>{
                                        tryKill('冰月仙人',()=>{
                                            endCallback && endCallback()
                                        },()=>{
                                            endCallback && endCallback()
                                        })
                                    })
                                },()=>{
                                    endCallback && endCallback()
                                })
                            })
                        },()=>{
                            endCallback && endCallback()
                        })
                    })
                },()=>{
                    endCallback && endCallback()
                })
            })
        },
        //================================================================================================
        autoXTL1(){
            clickButton('team create')
            PLU.killLHYD(err=>{
                return YFUI.writeToOut("<span style='color:#FFF;'>結束--"+err+"</span>")
            })
        },
        autoXTL2(){
            clickButton('team create')
            PLU.killSY(err=>{
                return YFUI.writeToOut("<span style='color:#FFF;'>結束--"+err+"</span>")
            })
        },
        path4FHMJ(endCallback){
            PLU.execActions('jh');
            if(g_obj_map.get('msg_jh_list')&&g_obj_map.get('msg_jh_list').get('finish43') == 0){
                return 'jh 1;e;n;n;n;n;w;event_1_90287255 go 6;e;s;sw;se;ne;se;s;'
            }else{
                return 'jh 43;sw;sw;sw;s;se;se;se;e;s;sw;se;ne;se;s;';
            }
        },
        //琅嬛玉洞
        killLHYD(endCallback){
            PLU.execActions(PLU.path4FHMJ()+'event_1_52732806',(f)=>{
                if(!f) return endCallback && endCallback(1);
                PLU.execActions('kill langhuanyudong_qixing;;kill langhuanyudong_benkuangxiao;;sw;;kill murong_tuboguoshi;;;get?吐蕃國師的屍體;;',(f2)=>{
                    if(!f2) return endCallback && endCallback(2);
                    PLU.execActions('ne;n;;event_1_96023188;w;event_1_39972900;w;event_1_92817399;w;event_1_91110342;s;event_1_74276536;se;event_1_14726005;se;se;;;',()=>{
                        let sd=g_obj_map.get("msg_room").elements.find(e=>e.value.indexOf("掃盪")>=0)
                        if(sd) {
                            let cmd_sd=g_obj_map.get("msg_room").get(sd.key.split("_")[0])
                            PLU.doSaoDang("langhuanyudong", cmd_sd, ()=>{
                                PLU.killLHYD(endCallback)
                            })
                        }else{
                            endCallback && endCallback(5)
                        }
                    })
                })
            })
        },
        //山崖
        killSY(endCallback){
            PLU.execActions(PLU.path4FHMJ()+'event_1_64526228',(f)=>{
                if(!f) return endCallback && endCallback(1);
                PLU.execActions('kill shanya_muzhaoxue;;kill shanya_qiongduwu;;kill shanya_yuanzhenheshang;;;',(f2)=>{
                    if(!f2) return endCallback && endCallback(2);
                    PLU.execActions('w;event_1_61179401;n;event_1_93134350;n;event_1_60227051;n;event_1_66986009;;kill mingjiao_mengmianrentoumu;;;;get?蒙面人頭目的屍體;;',()=>{
                        PLU.execActions('n;event_1_53067175;n;event_1_58530809;w;event_1_86449371;event_1_66983665;;',()=>{
                            let sd=g_obj_map.get("msg_room").elements.find(e=>e.value.indexOf("掃盪")>=0)
                            if(sd) {
                                let cmd_sd=g_obj_map.get("msg_room").get(sd.key.split("_")[0])
                                PLU.doSaoDang("shanya", cmd_sd, ()=>{
                                    PLU.killSY(endCallback)
                                })
                            }else{
                                endCallback && endCallback(5)
                            }
                        })
                    })
                })
            })
        },
        //================================================================================================
        execActions(str,endcallback){
            var acs=str.split(';');
            acs=acs.map(e=>{
                let np=e.match(/^#(\d+)\s(.*)/)
                if(np) {
                    let r=[];
                    for(let i=0;i<np[1];i++) r.push(np[2])
                    return r;
                };
                return e
            }).flat()
            acs=acs.map(e=>{
                if(PLU.YFD.pathCmds[e]) return PLU.YFD.pathCmds[e]+'.'+UTIL.rnd()
                return e
            })
            PLU.actions({
                paths:acs,
                idx:0,
                onPathsEnd(){
                    PLU.STATUS.isBusy = false
                    endcallback && endcallback(true)
                },
                onPathsFail(){
                    PLU.STATUS.isBusy = false
                    endcallback && endcallback(false)
                },
            })
        },
        //================================================================================================
        actions(params){
            PLU.STATUS.isBusy = true;
            //params:{paths,idx,onPathsEnd,onPathsFail}
            if(params.idx>=params.paths.length){
                return params.onPathsEnd && params.onPathsEnd()
            };
            let curAct = params.paths[params.idx]
            //null
            if(!curAct){
                setTimeout(()=>{
                    params.idx++
                    PLU.actions(params)
                }, 250);
                return
            }
            //去殺
            if (curAct.indexOf("kill?") > -1 || curAct.indexOf("kill ") > -1) {
                let kt = (parseInt(PLU.getCache('autoPerform'))<1)?'multi':'';
                PLU.autoFight({
                    targetName:curAct.indexOf("kill?") > -1?curAct.substring(5):null,
                    targetKey:curAct.indexOf("kill ") > -1?curAct.substring(5):null,
                    fightKind:'kill',
                    autoSkill:kt,
                    onFail(){
                        //params.retry = (params.retry||0) + 1;
                        //if(params.retry>0){
                        setTimeout(()=>{
                            params.idx++
                            PLU.actions(params)
                        }, 500);
                    },
                    onEnd(){
                        setTimeout(()=>{
                            params.idx++
                            PLU.actions(params)
                        }, 500);
                    }
                })
                return
            }
            // 去摸屍體
            if (curAct.indexOf("get?") > -1) {
                UTIL.getItemFrom(curAct.substring(4))
                setTimeout(()=>{
                    params.idx++
                    PLU.actions(params)
                }, 500);
                return
            }
            // 去摸屍體
            if (curAct.indexOf("@") > -1) {
                UTIL.getItemFrom(curAct.substring(1))
                setTimeout(()=>{
                    params.idx++
                    PLU.actions(params)
                }, 500);
                return
            }
            // 叫船
            if (curAct.indexOf("yell") > -1) {
                let yellBoatTimeout = setTimeout(e=>{
                    clearTimeout(yellBoatTimeout)
                    UTIL.delSysListener("goYellBoat")
                    params.idx++
                    PLU.actions(params)
                },120000)
                UTIL.addSysListener("goYellBoat", function(b, type, subtype, msg) {
                    if (type == "main_msg" && msg.indexOf("還沒有達到這") > -1) {
                        setTimeout(()=>{
                            clearTimeout(yellBoatTimeout)
                            UTIL.delSysListener("goYellBoat")
                            PLU.actions(params)
                        }, 2000);
                        return
                    }
                    if (type == "notice" && msg.indexOf("這兒沒有船可以喊") > -1){
                        setTimeout(()=>{
                            clearTimeout(yellBoatTimeout)
                            UTIL.delSysListener("goYellBoat")
                            params.idx++
                            PLU.actions(params)
                        }, 500);
                        return;
                    }
                    if (type != "jh" || subtype != "info") return;
                    for (var key of b.keys()) {
                        var val = b.get(key);
                        if (val.indexOf("yell") < 0) continue
                        clearTimeout(yellBoatTimeout)
                        UTIL.delSysListener("goYellBoat")
                        params.idx++
                        PLU.actions(params)
                        break;
                    }
                })
                clickButton(curAct)
                return;
            }
            //函式
            if (curAct.indexOf("eval_") > -1) {
                eval(curAct.substring(5));
                setTimeout(()=>{
                    params.idx++
                    PLU.actions(params)
                }, 500);
                return;
            }
            //檢查地點重走
            if (curAct.indexOf("place?") > -1) {
                var pName = curAct.split(/[?:]/)[1];
                var curName = UTIL.filterMsg(g_obj_map.get("msg_room").get("short")||'');
                var backStep = curAct.split(/[?:]/)[2];
                // 未到達指定地,重新走
                if (pName != curName) {
                    if(backStep){ //退後幾步
                        params.idx-=Number(backStep)
                        PLU.actions(params)
                        return
                    }
                    params.idx=0
                    PLU.actions(params)
                    return;
                }
                // 已到達指定地點,繼續下一個
                params.idx++
                PLU.actions(params)
                return;
            }
            //稱號飛修正
            if (curAct.indexOf("rank go") > -1) {
                let m = curAct.match(/rank go (\d+)/)
                if(m && m[1]){
                    curAct = 'rank go '+(Number(m[1])+1)
                }
            }
            //look,ask,
            if(curAct.match(/look|ask|get|buy|home|prev|moke|sort|share|sign|sleep|exercise|clan|work|vip |event_|lq_|wear |wield |remove |unwield/)){
                clickButton(curAct)
                setTimeout(()=>{
                    params.idx++
                    PLU.actions(params)
                },300);
                return;
            }
            //行動
            PLU.go({
                action:curAct,
                onEnd(){
                    if(params.idx+1>=params.paths.length){
                        return params.onPathsEnd && params.onPathsEnd()
                    }
                    params.idx++
                    PLU.actions(params)
                },
                onFail(flag){
                    if(flag && PLU.STATUS.inBattle){
                        PLU.autoEscape({
                            onEnd(){
                                setTimeout(()=>{
                                    PLU.actions(params)
                                },1000)
                            }
                        })
                        return
                    }else if(flag){
                        if(PLU.STO.REGO){
                            clearTimeout(PLU.STO.REGO)
                            PLU.STO.REGO = null
                        }
                        PLU.STO.REGO = setTimeout(()=>{
                            params.idx++
                            PLU.actions(params)
                        },1000)
                    }else{
                        params.onPathsFail && params.onPathsFail()
                    }
                },
            })
        },
        //================================================================================================
        go({action,onEnd,onFail}){
            if(!action) return onEnd && onEnd(false)
            let clearGoTimeout = function(timeoutKey){
                clearTimeout(timeoutKey)
                timeoutKey=null
                UTIL.delSysListener("goMove")
            };
            let goTimeout = setTimeout(function(){
                clearGoTimeout(goTimeout)
                onEnd && onEnd(false)
            },2000)
            UTIL.addSysListener("goMove", function(b, type, subtype, msg) {
                if (type == "notice" && subtype == "notify_fail") {
                    if (msg.indexOf("你正忙著呢") > -1) {
                        clearGoTimeout(goTimeout)
                        return onFail && onFail(true)
                    }
                    if (msg.indexOf("無法走動") > -1 ||
                        msg.indexOf("沒有這個方向") > -1 ||
                        msg.indexOf("只有VIP才可以直接去往此地") > -1 ||
                        msg.indexOf("你什麼都沒發覺") > -1 ||
                        msg.indexOf("就此鑽入恐有辱墓主") > -1 ||
                        msg.indexOf("你雖知這松林內有乾坤,但並沒發現任何線索") > -1 ||
                        msg.indexOf("此地圖還未解鎖,請先通關前面的地圖。") > -1
                       ) {
                        clearGoTimeout(goTimeout)
                        return onFail && onFail(false,msg)
                    }
                }
                if (type == "unknow_command" || (type == "jh" && subtype == "info")) {
                    clearGoTimeout(goTimeout)
                    setTimeout(function(){
                        onEnd && onEnd(true)
                    },200)
                    return;
                }
            })
            clickButton(action)
        },
        //================================================================================================
        fastExec(str,endcallback){
            var acs=str.split(';');
            acs=acs.map(e=>{
                let np=e.match(/^#(\d+)\s(.*)/)
                if(np) {
                    let r=[];
                    for(let i=0;i<np[1];i++) r.push(np[2])
                    return r;
                };
                return e
            }).flat()
            acs=acs.map(e=>{
                if(PLU.YFD.pathCmds[e]) return PLU.YFD.pathCmds[e]+'.'+UTIL.rnd()
                return e
            })
            let fastFunc=function(acts,idx){
                if(idx>=acts.length){
                    setTimeout(()=>{
                        endcallback && endcallback(true);
                    }, 1000);
                    return
                }
                let curAct = acts[idx]
                if(!curAct) return fastFunc(acts, idx+1);
                clickButton(curAct)
                setTimeout(()=>{
                    fastFunc(acts, idx+1)
                }, 200);
                return
            }
            fastFunc(acs,0)
        },
        //================================================================================================
        selectSkills(skillName){
            if(!PLU.battleData || !PLU.battleData.skills) return null;
            let keys=Object.keys(PLU.battleData.skills);
            if(skillName){
                for(let i=0;i<keys.length;i++){
                    let sk = PLU.battleData.skills[keys[i]]
                    if(sk && sk.name && sk.name.match(skillName)) return sk;
                }
            }else{
                let n=Math.floor(keys.length*Math.random())
                return PLU.battleData.skills[keys[n]]
            }
            return null
        },
        //================================================================================================
        autoFight(params){
            if(PLU.STO.autoF){
                clearTimeout(PLU.STO.autoF);
                PLU.STO.autoF=null;
            };
            if(!params.targetKey && !params.targetName){
                params.onFail && params.onFail(0)
                YFUI.writeToOut("<span style='color:#FFF;'>--戰鬥參數缺失--</span>")
                return
            };
            if(params.targetName && !params.targetKey){
                let npcObj = UTIL.findRoomNpc(params.targetName,false,true)
                if(npcObj){
                    params.targetKey = npcObj.key
                }else{
                    params.onFail && params.onFail(1)
                    YFUI.writeToOut("<span style='color:#FFF;'>--找不到NPC--</span>")
                    return
                }
            }
            let fightAct = params.fightKind=="fight" ? 'fight' : 'kill';
            let performTime = 0
            UTIL.addSysListener("onAutoFight", function(b, type, subtype, msg) {
                if(type=="vs" && subtype=="vs_info"){
                    setTimeout(()=>{
                        if(params.autoSkill && PLU.battleData) PLU.battleData.autoSkill = params.autoSkill;
                    },100)
                    if(PLU.TMP.loopCheckFight){
                        clearInterval(PLU.TMP.loopCheckFight)
                        PLU.TMP.loopCheckFight=null;
                    }
                    PLU.TMP.loopCheckFight = setInterval(()=>{
                        if(!g_gmain.is_fighting){
                            UTIL.delSysListener("onAutoFight")
                            if(PLU.STO.autoF){
                                clearTimeout(PLU.STO.autoF);
                                PLU.STO.autoF=null;
                            };
                            if(PLU.TMP.loopCheckFight){
                                clearInterval(PLU.TMP.loopCheckFight)
                                PLU.TMP.loopCheckFight=null;
                            }
                            params.onEnd && params.onEnd()
                        }
                    },2000)
                    params.onStart && params.onStart()
                }else if(type=="vs" && (subtype=="add_xdz" || subtype=="text" || subtype=="attack")){
                    let curTime=new Date().getTime();
                    if(curTime-performTime<500) return;
                    performTime = curTime;
                    let useSkill = null;
                    if(params.autoSkill){
                        if(!PLU.battleData || PLU.battleData.xdz<2) return;
                        if(params.autoSkill=="item"){
                            if(PLU.battleData.xdz>=6) useSkill={key:'playskill 7'}; else useSkill={};
                        }else if(params.autoSkill=="dodge"){
                            if(PLU.battleData.xdz>9) useSkill=PLU.selectSkills(/乾坤大挪移|凌波微步|無影毒陣|九妙飛天術/)
                        }else if(params.autoSkill=="multi"){
                            if(PLU.battleData.xdz>2) useSkill=PLU.selectSkills(/破軍棍法|千影百傷棍|八荒功|月夜鬼蕭|打狗棒法/)
                        }else if(params.autoSkill=="fast"){
                            if(PLU.battleData.xdz>=2) useSkill=PLU.selectSkills(/吸星大法|斗轉星移|無影毒陣|空明拳|乾坤大挪移/)
                        };
                        if(!useSkill){
                            if(PLU.getCache("autoPerform")>=1) {
                                PLU.battleData.autoSkill = '';
                                return;
                            }
                            if(params.autoSkill) PLU.battleData.autoSkill = '';
                            useSkill=PLU.selectSkills()
                        }
                        if(params.onFighting){
                            let block = params.onFighting(useSkill)
                            if(block) return;
                        }
                        useSkill && clickButton(useSkill.key,0)
                    }else{
                        params.onFighting && params.onFighting()
                    };
                }else if(type=="vs" && subtype=="combat_result"){
                    performTime = 0;
                    UTIL.delSysListener("onAutoFight")
                    if(PLU.STO.autoF){
                        clearTimeout(PLU.STO.autoF);
                        PLU.STO.autoF=null;
                    };
                    if(PLU.TMP.loopCheckFight){
                        clearInterval(PLU.TMP.loopCheckFight)
                        PLU.TMP.loopCheckFight=null;
                    }
                    clickButton('prev_combat')
                    params.onEnd && params.onEnd()
                }else if(type=="notice" && subtype=="notify_fail"){
                    let errCode = 0
                    if(msg.indexOf("沒有這個人")>-1){
                        errCode = 1
                    }else if(msg.indexOf("你正忙著呢")>-1){
                        errCode = 2
                    }else if(msg.indexOf("已經超量")>-1){
                        errCode = 3
                    }else if(msg.indexOf("已達到上限")>-1){
                        errCode = 4
                    }else if(msg.indexOf("太多人了")>-1){
                        errCode = 5
                    }else if(msg.indexOf("不能戰鬥")>-1){
                        errCode = 6
                    }else if(msg.indexOf("秒後才能攻擊這個人")>-1){
                        let sat = msg.match(/(\d+)秒後才能攻擊這個人/)
                        if(sat) errCode = 'delay_'+sat[1];
                        else errCode = 77
                    }else if(msg.indexOf("先觀察一下")>-1){
                        errCode = 88
                    }else{
                        if(!PLU.STATUS.inBattle){
                            errCode = 99
                        }
                    }
                    UTIL.delSysListener("onAutoFight");
                    if(PLU.STO.autoF){
                        clearTimeout(PLU.STO.autoF);
                        PLU.STO.autoF=null;
                    };
                    if(PLU.TMP.loopCheckFight){
                        clearInterval(PLU.TMP.loopCheckFight)
                        PLU.TMP.loopCheckFight=null;
                    }
                    params.onFail && params.onFail(errCode)
                }
            })
            PLU.STO.autoF=setTimeout(()=>{
                PLU.STO.autoF=null;
                if(!g_gmain.is_fighting){
                    UTIL.delSysListener("onAutoFight");
                    if(PLU.TMP.loopCheckFight){
                        clearInterval(PLU.TMP.loopCheckFight)
                        PLU.TMP.loopCheckFight=null;
                    }
                    return params.onFail && params.onFail(100);
                }
            },300000);
            clickButton(fightAct+' '+params.targetKey,0)

        },
        //================================================================================================
        autoEscape(params){
            if(!PLU.STATUS.inBattle) return params.onEnd && params.onEnd();
            let lastEscapeTime = new Date().getTime()
            UTIL.addSysListener("onAutoEscape", function(b, type, subtype, msg) {
                if(type=="vs" && subtype=="combat_result"){
                    UTIL.delSysListener("onAutoEscape")
                    clickButton('prev_combat');
                    return params.onEnd && params.onEnd();
                }else if(type=="vs" && (subtype=="add_xdz" || subtype=="text" || subtype=="attack")){
                    let nt = new Date().getTime()
                    if(nt-lastEscapeTime > 500){
                        lastEscapeTime = nt
                        clickButton('escape');
                    }
                }
            })
        },
        //================================================================================================
        setBtnRed($btn, flag, sColr){
            if(!PLU.ONOFF[$btn[0].id+'_color']) {
                PLU.ONOFF[$btn[0].id+'_color']=$btn.css("background-color")
                let carr=PLU.ONOFF[$btn[0].id+'_color'].split(/[\D\s]+/);
                carr.pop();carr.shift();
                if(carr[0]==carr[1] && carr[1]==carr[2]) {carr[1]=carr[1]-32;carr[2]=carr[2]-32;}
                let m=carr.reduce((a,b)=>(Number(a)+Number(b))/2);
                let narr=carr.map(e=>{return Math.min(e-96+4*(e-m),256)})
                PLU.ONOFF[$btn[0].id+'_colorDark']='rgb('+narr.join(',')+')'
            }
            if(flag==undefined){
                if(PLU.ONOFF[$btn[0].id]){
                    PLU.ONOFF[$btn[0].id]=0;
                    $btn.css({background:PLU.ONOFF[$btn[0].id+'_color'],color:'#000'})
                    return 0
                }else{
                    PLU.ONOFF[$btn[0].id]=1;
                    $btn.css({background:PLU.ONOFF[$btn[0].id+'_colorDark'],color:'#FFF'})
                    return 1
                }
            }else{
                PLU.ONOFF[$btn[0].id]=flag;
                let colr=sColr || PLU.ONOFF[$btn[0].id+'_color'], fcolr = '#000';
                if(flag){
                    colr=sColr || PLU.ONOFF[$btn[0].id+'_colorDark']
                    fcolr = '#FFF'
                }
                $btn.css({background:colr,color:fcolr})
                return flag
            }
        },
        getBtnRed($btn){
            if(PLU.ONOFF[$btn[0].id]) return 1;
            return 0
        },
        //================================================================================================
        /*
        answerQues($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                PLU.STO.ansTo && clearTimeout(PLU.STO.ansTo);
                return UTIL.delSysListener("onAnswerQuestions")
            }
            YFUI.showPop({
                title:"答題",
                text:"是否開始答題?",
                onOk(){
                    PLU.loopAnswerQues($btn)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        }, */
        //================================================================================================
        loopAnswerQues($btn){
            let setAnswerTimeout=function(){
                PLU.STO.ansTo && clearTimeout(PLU.STO.ansTo);
                PLU.STO.ansTo = setTimeout(()=>{
                    UTIL.delSysListener("onAnswerQuestions")
                    PLU.setBtnRed($btn,0)
                    YFUI.writeToOut("<span style='color:#FFF;'>--答案超時!--</span>")
                    return
                },5000)
            };
            UTIL.addSysListener("onAnswerQuestions", function(b, type, subtype, msg) {
                if (type == "notice" && msg.indexOf("每日武林知識問答次數已經達到限額")>-1) {
                    UTIL.delSysListener("onAnswerQuestions")
                    PLU.STO.ansTo && clearTimeout(PLU.STO.ansTo);
                    PLU.setBtnRed($btn,0)
                    return;
                }
                if (type != "show_html_page") return;
                var qs = msg.split("\n");
                if (!qs) return;
                if (qs[0].indexOf("知識問答第") < 0)  return;
                setAnswerTimeout()
                var qus = "";
                for (var i = 1; i < qs.length; i++) {
                    qus = $.trim(UTIL.filterMsg(qs[i]));
                    if (qus.length > 0) break;
                }
                if (qus.indexOf("回答正確")>=0) {
                    clickButton('question')
                    return;
                }
                var answer = PLU.getAnswer2Question(qus);
                if (answer == null){
                    UTIL.delSysListener("onAnswerQuestions")
                    PLU.STO.ansTo && clearTimeout(PLU.STO.ansTo);
                    PLU.setBtnRed($btn,0)
                    YFUI.writeToOut("<span style='color:#FFF;'>--未找到答案:"+qus+"--</span>")
                    return
                }
                setTimeout(()=>{
                    clickButton("question " + answer);
                },300)
            })
            setAnswerTimeout()
            clickButton('question')
        },
        //================================================================================================
        getAnswer2Question(localQuestion) {
            var answer = PLU.YFD.QuestAnsLibs[localQuestion]
            if (answer) return answer;
            var halfQuestion = localQuestion.substring(localQuestion.length / 2)
            for (var quest in PLU.YFD.QuestAnsLibs) {
                if (quest.indexOf(halfQuestion) == 0) {
                    return PLU.YFD.QuestAnsLibs[quest];
                }
            }
            return null;
        },
        //================================================================================================
        toAutoChuaiMo($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                PLU.STATUS.isBusy = false
                PLU.TMP.CMSkill = null
                return
            }
            YFUI.showPop({
                title:"自動揣摩技能",
                text:"一鍵自動揣摩所有能揣摩的技能!(除了六陰追魂劍法)",
                onOk(){
                    PLU.autoChuaiMo()
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        toAutoGetKey($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return UTIL.delSysListener("listenGetKey")
            }
            clickButton('get yin yaoshi')
            UTIL.addSysListener("listenGetKey", function(b, type, subtype, msg) {
                if(g_obj_map.get("msg_room") && g_obj_map.get("msg_room").get("short").match(/匾後/)){
                    if(type=='jh'){
                        if(subtype=='new_item'){
                            if(b.get('id')=='yin yaoshi') clickButton('get yin yaoshi')
                        }else if(subtype=='info'){
                            clickButton('get yin yaoshi')
                        }
                    }
                }
            })
        },
        //================================================================================================
        toAutoMoke($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                PLU.STATUS.isBusy = false
                return
            }
            PLU.getAllItems(list=>{
                let daoItems=list.find(it=>!!it.name.match('玄鐵刻刀'))
                let daoNum = daoItems? daoItems.num : 0;
                let eqItems = list.filter(it=>!!(it.key.match(/(equip|weapon)_\S+8/)&&!it.key.match('_moke_')&&!it.key.match('_xinwu')&&!it.key.match('_barcer')))
                let myNum = 0
                eqItems && eqItems.forEach(eq=>{myNum+=eq.num});
                console.log(eqItems)
                YFUI.showPop({
                    title:"自動摹刻所有明月",
                    text:"一鍵自動摹刻所有明月裝備!<br><span style='color:#F00;font-weight:bold;'>注意準備足夠的刻刀!!!</span><br>當前玄鐵刻刀數量 <span style='color:#F00;'>"+daoNum+"</span><br>當前未摹刻明月裝備數量 <span style='color:#F00;'>"+myNum+"</span>",
                    onOk(){
                        PLU.autoMoke(eqItems)
                    },
                    onNo(){
                        PLU.setBtnRed($btn,0)
                    }
                })
            })
        },
        autoMoke(eqList){
            if(!PLU.ONOFF["btn_bt_autoMoke"]) return YFUI.writeToOut("<span style='color:#F0F;'> ==摹刻暫停!== </span>")
            if(eqList && eqList.length>0){
                let eq=eqList.pop(), mokeCmds='';
                mokeCmds
                for(var i=0;i<eq.num;i++){
                    mokeCmds +='moke '+eq.key+';'
                }
                PLU.execActions(mokeCmds, ()=>{
                    PLU.autoMoke(eqList)
                })
            }else{
                PLU.setBtnRed($("#btn_bt_autoMoke"),0)
                YFUI.writeToOut("<span style='color:yellow;'> ==摹刻完畢!== </span>")
            }
        },
        //================================================================================================
        toAutoKillZYY($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return UTIL.delSysListener("listenLoopKillZYY")
            }
            YFUI.showPop({
                title:"自動去刷祝玉妍",
                text:"自動去刷祝玉妍!<br><span style='color:#FFF;background:#F00;font-weight:bold;'>----- 注意: -----</span><br><span style='color:#F00;font-weight:bold;'>1、準備足夠的邪帝舍利!!!<br>2、不要有隊伍!!!<br>3、切記要打開自動技能陣!!!<br>4、要上足夠的保險卡!!!</span>",
                onOk(){
                    PLU.execActions('rank go 232;s;s;;;', ()=>{
                        PLU.loopKillZYY()
                    })
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                    UTIL.delSysListener("listenLoopKillZYY")
                }
            })
        },
        loopKillZYY(){
            UTIL.addSysListener("listenLoopKillZYY", function(b, type, subtype, msg) {
                if(type=="vs" && subtype=="combat_result"){
                    if(!PLU.ONOFF["btn_bt_autoKillZYY"]){
                        PLU.execActions(';;;n;',()=>{
                            YFUI.writeToOut("<span style='color:yellow;'>=====刷祝玉妍結束!!=====</span>")
                            UTIL.delSysListener("listenLoopKillZYY")
                        })
                    }else{
                        PLU.execActions(';;;n;s')
                    }

                }
            })
            clickButton('s')
        },
        //================================================================================================
        toAutoFB11($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return UTIL.delSysListener("listenFB11")
            }
            YFUI.showPop({
                title:"自動副本11",
                text:`自動打副本11!<br>
					<span style='color:#F00;font-weight:bold;'>----- 選擇要打的門 -----</span><br>
					<div style="font-size:12px;line-height:2;box">
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">8 懶惰<input type="checkbox" name="chkfb11" value="nw" checked/></label>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">1非時食<input type="checkbox" name="chkfb11" value="n" checked/></label>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">2 殺生<input type="checkbox" name="chkfb11" value="ne" checked/></label>
					<br>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">7 奢華<input type="checkbox" name="chkfb11" value="w" checked/></label>
					<span style="display:inline-block;width: 31%;color:#999;text-align:center;border:1px solid transparent;">初心之地</span>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">3 偷盜<input type="checkbox" name="chkfb11" value="e" checked/></label>
					<br>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">6 飲酒<input type="checkbox" name="chkfb11" value="sw" checked/></label>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">5 妄語<input type="checkbox" name="chkfb11" value="s" checked/></label>
					<label style="display:inline-block;width: 31%;text-align:center;border:1px solid #333;">4 淫邪<input type="checkbox" name="chkfb11" value="se" checked/></label><br>
					</div>
					<span style='color:#F00;font-weight:bold;'>1、在副本外開始腳本<br>2、記得要組隊<br></span>`,
                okText:'開始',
                onOk(){
                    let chks=$('input[name="chkfb11"]:checked')
                    let selects = [];
                    $.each(chks,(i,e)=>{selects.push(e.value);})
                    if(selects.length==0) return false
                    console.log(selects)
                    //PLU.TMP.chkTmpList=[]
                    //PLU.execActions('rank go 232;s;s;;;', ()=>{
                    PLU.autoFB11(selects)
                    //})
                    //UTIL.findRoomNpcReg
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                    UTIL.delSysListener("listenFB11")
                }
            })
        },
        autoFB11(){

        },
        killAllNpc(callback){
            let npcObj = UTIL.findRoomNpcReg('')
            if(npcObj){
                let needAutoSkill = PLU.getCache("autoPerform")>=1 ? null : 'multi';
                PLU.autoFight({
                    targetKey:npcObj.key,
                    fightKind:'kill',
                    autoSkill:needAutoSkill,
                    onFail(){
                        setTimeout(t=>{
                            PLU.killAllNpc(callback)
                        },1000)
                    },
                    onEnd(){
                        setTimeout(t=>{
                            PLU.killAllNpc(callback)
                        },500)
                    }
                })
            }else{
                callback && callback()
            }
        },
        //================================================================================================
        checkYouxia($btn){
            YFUI.showPop({
                title:"檢查入室遊俠技能",
                text:`選擇需要的對應技能:<br>
				<div style="font-size:15px;">
					<label style="display:inline-block;">內功:<input type="checkbox" name="chkskiyx" value="內功" checked/></label>&nbsp;
					<label style="display:inline-block;">輕功:<input type="checkbox" name="chkskiyx" value="輕功" checked/></label>&nbsp;
					<label style="display:inline-block;">劍法:<input type="checkbox" name="chkskiyx" value="劍法" checked/></label>&nbsp;
					<label style="display:inline-block;">掌法:<input type="checkbox" name="chkskiyx" value="掌法" checked/></label>&nbsp;
					<label style="display:inline-block;">刀法:<input type="checkbox" name="chkskiyx" value="刀法" checked/></label>&nbsp;
					<label style="display:inline-block;">暗器:<input type="checkbox" name="chkskiyx" value="暗器"/></label>&nbsp;
					<label style="display:inline-block;">鞭法:<input type="checkbox" name="chkskiyx" value="鞭法"/></label>&nbsp;
					<label style="display:inline-block;">槍法:<input type="checkbox" name="chkskiyx" value="槍法"/></label>&nbsp;
					<label style="display:inline-block;">錘法:<input type="checkbox" name="chkskiyx" value="錘法"/></label>&nbsp;
					<label style="display:inline-block;">斧法:<input type="checkbox" name="chkskiyx" value="斧法"/></label>
				</div>`,
                onOk(){
                    let chks=$('input[name="chkskiyx"]:checked')
                    let selects = [];
                    PLU.TMP.chkTmpList=[]
                    $.each(chks,(i,e)=>{selects.push(e.value);})
                    PLU.getSkillsList((allSkills, tupoSkills)=>{
                        PLU.getYouxiaList(yxs=>{
                            PLU.checkMySkills(allSkills, yxs, selects)
                        })
                    })
                },
                onNo(){

                }
            })
        },
        checkMySkills(mySkills, myYouxia, checkList){
            // console.log(mySkills, myYouxia, checkList)
            let clstr = '';checkList.forEach(c=>clstr+='【'+c[0]+'】')
            YFUI.writeToOut("<span style='color:#FFF;'>--技能檢測 <span style='color:yellow;'>"+clstr+"</span>--</span>")
            checkList.forEach(cn=>{
                let carr = PLU.YFD.youxiaSkillMap.filter(r=>r.type==cn)
                carr.forEach(n=>{
                    PLU.checkPreSKill(n,mySkills,myYouxia)
                })
            })
            if(PLU.TMP.chkTmpList.length==0){
                YFUI.writeToOut("<span style='color:yellow;'>檢查的技能都準備好了!</span>")
            }
        },
        checkPreSKill(node, mySkills, myYouxia){
            let ms = mySkills.find(s=>s.name==node.skill)
            if(!ms && !PLU.TMP.chkTmpList.includes(node.skill)){
                PLU.TMP.chkTmpList.push(node.skill)
                let clr = node.kind=='宗師'||node.kind=='俠客'? '#E93' : '#36E'
                let htm = '<span style="color:'+clr+';">【'+node.type[0]+'】'+node.skill+' '
                //htm+= ms?'<span style="color:#3F3;display:inline-block;">('+ms.level+')</span>':'(缺)';
                htm+= '<span style="color:#F00;display:inline-block;">(未學)</span>';
                let myx = myYouxia.find(y=>y.name.match(node.name))
                htm+= ' - '+(myx?'<span style="color:#3F3;display:inline-block;">'+myx.name+'['+myx.level+']</span>':'<span style="color:#F36;display:inline-block;">需要:<span style="color:#FFF;background:'+clr+';"> '+node.kind+'-'+node.name+' </span></span>');
                htm+= '</span>'
                YFUI.writeToOut(htm)
            }
            if(node.pre){
                node.pre.forEach(n=>{
                    PLU.checkPreSKill(n,mySkills,myYouxia)
                })
            }
        },
        getYouxiaList(callback){
            UTIL.addSysListener("getYouxiaList", function(b, type, subtype, msg) {
                if (type != "fudi" && subtype != "juxian") return;
                UTIL.delSysListener("getYouxiaList");
                clickButton("prev");
                let youxias = []
                for(var i=0;i<41;i++){
                    let str=b.get('yx'+i)
                    if(str){
                        let attr = str.split(',')
                        let ns = UTIL.filterMsg(attr[1]).split('】')
                        let nam = ns.length>1?ns[1]:ns[0]
                        youxias.push({
                            key:attr[0],
                            name:nam,
                            level: Number(attr[4]),
                            kind: attr[3],
                        })
                    }
                }
                callback(youxias);
            })
            clickButton('fudi juxian')
        },
        //================================================================================================
        toAutoLearn($btn){
            if(!PLU.TMP.MASTER_SKILLS){
                return YFUI.showPop({
                    title:"缺少數據",
                    text:"需要打開師傅技能界面",
                    // onOk(){
                    // },
                })
            }
            // console.log(PLU.TMP.MASTER_ID, PLU.TMP.MASTER_SKILLS)
            let needSkills = []
            PLU.getSkillsList((allSkills, tupoSkills)=>{
                PLU.TMP.MASTER_SKILLS.forEach(ms=>{
                    let sk = allSkills.find(s=>s.key==ms.key)||{level:0}
                    if(sk.level<ms.level){
                        needSkills.push({key:ms.key, name:ms.name, lvl:(ms.level-sk.level), cmd:'learn '+ms.key+' from '+PLU.TMP.MASTER_ID+' to 10'})
                    }
                })
                //console.log(needSkills.map(e=>e.name))
                loopLearn(needSkills)
            })
            let curSkill = null;
            UTIL.addSysListener("loopLearnSkill", function(b, type, subtype, msg) {
                if (type== "notice" && msg.indexOf("不願意教你")>=0){
                    //UTIL.delSysListener("loopLearnSkill");
                    if(curSkill) curSkill.lvl=-1;
                }
                return;
            })
            let loopLearn=function(list){
                if(list.length>0){
                    if(list[0].lvl>0){
                        list[0].lvl-=10;
                        curSkill = list[0]
                        clickButton(list[0].cmd)
                    }else{
                        list.shift()
                    }
                    setTimeout(()=>{
                        loopLearn(list)
                    },200)
                }else{
                    UTIL.delSysListener("loopLearnSkill");
                    YFUI.writeToOut("<span style='color:#FFF;'>----自動學習結束,記得檢查噢!----</span>")
                }
            }
            },
        //================================================================================================
        autoChuaiMo(){
            if(!PLU.ONOFF["btn_bt_autoChuaiMo"]) return;
            PLU.STATUS.isBusy = true
            if(!PLU.TMP.CMSkill){
                PLU.getSkillsList((allSkills, tupoSkills)=>{
                    if(!PLU.TMP.CANTCMS) PLU.TMP.CANTCMS=[];
                    PLU.TMP.CMSkill = allSkills.find(
                        e=>e.level>=500&&e.level<600&&e.name!='六陰追魂劍法'&&(e.kind=='attack'||e.kind=='recovery'||e.kind=='force')&&(!PLU.TMP.CANTCMS.includes(e.name))
                    )
                    if(!PLU.TMP.CMSkill){
                        PLU.STATUS.isBusy = false
                        PLU.TMP.CMSkill = null
                        PLU.setBtnRed($("#btn_bt_autoChuaiMo"),0)
                    }else{
                        clickButton('enable '+PLU.TMP.CMSkill.key)
                        UTIL.addSysListener("listenChuaiMo", function(b, type, subtype, msg) {
                            if (type== "notice" && (msg.indexOf("揣摩最高等級為")>=0 || msg.indexOf("這項技能不能揣摩")>=0)){
                                UTIL.delSysListener("listenChuaiMo");
                                if(msg.indexOf("這項技能不能揣摩")>=0){
                                    PLU.TMP.CANTCMS.push(PLU.TMP.CMSkill.name)
                                }
                                YFUI.writeToOut("<span style='color:#FFF;'>--揣摩結束--</span>")
                                PLU.TMP.CMSkill = null;
                            }
                            return;
                        })
                    }
                    PLU.autoChuaiMo()
                })
            }else{
                clickButton('chuaimo go,'+PLU.TMP.CMSkill.key,0)
                setTimeout(e=>{
                    PLU.autoChuaiMo()
                },250)
            }
        },
        //================================================================================================
        toAutoTeach($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                PLU.STATUS.isBusy = false
                PLU.TMP.TeachSkill = null
                return
            }
            YFUI.showPop({
                title:"自動傳授遊俠技能",
                text:"一鍵自動傳授遊俠技能!<b style='color:#F00;'>需要點開遊俠技能界面,需要傳授的技能不能為0級</b>",
                onOk(){
                    PLU.autoTeach()
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        autoTeach(){
            if(!PLU.ONOFF["btn_bt_autoTeach"]) return;
            PLU.STATUS.isBusy = true
            if(PLU.TMP.CUR_YX_SKILLS){
                let ac = PLU.TMP.CUR_YX_SKILLS.find(e=> Number(e.lvl)>0 && Number(e.lvl)<Number(e.max))
                if(ac){
                    clickButton(ac.cmd,0)
                    setTimeout(e=>{
                        PLU.autoTeach()
                    },200)
                }else{
                    YFUI.writeToOut("<span style='color:#FFF;'>--傳授結束--</span>")
                    PLU.STATUS.isBusy = false
                    PLU.setBtnRed($("#btn_bt_autoTeach"),0)
                }
            }else{
                PLU.STATUS.isBusy = false
                PLU.setBtnRed($("#btn_bt_autoTeach"),0)
            }
        },
        //================================================================================================
        toAutoUpgrade($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                PLU.STATUS.isBusy = false
                PLU.TMP.TeachSkill = null
                return
            }
            YFUI.showPop({
                title:"自動升級遊俠等級",
                text:"一鍵升級遊俠等級!<b style='color:#F00;'>需要點開遊俠技能界面</b>",
                onOk(){
                    PLU.autoUpgrade()
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        // 今天提升鳩摩智等級的次數已達到上限了。
        //不能提升阿朱的等級。
        //遊俠等級超過上限了。
        //================================================================================================
        autoUpgrade(){
            if(!PLU.ONOFF["btn_bt_autoUpgrade"]) return;
            PLU.STATUS.isBusy = true
            if(PLU.TMP.CUR_YX_LEVEL && PLU.TMP.CUR_YX_SKILLS && PLU.TMP.CUR_YX_ENG){
                if(PLU.TMP.CUR_YX_SKILLS.length>4 && PLU.TMP.CUR_YX_LEVEL<2000){
                    var canUpgrade = true;
                    UTIL.addSysListener("listenAutoUpgrade", function(b, type, subtype, msg) {
                        if (type== "notice" && (msg.indexOf("等級的次數已達到上限了")>=0 || msg.indexOf("不能提升")>=0 || msg.indexOf("等級超過上限了")>=0)){
                            UTIL.delSysListener("listenAutoUpgrade");
                            canUpgrade = false;
                            PLU.STATUS.isBusy = false
                            YFUI.writeToOut("<span style='color:#FFF;'>--升級結束--</span>")
                            PLU.setBtnRed($("#btn_bt_autoUpgrade"),0)
                        }
                        return;
                    })
                    clickButton('fudi juxian upgrade go '+PLU.TMP.CUR_YX_ENG+' 100')
                    setTimeout(e=>{
                        if(canUpgrade) PLU.autoUpgrade();
                    },500)
                }else{
                    YFUI.writeToOut("<span style='color:#FFF;'>--升級結束--</span>")
                    PLU.STATUS.isBusy = false
                    PLU.setBtnRed($("#btn_bt_autoUpgrade"),0)
                }
            }else{
                PLU.STATUS.isBusy = false
                PLU.setBtnRed($("#btn_bt_autoUpgrade"),0)
            }
        },
        //================================================================================================
        toLoopKillByN($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $("#btn_bt_loopKillByN").text('計數擊殺')
                return
            }
            clickButton('golook_room');
            YFUI.showInput({
                title:"計數擊殺",
                text:"輸入數量,確定後單擊怪!!(數量後帶小數點為比試)",
                value:PLU.getCache("lookKillNum")||20,
                onOk(val){
                    if(!Number(val)) return;
                    setTimeout(o=>{
                        $(document).one('click',o=>{
                            let snpc = $(o.target).closest('button')[0].outerHTML.match(/clickButton\('look_npc (\w+)'/i)
                            if(snpc && snpc.length>=2){
                                let kf=String(val).indexOf('.')>0 ? 'fight' : 'kill'
                                PLU.setCache("lookKillNum",Number(val))
                                PLU.loopKillByN(snpc[1],parseInt(val),kf)
                            }else{
                                PLU.setBtnRed($btn,0)
                            }
                        })
                    },500)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopKillByN(npcId,killN, killorfight){
            if(killN<=0 || !PLU.ONOFF["btn_bt_loopKillByN"]) return;
            $("#btn_bt_loopKillByN").text('停('+killN+')');
            PLU.autoFight({
                targetKey:npcId,
                fightKind: killorfight,
                autoSkill:'fast',
                onFail(){
                    setTimeout(t=>{
                        PLU.loopKillByN(npcId,killN, killorfight)
                    },500)
                },
                onEnd(){
                    if(killN<=1){
                        PLU.setBtnRed($("#btn_bt_loopKillByN"),0)
                        $("#btn_bt_loopKillByN").text('計數擊殺')
                        clickButton('home',1);
                        return
                    }else{
                        setTimeout(t=>{
                            PLU.loopKillByN(npcId,killN-1, killorfight)
                        },500)
                    }
                }
            })
        },
        //================================================================================================
        toLoopKillName($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $("#btn_bt_loopKillName").text('名字連殺')
                return
            }
            YFUI.showInput({
                title:"名字連殺",
                text:`格式:次數|人物詞組<br>
						次數:省略則默認1次<br>
						人物詞組:以英文逗號分割多個關鍵詞<br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">99|鐵狼軍,銀狼軍,金狼軍,金狼將,十夫長,百夫長,千夫長</span><br>
						[例2] <span style="color:blue;">醉漢,收破爛的</span>;
						`,
                value:PLU.getCache("lookKillNames")||'299|鐵狼軍,銀狼軍,金狼軍,金狼將,十夫長,百夫長,千夫長',
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val), times=1, names='', arr=str.split('|');
                    if(arr.length>1){
                        times = Number(arr[0]) || 1;
                        names = arr[1];
                    }else{
                        names = arr[0];
                    }
                    PLU.setCache("lookKillNames",str)
                    PLU.loopKillName(names,Number(times))
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopKillName(names,killN){
            if(killN<=0 || !PLU.ONOFF["btn_bt_loopKillName"]) return;
            $("#btn_bt_loopKillName").text('停擊殺('+killN+')');
            let npcObj = null, namesArr=names.split(',');
            for(let i=0;i<namesArr.length;i++){
                npcObj = UTIL.findRoomNpc(namesArr[i],false,true)
                if(npcObj) break;
            }
            if(npcObj){
                let needAutoSkill = PLU.getCache("autoPerform")>=1 ? null : 'multi';
                PLU.autoFight({
                    targetKey:npcObj.key,
                    fightKind:'kill',
                    autoSkill:needAutoSkill,
                    onFail(){
                        setTimeout(t=>{
                            PLU.loopKillName(names,killN)
                        },1000)
                    },
                    onEnd(){
                        if(killN<=1){
                            PLU.setBtnRed($("#btn_bt_loopKillName"),0)
                            $("#btn_bt_loopKillName").text('名字連殺')
                            return
                        }else{
                            setTimeout(t=>{
                                PLU.loopKillName(names,killN-1)
                            },1000)
                        }
                    }
                })
            }else{
                setTimeout(t=>{
                    PLU.loopKillName(names,killN)
                },2000)
            }
        },
        //================================================================================================
        toLoopKill($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                // $("#btn_bt_kg_loopKill").text('循環殺')
                return
            }
            YFUI.showInput({
                title:"循環殺",
                text:`格式:名字詞組<br>
						名字詞組:以英文逗號分割多個關鍵詞, <b style="color:red;">可模糊匹配!</b><br>
						<span style="color:red;">不需要戰鬥時建議關閉以節省性能!!</span><br>
						[例1] <span style="color:blue;">鐵狼軍,銀狼軍,金狼軍,金狼將,十夫長,百夫長,千夫長,蠻荒鐵,蠻荒銀,蠻荒金,寨近衛,蠻荒近衛</span><br>
						`,
                type:"textarea",
                value:PLU.getCache("lookKillKeys")||'怯薛軍,蒙古突騎,草原槍騎,重裝鐵騎,狼軍,狼將,夫長,蠻荒,近衛',
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val), names=str.split(/[,,#]/);
                    PLU.setCache("lookKillKeys",str)
                    PLU.loopKills(str)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopKills(names){
            if(!PLU.ONOFF["btn_bt_kg_loopKill"]) return;
            // $("#btn_bt_kg_loopKill").text('停循環');
            let npcObj = null, namesArr=names.split(/[,,#]/);
            for(let i=0;i<namesArr.length;i++){
                npcObj = UTIL.findRoomNpcReg(namesArr[i])
                if(npcObj) break;
            }
            if(npcObj){
                let needAutoSkill = PLU.getCache("autoPerform")>=1 ? null : 'multi';
                PLU.autoFight({
                    targetKey:npcObj.key,
                    fightKind:'kill',
                    autoSkill:needAutoSkill,
                    onFail(){
                        setTimeout(t=>{
                            PLU.loopKills(names)
                        },1000)
                    },
                    onEnd(){
                        setTimeout(t=>{
                            PLU.loopKills(names)
                        },500)
                    }
                })
            }else{
                setTimeout(t=>{
                    PLU.loopKills(names)
                },1000)
            }
        },
        //================================================================================================
        toLoopReadBase($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                // $("#btn_bt_loopReadBase").text('讀技能書')
                return
            }
            YFUI.showInput({
                title:"讀書還神",
                text:`格式:比試NPC名稱|基礎秘籍名稱<br>
						比試NPC名稱:要比試進行回神的NPC名字<br>
						基礎秘籍名稱:基礎秘籍名稱關鍵詞<br>
						<span style="color:red;">戰鬥必刷道具欄必須用還神丹</span><br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">地痞|基本劍法秘籍</span>
						`,
                value:PLU.getCache("loopReadBase")||'地痞|基本劍法秘籍',
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val),
                        npcName='',
                        bookName='',
                        arr=str.split('|');
                    if(arr.length>1){
                        npcName = arr[0];
                        bookName = arr[1];
                        PLU.setCache("loopReadBase",str)
                        PLU.getAllItems(list=>{
                            let bookItem=list.find(it=>!!it.name.match(bookName))
                            let reN = Math.floor(g_obj_map.get('msg_attrs').get('max_shen_value')/55) || 1;
                            console.log(npcName,bookItem.key, reN)
                            if(bookItem){
                                PLU.toggleAutoPerform($("#btn_bt_kg_autoPerform"), "autoPerform", 0)
                                PLU.loopReadBase(npcName,bookItem.key, reN)
                            }
                        })
                    }else{
                        PLU.setBtnRed($btn,0)
                        return
                    }
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        loopReadBase(npcName, bookKey, reN){
            //你使用了一本

            //你的神值不足:10以上。
            //你目前不能使用
            //使用技能等級為
            if(!PLU.ONOFF["btn_bt_loopReadBase"]){
                UTIL.delSysListener("listenLoopReadBase");
                YFUI.writeToOut("<span style='color:#FFF;'>--讀基本技能書停止--</span>")
                PLU.setBtnRed($("#btn_bt_loopReadBase"),0)
                return;
            }
            UTIL.addSysListener("listenLoopReadBase", function(b, type, subtype, msg) {
                if(type== "main_msg" && msg.indexOf("你使用了一本")>=0){
                    UTIL.delSysListener("listenLoopReadBase");
                    setTimeout(()=>{
                        PLU.loopReadBase(npcName, bookKey, reN)
                    },500)
                }else if(type== "notice" && msg.indexOf("你的神值不足")>=0){
                    UTIL.delSysListener("listenLoopReadBase");
                    setTimeout(()=>{
                        let refreshNumber = 0
                        PLU.autoFight({
                            targetName: npcName,
                            fightKind: 'fight',
                            autoSkill: 'item',
                            onStart(){
                                console.log('start fight==')
                            },
                            onFighting(ps){
                                if(refreshNumber >= reN) return true;
                                if(ps && ps.key=='playskill 7'){
                                    refreshNumber++;
                                    console.log(ps.key, refreshNumber , reN)
                                    if(refreshNumber >= reN){
                                        PLU.autoEscape({})
                                    }
                                }
                            },
                            onFail(err){
                                console.log(err)
                                setTimeout(()=>{
                                    PLU.loopReadBase(npcName, bookKey, reN)
                                },1000)
                            },
                            onEnd(e){
                                setTimeout(()=>{
                                    PLU.loopReadBase(npcName, bookKey, reN)
                                },1000)
                            }
                        })
                    },500)
                }else if(type== "notice" && msg.indexOf("使用技能等級為")>=0){
                    UTIL.delSysListener("listenLoopReadBase");
                    YFUI.writeToOut("<span style='color:#FFF;'>--讀基本技能書結束--</span>")
                    PLU.setBtnRed($("#btn_bt_loopReadBase"),0)
                }else if(type== "notice" && msg.indexOf("你的揹包裡沒有這個物品")>=0){
                    YFUI.writeToOut("<span style='color:#FFF;'>--讀基本技能書停止--</span>")
                    PLU.setBtnRed($("#btn_bt_loopReadBase"),0)
                }
                return;
            })
            let cmds = 'items use '+bookKey;
            PLU.execActions(cmds)
        },
        //================================================================================================
        toSearchBangQS($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return
            }
            YFUI.showInput({
                title:"搜索幫派任務",
                text:`格式:任務包含的關鍵字,多個以英文逗號分隔<br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">硫磺,黝黑山洞</span>
						`,
                value:PLU.getCache("searchBangQS")||'硫磺,黝黑山洞',
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val),
                        arr=str.split(',');
                    if(arr.length>1){
                        PLU.setCache("searchBangQS",str)
                        clickButton('clan scene', 0)
                        PLU.loopSearchBangQS(arr)
                    }else{
                        PLU.setBtnRed($btn,0)
                        return
                    }
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        loopSearchBangQS(keys, cmd){
            if(!PLU.ONOFF["btn_bt_searchBangQS"]){
                UTIL.delSysListener("listenLoopSearchBangQS");
                YFUI.writeToOut("<span style='color:#FFF;'>--停止搜索--</span>")
                PLU.setBtnRed($("#btn_bt_searchBangQS"),0)
                return;
            }
            UTIL.addSysListener("listenLoopSearchBangQS", function(b, type, subtype, msg) {
                if(type== "main_msg"){
                    if(msg.indexOf('幫派使者一拂袖')>=0 || msg.indexOf('幫派使者:現在沒有任務')>=0){
                        UTIL.delSysListener("listenLoopSearchBangQS");
                        setTimeout(()=>{
                            PLU.loopSearchBangQS(keys)
                        },250)
                    }else if(msg.indexOf('你現在的任務是')>=0 || msg.indexOf('幫派使者:')>=0){
                        UTIL.delSysListener("listenLoopSearchBangQS");
                        let qsStr = msg.replace(/\x03(0)?|href;0;|[\033|\27|\0x1b]\[[0-9|;]+m/ig,'')
                        for(let i=0;i<keys.length;i++){
                            let key = $.trim(keys[i])
                            if(key && qsStr.indexOf(key)>=0){
                                YFUI.writeToOut("<span style='color:#FF0;'>========= 結束搜索 =========</span>")
                                PLU.setBtnRed($("#btn_bt_searchBangQS"),0)
                                break
                            }else{
                                setTimeout(()=>{
                                    PLU.loopSearchBangQS(keys, 'clan cancel_task go')
                                },250)
                            }
                        }
                    }
                }
            })
            if(cmd) clickButton(cmd);
            else clickButton('clan task', 0)
        },
        //================================================================================================
        toLoopClick($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $("#btn_bt_loopClick").text('自動點擊')
                return
            }
            YFUI.showInput({
                title:"自動點擊",
                text:"輸入自動點擊的次數,確定後點擊要點按鈕",
                value:PLU.getCache("autoClickNum")||20,
                onOk(val){
                    if(!Number(val)) return;
                    setTimeout(o=>{
                        $(document).one('click',o=>{
                            let snpc = $(o.target).closest('button')[0].outerHTML.match(/clickButton\([\'\"](.+)[\'\"](,\s*(\d+))*\)/i)
                            if(snpc && snpc.length>=2){
                                let param = snpc[3] ? snpc[3] : 0;
                                PLU.setCache("autoClickNum",Number(val))
                                PLU.loopClick(snpc[1], param, Number(val))
                            }else{
                                PLU.setBtnRed($btn,0)
                            }
                        })
                    },500)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopClick(btnCmd, param, clickNum){
            if(!clickNum || clickNum<1 || !PLU.ONOFF["btn_bt_loopClick"]){
                PLU.setBtnRed($("#btn_bt_loopClick"),0)
                $("#btn_bt_loopClick").text('連續點擊')
                return;
            };
            $("#btn_bt_loopClick").text('停點擊('+clickNum+')');
            clickButton(btnCmd, param);
            clickNum--;
            setTimeout(()=>{
                PLU.loopClick(btnCmd, param, clickNum)
            },250)
        },
        //================================================================================================
        loopSlowClick(btnCmd, param, clickNum, delay){
            if(!delay) delay=1000;
            if(!clickNum || clickNum<1 || !PLU.ONOFF["btn_bt_loopSlowClick"]){
                PLU.setBtnRed($("#btn_bt_loopSlowClick"),0)
                $("#btn_bt_loopSlowClick").text('慢速點擊')
                return;
            };
            $("#btn_bt_loopSlowClick").text('停('+clickNum+')');
            clickButton(btnCmd, param);
            clickNum--;
            setTimeout(()=>{
                PLU.loopSlowClick(btnCmd, param, clickNum, delay)
            },delay)
        },
        //================================================================================================
        toLoopSlowClick($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $("#btn_bt_loopSlowClick").text('慢速點擊')
                return
            }
            YFUI.showPop({
                title:"慢速點擊",
                text:`輸入自動點擊的次數,選擇點擊速度,確定後點擊遊戲中要點的按鈕<br>
						<div style='margin:10px 0;'>
							<span>速度(秒): </span>
							<select id="slowClickSec" style="font-size:16px;height:30px;width:15%;">
								<option selected>1</option>
								<option>2</option>
								<option>3</option>
								<option>5</option>
								<option>10</option>
								<option>30</option>
								<option>60</option>
							</select>
							<span>次數: </span>
							<input id="slowClickTimes" value="${PLU.getCache("autoClickNum")||20}" style="font-size:16px;height:26px;width:40%;"></input>
						</div>`,
                onOk(){
                    let times = Number($('#slowClickTimes').val()) ,
                        delay = Number($('#slowClickSec').val());
                    if(!Number(times)) return;
                    setTimeout(o=>{
                        $(document).one('click',o=>{
                            let snpc = $(o.target).closest('button')[0].outerHTML.match(/clickButton\([\'\"](.+)[\'\"](,\s*(\d+))*\)/i)
                            if(snpc && snpc.length>=2){
                                let param = snpc[3] ? snpc[3] : 0;
                                PLU.setCache("autoClickNum",times)
                                PLU.loopSlowClick(snpc[1], param, times, delay*1000)
                            }else{
                                PLU.setBtnRed($btn,0)
                            }
                        })
                    },500)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        autoMasterGem($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $("#btn_bt_autoMasterGem").text('一鍵合天神')
                return
            }
            let arr = ["碎裂的","裂開的","無前綴","無暇的","完美的","君王的","皇帝的"]
            let sel1='<select id="startGemLvl" style="font-size:16px;height:30px;width:25%;">'
            arr.forEach((p,pi)=>{
                sel1+='<option value="'+pi+'" '+(pi==0?'selected':'')+'>'+p+'</option>'
            })
            sel1+='</select>';
            YFUI.showPop({
                title:"一鍵合天神",
                text:`選擇合成起始寶石等級,選擇速度(請根據網速和遊戲速度選擇),確定後自動向上合成所有<br>
						<div style='margin:10px 0;'>
							<span>起始等級: </span>${sel1}
							<span>速度(秒): </span>
							<select id="combineSec" style="font-size:16px;height:30px;width:15%;">
								<option selected>0.5</option>
								<option>1</option>
								<option>2</option>
								<option>3</option>
							</select>
						</div>`,
                width:"382px",
                okText:"開始",
                onOk(){
                    let startLvl = Number($('#startGemLvl').val()) ,
                        delay = Number($('#combineSec').val());
                    PLU.autoCombineMasterGem(startLvl, delay*1000)
                    //console.log(startLvl,delay)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        autoCombineMasterGem(startLvl, delay, gemCode, count){
            if(!PLU.ONOFF["btn_bt_autoMasterGem"]){
                PLU.setBtnRed($("#btn_bt_autoMasterGem"),0)
                $("#btn_bt_autoMasterGem").text('一鍵合天神')
                YFUI.writeToOut("<span style='color:white;'>==停止合成寶石!==</span>")
                return;
            };
            if(!UTIL.sysListeners["listenCombineMasterGem"]){
                UTIL.addSysListener("listenCombineMasterGem", function(b, type, subtype, msg) {
                    if (type== "notice" && msg.indexOf("合成寶石需要")>=0){
                        UTIL.delSysListener("listenCombineMasterGem");
                        YFUI.writeToOut("<span style='color:#F00;'>--缺少銀兩, 合成結束--</span>")
                        PLU.setBtnRed($("#btn_bt_autoMasterGem"),0)
                    }
                    return;
                })
            }
            //合成寶石需要5萬銀兩。
            //沒有這麼多的完美的藍寶石
            if(!gemCode || count<3){
                PLU.getGemList(gemList=>{
                    // console.log(gemList)
                    let g = gemList.find(e=>e.key.indexOf(""+(startLvl+1))>0&&e.num>=3)
                    if(g){
                        PLU.autoCombineMasterGem(startLvl, delay, g.key, g.num);
                    }else{
                        if(startLvl<6) PLU.autoCombineMasterGem(startLvl+1, delay);
                        else{
                            PLU.setBtnRed($("#btn_bt_autoMasterGem"),0)
                            YFUI.writeToOut("<span style='color:white;'>==合成寶石結束!==</span>")
                        }
                    }
                })
            }else{
                let cd=(delay/4)|250, n=1;
                cd = cd>250?cd:250;
                if(count>=30000){n=10000;cd=delay;}
                else if(count>=15000){n=5000;cd=delay;}
                else if(count>=9000){n=3000;cd=delay;}
                else if(count>=3000){n=1000;cd=delay;}
                else if(count>=300){n=100;cd=delay;}
                else if(count>=150){n=50;cd=delay;}
                else if(count>=90){n=30;cd=(delay/2)|0;}
                else if(count>=30){n=10;cd=(delay/3)|0;}
                let cmd = 'items hecheng '+gemCode+ "_N_"+n+""
                // PLU.execActions(cmds, ()=>{})
                clickButton(cmd)
                setTimeout(()=>{
                    PLU.autoCombineMasterGem(startLvl, delay, gemCode, count-n*3);
                },cd)
            }
        },
        //================================================================================================
        toSellLaji($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                //$("#btn_bt_sellLaji").text('清理垃圾')
                return
            }
            let defaultList='樹枝,破爛衣服,水草,木盾,鐵盾,藤甲盾,青銅盾,鞶革,軍袍,麻帶,破披風,長斗篷,牛皮帶,錦緞腰帶,絲質披風,逆鉤匕,匕首,鐵甲,重甲,精鐵甲,逆鉤匕,銀絲甲,梅花匕,軟甲衣,羊角匕,金剛杖,白蟒鞭,天寒項鍊,天寒手鐲,新月棍,天寒戒,天寒帽,天寒鞋,金彈子,拜月掌套'
            YFUI.showInput({
                title:"清理垃圾",
                text:`格式:物品詞組<br>
						物品詞組:以英文逗號分割多個關鍵詞<br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">${defaultList}</span><br>
						`,
                value:PLU.getCache("sellItemNames")||defaultList,
                type:"textarea",
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val)
                    PLU.setCache("sellItemNames",str)
                    let keysList=str.split(",")
                    let itemsTimeOut=setTimeout(()=>{
                        UTIL.delSysListener("listItems");
                    },5000)
                    UTIL.addSysListener("listItems", function(b, type, subtype, msg) {
                        if(type != "items") return;
                        UTIL.delSysListener("listItems");
                        clearTimeout(itemsTimeOut)
                        clickButton("prev");
                        let iId=1, itemList=[];
                        while (b.get('items'+iId)) {
                            let it=UTIL.filterMsg(b.get('items'+iId)).split(',')
                            if(it && it.length>4 && it[3]=='0' && keysList.includes(it[1])) itemList.push({
                                key:it[0],
                                name:it[1],
                                num:Number(it[2])
                            })
                            iId++
                        }
                        PLU.loopSellItems(itemList)
                    })
                    clickButton('items',0)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopSellItems(itemList){
            if(itemList.length<=0){
                PLU.setBtnRed($("#btn_bt_sellLaji"),0)
                return YFUI.writeToOut("<span style='color:#F66;'>--無出售物件!--</span>")
            }
            let ac=[];
            itemList.forEach(it=>{
                let ct=it.num
                while(ct>0){
                    if(ct>=10000){
                        ac.push('items sell '+it.key+'_N_10000')
                        ct-=10000;
                    }else if(ct>=1000){
                        ac.push('items sell '+it.key+'_N_1000')
                        ct-=1000;
                    }else if(ct>=100){
                        ac.push('items sell '+it.key+'_N_100')
                        ct-=100;
                    }else if(ct>=50){
                        ac.push('items sell '+it.key+'_N_50')
                        ct-=50;
                    }else if(ct>=10){
                        ac.push('items sell '+it.key+'_N_10')
                        ct-=10;
                    }else{
                        ac.push('items sell '+it.key+'')
                        ct-=1;
                    }
                }
            })
            let acs = ac.join(';')
            PLU.fastExec(acs, ()=>{
                PLU.setBtnRed($("#btn_bt_sellLaji"),0)
                YFUI.writeToOut("<span style='color:white;'>==出售完成!==</span>")
            })
        },
        //================================================================================================
        toSplitItem($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return
            }
            let defaultList='玄武盾,破軍盾,金絲寶甲衣,夜行披風,羊毛斗篷,殘雪戒,殘雪項鍊,殘雪手鐲,殘雪鞋,金絲甲,寶玉甲,月光寶甲,虎皮腰帶,滄海護腰,紅光匕,毒龍鞭,玉清棍,霹靂掌套'
            YFUI.showInput({
                title:"分解裝備",
                text:`格式:物品詞組<br>
						物品詞組:以英文逗號分割多個關鍵詞<br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">${defaultList}</span><br>
						`,
                value:PLU.getCache("splitItemNames")||defaultList,
                type:"textarea",
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val)
                    PLU.setCache("splitItemNames",str)
                    let keysList=str.split(",")
                    let itemsTimeOut=setTimeout(()=>{
                        UTIL.delSysListener("listItems_si");
                    },5000)
                    UTIL.addSysListener("listItems_si", function(b, type, subtype, msg) {
                        if(type != "items") return;
                        UTIL.delSysListener("listItems_si");
                        clearTimeout(itemsTimeOut)
                        clickButton("prev");
                        let iId=1, itemList=[];
                        while (b.get('items'+iId)) {
                            let it=UTIL.filterMsg(b.get('items'+iId)).split(',')
                            if(it && it.length>4 && it[3]=='0' && keysList.includes(it[1])) itemList.push({
                                key:it[0],
                                name:it[1],
                                num:Number(it[2])
                            })
                            iId++
                        }
                        PLU.loopSplitItem(itemList)
                    })
                    clickButton('items',0)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopSplitItem(itemList){
            if(itemList.length<=0){
                PLU.setBtnRed($("#btn_bt_splitItem"),0)
                return YFUI.writeToOut("<span style='color:#F66;'>--無分解物件!--</span>")
            }
            let ac=[];
            itemList.forEach(it=>{
                let ct=it.num
                while(ct>0){
                    if(ct>=100){
                        ac.push('items splite '+it.key+'_N_100')
                        ct-=100;
                    }else if(ct>=50){
                        ac.push('items splite '+it.key+'_N_50')
                        ct-=50;
                    }else if(ct>=10){
                        ac.push('items splite '+it.key+'_N_10')
                        ct-=10;
                    }else{
                        ac.push('items splite '+it.key+'')
                        ct-=1;
                    }
                }
            })
            let acs = ac.join(';')
            PLU.fastExec(acs, ()=>{
                PLU.setBtnRed($("#btn_bt_splitItem"),0)
                YFUI.writeToOut("<span style='color:white;'>==分解完成!==</span>")
            })
        },
        //================================================================================================
        toPutStore($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return
            }
            let defaultList='碎片,璞玉,青玉,墨玉,白玉,秘籍木盒,錦袋,瑞雪針釦,武穆遺書,隱武竹箋,空識卷軸,技能書,開元寶票,霹靂彈,舞鳶尾,百宜雪梅'
            YFUI.showInput({
                title:"物品入庫",
                text:`格式:物品詞組<br>
						物品詞組:以英文逗號分割多個關鍵詞<br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">${defaultList}</span><br>
						`,
                value:PLU.getCache("putStoreNames")||defaultList,
                type:"textarea",
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val)
                    PLU.setCache("putStoreNames",str)
                    let keysList=str.split(",").join("|")
                    let itemsTimeOut=setTimeout(()=>{
                        UTIL.delSysListener("listItems_ps");
                    },5000)
                    UTIL.addSysListener("listItems_ps", function(b, type, subtype, msg) {
                        if(type != "items") return;
                        UTIL.delSysListener("listItems_ps");
                        clearTimeout(itemsTimeOut)
                        clickButton("prev");
                        let iId=1, itemList=[];
                        while (b.get('items'+iId)) {
                            let it=UTIL.filterMsg(b.get('items'+iId)).split(',')
                            if(it && it.length>4 && it[3]=='0' && it[1].match(keysList) && it[1]!='青龍碎片' && it[1]!='玄鐵碎片') itemList.push({
                                key:it[0],
                                name:it[1],
                                num:Number(it[2])
                            })
                            iId++
                        }
                        PLU.loopPutStore(itemList)
                    })
                    clickButton('items',0)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopPutStore(itemList){
            if(itemList.length<=0){
                PLU.setBtnRed($("#btn_bt_putStore"),0)
                return YFUI.writeToOut("<span style='color:#F66;'>--無物件入庫!--</span>")
            }
            let ac=[];
            itemList.forEach(it=>{
                ac.push('items put_store '+it.key+'')
            })
            let acs = ac.join(';')
            PLU.fastExec(acs, ()=>{
                PLU.setBtnRed($("#btn_bt_putStore"),0)
                YFUI.writeToOut("<span style='color:white;'>==入庫完成!==</span>")
            })
        },
        //================================================================================================
        toAutoUse($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return
            }
            let defaultList='*神秘寶箱,靈草,紫芝,狂暴丹,小還丹,大還丹,高級大還丹,高級狂暴丹,高級乾坤再造丹,百年靈草,百年紫芝,特級大還丹,特級狂暴丹,特級乾坤再造丹,千年靈草,千年紫芝,頂級大還丹,頂級狂暴補丸,頂級乾坤補丸,萬年靈草,萬年紫芝'
            YFUI.showInput({
                title:"物品使用",
                text:`格式:物品詞組<br>
						物品詞組:以英文逗號分割多個關鍵詞, 只能單個使用的物品前面加*星號<br>
						<span style="color:red;">例如:</span><br>
						[例1] <span style="color:blue;">${defaultList}</span><br>
						`,
                value:PLU.getCache("autoUseNames")||defaultList,
                type:"textarea",
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val)
                    PLU.setCache("autoUseNames",str)
                    let keysList=str.split(",")
                    let itemsTimeOut=setTimeout(()=>{
                        UTIL.delSysListener("listItems_au");
                    },5000)
                    UTIL.addSysListener("listItems_au", function(b, type, subtype, msg) {
                        if(type != "items") return;
                        UTIL.delSysListener("listItems_au");
                        clearTimeout(itemsTimeOut)
                        clickButton("prev");
                        let iId=1, itemList=[];
                        while (b.get('items'+iId)) {
                            let it=UTIL.filterMsg(b.get('items'+iId)).split(',')
                            if(!it[1]) continue;
                            if(it && it.length>4 && it[3]=='0'){
                                if(keysList.includes(it[1])) itemList.push({
                                    key:it[0],
                                    name:it[1],
                                    num:Number(it[2]),
                                    multi:true
                                }); else if(keysList.includes('*'+it[1])) itemList.push({
                                    key:it[0],
                                    name:it[1],
                                    num:Number(it[2]),
                                    multi:false
                                });
                            }
                            iId++
                        }
                        PLU.loopAutoUse(itemList)
                    })
                    clickButton('items',0)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopAutoUse(itemList){
            if(itemList.length<=0){
                PLU.setBtnRed($("#btn_bt_autoUse"),0)
                return YFUI.writeToOut("<span style='color:#F66;'>--無物件使用!--</span>")
            }
            let ac=[];
            itemList.forEach(it=>{
                let ct=it.num
                while(ct>0){
                    if(it.multi && ct>=100){
                        ac.push('items use '+it.key+'_N_100')
                        ct-=100;
                    }else if(it.multi && ct>=50){
                        ac.push('items use '+it.key+'_N_50')
                        ct-=50;
                    }else if(it.multi && ct>=10){
                        ac.push('items use '+it.key+'_N_10')
                        ct-=10;
                    }else{
                        ac.push('items use '+it.key+'')
                        ct-=1;
                    }
                }
            })
            let acs = ac.join(';')
            PLU.fastExec(acs, ()=>{
                PLU.setBtnRed($("#btn_bt_autoUse"),0)
                YFUI.writeToOut("<span style='color:white;'>==使用完成!==</span>")
            })
        },
        //================================================================================================
        toLoopScript($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $("#btn_bt_loopScript").text('循環執行')
                PLU.STO.loopScTo && clearTimeout(PLU.STO.loopScTo) && delete(PLU.STO.loopScTo)
                return
            }
            YFUI.showInput({
                title:"循環執行",
                text:`格式:循環次數@時間間隔|執行指令<br>
						循環次數:省略則默認1次<br>
						時間間隔:省略則默認5(5秒)<br>
						執行指令:以分號分隔的指令<br>
						<span style="color:red;">例如</span><br>
						[例1] 3@5|jh 1;e;n;home;<br>
						[例2] jh 5;n;n;n;w;sign7;
						`,
                value:PLU.getCache("loopScript")||"home;",
                type:"textarea",
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val), scripts="", times=1, interval=5, arr=str.split('|');
                    if(arr.length>1){
                        scripts = arr[1];
                        if(arr[0].indexOf('@')>=0){
                            times = Number(arr[0].split('@')[0]) || 1;
                            interval = Number(arr[0].split('@')[1]) || 5;
                        }else{
                            times = Number(arr[0]) || 1;
                        }
                    }else{
                        scripts = arr[0]
                    }
                    PLU.setCache("loopScript",str)
                    PLU.loopScript(scripts,times,interval)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        loopScript(scripts,times,interval){
            times--;
            $("#btn_bt_loopScript").text('停執行('+times+')');
            PLU.execActions(scripts, ()=>{
                if(times<=0 || !PLU.ONOFF["btn_bt_loopScript"]){
                    PLU.setBtnRed($("#btn_bt_loopScript"),0)
                    $("#btn_bt_loopScript").text('循環執行')
                    PLU.STO.loopScTo && clearTimeout(PLU.STO.loopScTo) && delete(PLU.STO.loopScTo)
                    return;
                }else{
                    PLU.STO.loopScTo=setTimeout(()=>{
                        PLU.loopScript(scripts,times,interval)
                    },interval*1000)
                }
            })
        },
        //================================================================================================
        toAutoAskQixia($btn, autoTime){
            if(g_gmain.is_fighting) return;
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                return
            }
            $(".menu").hide()
            YFUI.showPop({
                title:"自動訪問奇俠",
                text:"自動對話所有有親密度的奇俠, 請在做完20次贊助金錠後再進行<br><b style='color:#F00;'>是否現在進行?</b>",
                autoOk:autoTime?autoTime:null,
                onOk(){
                    let jhqxTimeOut=setTimeout(()=>{
                        UTIL.delSysListener("listQixia");
                        PLU.setBtnRed($btn,0)
                    },5000)
                    UTIL.addSysListener("listQixia", function(b, type, subtype, msg) {
                        if (type != "show_html_page" || msg.indexOf('江湖奇俠成長信息')<0) return;
                        UTIL.delSysListener("listQixia");
                        clearTimeout(jhqxTimeOut)
                        let listHtml = msg;
                        clickButton("prev");
                        let str="find_task_road qixia (\\d+)\x03(.{2,4})\x030\x03\\((\\d+)\\)(.{15,25}朱果)?.{30,50}已出師",
                            rg1=new RegExp(str,"g"),
                            rg2=new RegExp(str),
                            visQxs=[];
                        listHtml.match(rg1).forEach(e=>{
                            let a=e.match(rg2);
                            if(a) visQxs.push({key:a[1],name:a[2],num:Number(a[3]),link:'find_task_road qixia '+a[1],fast:a[4]?'open jhqx '+a[1]:null})
                        })
                        visQxs = visQxs.sort((a,b)=>{
                            if(a.fast && b.num>=25000) return -1;
                            else return 2;
                        });
                        visQxs.reverse();
                        PLU.toAskQixia(visQxs,0)
                    })
                    clickButton('open jhqx', 0)
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                }
            })

        },
        //================================================================================================
        toAskQixia(qxList,idx){
            clickButton('home');
            if(idx>=qxList.length || !PLU.ONOFF["btn_bt_autoAskQixia"]) {
                PLU.setBtnRed($("#btn_bt_autoAskQixia"),0)
                YFUI.writeToOut("<span style='color:#FFF;'>--奇俠訪問結束!--</span>")
                return
            }
            let qxObj = qxList[idx]
            if(qxObj.fast){
                clickButton(qxObj.fast, 0)
                setTimeout(()=>{
                    PLU.toAskQixia(qxList, idx+1)
                },500)
            }else{
                PLU.execActions(qxObj.link+';golook_room;',()=>{
                    let objNpc = UTIL.findRoomNpc(qxObj.name,false,true)
                    if(objNpc){
                        PLU.execActions('ask '+objNpc.key+';ask '+objNpc.key+';ask '+objNpc.key+';ask '+objNpc.key+';ask '+objNpc.key+';golook_room;',()=>{
                            setTimeout(()=>{
                                PLU.toAskQixia(qxList, idx+1)
                            },500)
                        })
                    }else{
                        YFUI.writeToOut("<span style='color:#FFF;'>--找不到奇俠:"+qxObj.name+"--</span>")
                        setTimeout(()=>{
                            PLU.toAskQixia(qxList, idx+1)
                        },500)
                    }
                })
            }
        },
        //================================================================================================
        getQixiaList(callback){
            let jhQixiaTimeOut=setTimeout(()=>{
                UTIL.delSysListener("getlistQixia");
            },5000)
            UTIL.addSysListener("getlistQixia", function(b, type, subtype, msg) {
                if (type != "show_html_page" || msg.indexOf('江湖奇俠成長信息')<0) return;
                UTIL.delSysListener("getlistQixia");
                clearTimeout(jhQixiaTimeOut)
                window.ttttt=msg
                let listHtml = msg.replace(/\x03(0)?|href;0;|[\033|\27|\0x1b]\[[0-9|;]+m/ig,'');
                clickButton("prev");
                let str="find_task_road qixia (\\d+)(.{2,4})(\\((\\d*)\\))?(open jhqx \\d+朱果)?<\\/td><td.{20,35}>(.{1,10})<\\/td><td.{20,35}>(.{1,15})<\\/td><td .{20,40}領悟(.{2,10})<\\/td><\\/tr>"
                let rg1=new RegExp(str,"g"),
                    rg2=new RegExp(str),
                    qxList=[];
                listHtml.match(rg1).forEach(e=>{
                    let a=e.match(rg2);
                    if(a) qxList.push({
                        index:a[1],
                        name:a[2],
                        num:Number(a[4])||0,
                        link:'find_task_road qixia '+a[1],
                        fast:a[5]?'open jhqx '+a[1]:null,
                        inJh:a[6]&&a[6].indexOf('未出世')<0?true:false
                    })
                })
                callback && callback(qxList)
            })
            clickButton('open jhqx', 0)
        },
        //================================================================================================
        toAutoVisitQixia($btn){
            if(g_gmain.is_fighting) return;
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                //$("#btn_bt_autoVisitQixia").text('親近奇俠')
                PLU.TMP.autoQixiaMijing = false
                return
            }
            $(".menu").hide()
            clickButton('open jhqx', 0)
            YFUI.showInput({
                title:"奇俠秘境",
                text:  `請輸入要提升親密度的遊俠的姓名<br>
                        格式:金錠數量|遊俠姓名@目標友好度<br>
						金錠數量:給予1或5或15金錠,可省略則只對話<br>
						遊俠姓名:只能輸入一個遊俠姓名<br>
						目標友好度:省略則以可學技能的友好度為目標<br>
						<span style="color:red;">例如</span><br>
						[例1] 15|風無痕 <span style="color:blue;">訪問風無痕贈與15金錠</span><br>
						[例2] 火雲邪神 <span style="color:blue;">訪問風無痕對話</span><br>
						[例2] 15|步驚鴻@30000 <span style="color:blue;">訪問風無痕對話</span><br>
						`+'<div style="text-align:right;"><label>不要掃盪秘境:<input type="checkbox" id="if_auto_mj" name="noamj" value="1"/></label></div>',
                value:PLU.getCache("visitQixiaName")||"15|風無痕",
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val), arr=str.split('|'), giveNum=15, qxName="", objectFN=0;
                    let ifAutoMj = $('#if_auto_mj').is(':checked')
                    if(arr.length>1){
                        giveNum = Number(arr[0])||15;
                        let nn=arr[1].split('@')
                        qxName = nn[0].trim()
                        if(nn.length>1) objectFN=Number(nn[1])
                    }else{
                        giveNum = 0;
                        let nn=arr[0].split('@')
                        qxName = nn[0].trim()
                        if(nn.length>1) objectFN=Number(nn[1])
                    }
                    PLU.setCache("visitQixiaName",str)
                    PLU.TMP.todayGetXT = 0;
                    UTIL.delSysListener("listenVisitNotice")
                    PLU.STO.listenVisit && clearTimeout(PLU.STO.listenVisit)
                    PLU.TMP.goingQixiaMijing = false;
                    PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, (err)=>{
                        if(err){
                            if(err.code==1){
                                PLU.setBtnRed($btn,0);
                                UTIL.delSysListener("listenVisitNotice")
                                PLU.toAutoAskQixia($("#btn_bt_autoAskQixia"),10)
                                YFUI.writeToOut("<span style='color:yellow;'> 今日一共獲得玄鐵令x"+PLU.TMP.todayGetXT+"</span>")
                                UTIL.log({msg:' 今日一共獲得玄鐵令x '+PLU.TMP.todayGetXT+'  ', type:'TIPS', time:new Date().getTime()})
                            }else{
                                YFUI.showPop({
                                    title:"提示",
                                    text:"<b style='color:#F00;'>"+err.msg+"</b>",
                                    onOk(){
                                        PLU.setBtnRed($btn,0);
                                        PLU.toAutoVisitQixia($btn)
                                    },
                                    onX(){
                                        PLU.setBtnRed($btn,0);
                                    }
                                });
                            }
                        }
                    })
                },
                onNo(){
                    PLU.setBtnRed($btn,0)
                },
                onX(){
                    PLU.setBtnRed($btn,0);
                }
            })
        },
        //================================================================================================
        tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback){
            PLU.TMP.autoQixiaMijing = true
            //發現
            PLU.getQixiaList(qxlist=>{
                let testDone = qxlist.find(e=>!!e.fast)
                if(testDone){
                    PLU.STO.listenVisit && clearTimeout(PLU.STO.listenVisit)
                    callback && callback({code:1,msg:"今日奇俠友好度操作已經完畢"});return;
                }
                let qx=qxlist.find(e=>e.name==qxName)
                if(!qx) {
                    callback && callback({code:2,msg:"沒有這個奇俠!"});return;
                }
                if(!qx.inJh) {
                    callback && callback({code:3,msg:"這個奇俠還沒出師!"});return;
                }
                let objectFriendNum = objectFN?objectFN:PLU.YFD.qixiaFriend.find(e=>e.name==qxName).skillFN;
                if(qx.num>=objectFriendNum) {
                    callback && callback({code:4,msg:"奇俠友好度已足夠"});return;
                }
                let listenVisitTimeout = function(){
                    if(!PLU.TMP.goingQixiaMijing) PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback)
                }
                UTIL.delSysListener("listenVisitNotice")
                //監聽場景消息
                UTIL.addSysListener("listenVisitNotice", function(b, type, subtype, msg) {
                    if (type != "notice" && type != "main_msg") return;
                    let msgTxt = UTIL.filterMsg(msg)
                    if(msgTxt.match("對你悄聲道:你現在去")){//奇俠說秘境
                        let l = msgTxt.match(/(.*)對你悄聲道:你現在去(.*),應當會有發現/);
                        if(l && l.length>2){
                            PLU.TMP.goingQixiaMijing = true;
                            let placeData=PLU.YFD.mjList.find(e=>e.n==l[2])
                            if(placeData){
                                PLU.execActions(placeData.v+';;find_task_road secret;;',()=>{
                                    setTimeout(()=>{
                                        let mapid = g_obj_map.get("msg_room").get("map_id");
                                        let shortName = g_obj_map.get("msg_room").get("short");
                                        YFUI.writeToOut("<span style='color:#FFF;'>--地圖ID:"+mapid+"--</span>")
                                        if(mapid=="public"){
                                            PLU.execActions('secret_op1;',()=>{
                                                PLU.TMP.goingQixiaMijing = false;
                                                PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback)
                                            })
                                        }else if(ifAutoMj){
                                            UTIL.delSysListener("listenVisitNotice")
                                            PLU.setBtnRed($("#btn_bt_autoVisitQixia"),0)
                                            YFUI.writeToOut("<span style='color:yellow;'> ===== 進入了秘境! ===== </span>")
                                        }else{
                                            let ss=g_obj_map.get("msg_room").elements.find(e=>e.value=="仔細搜索")
                                            if(ss) {
                                                let cmd_ss=g_obj_map.get("msg_room").get(ss.key.split("_")[0])
                                                PLU.execActions(cmd_ss+';;',()=>{
                                                    let sd=g_obj_map.get("msg_room").elements.find(e=>e.value.indexOf("掃盪")>=0)
                                                    if(sd) {
                                                        let cmd_sd=g_obj_map.get("msg_room").get(sd.key.split("_")[0])
                                                        PLU.doSaoDang(mapid, cmd_sd, ()=>{
                                                            PLU.TMP.goingQixiaMijing = false;
                                                            PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback)
                                                        })
                                                    }else if(shortName == '無盡深淵'){
                                                        PLU.goWuJinShenYuan(()=>{
                                                            PLU.TMP.goingQixiaMijing = false;
                                                            PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback)
                                                        })
                                                    }else{
                                                        UTIL.delSysListener("listenVisitNotice")
                                                        PLU.setBtnRed($("#btn_bt_autoVisitQixia"),0)
                                                        YFUI.writeToOut("<span style='color:yellow;'> ===進入了未通關秘境!=== </span>")
                                                    }
                                                })
                                            }
                                        }
                                    },1500)
                                })
                            }
                            return
                        }
                    }
                    let vis=msgTxt.match(/今日親密度操作次數\((\d+)\/20\)/)
                    if(vis){
                        PLU.STO.listenVisit && clearTimeout(PLU.STO.listenVisit)
                        setTimeout(()=>{
                            if(!PLU.TMP.goingQixiaMijing){
                                PLU.STO.listenVisit = setTimeout(listenVisitTimeout,4000)
                                let objNpc = UTIL.findRoomNpc(qxName,false,true)
                                if(objNpc){
                                    PLU.doVisitAction(objNpc.key, giveNum)
                                }else{
                                    YFUI.writeToOut("<span style='color:#FFF;'>--找不到奇俠!--</span>")
                                    setTimeout(()=>{
                                        PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback)
                                    },500)
                                }
                            }
                        },500)
                        return
                    }
                    if(msgTxt.match("今日做了太多關於親密度的操作")){
                        PLU.STO.listenVisit && clearTimeout(PLU.STO.listenVisit)
                        callback && callback({code:1,msg:"今日奇俠友好度操作已經完畢"});
                        return;
                    }
                    if(msgTxt.match(/今日奇俠贈送次數(\d+)\/(\d+),.*贈送次數(\d+)\/(\d+)/)){
                        PLU.STO.listenVisit && clearTimeout(PLU.STO.listenVisit)
                        callback && callback({code:1,msg:"今日奇俠友好度操作已經完畢"});
                        return;
                    }
                    if(msgTxt.match("掃盪成功,獲得:")){
                        let xtnum=parseInt(msgTxt.split("、")[0].split("玄鐵令x")[1]);
                        if(xtnum) PLU.TMP.todayGetXT+=xtnum;
                        xtnum &&
                            YFUI.writeToOut("<span>--玄鐵令+"+xtnum+"--</span>")
                        return;
                    }
                    if(msgTxt.match("你開始四處搜索……你找到了")){
                        let xtnum=parseInt(msgTxt.split("、")[0].split("玄鐵令x")[1]);
                        if(xtnum) PLU.TMP.todayGetXT+=xtnum;
                        xtnum && YFUI.writeToOut("<span>--玄鐵令+"+xtnum+"--</span>")
                        return;
                    }
                })
                PLU.execActions(qx.link+';;',()=>{
                    let objNpc = UTIL.findRoomNpc(qxName,false,true)
                    if(objNpc){
                        PLU.STO.listenVisit = setTimeout(listenVisitTimeout,3000)
                        PLU.doVisitAction(objNpc.key, giveNum)
                    }else{
                        YFUI.writeToOut("<span style='color:#FFF;'>--找不到奇俠:"+qxName+"--</span>")
                        setTimeout(()=>{
                            PLU.tryVisitQixia(qxName, giveNum, objectFN, ifAutoMj, callback)
                        },500)
                    }
                });
            })
        },
        //================================================================================================
        doVisitAction(qxKey, giveNum){
            if(giveNum==0){
                PLU.execActions('ask '+qxKey+';')
            }else if(giveNum==1){
                PLU.execActions('auto_zsjd_'+qxKey.split("_")[0]+';')
            }else if(giveNum==5){
                PLU.execActions('auto_zsjd5_'+qxKey.split("_")[0]+';')
            }else{
                PLU.execActions('auto_zsjd20_'+qxKey.split("_")[0]+';')
            }
        },
        //================================================================================================
        doSaoDang(mapid, cmd, callback){
            UTIL.addSysListener("listenVisitSaodang", function(b, type, subtype, msg) {
                if (type != "prompt") return;
                let xtnum = parseInt(msg.split("、")[0].split("玄鐵令x")[1]);
                if(["yaowanggu","leichishan"].includes(mapid)){
                    if(xtnum<5) return setTimeout(()=>{clickButton(cmd);},300);
                }else if(["liandanshi","lianhuashanmai","qiaoyinxiaocun","duzhanglin","shanya","langhuanyudong","dixiamigong"].includes(mapid)){
                    if(xtnum<3) return setTimeout(()=>{clickButton(cmd);},300);
                };
                UTIL.delSysListener("listenVisitSaodang")
                PLU.execActions(cmd+" go;", ()=>{
                    callback && callback()
                });
            })
            setTimeout(()=>{clickButton(cmd);},300);
        },
        //================================================================================================
        goWuJinShenYuan(endcallback){//無盡深淵
            //'e;e;s;w;w;s;s;e;n;e;s;e;e;n;w;n;e;n;w;fight henshan_guguai_laozhe'
            let paths='e;e;s;w;w;s;s;e;n;e;s;e;e;n;w;n;e;n;w'.split(';')
            var sidx=0;
            let gostep=function(pathArray,stepFunc){
                let ca=pathArray[sidx]
                PLU.execActions(ca+"", ()=>{
                    stepFunc && stepFunc();
                    sidx++;
                    if(sidx>=pathArray.length){
                        endcallback && endcallback()
                    }else{
                        setTimeout(()=>{
                            gostep(pathArray,stepFunc)
                        },250)
                    }
                });
            }
            gostep(paths,()=>{
                let fc=g_obj_map.get("msg_room").elements.find(e=>e.value=="翻查")
                if(fc){
                    let cmd_fc=g_obj_map.get("msg_room").get(fc.key.split("_")[0])
                    PLU.execActions(cmd_fc+"")
                }
            })
        },
        //================================================================================================
        toWaitCDKill($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                //$("#btn_bt_waitCDKill").text('')
                return
            }
            clickButton('golook_room');
            YFUI.showPop({
                title:"倒計時叫殺門派紛爭",
                text:"倒計時最後5秒叫殺最近結束時間的門派紛爭!,確定後單擊NPC<br>",
                onOk(){
                    setTimeout(o=>{
                        $(document).one('click',o=>{
                            let npcbtn = $(o.target).closest('button')
                            let snpc = npcbtn[0].outerHTML.match(/clickButton\('look_npc (\w+)'/i)
                            if(snpc && snpc.length>=2){
                                let nowTime = new Date().getTime(), cMPFZ=null;
                                for(let k in PLU.MPFZ){
                                    if(!cMPFZ || cMPFZ.t> PLU.MPFZ[k].t) cMPFZ = PLU.MPFZ[k]
                                }
                                if(cMPFZ){
                                    PLU.TMP.DATA_MPFZ = Object.assign({}, cMPFZ, {killId:snpc[1]})
                                    YFUI.showPop({
                                        title:"倒計時叫殺門派紛爭",
                                        text:'<div style="line-height:2;">人物:'+npcbtn.text()+'<br>地點:'+PLU.TMP.DATA_MPFZ.p+'<br>對決:'+PLU.mp2icon(PLU.TMP.DATA_MPFZ.v)+'</div>',
                                        okText:"好的",
                                        onOk(){},
                                        onNo(){
                                            PLU.TMP.DATA_MPFZ = null
                                            PLU.setBtnRed($btn,0)
                                        }
                                    })
                                }
                            }else{
                                PLU.TMP.DATA_MPFZ = null
                                PLU.setBtnRed($btn,0)
                            }
                        })
                    },500)
                },
                onNo(){
                    PLU.TMP.DATA_MPFZ = null
                    PLU.setBtnRed($btn,0)
                }
            })
        },
        //================================================================================================
        mp2icon(mplist){
            let htm='',zfarr=mplist.split(" VS "),zarr=zfarr[0].split("、"),farr=zfarr[1].split("、");
            zarr.forEach(zm=>{
                htm+='<span style="display:inline-block;background:#F66;border-radius:2px;padding:0 2px;margin:1px;color:#FFF;">'+zm+'</span>'
            })
            htm+='<span style="color:#FFF;background:#F00;font-weight:bold;border-radius:50%;padding:2px;">VS</span>'
            farr.forEach(fm=>{
                htm+='<span style="display:inline-block;background:#66F;border-radius:2px;padding:0 2px;margin:1px;color:#FFF;">'+fm+'</span>'
            })
            return htm
        },
        //================================================================================================
        toCheckAndWaitCDKill(nowTime){
            let k = PLU.TMP.DATA_MPFZ.t+1560000;
            let dt = Math.floor((k-nowTime)/1000);
            if(dt==5){
                YFUI.writeToOut("<span style='color:#F99;'>--最後5秒,進入戰鬥!--</span>")
                //PLU.TMP.DATA_MPFZ = null
                //PLU.setBtnRed($btn,0)
                PLU.autoFight({
                    targetKey:PLU.TMP.DATA_MPFZ.killId,
                    fightKind:'kill',
                    onFail(){
                        PLU.TMP.DATA_MPFZ = null
                        PLU.setBtnRed($("#btn_bt_waitCDKill"),0)
                        setTimeout(t=>{
                            PLU.execActions('prev_combat;golook_room;home;');
                        },500)
                    },
                    onEnd(){
                        PLU.TMP.DATA_MPFZ = null
                        PLU.setBtnRed($("#btn_bt_waitCDKill"),0)
                        setTimeout(t=>{
                            PLU.execActions('prev_combat;golook_room;home;');
                        },500)
                    }
                })
            }
        },
        //================================================================================================
        setListen($btn, listenKey, stat){
            let btnFlag = 0;
            if(stat!=undefined){
                btnFlag = PLU.setBtnRed($btn, stat)
                PLU.setCache(listenKey,stat)
                return
            }else{
                btnFlag = PLU.setBtnRed($btn)
            }
            if(!btnFlag) {
                PLU.setCache(listenKey,0)
                return
            }
            if(listenKey=="listenQL"){//監聽青龍
                YFUI.showInput({
                    title:"監聽本服青龍",
                    text:`格式:擊殺類型|物品詞組<br>
                            擊殺類型:0殺守方(好人),1殺攻方(壞人)。<br>
                            物品詞組:以英文逗號分割多個關鍵詞<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">0|斬龍,斬龍寶鐲,碎片</span><br>
                            [例2] <span style="color:blue;">1|*</span>;
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"0|斬龍,開天寶棍,天罡掌套,龍皮至尊甲衣",
                    type:"textarea",
                    onOk(val){
                        let str=$.trim(val);
                        if(!str || str.indexOf("|")<0) return PLU.setBtnRed($btn,0);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.setCache(listenKey,1)
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="listenTF"){//監聽夜魔
                YFUI.showInput({
                    title:"監聽逃犯",
                    text:`格式:擊殺類型|逃犯詞組<br>
                            擊殺類型:0殺守方(逃犯),1殺攻方(捕快)。<br>
                            逃犯詞組:以英文逗號分割多個關鍵詞<br>
                            <span style="color:#F00;">【新人】以#開頭則等候他人開殺再進</span><br>
                            <span style="color:#933;">例如:</span><br>
                            [例1] <span style="color:blue;">0|夜魔*段老大,#夜魔*流寇</span>
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"0|夜魔*段老大,夜魔*二娘,#夜魔*嶽老三,#夜魔*雲老四,#夜魔*流寇,#夜魔*惡棍,#夜魔*劇盜",
                    type:"textarea",
                    onOk(val){
                        let str=$.trim(val);
                        if(!str || str.indexOf("|")<0) return PLU.setBtnRed($btn,0);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.setCache(listenKey,1)
                        PLU.splitTFParam()
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="listenGCQL"){//監聽廣場青龍
                YFUI.showInput({
                    title:"監聽廣場青龍",
                    text:`格式:擊殺類型|物品詞組<br>
                            擊殺類型:0殺守方(好人),1殺攻方(壞人)。<br>
                            物品詞組:以英文逗號分割多個關鍵詞<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">0|斬龍,斬龍寶鐲,碎片</span><br>
                            [例2] <span style="color:blue;">1|*</span>;
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"1|斬龍,開天寶棍,天罡掌套,龍皮至尊甲衣",
                    type:"textarea",
                    onOk(val){
                        let str=$.trim(val);
                        if(!str || str.indexOf("|")<0) return PLU.setBtnRed($btn,0);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.setCache(listenKey,1)
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="listenYX"){//監聽遊俠
                YFUI.showInput({
                    title:"監聽遊俠",
                    text:`格式:遊俠詞組<br>
                            遊俠詞組:以英文逗號分割多個關鍵詞<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">王語嫣,厲工,金輪法王,虛夜月,雲夢璃,葉孤城</span><br>
                            `,
                    value:PLU.getCache(listenKey+"_keys")||[].concat(...PLU.YFD.youxiaList.map(e=>e.v)).join(","),
                    type:"textarea",
                    onOk(val){
                        let str=$.trim(val);
                        if(!str) return PLU.setBtnRed($btn,0);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.setCache(listenKey,1)
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="autoTP"){//監聽突破
                YFUI.showInput({
                    title:"持續突破",
                    text:`請輸入需要自動突破的技能,以英文逗號分割,自動突破將在當前全部突破完後才開始。<br>
                            以*開頭使用金剛舍利加速<br>
                            以**開頭使用通天丸加速<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">千影百傷棍,*排雲掌法,**無相金剛掌,降龍十八掌,獨孤九劍</span>
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"*千影百傷棍,*排雲掌法,*不動明王訣",
                    type:"textarea",
                    onOk(val){
                        let str=$.trim(val);
                        if(!str) return PLU.setBtnRed($btn,0);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.setCache(listenKey,1)
                        PLU.getSkillsList((allSkills, tupoSkills)=>{
                            if (tupoSkills.length == 0) {
                                PLU.toToPo()
                            }
                        })
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="autoConnect"){
                YFUI.showInput({
                    title:"自動重連",
                    text:`請輸入斷線後自動重連的時間,重連方式為到時間自動刷新頁面。<br>單位為秒,0代表不自動重連。<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">60</span> 代表60秒後刷新頁面
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"0",
                    //type:"textarea",
                    onOk(val){
                        let v=Number(val);
                        if(val=="") return PLU.setBtnRed($btn,0);
                        PLU.setCache(listenKey+"_keys",v)
                        PLU.setCache(listenKey,1)
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="autoSignIn"){ //YFUI.showPop(
                YFUI.showPop({
                    title:"定時一鍵簽到",
                    text:`請輸入自動簽到的時間。<br>
						<div><span style="font-size:18px;line-height:2;">每日: </span><input id="autoSignInTime" type="time" style="font-size:20px;border-radius:5px;margin:10px 0"/></div>
						`,
                    onOk(){
                        let v=$.trim($('#autoSignInTime').val());
                        if(v=="") return PLU.setBtnRed($btn,0);
                        //console.log($('#autoSignInTime').val(),$('#autoSignInTime'))
                        // setCache
                        PLU.setCache(listenKey,1)
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else if(listenKey=="autoQuitTeam"){ //進塔離隊
                YFUI.showPop({
                    title:"進塔自動離隊",
                    text:`是否進塔自動離隊?<br>`,
                    onOk(){
                        PLU.setCache(listenKey,1)
                    },
                    onNo(){
                        PLU.setCache(listenKey,0)
                        PLU.setBtnRed($btn,0)
                    }
                })
            }else{
                PLU.setCache(listenKey,1)
                return
            }
        },
        //================================================================================================
        splitTFParam(){
            let ltl = (PLU.getCache("listenTF_keys").split("|")[1]||"").split(",")
            PLU.TMP.lis_TF_list=[]; PLU.TMP.lis_TF_force=[]
            ltl.map((e,i)=>{
                if(e.charAt(0)=="#"){
                    PLU.TMP.lis_TF_list.push(e.substring(1))
                    PLU.TMP.lis_TF_force.push(0)
                }else{
                    PLU.TMP.lis_TF_list.push(e)
                    PLU.TMP.lis_TF_force.push(1)
                }
            })
        },
        //================================================================================================
        goQinglong(npcName, place, prize, gb){
            let placeData=PLU.YFD.qlList.find(e=>e.n==place)
            if(UTIL.inHome() && placeData){
                PLU.execActions(placeData.v+';golook_room;',()=>{
                    let objNpc = UTIL.findRoomNpc(npcName,!Number(gb))
                    if(objNpc){
                        PLU.killQinglong(objNpc.key,0)
                    }else{
                        YFUI.writeToOut("<span style='color:#FFF;'>--尋找目標失敗!--</span>")
                        PLU.execActions('golook_room;home')
                    }
                })
            }
        },
        //================================================================================================
        killQinglong(npcId, tryNum){
            PLU.autoFight({
                targetKey:npcId,
                fightKind:'kill',
                autoSkill:'random',
                onFail(errCode){
                    if(errCode>=88 && tryNum<44){
                        setTimeout(()=>{
                            PLU.killQinglong(npcId, tryNum+1);
                        },500)
                        return;
                    }
                    YFUI.writeToOut("<span style='color:#FFF;'>--搶青龍失敗!--</span>")
                    PLU.execActions('home;')
                },
                onEnd(){
                    PLU.execActions('prev_combat;home;')
                }
            })
        },
        //================================================================================================
        goTaofan(npcName, npcPlace, flyLink, gb, force){
            if(UTIL.inHome()){
                let ctn=0, gocmd=flyLink;
                PLU.YFD.cityList.forEach((e,i)=>{if(e==npcPlace) ctn=i+1});
                if(ctn>0) gocmd='jh '+ctn;
                PLU.execActions(gocmd+';golook_room;', e=>{
                    setTimeout(t=>{
                        PLU.killTaofan(npcName, Number(gb), force, 0)
                    },1000)
                })
            }
        },
        //================================================================================================
        killTaofan(npcName, gb, force, tryCount){
            let npcObj = UTIL.findRoomNpc(npcName,Number(gb))
            if(npcObj){
                if(force){
                    PLU.autoFight({
                        targetKey:npcObj.key,
                        fightKind:'kill',
                        autoSkill:'random',
                        onFail(errCode){
                            if(errCode==4){
                                YFUI.writeToOut("<span style='color:#FFF;'>--已達到上限!取消逃犯監聽!--</span>")
                                PLU.setListen($("#btn_bt_listenTF"), "listenTF", 0)
                            }else if(errCode>1 && tryCount<36){
                                setTimeout(()=>{
                                    PLU.killTaofan(npcName, gb, force, tryCount+1);
                                },500)
                                return;
                            }
                            PLU.execActions('golook_room;home;')
                        },
                        onEnd(){
                            PLU.execActions('prev_combat;home;')
                        }
                    })
                }else{
                    PLU.waitDaLaoKill({
                        targetId: npcObj.key,
                        onFail(ec){
                            if(ec==30) YFUI.writeToOut("<span style='color:#FFF;'>--無大佬攻擊,返回!--</span>")
                            return PLU.execActions('golook_room;home;');
                        },
                        onOk(){
                            PLU.autoFight({
                                targetKey:npcObj.key,
                                fightKind:'kill',
                                autoSkill:'random',
                                onFail(errCode){
                                    if(errCode==4){
                                        YFUI.writeToOut("<span style='color:#FFF;'>--已達到上限!取消逃犯監聽--</span>")
                                        PLU.setListen($("#btn_bt_listenTF"), "listenTF", 0)
                                    }else YFUI.writeToOut("<span style='color:#FFF;'>--'ERR="+errCode+"--</span>")
                                    PLU.execActions('golook_room;home;')
                                },
                                onEnd(){
                                    PLU.execActions('prev_combat;home;')
                                }
                            })
                        }
                    })
                }
            }else{
                YFUI.writeToOut("<span style='color:#FFF;'>--找不到NPC!--</span>")
                if(tryCount<4){
                    return setTimeout(()=>{
                        PLU.killTaofan(npcName, gb, force, tryCount+1);
                    },500)
                }
                PLU.execActions('golook_room;home;');
            }
        },
        //================================================================================================

        waitDaLaoKill({targetId,onOk,onFail}){
            let tryTimes=0;
            UTIL.addSysListener("lookNpcWait", function(b, type, subtype, msg) {
                if(type=="notice" && subtype=="notify_fail" && msg.indexOf('沒有這個人')>=0){
                    YFUI.writeToOut("<span style='color:#FFF;'>--目標已丟失!--</span>")
                    UTIL.delSysListener("lookNpcWait")
                    return onFail && onFail(1)
                }
                if(type=='look_npc'){
                    let desc=UTIL.filterMsg(b.get('long'))
                    let lookInfo = desc.match(/[他|她]正與 (\S*)([\S\s]*) 激烈爭鬥中/)
                    if(lookInfo && lookInfo.length>2 && $.trim(lookInfo[2])!=""){
                        YFUI.writeToOut("<span style='color:#9F9;'>--目標已被大佬攻擊,可以跟進--</span>")
                        UTIL.delSysListener("lookNpcWait")
                        return onOk && onOk()
                    }
                    tryTimes++;
                    if(tryTimes>30){
                        UTIL.delSysListener("lookNpcWait")
                        return onFail && onFail(30)
                    }else{
                        setTimeout(()=>{
                            clickButton('look_npc '+targetId)
                        },500)
                    }
                }
                //如提前進入戰鬥可能是因為殺氣, 逃跑後繼續
                if(type=="vs" && subtype=="vs_info" && b.get("vs2_pos1")!=targetId){
                    PLU.autoEscape({
                        onEnd(){
                            setTimeout(()=>{
                                clickButton('look_npc '+targetId)
                            },500)
                        }
                    })
                }
            })
            clickButton('look_npc '+targetId)
        },
        //================================================================================================
        goGCQinglong(npcName, place, prize, gb){
            if(UTIL.inHome()){
                YFUI.writeToOut("<span style='color:#F99;'>--出擊廣場!!!--</span>")
                let objMc = place.match(/武林廣場([\d]+)/)
                if(!objMc) return;
                let objIndex = Number(objMc[1])
                PLU.execActions('jh 1;e;n;n;n;n;w;event_1_64058963 go;home;',e=>{
                    let hasInKuafu = false;
                    let kuafuTimeOut = setTimeout(()=>{
                        if(!hasInKuafu) window.location.reload();
                    },60000)
                    UTIL.addSysListener("listenKuafuGuangchang", function(b, type, subtype, msg) {
                        if(type=="jh" && subtype=="info"){
                            let curIndex=0;
                            if(g_obj_map.get("msg_room").get("short").match(/聚義廳/)){
                                curIndex=11;
                            }else if(g_obj_map.get("msg_room").get("short").match(/武林廣場([\d]+)/)){
                                let rm = g_obj_map.get("msg_room").get("short").match(/武林廣場([\d]+)/)
                                if(rm) curIndex=rm[1]
                            }
                            if(curIndex){
                                hasInKuafu = true;
                                UTIL.delSysListener("listenKuafuGuangchang")
                                clearTimeout(kuafuTimeOut)
                                let gocmd=''
                                if(curIndex==objIndex){
                                    gocmd = 'golook_room;'
                                }else if(objIndex>curIndex){
                                    gocmd = '#'+(objIndex-curIndex)+' e;;'
                                }else{
                                    gocmd = '#'+(curIndex-objIndex)+' w;;'
                                }
                                PLU.execActions(gocmd,r=>{
                                    let objNpc = UTIL.findRoomNpc(npcName,!Number(gb))
                                    if(objNpc){
                                        PLU.killQinglong(objNpc.key, 0)
                                    }else{
                                        YFUI.writeToOut("<span style='color:#FFF;'>--尋找目標失敗!--</span>")
                                        setTimeout(()=>{
                                            PLU.execActions("home")
                                        }, 500);
                                    }
                                })
                            }
                        }
                    })
                    clickButton('change_server world')
                })
            }
        },
        //================================================================================================
        fixJhName(name) {
            switch (name) {
                case "白駝山":
                    return "白馱山";
                case "黑木崖":
                    return "魔教";
                case "光明頂":
                    return "明教";
                case "鐵血大旗門":
                    return "大旗門";
                case "梅莊":
                    return "寒梅莊";
            }
            return name
        },
        //================================================================================================
        goFindYouxia(params){//{paths,idx,objectNPC}
            if(params.idx>=params.paths.length){
                setTimeout(()=>{
                    PLU.execActions("home")
                }, 500);
                YFUI.writeToOut("<span style='color:#FFF;'>--找不到遊俠!...已搜索完地圖--</span>")
                return
            }
            let acs=[params.paths[params.idx]]
            PLU.actions({
                paths:acs,
                idx:0,
                onPathsEnd(){
                    setTimeout(()=>{
                        let npcObj = UTIL.findRoomNpc(params.objectNPC,false,true)
                        if(npcObj){
                            YFUI.writeToOut("<span style='color:#FFF;'>--遊俠已找到--</span>")
                            //npcObj.key
                            PLU.killYouXia(npcObj.key,0)
                        }else{
                            params.idx++;
                            PLU.goFindYouxia(params)
                        }
                    },300)
                },
                onPathsFail(){
                    setTimeout(()=>{
                        PLU.execActions("home")
                    }, 500);
                    YFUI.writeToOut("<span style='color:#FFF;'>--找不到遊俠!...路徑中斷--</span>")
                    return
                },
            })
        },
        //================================================================================================
        killYouXia(npcId, tryNum){
            PLU.autoFight({//autoFight(p
                targetKey:npcId,
                fightKind:'kill',
                autoSkill:'multi',
                onFail(errCode){
                    if(String(errCode).indexOf('delay_')>=0){
                        let mc = String(errCode).match(/delay_(\d+)/)
                        if(mc){
                            let wtime = 500+1000*Number(mc[1])
                            PLU.execActions('follow_play '+npcId+';')
                            YFUI.writeToOut("<span style='color:#FFF;'>▶開始嘗試做遊俠跟班!!</span>")
                            setTimeout(()=>{
                                PLU.execActions('follow_play none',()=>{
                                    YFUI.writeToOut("<span style='color:#FFF;'>◼停止做遊俠跟班!!準備開殺!!</span>")
                                    PLU.killYouXia(npcId, tryNum+1);
                                })
                            },wtime)
                            return;
                        }
                    }else if(errCode>=88 && tryNum<44){
                        setTimeout(()=>{
                            PLU.killYouXia(npcId, tryNum+1);
                        },1000)
                        return;
                    }else if(errCode==1){
                        YFUI.writeToOut("<span style='color:#F99;'>--現場找不到遊俠了!--</span>")
                    }else{
                        YFUI.writeToOut("<span style='color:#F99;'>--攻擊遊俠失敗!--</span>")
                    }
                    PLU.execActions('home;')
                },
                onEnd(){
                    PLU.execActions('prev_combat;home;')
                }
            })
        },
        //================================================================================================
        getSkillsList(callback) {
            UTIL.addSysListener("getSkillsList", function(b, type, subtype, msg) {
                if (type != "skills" && subtype != "list") return;
                UTIL.delSysListener("getSkillsList");
                clickButton("prev");
                let all = [], tupo = [];
                all = PLU.parseSkills(b)
                all.forEach(skill=>{
                    if (skill.state >= 4) {
                        tupo.push(skill);
                    }
                })
                // window.tempSkills=b.elements
                // console.log(b.elements,all)
                callback(all, tupo);
            })
            clickButton("skills")
        },
        //================================================================================================
        parseSkills(b){
            let allSkills = []
            for (var i = b.elements.length - 1; i > -1; i--) {
                if(b.elements[i].key && b.elements[i].key.match(/skill(\d+)/)){
                    var attr = b.elements[i].value.split(",");
                    var skill = {
                        key: attr[0],
                        name: $.trim(UTIL.filterMsg(attr[1])),
                        level: Number(attr[2]),
                        kind: attr[4],
                        prepare: Number(attr[5]),
                        state: Number(attr[6]),
                        from: attr[7],
                    }
                    allSkills.push(skill);
                }
            }
            allSkills = allSkills.sort((a,b)=>{
                if(a.kind=='known') return -1;
                else if(b.kind!='known' && a.from=='基礎武功') return -1;
                else if(b.kind!='known' && b.from!='基礎武功' && a.kind=='force') return -1;
                else return 1
            })
            return allSkills
        },
        //================================================================================================
        toToPo(){
            setTimeout(function() {
                if(UTIL.inHome()){
                    PLU.getSkillsList((allSkills, tupoSkills)=>{
                        if (tupoSkills.length > 0) {
                            if(PLU.STO.outSkillList) clearTimeout(PLU.STO.outSkillList)
                            PLU.STO.outSkillList=setTimeout(() => {
                                PLU.STO.outSkillList=null
                                if(!!$("#out_top").height() && $("#out_top .outtitle").text()=='我的技能') clickButton('home');
                            }, 200);
                            return;
                        }
                        let tpArr = PLU.getCache('autoTP_keys').split(',')
                        let tpList=[];
                        tpArr.forEach(s=>{
                            let sk={}, cs = s.match(/([\*]+)(.*)/)
                            if(cs) {
                                sk.name=cs[2]; sk.sp=cs[1].length;
                            }else{
                                sk.name=s; sk.sp=0;
                            }
                            let skobj = allSkills.find(e=>e.name.match(sk.name))
                            if(skobj) tpList.push(Object.assign({},skobj,sk))
                        })
                        PLU.TMP.stopToPo = false
                        PLU.toPo(tpList, 0)
                    })
                }
            },500)
        },
        //================================================================================================
        toPo(tpList, skIdx){
            if(skIdx < tpList.length && !PLU.TMP.stopToPo){
                let acts='enable '+tpList[skIdx].key+';tupo go,'+tpList[skIdx].key+';'
                if(tpList[skIdx].sp==1) acts+='tupo_speedup4_1 ' + tpList[skIdx].key + ' go;';
                else if(tpList[skIdx].sp==2) acts+='tupo_speedup3_1 ' + tpList[skIdx].key + ' go;';

                PLU.execActions(acts, ()=>{
                    setTimeout(()=>{
                        if(PLU.STO.outSkillList) clearTimeout(PLU.STO.outSkillList)
                        PLU.STO.outSkillList=null
                        PLU.toPo(tpList, skIdx+1)
                    },300)
                })
            }else{
                YFUI.writeToOut("<span style='color:yellow;'> ==突破完畢!== </span>")
                clickButton('home');
            }
            // tpList.forEach(e=>{
            //     acts+='enable '+e.key+';tupo go,'+e.key+';'
            //     if(e.sp==1) acts+='tupo_speedup4_1 ' + e.key + ' go;';
            //     else if(e.sp==2) acts+='tupo_speedup3_1 ' + e.key + ' go;';
            // })
            // PLU.execActions(acts, ()=>{
            // 	setTimeout(()=>{
            // 		if(PLU.STO.outSkillList) clearTimeout(PLU.STO.outSkillList)
            // 		PLU.STO.outSkillList=null
            // 		clickButton('home');
            // 	},500)
            // })
        },
        //================================================================================================
        toBangFour(n){
            UTIL.log({msg:' 進入幫四('+n+') ', type:'TIPS', time:new Date().getTime()})
            PLU.STO.bangFourTo && clearTimeout(PLU.STO.bangFourTo);
            PLU.STO.bangFourTo = setTimeout(function(){
                clickButton('home')
            },30*60*1000)
            clickButton('clan fb enter shiyueweiqiang-'+n, 0)
        },
        toBangSix(){
            UTIL.log({msg:' 進入幫六 ', type:'TIPS', time:new Date().getTime()})
            PLU.STO.bangSixTo && clearTimeout(PLU.STO.bangSixTo);
            PLU.STO.bangSixTo = setTimeout(function(){
                clickButton('home')
            },30*60*1000)
            clickButton('clan fb enter manhuanqishenzhai', 0)
        },
        //================================================================================================
        inBangFiveEvent(){
            PLU.toggleFollowKill($("#btn_bt_kg_followKill"), "followKill", 1);
            var moving = false;
            PLU.TMP.listenBangFive = true;
            UTIL.addSysListener("listenBangFive", function(b, type, subtype, msg) {
                if(!moving && type=='jh' && (subtype=='dest_npc' || subtype=='info')){
                    moving = true;
                    let roomName = UTIL.filterMsg(g_obj_map.get("msg_room").get('short'))
                    if(roomName.match(/蒙古高原|成吉思汗的金帳/) && !UTIL.roomHasNpc()){
                        PLU.execActions(';;n;',()=>{
                            moving = false;
                        })
                    }else{
                        moving = false;
                    }
                }
                if(type=='home' && subtype=='index'){
                    UTIL.delSysListener("listenBangFive");
                    YFUI.writeToOut("<span style='color:white;'> ==幫五完畢!== </span>")
                    PLU.execActions('golook_room;home')
                }
            })
        },
        intervene(){
            setTimeout(o=>{
                $(document).one('click',o=>{
                    eval($(o.target).closest('button')[0].getAttributeNode("onclick").value.replace('score', 'watch_vs'));
                    console.log(g_obj_map)
                })
            },500)
            while (! g_obj_map.get("msg_vs_info")) {
                if (g_obj_map.get("msg_vs_info").get("vs2_pos1")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos1") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos1") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos1") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos2")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos2") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos2") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos2") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos3")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos3") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos3") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos3") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos4")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos4") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos4") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos4") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos5")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos5") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos5") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos5") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos6")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos6") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos6") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos6") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos7")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos7") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos7") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos7") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs2_pos8")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs2_pos8") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs2_pos8") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs2_pos8") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos1")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos1") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos1") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos1") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos2")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos2") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos2") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos2") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos3")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos3") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos3") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos3") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos4")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos4") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos4") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos4") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos5")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos5") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos5") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos5") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos6")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos6") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos6") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos6") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos7")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos7") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos7") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos7") + "')\">切磋</a>]", 2, 1)
                }
                if (g_obj_map.get("msg_vs_info").get("vs1_pos8")) {
                    writeToScreen(g_obj_map.get("msg_vs_info").get("vs1_pos8") + " [<a href=\"javascript:clickButton('kill " + g_obj_map.get("msg_vs_info").get("vs1_pos8") + "')\">殺</a> , <a href=\"javascript:clickButton('fight " + g_obj_map.get("msg_vs_info").get("vs1_pos8") + "')\">切磋</a>]", 2, 1)
                }

                console.log(1)
            }

        },

        //================================================================================================
        checkUseSkills(){
            let curTime = new Date().getTime();
            if(!PLU.battleData.performTime || curTime-PLU.battleData.performTime >= 400) {
                PLU.battleData.performTime = curTime
                if(!PLU.battleData.mySide){
                    let vsInfo = g_obj_map.get("msg_vs_info");
                    for (let i = vsInfo.elements.length - 1; i > -1; i--) {
                        let val = vsInfo.elements[i].value + "";
                        if (!val || val.indexOf(PLU.accId) < 0) continue;
                        PLU.battleData.myPos = vsInfo.elements[i].key.charAt(7);
                        PLU.battleData.mySide = vsInfo.elements[i].key.substring(0, 3);
                        break;
                    }
                }
                if(PLU.battleData.mySide){
                    if(PLU.getCache("autoCure")==1){
                        PLU.checkAutoCure()
                    }
                    if(PLU.getCache("autoPerform")>=1){
                        PLU.checkAutoPerform()
                    }
                }
            }
        },
        //================================================================================================
        setAutoCure($btn, listenKey, stat){
            if(listenKey=="autoCure"){//自動加血藍
                YFUI.showInput({
                    title:"自動加血加藍",
                    text:`格式:血百分比|加血技能,藍百分比|加藍技能,以英文逗號分割,每樣只能設置一個技能。<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">50|道種心魔經,10|不動明王訣</span><br> 血低於50%自動加血,藍低於10%自動加藍<br>
                            [例2] <span style="color:blue;">30|紫血大法</span><br> 血低於30%自動加血技能,不自動加藍<br>
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"10|道種心魔經,10|不動明王訣",
                    onOk(val){
                        let str=$.trim(val);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.splitCureSkills()
                    },
                    onNo(){
                    }
                })
            }
        },
        toggleAutoCure($btn, listenKey, stat){
            let btnFlag = 0;
            if(stat!=undefined){
                btnFlag = PLU.setBtnRed($btn, stat)
                PLU.setCache(listenKey,stat)
            }else{
                btnFlag = PLU.setBtnRed($btn)
            }
            if(!btnFlag) {
                return PLU.setCache(listenKey,0)
            }else{
                PLU.setCache(listenKey,1)
                setTimeout(()=>{
                    YFUI.writeToOut("<span style='color:yellow;'>自動血藍: "+PLU.getCache(listenKey+"_keys")+" </span>")
                },100)
            }
        },
        //================================================================================================
        splitCureSkills(){
            let kf = (PLU.getCache("autoCure_keys")||'').split(',')
            PLU.TMP.autoCure_percent = '';
            PLU.TMP.autoCure_skills = '';
            PLU.TMP.autoCure_force_percent = '';
            PLU.TMP.autoCure_force_skills = '';
            if(kf.length>0){
                let acp = kf[0].split('|')
                PLU.TMP.autoCure_percent = Number(acp[0])||50
                PLU.TMP.autoCure_skills = acp[1]
                if(kf.length>1){
                    let acf = kf[1].split('|')
                    PLU.TMP.autoCure_force_percent = Number(acf[0])||10
                    PLU.TMP.autoCure_force_skills = acf[1]
                }
            }
        },
        //================================================================================================
        checkAutoCure(){
            let vsInfo = g_obj_map.get("msg_vs_info");
            let userInfo = g_obj_map.get("msg_attrs");
            let keePercent = (100*Number(vsInfo.get(PLU.battleData.mySide+"_kee"+PLU.battleData.myPos)) / Number(userInfo.get("max_kee"))).toFixed(2)
            let forcePercent = (100*Number(vsInfo.get(PLU.battleData.mySide+"_force"+PLU.battleData.myPos)) / Number(userInfo.get("max_force"))).toFixed(2)
            if(!PLU.TMP.autoCure_percent){
                PLU.splitCureSkills()
            }
            if(PLU.TMP.autoCure_force_skills && Number(forcePercent)<PLU.TMP.autoCure_force_percent){
                PLU.autoCureByKills(PLU.TMP.autoCure_force_skills, forcePercent)
            }else if(PLU.TMP.autoCure_skills && Number(keePercent)<PLU.TMP.autoCure_percent && PLU.battleData.cureTimes<3){
                PLU.autoCureByKills(PLU.TMP.autoCure_skills, forcePercent)
            }
        },
        //================================================================================================
        autoCureByKills(skill, forcePercent){
            if(PLU.battleData && PLU.battleData.xdz>2){
                let rg=new RegExp(skill)
                let useSkill=PLU.selectSkills(rg)
                if(useSkill){
                    clickButton(useSkill.key,0)
                    if(Number(forcePercent)>1) PLU.battleData.cureTimes++;
                }
            }
        },
        //================================================================================================
        setAutoPerform($btn, listenKey, stat){
            if(listenKey=="autoPerform"){//自動技能
                let skillsList = []
                try {
                    skillsList = JSON.parse(PLU.getCache(listenKey+"_keysList"))
                } catch (error) {
                    skillsList = ["6|千影百傷棍,九天龍吟劍法"]
                }
                YFUI.showInput({
                    title:"自動技能",
                    text:`格式:觸發氣值|技能詞組,以英文逗號分割多個關鍵詞。<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">9|千影百傷棍,九天龍吟劍法,排雲掌法</span><br> 氣大於等於9時自動使用技能<br>
                            `,
                    value:skillsList,
                    inputs:['技能1','技能2','技能3','技能4'],
                    onOk(val){
                        PLU.setCache(listenKey+"_keysList",JSON.stringify(val))
                        if(PLU.getCache(listenKey)){
                            PLU.setPerformSkill(PLU.getCache(listenKey))
                        }
                    },
                    onNo(){
                    }
                })
            }
        },
        toggleAutoPerform($btn, listenKey, stat){
            let curIdx = Number(PLU.getCache(listenKey));
            if(stat!=undefined){
                if(stat>0){
                    PLU.setBtnRed($btn, 1);
                    PLU.setPerformSkill(stat)
                }else PLU.setBtnRed($btn, 0);
                $btn.text(['連招','技一','技二','技三','技四'][stat])
                PLU.setCache(listenKey,stat)
                if(stat>0) PLU.TMP.lastAutoPerformSet = stat;
            }else{
                let nowTime = Date.now();
                if(curIdx==0 && nowTime-(PLU.TMP.lastClickAutoPerform||0) < 350){
                    curIdx = PLU.TMP.lastAutoPerformSet||1;
                    curIdx++;
                    if(curIdx>4) curIdx=1;
                }else{
                    curIdx = curIdx==0 ? (PLU.TMP.lastAutoPerformSet||1) : 0;
                }
                PLU.TMP.lastClickAutoPerform = nowTime;
                if(curIdx>0) PLU.TMP.lastAutoPerformSet = curIdx;
                PLU.setCache(listenKey,curIdx)
                if(curIdx==0){
                    PLU.setBtnRed($btn, 0)
                    $btn.text('連招')
                }else{
                    PLU.setBtnRed($btn, 1)
                    $btn.text(['連招','技一','技二','技三','技四'][curIdx])
                    PLU.setPerformSkill(curIdx)
                }
            }
        },
        setPerformSkill(idx){
            let skillsList = [];
            idx = idx-1;
            try {
                skillsList = JSON.parse(PLU.getCache("autoPerform_keysList"))
            } catch (error) {
                skillsList = []
            }
            let str = skillsList[idx] || "";
            let aps = str.split('|')
            if(aps && aps.length==2){
                PLU.TMP.autoPerform_xdz = Number(aps[0])
                PLU.TMP.autoPerform_skills = aps[1].split(',')
            }else{
                PLU.TMP.autoPerform_xdz = 0
                PLU.TMP.autoPerform_skills = []
            }
            setTimeout(()=>{
                let setCh = ['一','二','三','四'][idx]
                YFUI.writeToOut("<span style='color:yellow;'>自動技能["+setCh+"] : "+str+" </span><br><span style='color:white;'>** 雙擊自動技能按鈕切換技能設置 **</span>")
            },100)
        },
        //================================================================================================
        checkAutoPerform(){
            // if(PLU.battleData.autoSkill) return;
            if(!PLU.TMP.autoPerform_xdz) return;
            // if(!PLU.TMP.autoPerform_xdz){
            //     let aps = PLU.getCache("autoPerform_keys").split('|')
            //     PLU.TMP.autoPerform_xdz = Number(aps[0])
            //     PLU.TMP.autoPerform_skills = aps[1].split(',')
            // }
            if(PLU.battleData.xdz >= PLU.TMP.autoPerform_xdz){
                if(PLU.TMP.autoPerform_skills && PLU.TMP.autoPerform_skills.length>0){
                    PLU.TMP.autoPerform_skills.forEach((skn,idx)=>{
                        let useSkill=PLU.selectSkills(skn)
                        if(useSkill){
                            setTimeout(e=>{
                                clickButton(useSkill.key,0)
                            },idx*100)
                        }
                    })
                }
            }
        },
        //================================================================================================
        setFightSets($btn, listenKey, stat){
            if(listenKey=="followKill"){//開跟殺
                YFUI.showInput({
                    title:"開跟殺",
                    text:`格式:跟殺的人名詞組,以英文逗號分割多個關鍵詞,人名前帶*為反跟殺。<br>
                            <span style="color:red;">例如:</span><br>
                            [例1] <span style="color:blue;">步驚鴻,*醉漢</span><br> 步驚鴻攻擊(殺or比試)誰我攻擊誰;誰攻擊醉漢我攻擊誰<br>
                            `,
                    value:PLU.getCache(listenKey+"_keys")||"自由的風,諸葛豆,唐伯虎,關七,冷月影,粉味野貓",
                    //type:"textarea",
                    onOk(val){
                        let str=$.trim(val);
                        PLU.setCache(listenKey+"_keys",str)
                        PLU.splitFollowKillKeys();
                    },
                    onNo(){
                    }
                })
            }
        },
        toggleFollowKill($btn, listenKey, stat){
            let btnFlag = 0;
            if(stat!=undefined){
                btnFlag = PLU.setBtnRed($btn, stat)
                PLU.setCache(listenKey,stat)
            }else{
                btnFlag = PLU.setBtnRed($btn)
            }
            if(!btnFlag) {
                return PLU.setCache(listenKey,0)
            }else{
                PLU.splitFollowKillKeys();
                PLU.setCache(listenKey,1)
                setTimeout(()=>{
                    YFUI.writeToOut("<span style='color:yellow;'>自動跟殺: "+PLU.getCache(listenKey+"_keys")+" </span>")
                },100)
            }
        },
        //================================================================================================
        splitFollowKillKeys(){
            let keystr = PLU.getCache("followKill_keys")||''
            let keys = keystr.split(/[,,]/);
            PLU.FLK={
                followList:[],
                defendList:[]
            }
            keys.forEach(e=>{
                if(!e) return;
                if(e.charAt(0)=="*"){
                    PLU.FLK.defendList.push(e.substring(1))
                }else{
                    PLU.FLK.followList.push(e)
                }
            })
        },
        //================================================================================================
        toCheckFollowKill(attacker, defender, fightType, msgText){
            if(!PLU.FLK) PLU.splitFollowKillKeys();
            for (let i = 0; i < PLU.FLK.followList.length; i++) {
                let flname = PLU.FLK.followList[i]
                if(attacker.match(flname)){
                    PLU.autoFight({
                        targetName: defender,
                        fightKind: fightType,
                        onFail(){},
                        onEnd(){}
                    })
                    return
                }
            }
            for (let i = 0; i < PLU.FLK.defendList.length; i++) {
                let dfname = PLU.FLK.defendList[i]
                if(defender.match(dfname)){
                    PLU.autoFight({
                        targetName: attacker,
                        fightKind: fightType,
                        onFail(){},
                        onEnd(){}
                    })
                    return
                }
            }
        },
        //================================================================================================
        startSync($btn){
            PLU.getTeamInfo(t=>{
                if(!t) PLU.setBtnRed($btn);
                else{
                    YFUI.writeToOut("<span style='color:yellow;'>===隊伍同步開始"+(t.is_leader?", <b style='color:#F00;'>我是隊長</b>":"")+" ===</span>")
                    if(t.is_leader){
                        PLU.TMP.leaderTeamSync = true;
                    }else{
                        PLU.listenTeamSync(t.leaderId)
                    }
                }
            })
        },
        toggleTeamSync($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(btnFlag) {
                if(PLU.TMP.firstSync) PLU.startSync($btn);
                else{
                    YFUI.showPop({
                        title:"隊伍同步",
                        text: "<b style='color:#F00;'>入隊後再打開隊伍同步!!</b><br>隊長髮布指令, 隊員監聽同步指令!",
                        okText:"同步",
                        onOk(e){
                            PLU.TMP.firstSync = 1;
                            PLU.startSync($btn)
                        },
                        onNo(){
                            PLU.setBtnRed($btn)
                        },
                        onX(){
                            PLU.setBtnRed($btn)
                        }
                    })
                }
            }else{
                PLU.TMP.leaderTeamSync = false;
                UTIL.delSysListener("syncTeamChannel");
            }
        },
        //================================================================================================
        commandTeam(args){
            if(!PLU.TMP.leaderTeamSync) return;
            if(!g_gmain.is_fighting && !args[0].match(/chat|attr|watch\_vs|items\ |score/)){
                var cmd = PLU.Base64.encode(args[0]).split("").join("-");
                clickButton("team chat " + cmd + "\n")
            }
        },
        //================================================================================================
        listenTeamSync(leaderId){
            UTIL.addSysListener("syncTeamChannel", function(b, type, subtype, msg) {
                if (type == "channel" && subtype == "team" && msg.indexOf(leaderId) > 0 && msg.indexOf("【隊伍】") > 0) {
                    var cmd = PLU.Base64.decode(msg.split(':')[1].replace("", "").replace(/-/g, "")).replace(/\n/g, "");
                    if (!cmd.match(/chat|attr|watch\_vs|items\ |score/)){
                        clickButton(cmd);
                    }
                }
            })
        },
        //================================================================================================
        getTeamInfo(callback){
            UTIL.addSysListener("checkTeam", function(b, type, subtype, msg) {
                if (type != "team" && subtype != "info") return;
                UTIL.delSysListener("checkTeam");
                if(b.get("team_id")){
                    if(b.get("is_member_of")=='1'){
                        callback && callback({
                            is_leader: parseInt(b.get("is_leader")),
                            leaderId: b.get("member1").split(',')[0]
                        })
                    }else{
                        callback && callback(0)
                    }
                }else{
                    callback && callback(0)
                }
                clickButton("prev");
            })
            clickButton("team");
        },
        //================================================================================================
        setSkillGroup(idx){
            if(g_gmain.is_fighting) return;
            $(".menu").hide()
            let lsgTimeOut=setTimeout(()=>{
                UTIL.delSysListener("loadSkillGroup");
            },5000)
            UTIL.addSysListener("loadSkillGroup", function(b, type, subtype, msg) {
                if (type != "enable" && subtype !== "list") return;
                UTIL.delSysListener("loadSkillGroup");
                clearTimeout(lsgTimeOut)
                clickButton("prev");
            })
            clickButton("enable mapped_skills restore go " + idx);
        },
        //================================================================================================
        setWearEquip(idx){
            if(g_gmain.is_fighting) return;
            $(".menu").hide()
            let equipKey = "equip_"+idx+"_keys";
            YFUI.showInput({
                title:"裝備組-"+idx,
                text:`格式:武器裝備詞組,以英文逗號分割多個關鍵詞,<br>
						<span style="color:#D60;">武器名前必須帶上*,入脈武器名前帶**。<br>
						卸下武器名前帶上#。</span><br>
                        <span style="color:red;">例如:</span><br>
                        [例1] <span style="color:blue;">#風泉之劍,*離別鉤,*傾宇破穹棍,**馭風騰雲,霸天聖袍,紫貪狼戒</span><br>
                        `,
                value:PLU.getCache(equipKey)||"",
                type:"textarea",
                onOk(val){
                    let str=$.trim(val);
                    if(!str) return;
                    PLU.setCache(equipKey,str)
                    PLU.wearEquip(str);
                },
                onNo(){
                }
            })
        },
        wearEquip(equipsStr){
            PLU.getAllItems(list=>{
                let equips=equipsStr.split(','), equipCmds='';
                let equipArr=equips.forEach(e=>{
                    let eqObj={}
                    if(e.substr(0,1)=="#"){
                        eqObj={type:-1,name:e.substr(1)}
                    }else if(e.substr(0,2)=="**"){
                        eqObj={type:2,name:e.substr(2)}
                    }else if(e.substr(0,1)=="*"){
                        eqObj={type:1,name:e.substr(1)}
                    }else{
                        eqObj={type:0,name:e}
                    }
                    let bagItem=list.find(it=>!!it.name.match(eqObj.name))
                    if(bagItem){
                        if(eqObj.type==-1) equipCmds+='unwield '+bagItem.key+';';
                        else if(eqObj.type==2) equipCmds+='wield '+bagItem.key+' rumai;';
                        else if(eqObj.type==1) equipCmds+='wield '+bagItem.key+';';
                        else equipCmds+='wear '+bagItem.key+';';
                    }
                })
                PLU.execActions(equipCmds, ()=>{
                    YFUI.writeToOut("<span style='color:yellow;'> ==裝備完畢!== </span>")
                })
            })
        },
        //================================================================================================
        showLog(){
            if($('#myTools_InfoPanel').length>0) return $('#myTools_InfoPanel').remove();
            let $logPanel = YFUI.showInfoPanel({
                text:'',
                onOpen(){
                    $('#myTools_InfoPanel .infoPanel-wrap').html(PLU.logHtml)
                    $('#myTools_InfoPanel .infoPanel-wrap').scrollTop($('#myTools_InfoPanel .infoPanel-wrap')[0].scrollHeight);
                },
                onNo(){
                    PLU.logHtml='';
                    UTIL.logHistory=[];
                    UTIL.setMem("HISTORY",JSON.stringify(this.logHistory));
                    $('#myTools_InfoPanel .infoPanel-wrap').empty()
                },
                onClose(){
                }
            })
            },
        //================================================================================================
        updateShowLog(e){
            let html = `<div style="${e.ext.style}">${UTIL.getNow(e.ext.time)} ${e.ext.msg}</div>`
			PLU.logHtml+=html;
            if($('#myTools_InfoPanel').length<1) return;
            $('#myTools_InfoPanel .infoPanel-wrap').append(html)
            $('#myTools_InfoPanel .infoPanel-wrap').scrollTop($('#myTools_InfoPanel .infoPanel-wrap')[0].scrollHeight);
        },
        //================================================================================================
        goHJS(){
            let roomInfo = g_obj_map.get("msg_room")
            let curName = UTIL.filterMsg(roomInfo.get("short")||'');
            let act=''
            if(curName=='青苔石階' && roomInfo.get('northwest')=='青苔石階') act='nw';
            else if(curName=='青苔石階' && roomInfo.get('northeast')=='青苔石階') act='ne';
            else if(curName=='青苔石階' && roomInfo.get('southwest')=='青苔石階') act='sw';
            else if(curName=='榆葉林' && roomInfo.get('north')=='榆葉林') act='n';
            else if(curName=='榆葉林' && roomInfo.get('south')=='榆葉林') act='s';
            if(act) PLU.execActions(act, ()=>{
                PLU.goHJS()
            })
        },
        //================================================================================================
        goHaRi(){
            let roomInfo = g_obj_map.get("msg_room")
            let curName = UTIL.filterMsg(roomInfo.get("short")||'');
            let act=''
            if(curName=='沙漠迷宮'){
                if(roomInfo.get('east')=='沙漠迷宮') act='e';
                else if(roomInfo.get('north')=='沙漠迷宮') act='n';
                else if(roomInfo.get('west')=='沙漠迷宮') act='w';
                else if(roomInfo.get('south')=='沙漠迷宮') act='s';
                if(act) PLU.execActions(act, ()=>{
                    PLU.goHaRi()
                })
            }else if(curName=='荒漠'){
                PLU.execActions('n;n;nw;n;ne', ()=>{
                    YFUI.writeToOut("<span style='color:#FFF;'>--到達--</span>")
                })
            }else{
                PLU.execActions('rank go 263;e;s;w;w;s;sw;sw;sw;sw;nw;nw;n;nw;ne;', ()=>{
                    PLU.goHaRi()
                })
            }

        },
        //================================================================================================
        queryJHMenu($btn, jhname){
            let npcList = PLU.YFD.mapsLib.Npc.filter(e=>e.jh==jhname)
            npcList.forEach(e=>{
                let str=[e.jh,e.loc,e.name].filter(s=>!!s).join('-')
                YFUI.writeToOut("<span><a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.goNpcWay(\""+str+"\",\""+e.way+"\")'>"+str+"</a> &nbsp;&nbsp;<a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.showNpcWay(\""+str+"\",\""+e.way+"\")'>路徑詳情</a></span>")
            })
            YFUI.writeToOut("<span>----------</span>")
        },
        //================================================================================================
        toQueryNpc(){
            YFUI.showInput({
                title:"查找NPC",
                text:"輸入NPC名字,可模糊匹配",
                value:PLU.getCache("prevSearchStr")||'',
                onOk(val){
                    if(!$.trim(val)) return;
                    let str=$.trim(val)
                    PLU.setCache("prevSearchStr",str)
                    PLU.queryNpc(str)
                },
                onNo(){
                }
            })
        },
        //================================================================================================
        queryNpc(name){
            if(!name) return
            let npcLib=PLU.YFD.mapsLib.Npc
            let findList = npcLib.filter(e=>{
                if(e.name.match(name)) return true;
                return false
            })
            if(findList && findList.length>0){
                findList.forEach(e=>{
                    let str=[e.jh,e.loc,e.name].filter(s=>!!s).join('-')
                    YFUI.writeToOut("<span><a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.goNpcWay(\""+str+"\",\""+e.way+"\")'>"+str+"</a> &nbsp;&nbsp;<a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.showNpcWay(\""+str+"\",\""+e.way+"\")'>路徑詳情</a></span>")
                })
                YFUI.writeToOut("<span>----------</span>")
            }else{
                YFUI.writeToOut("<span style='color:#F66;'>查詢不到相關數據</span>")
            }
        },
        //================================================================================================
        toPathNpc(){
            let defaultMapId =  PLU.getCache("pathFindMap") || '1';
            let citys = PLU.YFD.cityList.map((c,i)=>{
                let issel = (i+1)==defaultMapId ? 'selected':''
                return '<option value="'+(i+1)+'" '+issel+'>'+c+'</option>'
            }).join('')
            YFUI.showPop({
                title:"全圖找NPC",
                text: `選擇地圖, 輸入NPC名字,可模糊匹配<br>
				<div style='margin:10px 0;'>
					<span>地圖: </span>
					<select id="pathFindMap" style="font-size:15px;height:32px;width:81%;border:1px solid #444;">
						${citys}
					</select>
				</div>
				<div style='margin:10px 0;'>
					<span>名字: </span>
					<input id="pathFindNpc" value="${PLU.getCache("pathFindNpc")||''}" style="font-size:14px;height:26px;width:80%;border:1px solid #444;"></input>
				</div>`,
                onOk(){
                    let mapStr = $.trim($('#pathFindMap').val()) ,
                        npcStr = $.trim($('#pathFindNpc').val());
                    console.log(mapStr,npcStr)
                    if(!npcStr) return;
                    PLU.setCache("pathFindMap",mapStr)
                    PLU.setCache("pathFindNpc",npcStr)
                    let jhMap = PLU.YFD.mapsLib.Map.find(e=>e.jh==mapStr)
                    if(!jhMap){
                        return YFUI.writeToOut("<span style='color:#F66;'>---無地圖數據---</span>")
                    }else{
                        let ways = jhMap.way.split(";")
                        console.log({paths:ways,idx:0,objectNPC:npcStr})
                        PLU.goPathFindNpc({paths:ways,idx:0,objectNPC:npcStr})
                    }
                },
                onNo(){

                }
            })
        },
        goPathFindNpc(params){
            //goFindYouxia
            if(params.idx>=params.paths.length){
                setTimeout(()=>{
                    PLU.execActions("home")
                }, 1000);
                YFUI.writeToOut("<span style='color:#FFF;'>--找不到目標NPC!...已搜索完地圖--</span>")
                return
            }
            let acs=[params.paths[params.idx]]
            PLU.actions({
                paths:acs,
                idx:0,
                onPathsEnd(){
                    setTimeout(()=>{
                        let npcObj = UTIL.findRoomNpcReg(params.objectNPC)
                        if(npcObj){
                            YFUI.writeToOut("<span style='color:#FFF;'>--目標NPC已找到--</span>")
                        }else{
                            params.idx++;
                            PLU.goPathFindNpc(params)
                        }
                    },200)
                },
                onPathsFail(){
                    setTimeout(()=>{
                        PLU.execActions("home")
                    }, 500);
                    YFUI.writeToOut("<span style='color:#FFF;'>--找不到目標NPC!...路徑中斷--</span>")
                    return
                },
            })
        },
        //================================================================================================
        goNpcWay(desc,way){
            let goList = PLU.getCache("prevQueryList") || [];
            let newList = goList.filter(e=>e.desc!=desc)
            let len = newList.unshift({desc:desc,way:way})
            if(len>10) newList.length=10;
            PLU.setCache("prevQueryList",newList)
            PLU.execActions(way)
        },

        //================================================================================================
        //================================================================================================
        showNpcWay(desc,way){
            YFUI.showPop({
                title:"路徑詳情:"+desc,
                text:"<span style='color:blue;background:rgba(255,255,244,0.8);padding:1px 10px;display:inline-block;word-break:break-all;'>"+way+"</span></br>",
                autoOk:10,
                okText:"關閉",
                noText:"前往",
                onOk(){},
                onNo(){
                    PLU.goNpcWay(desc, way)
                }
            })
        },
        //================================================================================================
        toQueryHistory(){
            let prevList = PLU.getCache("prevQueryList") || [];
            if(prevList.length==0) return YFUI.writeToOut("<span style='color:#F66;'>---無歷史數據---</span>")
            for(let i=prevList.length-1;i>=0;i--){
                let e=prevList[i]
                YFUI.writeToOut("<span><a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.goNpcWay(\""+e.desc+"\",\""+e.way+"\")'>"+e.desc+"</a> &nbsp;&nbsp;<a style='text-decoration:underline;color:yellow;cursor:pointer;' onclick='PLU.showNpcWay(\""+e.desc+"\",\""+e.way+"\")'>路徑詳情</a></span>")
            }
            YFUI.writeToOut("<span>----------</span>")
        },
        //================================================================================================
        showMPFZ($btn){
            let btnFlag = PLU.setBtnRed($btn)
            if(!btnFlag) {
                $('#topMonitor').hide();
                $("#btn_bt_showMPFZ").text('紛爭顯示')
                PLU.setCache('showTopMonitor',0)
                return
            }
            $('#topMonitor').show();
            $("#btn_bt_showMPFZ").text('紛爭隱藏')
            PLU.setCache('showTopMonitor',1)
        },
        //================================================================================================
        openCombineGem(){
            let htm='<div>'
            PLU.YFD.gemType.forEach((t,ti)=>{
                htm+='<div>'
                PLU.YFD.gemPrefix.forEach((p,pi)=>{
                    if(pi>2) htm+='<button onclick="PLU.combineGem('+ti+','+pi+')" style="color:'+t.color+';width:18%;margin:2px 1%;padding:3px;">'+(p.substr(0,2)+t.name.substr(0,1))+'</button>'
                })
                htm+='</div>'
            })
            htm+='</div>'
            htm+=`<div style="margin:10px 0 0 3px;position:absolute;left:15px;bottom:10px;">每次連續合成最多 <input id="maxCombine" type="number" value="1" style="width:50px;height:25px;line-height:25px;" maxlength="3" min=1 max=9999 oninput="if(value.length>4)value=value.substr(0,4)"/> 顆寶石。</div>`
            YFUI.showPop({
                title:"合成寶石",
                text:htm,
                width:"382px",
                okText:"關閉",
                onOk(){}
            })
        },
        //================================================================================================
        combineGem(type,grade){
            if(PLU.TMP.combineTooFast) return YFUI.writeToOut("<span style='color:#F66;'>--點擊不要太快!--</span>");
            PLU.TMP.combineTooFast = setTimeout(()=>{ PLU.TMP.combineTooFast = null; },600000)
            let targetNum = parseInt($("#maxCombine").val())||1
            let getNum = 0
            let countString=function(combineNum, gemCode){
                let combineStr=''
                if(combineNum%3 != 0) return ""
                while (combineNum>0) {
                    if(combineNum>=30){
                        combineStr+="items hecheng " + gemCode + "_N_10;";
                        combineNum-=30
                    }else{
                        combineStr+="items hecheng " + gemCode + "_N_1;";
                        combineNum-=3
                    }
                }
                return combineStr
            }
            let needGem=function(gemGrade, needNum, gemList){
                if(gemGrade<0) return null
                let gemName = PLU.YFD.gemPrefix[gemGrade]+PLU.YFD.gemType[type].name
                let gemCode = PLU.YFD.gemType[type].key+''+(gemGrade+1)
                let objGem = gemList.find(e=>e.name==gemName)
                let gemNum = objGem?objGem.num:0
                if(gemNum>=needNum){
                    return countString(needNum, gemCode)
                }else {
                    let dtNum = needNum-gemNum
                    let next = needGem(gemGrade-1, 3*dtNum, gemList)
                    if(next) return next+countString(needNum, gemCode)
                    return null
                }
            }
            let countCombine=function(cb){
                PLU.getGemList(gemList=>{
                    let runStr = needGem(grade-1, 3, gemList)
                    if(runStr){
                        PLU.fastExec(runStr+'items', ()=>{
                            YFUI.writeToOut("<span style='color:white;'>==合成寶石x1==</span>")
                            getNum++;
                            targetNum--;
                            if(targetNum>0){
                                countCombine(()=>{
                                    cb && cb(true)
                                })
                            }else{
                                cb && cb(true)
                            }
                        })
                    }else{
                        YFUI.writeToOut("<span style='color:#F66;'>--沒有足夠的寶石!--</span>")
                        cb && cb(false)
                    }
                })
            }
            countCombine(end=>{
                clearTimeout(PLU.TMP.combineTooFast);PLU.TMP.combineTooFast = null;
                YFUI.writeToOut("<span style='color:white;'>==合成寶石結束! 得到寶石x"+getNum+"==</span>")
            })
        },
        //================================================================================================
        getGemList(callback){
            let getItemsTimeOut=setTimeout(()=>{
                UTIL.delSysListener("getListItems");
            },5000)
            UTIL.addSysListener("getListItems", function(b, type, subtype, msg) {
                if(type != "items" || subtype != "list") return;
                UTIL.delSysListener("getListItems");
                clearTimeout(getItemsTimeOut)
                //clickButton("prev");
                let iId=1, itemList=[];
                while (b.get('items'+iId)) {
                    let it=UTIL.filterMsg(b.get('items'+iId)).split(',')
                    if(it && it.length>4 && it[3]=='0' && it[1].match('寶石')) itemList.push({
                        key:it[0],
                        name:it[1],
                        num:Number(it[2])
                    })
                    iId++
                }
                callback && callback(itemList)
            })
            clickButton('items',0)
        },
        //================================================================================================
        getAllItems(callback){
            let getItemsTimeOut=setTimeout(()=>{
                UTIL.delSysListener("getListItems");
            },5000)
            UTIL.addSysListener("getListItems", function(b, type, subtype, msg) {
                if(type != "items" || subtype != "list") return;
                UTIL.delSysListener("getListItems");
                clearTimeout(getItemsTimeOut)
                clickButton("prev");
                let iId=1, itemList=[];
                while (b.get('items'+iId)) {
                    let it=UTIL.filterMsg(b.get('items'+iId)).split(',')
                    if(it && it.length>4) itemList.push({
                        key:it[0],
                        name:it[1],
                        num:Number(it[2]),
                        equipped:(it[3]=='0'),
                    })
                    iId++
                }
                callback && callback(itemList)
            })
            clickButton('items',0)
        },
        //================================================================================================
        saveSetting(){
            YFUI.showPop({
                title:"設置上傳",
                text:"<b style='color:red;'>確定要上傳當前角色腳本設置嗎?</b>",
                onOk(){
                    let cacheData = UTIL.getMem("CACHE")
                    $.ajax({
                        url:'http://www.jiaozis.work:8765/comm/save',
                        type:'POST',
                        data:{data_key:btoa(escape(PLU.accId)),data_type:"CACHE",data_value:btoa(escape(cacheData))},
                        dataType:'json',
                        success:res=>{
                            if(res.code=="00000"){
                                YFUI.writeToOut("<span><span style='color:#AF0;'>本地腳本設置上傳成功!</span></span>")
                            }else{
                                YFUI.writeToOut("<span><span style='color:#F80;'>上傳失敗!("+res.msg+")</span></span>")
                            }
                        },
                    })
                },
                onNo(){
                }
            })
        },
        //================================================================================================
        loadSetting(){
            $.ajax({
                url:'http://www.jiaozis.work:8765/comm/load',
                type:'POST',
                data:{data_key:btoa(escape(PLU.accId))},
                dataType:'json',
                success:res=>{
                    if(res.code=="00000"){
                        let cacheData = unescape(atob(res.data[0].data_value))
                        YFUI.showPop({
                            title:"設置下載",
                            text:"<span style='color:#360;'>角色腳本設置下載成功!是否替換本地設置?</span>",
                            autoOk:10,
                            onOk(){
                                UTIL.setMem("CACHE",cacheData)
                                PLU.initStorage()
                                YFUI.writeToOut("<span><span style='color:#AF0;'>本地腳本設置替換成功!</span></span>")
                            },
                            onNo(){
                            }
                        })
                    }else{
                        YFUI.writeToOut("<span><span style='color:#F80;'>下載失敗!("+res.msg+")</span></span>")
                    }
                },
            })
        },
    }
    //=================================================================================
    // UTIL模塊
    //=================================================================================
    window.UTIL = {
        //================
        accId:null,
        sysListeners:{},
        logHistory:[],
        //================
        getUrlParam(key){
            let res=null,
                au = location.search.split("?"),
                sts = au[au.length-1].split("&");
            sts.forEach(p=>{
                if(p.split("=").length>1 && key==p.split("=")[0]) res=unescape(p.split("=")[1])
            })
            return res;
        },
        getAccId(){
            this.accId = this.getUrlParam('id')
            return this.accId
        },
        setMem(key,data){
            localStorage.setItem('PLU_'+this.accId+'_'+key, data)
        },
        getMem(key){
            return localStorage.getItem('PLU_'+this.accId+'_'+key)
        },
        rnd(){
            return Math.floor(Math.random()*1000000)
        },
        getuuid:function(){
            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c){
                var r = Math.random() * 16 | 0,
                    v = c=='x' ? r : (r & 0x3 | 0x8);
                return v.toString(16);
            });
        },
        getNow(timestamp) {
            var date = timestamp?new Date(timestamp):new Date();
            var Y = date.getFullYear();
            var M = (date.getMonth() + 1 +'').padStart(2,'0');
            var D = (date.getDate()+'').padStart(2,'0');
            var h = (date.getHours()+'').padStart(2,'0');
            var m = (date.getMinutes()+'').padStart(2,'0');
            var s = (date.getSeconds()+'').padStart(2,'0');
            return M + '-' + D + ' ' + h + ':' + m + ':' + s;
        },
        log({msg, type, time, isHistory}){
            let style='color:#333'
            if(type=="TF"){
                let co=msg.match('夜魔')?'#F0F':'#666';
                style = 'color:'+co;
            }else if(type=="QL"){
                style = 'color:#00F';
            }else if(type=="MPFZ"){
                style = 'color:#F60';
            }else if(type=="LPFZ"){
                style = 'color:#033';
            }else if(type=="GCQL"){
                style = 'color:#F00;background:#FF9;';
            }else if(type=="YX"){
                let co2=msg.match('宗師】')?'#00F':msg.match('俠客】')?'#08F':msg.match('魔尊】')?'#F00':msg.match('魔武】')?'#F80':'#999';
                style = 'color:'+co2+';background:#CFC;';
            }else if(type=="BF"){
                style = 'color:#FFF;background:#93C;';
            }else if(type=="TIPS"){
                style = 'color:#29F';
            };
            //console.log('%c%s',style,this.getNow(time)+msg)
            if(!isHistory){
                this.logHistory.push({msg, type, time})
                this.setMem("HISTORY",JSON.stringify(this.logHistory))
            }
            let evt = new Event('addLog')
            evt.ext = {msg, type, time, style}
            document.dispatchEvent(evt)
        },
        filterMsg(s){
            if(typeof(s)=='string') return s.replace(/[\033|\27|\0x1b]\[[0-9|;]+m/ig,'');
            return '';
        },
        sysDispatchMsg(b, type, subtype, msg) {
            for (var key in this.sysListeners) {
                this.sysListeners[key](b, type, subtype, msg);
            }
        },
        addSysListener(key, fn) {
            this.sysListeners[key] = fn;
        },
        delSysListener(key) {
            delete this.sysListeners[key]
        },
        findRoomNpc(npcName,gb, searchAll){
            let roomInfo = g_obj_map.get("msg_room");
            if (!roomInfo) return null;
            for (let i = roomInfo.elements.length - 1; i > 0; i--) {
                let bNpc = this.getSpNpcByIdx(roomInfo,i, searchAll)
                if(bNpc && bNpc.name==npcName){
                    if(!gb) return bNpc;
                    else{
                        let gNpc = this.getSpNpcByIdx(roomInfo,i-1)
                        if(gNpc) return gNpc;
                    }
                }
            }
            return null;
        },
        roomHasNpc(){
            let roomInfo = g_obj_map.get("msg_room");
            let res = false;
            if (!roomInfo) return null;
            for (let i = roomInfo.elements.length - 1; i > 0; i--) {
                if(roomInfo.elements[i].key.match('npc')){
                    res = true;
                    break;
                }
            }
            return res;
        },
        findRoomNpcReg(npcName){
            let roomInfo = g_obj_map.get("msg_room");
            if (!roomInfo) return null;
            for (let i = roomInfo.elements.length - 1; i > 0; i--) {
                let npc = roomInfo.elements[i].key.match(/npc(\d+)/)
                if(npc){
                    let infoArr = roomInfo.elements[i].value.split(",");
                    let name = this.filterMsg(infoArr[1])
                    if(name.match(npcName)) return {name:name,key:infoArr[0]};
                }
            }
            return null;
        },
        getSpNpcByIdx(roomInfo, idx, searchAll){
            let npcInfo = roomInfo.get("npc" + idx)
            if(npcInfo){
                let infoArr = npcInfo.split(",");
                let name = this.filterMsg(infoArr[1])
                if(searchAll) return {name:name,key:infoArr[0]};
                if(name != infoArr[1]) return {name:name,key:infoArr[0]}
            }
            return null
        },
        getItemFrom(name) {
            if (g_gmain.is_fighting) return;
            var roomInfo = g_obj_map.get("msg_room");
            if (!roomInfo) return;
            let item=roomInfo.elements.find(it=> it.key.substring(0,4)=="item" && it.value.indexOf(name)>=0)
            if(item){
                clickButton("get " + item.value.split(",")[0])
            }
        },
        inHome(){
            return $('.out .cmd_main_jh').length
        },
    }
    //=================================================================================
    // UI模塊
    //=================================================================================
    window.YFUI = {
        init(){
            let maxW = $('#out').width()>634 ? 634 : $('#out').width();
            console.log($('#page').width(),$('#out').width())
            let rightStyle = ($('#page').width()-$('#out').width()>4)? 'left:'+(maxW-76+4)+'px;' : 'right:0;'
            this.$Panel=$('<div id="WJPlug_Panel" style="pointer-events:none;position:absolute;z-index:9999;'+rightStyle+';top:5.5%;font-size:12px;line-height:1.2;text-align:right;list-style:none;">')
            $('body').append(this.$Panel)
        },
        addBtnGroup({id,style}){
            let $box=$('<div id="'+id+'" style="position:relative;"></div>')
            style && $box.css(style);
            this.$Panel.append($box)
            return $box
        },
        addBtn({id,groupId,text,onclick,style,boxStyle,extend,children,canSet}){
            let $box=$('<div id="'+id+'" class="btn-box" style="position:relative;pointer-events:auto;"></div>')
            let $btn=$('<button id="btn_'+id+'" style="padding:4px 2px;box-sizing:content-box;margin:1px 1px;border:1px solid #333;border-radius:4px;width:68px;">'+text+'</button>')
            style && $btn.css(style);
            boxStyle && $box.css(boxStyle);
            $btn.$extend = extend;
            $btn.click(e=>{
                onclick && onclick($btn, $box);
            });
            $box.append($btn)
            if(children) $box.append($('<b style="position:absolute;left:1px;top:3px;font-size:12px;">≡</b>'))
            if(canSet){
                let $setbtn = $('<i style="position:absolute;right:-8px;top:2px;font-size:14px;background:#333;color:#fff;font-style:normal;;line-height:1;border:1px solid #CCC;border-radius:100%;padding:2px 6px;cursor:pointer;">S</i>')
                $box.append($setbtn)
                $setbtn.click(e=>{
                    onclick && onclick($btn, $box, 'setting');
                });
            }
            groupId ? $('#'+groupId).append($box) : this.$Panel.append($box)
            $box.$button = $btn
            return $box
        },
        addMenu({id,groupId,text,extend,style,menuStyle,multiCol,onclick,children}){//{text,id,btnId}
            let $btnBox=this.addBtn({id,groupId,text,extend,style,children}), _this=this;
            function addMenuToBtn({btnId,$parent,list,menuStyle}){
                let $listBox=$('<div id="menu_'+btnId+'" class="menu" style="position:absolute;top:0;right:'+($parent.width())+'px;display:none;"></div>')
                $parent.append($listBox)
                list && list.forEach(sub => {
                    let btnOpt = Object.assign({}, sub, {groupId:'menu_'+btnId})
                    if(!btnOpt.onclick){
                        btnOpt.onclick=onclick;
                    }
                    if(multiCol) btnOpt.boxStyle=Object.assign({},{display:'inline-block'},btnOpt.boxStyle)
                    let $subBtnBox=_this.addBtn(btnOpt);
                    if(sub.children) $subBtnBox.$list=addMenuToBtn({btnId:sub.id,$parent:$subBtnBox,list:sub.children,menuStyle:sub.menuStyle})
                });
                $parent.$button.click(e=>{
                    $listBox.toggle().css({right: $parent.width()+5})
                    menuStyle && $listBox.css(menuStyle)
                    $listBox.is(':visible') && $listBox.parent().siblings('.btn-box').find('.menu').hide();
                    onclick && onclick($parent.$button,$parent)
                })
                return $listBox
            }
            $btnBox.$list=addMenuToBtn({btnId:id,$parent:$btnBox,list:children,menuStyle:menuStyle})
            return $btnBox
        },
        showPop(params){
            if($('#myTools_popup').length) $('#myTools_popup').remove()
            params=params||{};
            let okText=params.okText||'確定', noText=params.noText||'取消', _this=this;
            _this.SI_autoOk && clearInterval(_this.SI_autoOk);_this.SI_autoOk=null;
            let ph=`<div style="z-index:9999;position:fixed;top: 40%;left:50%;width:100%;height:0;font-size:14px;" id="myTools_popup">
			<div class="popup-content" style="width:${params.width||'70%'};max-width:512px;background: rgba(255,255,255,.8);border:1px solid #999999;border-radius: 10px;transform: translate(-50%,-50%) scale(.1,.1);transition:all .1s;">
			<div style="padding: 10px 15px;"><span style="font-weight:700;">${params.title||''}</span><span style="float:right;color:#666;cursor:pointer;" class="btncl">✖</span></div>
			<div style="padding: 0 15px;line-height:1.5;max-height:500px;overflow-y:auto;">${params.text||''}</div>
			<div style="text-align:right;padding: 10px;">`;
            if(params.onNo) ph+=`<button style="margin-right: 15px;padding: 5px 20px;border: 1px solid #000;border-radius:5px;" class="btnno">${noText}</button>`;
            ph+=`<button style="padding: 5px 20px;background-color: #963;color:#FFF;border: 1px solid #000;border-radius: 5px;" class="btnok">${okText}</button>
			</div></div></div>`
			let $ph=$(ph)
            $('body').append($ph)
            setTimeout(()=>{
                $ph.find(".popup-content").css({transform:"translate(-50%,-50%) scale(1,1)"})
                params.afterOpen && params.afterOpen($ph)
            },100)
            if(params.autoOk){
                let autoCloseN = Number(params.autoOk)
                $('#myTools_popup .btnok').text(okText+'('+autoCloseN+'s)')
                _this.SI_autoOk=setInterval(() => {
                    autoCloseN--;
                    $('#myTools_popup .btnok').text(okText+'('+autoCloseN+'s)')
                    if(autoCloseN<1){
                        $ph.find('.btnok').click();
                    }
                }, 1000);
            }else if(params.autoNo){
                let autoCloseN = Number(params.autoNo)
                $('#myTools_popup .btnno').text(noText+'('+autoCloseN+'s)')
                _this.SI_autoOk=setInterval(() => {
                    autoCloseN--;
                    $('#myTools_popup .btnno').text(noText+'('+autoCloseN+'s)')
                    if(autoCloseN<1){
                        $ph.find('.btnno').click();
                    }
                }, 1000);
            }
            $ph.find('.btncl').click(e=>{_this.SI_autoOk && clearInterval(_this.SI_autoOk);params.onX && params.onX();$ph.remove();})
            $ph.find('.btnno').click(e=>{_this.SI_autoOk && clearInterval(_this.SI_autoOk);params.onNo && params.onNo();$ph.remove();})
            $ph.find('.btnok').click(e=>{_this.SI_autoOk && clearInterval(_this.SI_autoOk);params.onOk && params.onOk($ph);$ph.remove();})
        },
        showInput(params){
            let popParams=Object.assign({},params)
            let inpstyle="font-size:14px;line-height:1.5;width:100%;padding:5px;border:1px solid #999;border-radius:5px;margin:5px 0;outline:none;box-sizing:border-box;"
            if(params.inputs && params.inputs.length>1){
                for(let i=0;i<params.inputs.length;i++){
                    let val = params.value[i]||''
                    popParams.text+=params.type=="textarea"?`<div><div style="width:20%;float:left;margin:5px 0;line-height:2;text-align:right;">${params.inputs[i]}: </div><div style="width:73%;margin-left:21%;"><textarea id="myTools_popup_input_${i}" rows="4" style="${inpstyle}">${val}</textarea></div></div>`:`<div><div style="width:20%;float:left;margin:5px 0;line-height:2;text-align:right;">${params.inputs[i]}: </div><div style="width:73%;margin-left:21%;"><input id="myTools_popup_input_${i}" type="text" value="${val}" style="${inpstyle}"/></div></div>`
				}
                popParams.onOk=()=>{
                    let val=[]
                    for(let i=0;i<params.inputs.length;i++){
                        val.push($("#myTools_popup_input_"+i).val())
                    }
                    params.onOk(val)
                }
            }else{
                popParams.text+=params.type=="textarea"?`<div><textarea id="myTools_popup_input" rows="4" style="${inpstyle}">${params.value||''}</textarea></div>`:`<div><input id="myTools_popup_input" type="text" value="${params.value||''}" style="${inpstyle}"/></div>`
				popParams.onOk=()=>{
                    let val=$("#myTools_popup_input").val()
                    params.onOk(val)
                }
            }
            this.showPop(popParams)
        },
            showInfoPanel(params){
                if($('#myTools_InfoPanel').length) $('#myTools_InfoPanel').remove()
                params=params||{};

                let okText=params.okText||'關閉',noText=params.noText||'清空', _this=this;
                let $ph=$(`<div style="z-index:9900;position:fixed;top:10%;left:0;width:100%;height:0;font-size:12px;" id="myTools_InfoPanel">
			<div class="infoPanel-content" style="width:${params.width||'75%'};max-width:512px;height:620px;background: rgba(255,255,255,.9);border:1px solid #999;border-radius:0 10px 10px 0;transform: translate(-100%,0);transition:all .1s;">
				<div style="padding: 10px 15px;"><span style="font-weight:700;">${params.title||''}</span><span style="float:right;color:#666;cursor:pointer;" class="btncl">✖</span></div>
				<div style="padding: 0 15px;line-height:1.5;height:550px;overflow-y:auto;" class="infoPanel-wrap">${params.text||''}</div>
				<div style="text-align:right;padding: 10px;">
				<button style="padding: 5px 20px;background-color: #969;color:#FFF;border: 1px solid #000;border-radius: 5px;margin-right:25px;" class="btnno">${noText}</button>
				<button style="padding: 5px 20px;background-color: #963;color:#FFF;border: 1px solid #000;border-radius: 5px;" class="btnok">${okText}</button>
				</div>
			</div></div>`);
            $('body').append($ph)
            setTimeout(()=>{
                $ph.find(".infoPanel-content").css({transform:"translate(0,0)"});
                params.onOpen && params.onOpen();
            },100)
            $ph.find('.btncl').click(e=>{params.onClose && params.onClose();$ph.remove();})
            $ph.find('.btnok').click(e=>{params.onOk && params.onOk();params.onClose && params.onClose();$ph.remove();})
            $ph.find('.btnno').click(e=>{params.onNo && params.onNo();})
            return $ph
        },
            writeToOut(html) {
                var m = new unsafeWindow.Map();
                m.put("type", "main_msg");
                m.put("subtype", "html");
                m.put("msg", html);
                gSocketMsg.dispatchMessage(m);
            }
}

init();
})