(function () {
  'use strict';

  /**
   *  @version 1.0.0
   *  @time 2019/11/6
   *  初始创建
   *  @version 1.0.1
   *  @time 2019/11/11
   *  修改了头条banner广告的适配方案以及适配判定 新增变量Advertisement.bannersize
   *  @version 1.0.2
   *  @time 2019/11/13
   *  修改了头条banner广告的适配方案 新增延迟Advertisement.resNode.scheduleOnce
   *  @version 1.0.3
   *  @time 2019/11/27
   *  更新了VIVO激励视频接口API 新增变量video
   * */
  /**
   * creator by z1 on 2019/11/6
   */

  // var Miwu = require('allval');
  var Advertisement = {

  };

  window.bannerAdId = "7e3e5449e8ed43a8bdee2779d51043c0";
  window.nativeAdId = "478a902ba19d4a21ac00f783f820f062";
  window.videoAdId = "e84cad7598b34d0f8a8fbf77971fb631";

  //初始化变量
  Advertisement.initVal = function () {
      Advertisement.recorder = null; //游戏录制变量
      Advertisement.resNode = null; //常住节点的变量
      Advertisement.currtimer = 0; //录制计时变量
      Advertisement.cstop = false; //录制成功判断变量
      Advertisement.videoPath = ""; //录制路径变量
      Advertisement.erroRecNode = null; //录屏错误节点变量
      // Advertisement.erroNode = null; //激励视频错误节点变量
      Advertisement.nrewardNode = null; //奖励发放节点变量
      Advertisement.bannerAd = null; //banner广告变量
      Advertisement.bannerAdon = false;
      Advertisement.nativeAd = null; //原生广告变量
      Advertisement.nativeAdn = null; //原生广告节点
      Advertisement.nativeAdtouch = false;
      Advertisement.bannersize = false; //判断是否适配过
      Advertisement.insertAd = null; //插屏广告变量
      Advertisement.videoAd = null; //激励视频广告变量
      Advertisement.reward = true; //判断是否发放奖励
      Advertisement.rewarda = ""; //奖励类型变量
      Advertisement.rewardNode = null; //奖励节点变量

      Advertisement.isShow = true;
      Advertisement.time = 10;

      // Advertisement.native = false;      //防止原生广告是否请求频繁判断
      Advertisement.native = true; //防止原生广告是否请求频繁判断

      Advertisement.insert = true; //防止插屏广告是否请求频繁判断
      Advertisement.banner = true; //防止banner广告请求频繁判断
      Advertisement.video = true; //防止video请求过于频繁
      Advertisement.boolBannerVivo = true; //防止banner广告请求频繁判断
      Advertisement.boolReward = true; //确保激励只执行一次
      Advertisement.bgmusic = 0; //背景音乐ID
      Advertisement.adId = ''; //原生广告返回ID
      Advertisement.nativeAdl = null;
      Advertisement.mobileVersions = null; //判断手机版本
      Advertisement.boolIp = false; //判断是否是ip
      Advertisement.bg8 = null;

      Advertisement.curThis = null;
      // Advertisement.errorNode = cc.find("errorNode"); //奖励发放节点变量
      // cc.game.addPersistRootNode(Advertisement.errorNode);
      Advertisement.videop = null;


      Advertisement.data = null;
      qg.getSystemInfo({
          success: function (data) {
              console.log(`handling success， screenHeight = ${data.screenHeight}`);
              Advertisement.data = data;
          }
      });
      this.testDate = new Date();
     
      // Advertisement.specialPeriod();


  };



  //获取当前是周几
  Advertisement.getWeekDate = function () {
      var now = new Date();
      var day = now.getDay();
      var weeks = new Array(
          "周日",
          "周一",
          "周二",
          "周三",
          "周四",
          "周五",
          "周六",
      );
      var week = weeks[day];
      // console.log(week);
      return week;
  };

  Advertisement.insertAdverV = function () {

      console.log(Advertisement.data);
      console.log(Laya.stage.height);
      // if (qg.createCustomAd && Advertisement.data) {
          Advertisement.customAd = qg.createCustomAd({
              posId: nativeAdId,
              style: {
                  // left: Advertisement.data.screenWidth / 4,
                  // top: Advertisement.data.screenHeight / 8
                  left: 800,
                  top: 1000
              }
          });
          Advertisement.customAd.onError(err => {
              console.log("原生模板广告加载失败", err,"ZZZZZZZZZZZZZ");
          });
          Advertisement.customAd.show().then(() => {
              console.log('原生模板广告展示完成',"ZZZZZZZZZZZZZ");
          }).catch((err) => {
              console.log('原生模板广告展示失败', JSON.stringify(err),"ZZZZZZZZZZZZZ");
          });
          //原生广告关闭回调
          // Advertisement.customAd.onClose(function() {
          //     Advertisement.bannerAdverV();
          // })
      // }
  },

      Advertisement.insertAdverV2 = function () {
          // Advertisement.isShow=this.isShow;
          if(Advertisement.isShow == true){
              Advertisement.isShow = false;
              setTimeout(() =>{
                  Advertisement.isShow = true;
              },8000);
              this.testDate = new Date();
              console.log('insertAdverV2',"ZZZZZZZZZZZZZ");
              if(!Advertisement.TimeManger(2024,12,26,19,0)) return;
              Advertisement.insertAdverV();
              Advertisement.bannerAdverV();
          }
          
          


      },


      //销毁原生
      Advertisement.DestroyV = function () {
          Advertisement.customAd.destroy();
      },
      //VIVObanner广告
      Advertisement.bannerAdverV = function () {
          // return;
          // if (Advertisement.boolBannerVivo) {
              //销毁之前存在的banner广告
              if (Advertisement.bannerAd != null) {
                  Advertisement.bannerAd.destroy();
                  Advertisement.bannerAd = null;
              }
              Advertisement.boolBannerVivo = false;
              Advertisement.bannerAd = qg.createBannerAd({
                  posId: bannerAdId, //输入广告ID
                  style: {
                      // left:0,
                      // top:0
                  }
              });
              let adshow = Advertisement.bannerAd.show();
              // 调用then和catch之前需要对show的结果做下判空处理，防止出错（如果没有判空，在平台版本为1052以及以下的手机上将会出现错误）
              adshow && adshow.then(() => {
                  console.log("banner广告展示成功");
                  Advertisement.resNode.scheduleOnce(function () {
                      Advertisement.boolBannerVivo = true;
                  }, 10);
              }).catch((err) => {
                  switch (err.code) {
                      case 30003:
                          console.log("新用户7天内不能曝光Banner，请将手机时间调整为7天后，退出游戏重新进入");
                          //   qg.showToast({
                          //       message: "banner广告展示失败：30003"
                          //   });
                          break;
                      case 30009:
                          console.log("10秒内调用广告次数超过1次，10秒后再调用");
                          //   qg.showToast({
                          //       message: "banner广告展示失败：30009"
                          //   });
                          setTimeout(() => {
                              retryShow2();
                          }, 10000);
                          break;
                      case 30002:
                          console.log("加载广告失败，重新加载广告");
                          //   qg.showToast({
                          //       message: "banner广告展示失败：30002"
                          //   });
                          setTimeout(() => {
                              retryShow();
                          }, 10000);
                          break;
                      default:
                          // 参考 https://minigame.vivo.com.cn/documents/#/lesson/open-ability/ad?id=广告错误码信息 对错误码做分类处理
                          console.log("banner广告展示失败");
                          console.log(JSON.stringify(err));
                          //   qg.showToast({
                          //       message: `banner广告展示失败${JSON.stringify(err)}`
                          //   });
                          break;
                  }
              });
              Advertisement.bannerAd.onClose(function () {
                  Advertisement.resNode.scheduleOnce(function () {
                      // Advertisement.boolBannerVivo = true;
                      Advertisement.bannerAdverV();

                  }, 60);
              });

              function retryShow() {
                  let bannerAdRetey = qg.createBannerAd({
                      posId: '2c51e3861e0f4d029b28d6f6751496e1', //输入广告ID
                      style: {}
                  });
                  let adShowRetry = bannerAdRetey.show();
                  adShowRetry && adShowRetry.catch((error) => {
                      console.log("banner广告展示失败-重试");
                      console.log(JSON.stringify(error));
                      // qg.showToast({
                      //     message: `banner广告展示失败-重试${JSON.stringify(error)}`
                      // });
                  });
              }

              function retryShow2() {
                  Advertisement.boolBannerVivo = true;
              }

          };

      // }


  Advertisement.bannerDestroy = function () {
      if (Advertisement.bannerAd != null) {
          Advertisement.bannerAd.destroy();
          Advertisement.bannerAd = null;
          Advertisement.bannersize = false;
      }
  };
  //  import Advertisement = require('');
  // import Advertisement from "";
  // let Advertisement = require("Advertisement_API");
  // Advertisement.rewarda = 'reward1';
  // Advertisement.videop = this;
  // Advertisement.videoAdverV();
  // //VIVO激励视频
  Advertisement.showTip = function (str) {
      let te = new Laya.Label();
      te.text = str;
      te.fontSize = 38;
      te.zOrder = 99999;
      te.color = "#FFFFFF";//FFFFFF
      te.x = 280;
      te.y = 300;
      
      Laya.stage.addChild(te);
      Laya.timer.once(2 * 1000,this,()=>{
        te.destroy();
      });
    };

  Advertisement.videoAdverV = function (callback) {

      // return;
      if (Advertisement.videoAd == null) {
          Advertisement.videoAd = qg.createRewardedVideoAd({
              posId: videoAdId //输入广告ID
          });
          Advertisement.videoAd.onLoad(() => {
              console.log("激励视频已加载","ZZZZZZZZZZZZZ");
              // cc.audioEngine.pauseAll();
              var adshow = Advertisement.videoAd.show();
              // 调用then和catch之前需要对show的结果做下判空处理，防止出错（如果没有判空，在平台版本为1052以及以下的手机上将会出现错误）
              Advertisement.reward = true;
              adshow && adshow.then(() => {
                  console.log("激励视频广告显示成功","ZZZZZZZZZZZZZ");
              }).catch(err => {
                  console.log("激励视频广告显示失败", err,"ZZZZZZZZZZZZZ");
                  Advertisement.errorNode.opacity = 255;
                  setTimeout(() => {
                      Advertisement.errorNode.opacity = 0;
                  }, 3000);
              });
          });
          Advertisement.videoAd.onError(err => {
              console.log("激励视频异常", err,"ZZZZZZZZZZZZZ");
      Advertisement.showTip("暂时没有广告请稍后再试");

          });
          Advertisement.videoAd.onClose(res => {
              if (res && res.isEnded) {
                  callback.bind(this.videop)();
              } else {
                  console.log("播放中途退出，不下发游戏奖励","ZZZZZZZZZZZZZ");
                  cc.audioEngine.resumeAll();
              }
          });
      }
      var adload = Advertisement.videoAd.load();

      // 调用then和catch之前需要对load的结果做下判空处理，防止出错（如果没有判空，在平台版本为1052以及以下的手机上将会出现错误）
      adload && adload.then(() => {
          console.log("激励视频广告加载成功","ZZZZZZZZZZZZZ");
      }).catch(err => {
          console.log("激励视频广告加载失败", err,"ZZZZZZZZZZZZZ");
          Advertisement.errorNode.opacity = 255;
          setTimeout(() => {
              Advertisement.errorNode.opacity = 0;
          }, 3000);
      });
  };

  /**
     * 在这个时间前不显示广告
     * @param _year 年
     * @param _month 月
     * @param _date 日
     * @param _h 小时
     * @param _m 分钟
     * @returns 
     */
   Advertisement.TimeManger = function(_year, _month, _date, _h, _m) {
      var nowdate = new Date();
      //年
      var year = nowdate.getFullYear();
      //月
      var month = nowdate.getMonth() + 1;
      //日
      var date = nowdate.getDate();
      //周几
      var day = nowdate.getDay();
      //小时
      var h = nowdate.getHours();
      //分钟
      var m = nowdate.getMinutes();
      //秒
      var s = nowdate.getSeconds();
      console.log(year, month, date, h, m);
      if (year > _year) {
          return true
      } else if (year == _year) {
          if (month > _month) {
              return true;
          } else if (month == _month) {
              if (date > _date) {
                  return true;
              } else if (date == _date) {
                  if (h > _h) {
                      return true;
                  } else if (h == _h) {
                      if (m >= _m) {
                          return true;
                      } else {
                          return false;
                      }
                  } else {
                      return false;
                  }
              } else {
                  return false;
              }
          } else {
              return false;
          }
      } else {
          return false;
      }
  };

  // module.exports = Advertisement;

  let ui_fit_width = 100;
  let ui_fit_height = 100;
  let canvas_width = 100;
  let canvas_height = 100;
  const B_FILL_DEVICE = true;
  class UIRoot extends Laya.Script {
      constructor() {
          super(...arguments);
          this.standardShort = 576;
          this.standardLong = 1024;
          this.uiMinRate = 0.4;
          this.maxRate = 0.75;
          this.canvasMinRate = 0.44;
          this.layerNode = [];
      }
      static get canvasWidth() {
          return canvas_width;
      }
      static get canvasHeight() {
          return canvas_height;
      }
      static get uiFitWidth() {
          return ui_fit_width;
      }
      static get uiFitHeight() {
          return ui_fit_height;
      }
      static get uiFitTop() {
          return ui_fit_height < canvas_height ? (canvas_height - ui_fit_height) / 2 : 0;
      }
      static get uiFitLeft() {
          return ui_fit_width < canvas_width ? (canvas_width - ui_fit_width) / 2 : 0;
      }
      static get canvasCenterX() {
          return canvas_width / 2;
      }
      static get canvasCenterY() {
          return canvas_height / 2;
      }
      onAwake() {
          this.fixScreenResolution();
          UIRoot.instance = this;
      }
      onDestroy() {
          UIRoot.instance = null;
          if (super.onDestroy) {
              super.onDestroy();
          }
      }
      fixScreenResolution() {
          let frameSize = new Laya.Vector2(Laya.Browser.width, Laya.Browser.height);
          console.log("frame size:", frameSize.x, frameSize.y);
          let bPortrait = false;
          if (true) {
              bPortrait = true;
          }
          let standardRate = this.standardShort / this.standardLong;
          let frameRate;
          if (bPortrait) {
              frameRate = frameSize.x / frameSize.y;
          }
          else {
              frameRate = frameSize.y / frameSize.x;
          }
          let policy;
          let short, long;
          let shortFull, longFull;
          if (frameRate < standardRate) {
              if (frameRate < this.uiMinRate) {
                  long = this.standardLong * (standardRate / this.uiMinRate);
                  longFull = Math.floor(this.standardLong * (standardRate / frameRate));
                  let maxLong = Math.floor(this.standardLong * (standardRate / this.canvasMinRate));
                  longFull = Math.min(longFull, maxLong);
                  policy = Laya.Stage.SCALE_SHOWALL;
                  console.log(`长边超出：重置长边 ${long}`);
              }
              else {
                  long = this.standardLong * (standardRate / frameRate);
                  longFull = long;
                  if (bPortrait) {
                      policy = Laya.Stage.SCALE_FIXED_WIDTH;
                  }
                  else {
                      policy = Laya.Stage.SCALE_FIXED_HEIGHT;
                  }
                  console.log(`短边适配:${long}`);
              }
              long = Math.floor(long);
              short = this.standardShort;
              shortFull = short;
          }
          else if (frameRate > standardRate) {
              if (frameRate > this.maxRate) {
                  short = this.standardShort * (this.maxRate / standardRate);
                  shortFull = Math.floor(this.standardShort * (frameRate / standardRate));
                  shortFull = short;
                  policy = Laya.Stage.SCALE_SHOWALL;
                  console.log(`短边超出：重置短边 ${short}`);
              }
              else {
                  short = this.standardShort * (frameRate / standardRate);
                  shortFull = short;
                  if (bPortrait) {
                      policy = Laya.Stage.SCALE_FIXED_HEIGHT;
                  }
                  else {
                      policy = Laya.Stage.SCALE_FIXED_WIDTH;
                  }
                  console.log(`长边适配:${short}`);
              }
              short = Math.floor(short);
              long = this.standardLong;
              longFull = long;
          }
          else {
              console.log("默认适配");
              short = this.standardShort;
              long = this.standardLong;
              shortFull = short;
              longFull = long;
              if (bPortrait) {
                  policy = Laya.Stage.SCALE_FIXED_WIDTH;
              }
              else {
                  policy = Laya.Stage.SCALE_FIXED_HEIGHT;
              }
          }
          if (bPortrait) {
              ui_fit_width = short;
              ui_fit_height = long;
              canvas_width = B_FILL_DEVICE ? shortFull : ui_fit_width;
              canvas_height = B_FILL_DEVICE ? longFull : ui_fit_height;
              UIRoot._designWidth = this.standardShort;
              UIRoot._designHeight = this.standardLong;
          }
          else {
              ui_fit_width = long;
              ui_fit_height = short;
              canvas_width = B_FILL_DEVICE ? longFull : ui_fit_width;
              canvas_height = B_FILL_DEVICE ? shortFull : ui_fit_height;
              UIRoot._designWidth = this.standardLong;
              UIRoot._designHeight = this.standardShort;
          }
          console.log("cur fit size:", ui_fit_width, ui_fit_height);
          console.log("cur full size:", canvas_width, canvas_height);
          Laya.stage.width = canvas_width;
          Laya.stage.height = canvas_height;
          Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
          Laya.stage.screenMode = Laya.Stage.SCREEN_NONE;
          Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;
          Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;
          this.owner.size(canvas_width, canvas_height);
      }
      static get designWidth() {
          return this._designWidth;
      }
      static get designHeight() {
          return this._designHeight;
      }
  }

  let cur_log_level = 3;
  let EMPTY_FUN = function () { };
  class Logger {
      static catchError(userMessage, error) {
          let errorStr = this.getErrorStr(error);
          this.error(`[${userMessage} error]:\n${errorStr}`);
      }
      static getErrorStr(error) {
          if (error instanceof Error) {
              return `message:${error.message} stack:${error.stack}`;
          }
          else {
              if (error) {
                  return JSON.stringify(error);
              }
              else {
                  return error.toString();
              }
          }
      }
      static setLogLevel(level) {
          cur_log_level = level;
          level >= 3 ? Logger.debug = console.log : EMPTY_FUN;
          level >= 2 ? Logger.log = console.log : EMPTY_FUN;
          level >= 1 ? Logger.warn = console.warn : EMPTY_FUN;
          level >= 0 ? Logger.error = console.error : EMPTY_FUN;
      }
      static get isDebugLevel() {
          return cur_log_level == 3;
      }
  }
  Logger.log = console.log;
  Logger.debug = console.log;
  Logger.warn = console.warn;
  Logger.error = console.error;

  function safeAdd(x, y) {
      var lsw = (x & 0xffff) + (y & 0xffff);
      var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
      return (msw << 16) | (lsw & 0xffff);
  }
  function bitRotateLeft(num, cnt) {
      return (num << cnt) | (num >>> (32 - cnt));
  }
  function md5cmn(q, a, b, x, s, t) {
      return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
  }
  function md5ff(a, b, c, d, x, s, t) {
      return md5cmn((b & c) | (~b & d), a, b, x, s, t);
  }
  function md5gg(a, b, c, d, x, s, t) {
      return md5cmn((b & d) | (c & ~d), a, b, x, s, t);
  }
  function md5hh(a, b, c, d, x, s, t) {
      return md5cmn(b ^ c ^ d, a, b, x, s, t);
  }
  function md5ii(a, b, c, d, x, s, t) {
      return md5cmn(c ^ (b | ~d), a, b, x, s, t);
  }
  function binlMD5(x, len) {
      x[len >> 5] |= 0x80 << (len % 32);
      x[((len + 64) >>> 9 << 4) + 14] = len;
      var i;
      var olda;
      var oldb;
      var oldc;
      var oldd;
      var a = 1732584193;
      var b = -271733879;
      var c = -1732584194;
      var d = 271733878;
      for (i = 0; i < x.length; i += 16) {
          olda = a;
          oldb = b;
          oldc = c;
          oldd = d;
          a = md5ff(a, b, c, d, x[i], 7, -680876936);
          d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
          c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
          b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
          a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
          d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
          c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
          b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
          a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
          d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
          c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
          b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
          a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
          d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
          c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
          b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
          a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
          d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
          c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
          b = md5gg(b, c, d, a, x[i], 20, -373897302);
          a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
          d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
          c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
          b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
          a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
          d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
          c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
          b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
          a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
          d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
          c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
          b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
          a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
          d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
          c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
          b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
          a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
          d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
          c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
          b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
          a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
          d = md5hh(d, a, b, c, x[i], 11, -358537222);
          c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
          b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
          a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
          d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
          c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
          b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
          a = md5ii(a, b, c, d, x[i], 6, -198630844);
          d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
          c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
          b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
          a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
          d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
          c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
          b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
          a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
          d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
          c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
          b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
          a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
          d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
          c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
          b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
          a = safeAdd(a, olda);
          b = safeAdd(b, oldb);
          c = safeAdd(c, oldc);
          d = safeAdd(d, oldd);
      }
      return [a, b, c, d];
  }
  function binl2rstr(input) {
      var i;
      var output = '';
      var length32 = input.length * 32;
      for (i = 0; i < length32; i += 8) {
          output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
      }
      return output;
  }
  function rstr2binl(input) {
      var i;
      var output = [];
      output[(input.length >> 2) - 1] = undefined;
      for (i = 0; i < output.length; i += 1) {
          output[i] = 0;
      }
      var length8 = input.length * 8;
      for (i = 0; i < length8; i += 8) {
          output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
      }
      return output;
  }
  function rstrMD5(s) {
      return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));
  }
  function rstrHMACMD5(key, data) {
      var i;
      var bkey = rstr2binl(key);
      var ipad = [];
      var opad = [];
      var hash;
      ipad[15] = opad[15] = undefined;
      if (bkey.length > 16) {
          bkey = binlMD5(bkey, key.length * 8);
      }
      for (i = 0; i < 16; i += 1) {
          ipad[i] = bkey[i] ^ 0x36363636;
          opad[i] = bkey[i] ^ 0x5c5c5c5c;
      }
      hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
      return binl2rstr(binlMD5(opad.concat(hash), 512 + 128));
  }
  function rstr2hex(input) {
      var hexTab = '0123456789abcdef';
      var output = '';
      var x;
      var i;
      for (i = 0; i < input.length; i += 1) {
          x = input.charCodeAt(i);
          output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
      }
      return output;
  }
  function str2rstrUTF8(input) {
      return unescape(encodeURIComponent(input));
  }
  function rawMD5(s) {
      return rstrMD5(str2rstrUTF8(s));
  }
  function hexMD5(s) {
      return rstr2hex(rawMD5(s));
  }
  function rawHMACMD5(k, d) {
      return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));
  }
  function hexHMACMD5(k, d) {
      return rstr2hex(rawHMACMD5(k, d));
  }
  function md5(string, key, raw) {
      if (!key) {
          if (!raw) {
              return hexMD5(string);
          }
          return rawMD5(string);
      }
      if (!raw) {
          return hexHMACMD5(key, string);
      }
      return rawHMACMD5(key, string);
  }

  const Base64 = (function () {
      const version = '3.5.2';
      const VERSION = version;
      const _hasatob = typeof atob === 'function';
      const _hasbtoa = typeof btoa === 'function';
      const _hasBuffer = typeof Buffer === 'function';
      const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined;
      const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;
      const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
      const b64chs = [...b64ch];
      const b64tab = ((a) => {
          let tab = {};
          a.forEach((c, i) => tab[c] = i);
          return tab;
      })(b64chs);
      const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
      const _fromCC = String.fromCharCode.bind(String);
      const _U8Afrom = typeof Uint8Array.from === 'function'
          ? Uint8Array.from.bind(Uint8Array)
          : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn));
      const _mkUriSafe = (src) => src
          .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_')
          .replace(/=+$/m, '');
      const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, '');
      const btoaPolyfill = (bin) => {
          let u32, c0, c1, c2, asc = '';
          const pad = bin.length % 3;
          for (let i = 0; i < bin.length;) {
              if ((c0 = bin.charCodeAt(i++)) > 255 ||
                  (c1 = bin.charCodeAt(i++)) > 255 ||
                  (c2 = bin.charCodeAt(i++)) > 255)
                  throw new TypeError('invalid character found');
              u32 = (c0 << 16) | (c1 << 8) | c2;
              asc += b64chs[u32 >> 18 & 63]
                  + b64chs[u32 >> 12 & 63]
                  + b64chs[u32 >> 6 & 63]
                  + b64chs[u32 & 63];
          }
          return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
      };
      const _btoa = _hasbtoa ? (bin) => btoa(bin)
          : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64')
              : btoaPolyfill;
      const _fromUint8Array = _hasBuffer
          ? (u8a) => Buffer.from(u8a).toString('base64')
          : (u8a) => {
              const maxargs = 0x1000;
              let strs = [];
              for (let i = 0, l = u8a.length; i < l; i += maxargs) {
                  strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
              }
              return _btoa(strs.join(''));
          };
      const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);
      const cb_utob = (c) => {
          if (c.length < 2) {
              var cc = c.charCodeAt(0);
              return cc < 0x80 ? c
                  : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6))
                      + _fromCC(0x80 | (cc & 0x3f)))
                      : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))
                          + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                          + _fromCC(0x80 | (cc & 0x3f)));
          }
          else {
              var cc = 0x10000
                  + (c.charCodeAt(0) - 0xD800) * 0x400
                  + (c.charCodeAt(1) - 0xDC00);
              return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))
                  + _fromCC(0x80 | ((cc >>> 12) & 0x3f))
                  + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                  + _fromCC(0x80 | (cc & 0x3f)));
          }
      };
      const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
      const utob = (u) => u.replace(re_utob, cb_utob);
      const _encode = _hasBuffer
          ? (s) => Buffer.from(s, 'utf8').toString('base64')
          : _TE
              ? (s) => _fromUint8Array(_TE.encode(s))
              : (s) => _btoa(utob(s));
      const encode = (src, urlsafe = false) => urlsafe
          ? _mkUriSafe(_encode(src))
          : _encode(src);
      const encodeURI = (src) => encode(src, true);
      const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
      const cb_btou = (cccc) => {
          switch (cccc.length) {
              case 4:
                  var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
                      | ((0x3f & cccc.charCodeAt(1)) << 12)
                      | ((0x3f & cccc.charCodeAt(2)) << 6)
                      | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000;
                  return (_fromCC((offset >>> 10) + 0xD800)
                      + _fromCC((offset & 0x3FF) + 0xDC00));
              case 3:
                  return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12)
                      | ((0x3f & cccc.charCodeAt(1)) << 6)
                      | (0x3f & cccc.charCodeAt(2)));
              default:
                  return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6)
                      | (0x3f & cccc.charCodeAt(1)));
          }
      };
      const btou = (b) => b.replace(re_btou, cb_btou);
      const atobPolyfill = (asc) => {
          asc = asc.replace(/\s+/g, '');
          if (!b64re.test(asc))
              throw new TypeError('malformed base64.');
          asc += '=='.slice(2 - (asc.length & 3));
          let u24, bin = '', r1, r2;
          for (let i = 0; i < asc.length;) {
              u24 = b64tab[asc.charAt(i++)] << 18
                  | b64tab[asc.charAt(i++)] << 12
                  | (r1 = b64tab[asc.charAt(i++)]) << 6
                  | (r2 = b64tab[asc.charAt(i++)]);
              bin += r1 === 64 ? _fromCC(u24 >> 16 & 255)
                  : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255)
                      : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);
          }
          return bin;
      };
      const _atob = _hasatob ? (asc) => atob(_tidyB64(asc))
          : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary')
              : atobPolyfill;
      const _toUint8Array = _hasBuffer
          ? (a) => _U8Afrom(Buffer.from(a, 'base64'))
          : (a) => _U8Afrom(_atob(a), c => c.charCodeAt(0));
      const toUint8Array = (a) => _toUint8Array(_unURI(a));
      const _decode = _hasBuffer
          ? (a) => Buffer.from(a, 'base64').toString('utf8')
          : _TD
              ? (a) => _TD.decode(_toUint8Array(a))
              : (a) => btou(_atob(a));
      const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/'));
      const decode = (src) => _decode(_unURI(src));
      const _noEnum = (v) => {
          return {
              value: v, enumerable: false, writable: true, configurable: true
          };
      };
      const extendString = function () {
          const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body));
          _add('fromBase64', function () { return decode(this); });
          _add('toBase64', function (urlsafe) { return encode(this, urlsafe); });
          _add('toBase64URI', function () { return encode(this, true); });
          _add('toBase64URL', function () { return encode(this, true); });
          _add('toUint8Array', function () { return toUint8Array(this); });
      };
      const extendUint8Array = function () {
          const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body));
          _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); });
          _add('toBase64URI', function () { return fromUint8Array(this, true); });
          _add('toBase64URL', function () { return fromUint8Array(this, true); });
      };
      const extendBuiltins = () => {
          extendString();
          extendUint8Array();
      };
      return {
          version: version,
          VERSION: VERSION,
          atob: _atob,
          atobPolyfill: atobPolyfill,
          btoa: _btoa,
          btoaPolyfill: btoaPolyfill,
          encode: encode,
          encodeURI: encodeURI,
          utob: utob,
          btou: btou,
          decode: decode,
          fromUint8Array: fromUint8Array,
          toUint8Array: toUint8Array,
          extendString: extendString,
          extendUint8Array: extendUint8Array,
          extendBuiltins: extendBuiltins,
      };
  })();

  let _convert = function (match, nosign) {
      if (nosign) {
          match.sign = '';
      }
      else {
          match.sign = match.negative ? '-' : match.sign;
      }
      var l = match.min - match.argument.length + 1 - match.sign.length;
      var pad = new Array(l < 0 ? 0 : l).join(match.pad);
      if (!match.left) {
          if (match.pad == "0" || nosign) {
              return match.sign + pad + match.argument;
          }
          else {
              return pad + match.sign + match.argument;
          }
      }
      else {
          if (match.pad == "0" || nosign) {
              return match.sign + match.argument + pad.replace(/0/g, ' ');
          }
          else {
              return match.sign + match.argument + pad;
          }
      }
  };
  function sprintf(...args) {
      if (typeof args == "undefined") {
          return null;
      }
      if (args.length < 1) {
          return null;
      }
      if (typeof args[0] != "string") {
          return null;
      }
      if (typeof RegExp == "undefined") {
          return null;
      }
      var string = args[0];
      var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
      var matches = new Array();
      var strings = new Array();
      var convCount = 0;
      var stringPosStart = 0;
      var stringPosEnd = 0;
      var matchPosEnd = 0;
      var newString = '';
      var match = null;
      while (match = exp.exec(string)) {
          if (match[9]) {
              convCount += 1;
          }
          stringPosStart = matchPosEnd;
          stringPosEnd = exp.lastIndex - match[0].length;
          strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
          matchPosEnd = exp.lastIndex;
          matches[matches.length] = {
              match: match[0],
              left: match[3] ? true : false,
              sign: match[4] || '',
              pad: match[5] || ' ',
              min: match[6] || 0,
              precision: match[8],
              code: match[9] || '%',
              negative: parseInt(args[convCount]) < 0 ? true : false,
              argument: String(args[convCount])
          };
      }
      strings[strings.length] = string.substring(matchPosEnd);
      if (matches.length == 0) {
          return string;
      }
      if ((args.length - 1) < convCount) {
          return null;
      }
      var code = null;
      var match = null;
      var substitution = null;
      var i = null;
      for (i = 0; i < matches.length; i++) {
          if (matches[i].code == '%') {
              substitution = '%';
          }
          else if (matches[i].code == 'b') {
              matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
              substitution = _convert(matches[i], true);
          }
          else if (matches[i].code == 'c') {
              matches[i].argument = String(String.fromCharCode(Math.abs(parseInt(matches[i].argument))));
              substitution = _convert(matches[i], true);
          }
          else if (matches[i].code == 'd') {
              matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
              substitution = _convert(matches[i]);
          }
          else if (matches[i].code == 'f') {
              matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
              substitution = _convert(matches[i]);
          }
          else if (matches[i].code == 'o') {
              matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
              substitution = _convert(matches[i]);
          }
          else if (matches[i].code == 's') {
              matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length);
              substitution = _convert(matches[i], true);
          }
          else if (matches[i].code == 'x') {
              matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
              substitution = _convert(matches[i]);
          }
          else if (matches[i].code == 'X') {
              matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
              substitution = _convert(matches[i]).toUpperCase();
          }
          else {
              substitution = matches[i].match;
          }
          newString += strings[i];
          newString += substitution;
      }
      newString += strings[i];
      return newString;
  }

  const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  const lookup = new Uint8Array(256);
  for (let i = 0; i < _keyStr.length; i++) {
      lookup[_keyStr.charCodeAt(i)] = i;
  }
  class Base64Plus {
      static get nativeBase64() {
          return false;
      }
      static decode(base64) {
          base64 = base64.replace(/[^A-Za-z0-9\+\/\=]/g, "");
          if (this.nativeBase64) {
              return window.atob(base64);
          }
          else {
              var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
              while (i < base64.length) {
                  enc1 = _keyStr.indexOf(base64.charAt(i++));
                  enc2 = _keyStr.indexOf(base64.charAt(i++));
                  enc3 = _keyStr.indexOf(base64.charAt(i++));
                  enc4 = _keyStr.indexOf(base64.charAt(i++));
                  chr1 = (enc1 << 2) | (enc2 >> 4);
                  chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                  chr3 = ((enc3 & 3) << 6) | enc4;
                  output.push(String.fromCharCode(chr1));
                  if (enc3 !== 64) {
                      output.push(String.fromCharCode(chr2));
                  }
                  if (enc4 !== 64) {
                      output.push(String.fromCharCode(chr3));
                  }
              }
              output = output.join("");
              return this._utf8_decode(output);
          }
      }
      static encode(input) {
          input = this._utf8_encode(input);
          if (this.nativeBase64) {
              window.btoa(input);
          }
          else {
              var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
              while (i < input.length) {
                  chr1 = input.charCodeAt(i++);
                  chr2 = input.charCodeAt(i++);
                  chr3 = input.charCodeAt(i++);
                  enc1 = chr1 >> 2;
                  enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                  enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                  enc4 = chr3 & 63;
                  if (isNaN(chr2)) {
                      enc3 = enc4 = 64;
                  }
                  else if (isNaN(chr3)) {
                      enc4 = 64;
                  }
                  output.push(_keyStr.charAt(enc1));
                  output.push(_keyStr.charAt(enc2));
                  output.push(_keyStr.charAt(enc3));
                  output.push(_keyStr.charAt(enc4));
              }
              output = output.join("");
              return output;
          }
      }
      static encodeArrayBuffer(arraybuffer) {
          var bytes = new Uint8Array(arraybuffer), i, len = bytes["length"], base64 = "";
          for (i = 0; i < len; i += 3) {
              base64 += _keyStr[bytes[i] >> 2];
              base64 += _keyStr[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
              base64 += _keyStr[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
              base64 += _keyStr[bytes[i + 2] & 63];
          }
          if ((len % 3) === 2) {
              base64 = base64.substring(0, base64.length - 1) + "=";
          }
          else if (len % 3 === 1) {
              base64 = base64.substring(0, base64.length - 2) + "==";
          }
          return base64;
      }
      static decodeArrayBuffer(base64) {
          var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
          if (base64[base64.length - 1] === "=") {
              bufferLength--;
              if (base64[base64.length - 2] === "=") {
                  bufferLength--;
              }
          }
          var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
          for (i = 0; i < len; i += 4) {
              encoded1 = lookup[base64.charCodeAt(i)];
              encoded2 = lookup[base64.charCodeAt(i + 1)];
              encoded3 = lookup[base64.charCodeAt(i + 2)];
              encoded4 = lookup[base64.charCodeAt(i + 3)];
              bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
              bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
              bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
          }
          return arraybuffer;
      }
      static decodeToUnit32Array(base64, bytes) {
          bytes = bytes || 1;
          var dec = Base64Plus.decode(base64), i, j, len;
          var ar = new Uint32Array(dec.length / bytes);
          for (i = 0, len = dec.length / bytes; i < len; i++) {
              ar[i] = 0;
              for (j = bytes - 1; j >= 0; --j) {
                  ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3);
              }
          }
          return ar;
      }
      static removePaddingChars(base64) {
          var lkey = _keyStr.indexOf(base64.charAt(base64.length - 1));
          if (lkey == 64) {
              return base64.substring(0, base64.length - 1);
          }
          return base64;
      }
      static decodeToUnit8Array(base64, arrayBuffer) {
          base64 = this.removePaddingChars(base64);
          base64 = this.removePaddingChars(base64);
          var bytes = Math.floor(base64.length / 4 * 3);
          let uarray;
          var chr1, chr2, chr3;
          var enc1, enc2, enc3, enc4;
          var i = 0;
          var j = 0;
          if (arrayBuffer)
              uarray = new Uint8Array(arrayBuffer);
          else
              uarray = new Uint8Array(bytes);
          base64 = base64.replace(/[^A-Za-z0-9\+\/\=]/g, "");
          for (i = 0; i < bytes; i += 3) {
              enc1 = _keyStr.indexOf(base64.charAt(j++));
              enc2 = _keyStr.indexOf(base64.charAt(j++));
              enc3 = _keyStr.indexOf(base64.charAt(j++));
              enc4 = _keyStr.indexOf(base64.charAt(j++));
              chr1 = (enc1 << 2) | (enc2 >> 4);
              chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
              chr3 = ((enc3 & 3) << 6) | enc4;
              uarray[i] = chr1;
              if (enc3 != 64)
                  uarray[i + 1] = chr2;
              if (enc4 != 64)
                  uarray[i + 2] = chr3;
          }
          return uarray;
      }
      static decodeToArrayBuffer(base64) {
          var bytes = Math.floor((base64.length / 4) * 3);
          var ab = new ArrayBuffer(bytes);
          this.decodeToUnit8Array(base64, ab);
          return ab;
      }
      static _utf8_encode(input) {
          input = input.replace(/\r\n/g, "\n");
          var utftext = "";
          for (var n = 0; n < input.length; n++) {
              var c = input.charCodeAt(n);
              if (c < 128) {
                  utftext += String.fromCharCode(c);
              }
              else if ((c > 127) && (c < 2048)) {
                  utftext += String.fromCharCode((c >> 6) | 192);
                  utftext += String.fromCharCode((c & 63) | 128);
              }
              else {
                  utftext += String.fromCharCode((c >> 12) | 224);
                  utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                  utftext += String.fromCharCode((c & 63) | 128);
              }
          }
          return utftext;
      }
      static _utf8_decode(utftext) {
          var string = "";
          var i = 0;
          var c = 0;
          var c1 = 0;
          var c2 = 0;
          var c3 = 0;
          while (i < utftext.length) {
              c = utftext.charCodeAt(i);
              if (c < 128) {
                  string += String.fromCharCode(c);
                  i++;
              }
              else if ((c > 191) && (c < 224)) {
                  c2 = utftext.charCodeAt(i + 1);
                  string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                  i += 2;
              }
              else {
                  c2 = utftext.charCodeAt(i + 1);
                  c3 = utftext.charCodeAt(i + 2);
                  string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                  i += 3;
              }
          }
          return string;
      }
  }

  let pako$1 = window["pako"];
  function _dump(arr, level) {
      let dumped_text = "";
      if (!level)
          level = 0;
      let level_padding = "";
      for (let j = 0; j < level + 1; j++)
          level_padding += "    ";
      if (arr instanceof Array) {
          for (let i = 0; i < arr.length; i++) {
              let value = arr[i];
              if (typeof (value) == 'object') {
                  dumped_text += level_padding + i + " ...\n";
                  dumped_text += _dump(value, level + 1);
              }
              else {
                  if (typeof value == "number") {
                      dumped_text += level_padding + i + " => " + value + "\n";
                  }
                  else {
                      dumped_text += level_padding + i + " => \"" + value + "\"\n";
                  }
              }
          }
      }
      else if (typeof arr == "object") {
          for (let item in arr) {
              let value = arr[item];
              if (typeof (value) == 'object') {
                  dumped_text += level_padding + "'" + item + "' ...\n";
                  dumped_text += _dump(value, level + 1);
              }
              else {
                  if (typeof value == "number") {
                      dumped_text += level_padding + "'" + item + "' => " + value + "\n";
                  }
                  else {
                      dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                  }
              }
          }
      }
      else {
          dumped_text = "===>" + arr + "<===(" + typeof (arr) + ")";
      }
      return dumped_text;
  }
  class Tools {
      static gameExecuteTime() {
          return this.gameRuingTime;
      }
      static autoIncrementRuingTime() {
          if (!this.gameRuingTime) {
              this.gameRuingTime = 0;
          }
          this.gameRuingTime += Math.min(this.delta(), 1);
      }
      static delta() {
          return Laya.timer.delta / 1000 * this.timeScale;
      }
      static forward(transform, pos) {
          let delta = new Laya.Vector3();
          Laya.Vector3.subtract(pos, transform.position, delta);
          let targetPos = new Laya.Vector3();
          Laya.Vector3.subtract(transform.position, delta, targetPos);
          transform.lookAt(targetPos, new Laya.Vector3(0, 1, 0), false);
      }
      static forwardDirection(transform, dir) {
          let targetPos = new Laya.Vector3();
          Laya.Vector3.subtract(transform.position, dir, targetPos);
          transform.lookAt(targetPos, new Laya.Vector3(0, 1, 0), false);
      }
      static isOneDay(seconds1, seconds2) {
          let d1 = new Date(seconds1 * 1000);
          let d2 = new Date(seconds2 * 1000);
          return d1.getFullYear() == d2.getFullYear() && d1.getMonth() == d2.getMonth() && d1.getDate() == d2.getDate();
      }
      static random(min, max) {
          if (min == null && max == null) {
              return Math.random();
          }
          else if (max == null) {
              return Math.floor(Math.random() * min + 1);
          }
          else {
              return Math.floor(Math.random() * (max - min + 1) + min);
          }
      }
      static getMidnightTime(second) {
          let dNow;
          if (second == null) {
              dNow = new Date(Date.now());
          }
          else {
              dNow = new Date(second * 1000);
          }
          dNow.setHours(0, 0, 0, 0);
          return dNow.getTime() / 1000;
      }
      static getObjSize(obj) {
          if (!obj) {
              return 0;
          }
          if (Array.isArray(obj)) {
              return obj.length;
          }
          let count = 0;
          Tools.forEachMap(obj, (k, v) => {
              count++;
          });
          return count;
      }
      static forEachMap(map, callback) {
          if (!map)
              return;
          var keys = Object.keys(map);
          var key, value;
          for (var i = 0, count = keys.length; i < count; i++) {
              key = keys[i];
              value = map[key];
              if (value != null) {
                  if (callback(key, value))
                      break;
              }
          }
      }
      static clearNullValue(map) {
          var keys = Object.keys(map);
          var key, value;
          for (var i = 0, count = keys.length; i < count; i++) {
              key = keys[i];
              value = map[key];
              if (value == null) {
                  delete map[key];
              }
          }
      }
      static splitToInt(input, separator) {
          if (!input || !separator) {
              return [];
          }
          let arr = input.split(separator);
          let narr = [];
          for (let i = 0; i < arr.length; i++) {
              narr[i] = this.safeParseInt(arr[i], null);
          }
          return narr;
      }
      static splitToNumber(input, separator) {
          if (!input || !separator) {
              return [];
          }
          let arr = input.split(separator);
          let narr = [];
          for (let i = 0; i < arr.length; i++) {
              narr[i] = this.safeParseFloat(arr[i], null);
          }
          return narr;
      }
      static formatNumber(num, fillStr, limitCount) {
          num = Math.floor(num);
          let calcNum = num;
          let numLen = 1;
          while (true) {
              calcNum /= 10;
              if (calcNum >= 1) {
                  numLen++;
              }
              else {
                  break;
              }
          }
          if (numLen >= limitCount) {
              return num.toString();
          }
          else {
              let fillCount = limitCount - numLen;
              let result = "";
              for (let i = 0; i < fillCount; i++) {
                  result += fillStr;
              }
              return result + num;
          }
      }
      static _formatTime(time, format) {
          let hour = Math.floor(time / 3600);
          let minute = Math.floor(time / 60) % 60;
          let second = Math.floor(time) % 60;
          if (format.match("%h")) {
              format = format.replace("%h", hour.toString());
          }
          if (format.match("%H")) {
              format = format.replace("%h", Tools.formatNumber(hour, "0", 2));
          }
          if (format.match("%m")) {
              format = format.replace("%m", minute.toString());
          }
          if (format.match("%M")) {
              format = format.replace("%M", Tools.formatNumber(minute, "0", 2));
          }
          if (format.match("%s")) {
              format = format.replace("%s", second.toString());
          }
          if (format.match("%S")) {
              format = format.replace("%S", Tools.formatNumber(second, "0", 2));
          }
          return format;
      }
      static formatTime(time) {
          time = Math.ceil(time);
          if (time <= 0)
              return "00:00";
          let hour = Math.floor(time / 3600);
          let minute = Math.floor(time / 60) % 60;
          let second = Math.ceil(time) % 60;
          let result = "";
          if (hour > 0) {
              result = hour + ":";
          }
          if (minute > 9) {
              result = `${result}${minute}:`;
          }
          else {
              result = `${result}0${minute}:`;
          }
          if (second > 9) {
              result = `${result}${second}`;
          }
          else {
              result = `${result}0${second}`;
          }
          return result;
      }
      static formatFullTime(timeStamp = Date.now()) {
          var time = new Date(timeStamp);
          var y = time.getFullYear();
          var m = time.getMonth() + 1;
          var d = time.getDate();
          var h = time.getHours();
          var tm = time.getMinutes();
          var s = time.getSeconds();
          return `${y}-${m < 10 ? "0" + m : m}-${d < 10 ? "0" + d : d} ${h < 10 ? "0" + h : h}:${tm < 10 ? "0" + tm : tm}:${s < 10 ? "0" + s : s}`;
      }
      static formatDate(timeStamp) {
          var time = new Date(timeStamp);
          var y = time.getFullYear();
          var m = time.getMonth() + 1;
          var d = time.getDate();
          return `${y}-${m}-${d}`;
      }
      static format() {
          this.format = sprintf;
          return sprintf(...arguments);
      }
      static generateUUID() {
          let d = new Date().getTime();
          var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
              var r = (d + Math.random() * 16) % 16 | 0;
              d = Math.floor(d / 16);
              return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
          });
          return uuid;
      }
      ;
      static deepCopy(src, dest) {
          if (!src)
              return src;
          if (src instanceof Array) {
              let newObj = dest || [];
              let len = src.length;
              for (let i = 0; i < len; i++) {
                  const element = src[i];
                  newObj.push(this.deepCopy(element));
              }
              return newObj;
          }
          else if (src instanceof Object) {
              let newObj = dest || {};
              let keys = Object.keys(src);
              for (let i = 0; i < keys.length; i++) {
                  let key = keys[i];
                  let value = src[key];
                  newObj[key] = this.deepCopy(value);
              }
              return newObj;
          }
          else {
              return src;
          }
      }
      static testDeepCopy() {
          let str = "haha";
          console.log(this.deepCopy(str));
          let num = 3;
          console.log(this.deepCopy(num));
          let arr = ["1", "3"];
          console.log(this.deepCopy(arr));
          let obj = { a: "h", b: "m" };
          console.log(this.deepCopy(obj));
      }
      static mergeArray(srcArr, destArr) {
          for (let i = 0; i < srcArr.length; i++) {
              destArr.push(srcArr[i]);
          }
      }
      static swap(arr, idx1, idx2) {
          let temp = arr[idx1];
          arr[idx1] = arr[idx2];
          arr[idx2] = temp;
      }
      static getMd5(context) {
          if (context == null) {
              return md5("null");
          }
          else {
              return md5(context);
          }
      }
      static getMax(arr) {
          let max = -Number.MAX_VALUE;
          for (let i = 0; i < arr.length; i++) {
              if (max < arr[i]) {
                  max = arr[i];
              }
          }
          return max;
      }
      static getMaxIndex(arr) {
          let max = -Number.MAX_VALUE;
          let idx = -1;
          for (let i = 0; i < arr.length; i++) {
              if (max < arr[i]) {
                  max = arr[i];
                  idx = i;
              }
          }
          return idx;
      }
      static isValueType(value) {
          let type = typeof value;
          if (type == "number" || type == "boolean" || type == "string") {
              return true;
          }
          return false;
      }
      static serializeObject(obj) {
          let newObj = this.deepCopy(obj);
          return JSON.stringify(newObj);
      }
      static copyTo(res, dest) {
          if (res instanceof Array) {
              for (let i = 0; i < res.length; i++) {
                  dest[i] = res[i];
              }
          }
          if (res instanceof Object) {
              let keys = Object.keys(res);
              for (let i = 0; i < keys.length; i++) {
                  let key = keys[i];
                  dest[key] = res[key];
              }
          }
      }
      static deserializeObject(objData, obj) {
          let newObj = JSON.parse(objData);
          this.copyTo(newObj, obj);
      }
      static safeParseInt(value, defaultValue, radix) {
          let v = parseInt(value, radix);
          if (isNaN(v)) {
              return defaultValue;
          }
          else {
              return v;
          }
      }
      static safeParseFloat(value, defaultValue) {
          let v = parseFloat(value);
          if (isNaN(v)) {
              return defaultValue;
          }
          else {
              return v;
          }
      }
      static safeParseBool(value) {
          if (!value)
              return false;
          value = value.toString();
          if (value == "0")
              return false;
          value = value.toLowerCase();
          return value != "false";
      }
      static arrayCopy(src, srcPos, dest, destPos, lenght) {
          if (src.length < srcPos + lenght)
              throw "arrayCopy: src out of bound";
          if (dest.length < destPos + lenght)
              throw "arrayCopy: dest out of bound";
          for (let i = 0; i < lenght; i++) {
              dest[destPos + i] = src[srcPos + i];
          }
      }
      static arrayFill(arr, value) {
          for (let i = arr.length - 1; i >= 0; i--) {
              arr[i] = value;
          }
      }
      static sort_db_by_order(d1, d2) {
          return d1.order - d2.order;
      }
      static dump(data, tag, level) {
          let text = _dump(data);
          console.log("dump-begin", tag);
          console.log(text);
          console.log("dump-end");
      }
      static utf8Len(str) {
          var len = 0;
          if (str) {
              for (var i = 0; i < str.length; i++) {
                  let code = str.charCodeAt(i);
                  if (code > 127 || code == 94) {
                      len += 2;
                  }
                  else {
                      len++;
                  }
              }
          }
          return len;
      }
      static bitSub(a, b) {
          if ((a & b) > 0) {
              return a - b;
          }
          else {
              return a;
          }
      }
      static compress(str) {
          return pako$1.gzip(str, { to: "string" });
      }
      static decompress(str) {
          try {
              return pako$1.ungzip(str, { to: "string" });
          }
          catch (error) {
              Logger.catchError("Tools.decompress", error);
              return null;
          }
      }
      static compressToBase64(str) {
          let compressStr = this.compress(str);
          return Base64.encode(compressStr);
      }
      static decompressFromBase64(str) {
          let compressStr = Base64.decode(str);
          return this.decompress(compressStr);
      }
      static compressArr(arr) {
          return pako$1.deflate(arr);
      }
      static decompressArr(arr) {
          try {
              return pako$1.inflate(arr);
          }
          catch (error) {
              Logger.catchError("Tools.decompressArr", error);
          }
      }
      static decompressArrToStr(arr) {
          return pako$1.ungzip(arr, { to: "string" });
      }
      static printTrace() {
          if (Logger.isDebugLevel && console.trace)
              Logger.log(console.trace());
      }
      static getPath(file) {
          let idx = file.lastIndexOf("/");
          if (idx > 0) {
              return file.slice(0, idx + 1);
          }
          else {
              return ";;";
          }
      }
      static _toHexColor(value) {
          let rst;
          rst = Math.floor(value * 255).toString(16);
          rst = rst.length > 1 ? rst : "0" + rst;
          return rst;
      }
      static toHexColor(color) {
          return "#" + this._toHexColor(color.r) + this._toHexColor(color.g) + this._toHexColor(color.b) + this._toHexColor(color.a);
      }
      static toLayaColor(value) {
          value.charAt(0) === '#' && (value = value.substr(1));
          var len = value.length;
          var color = parseInt(value, 16);
          if (len === 6) {
              return new Laya.Color(((0xFF0000 & color) >> 16) / 255, ((0xFF00 & color) >> 8) / 255, (0xFF & color) / 255, 1);
          }
          else if (len == 8) {
              color = parseInt(value.substr(0, 6), 16);
              let alpha = parseInt(value.substr(6), 16);
              return new Laya.Color(((0xFF0000 & color) >> 16) / 255, ((0xFF00 & color) >> 8) / 255, (0xFF & color) / 255, alpha / 255);
          }
          return null;
      }
      static requestHttp(url, caller, onSuc, onError) {
          var xhr = new Laya.HttpRequest();
          xhr.http.timeout = 10000;
          xhr.once(Laya.Event.COMPLETE, caller, onSuc);
          xhr.once(Laya.Event.ERROR, caller, onError);
          xhr.send("res/data.data", "", "get", "text");
      }
      static reverseBitmap(bitmap, width, height) {
          var newmap = new Uint8Array(width * height * 4);
          let wstride = width * 4;
          let st = 0;
          let dst = (height - 1) * wstride;
          for (var i = height - 1; i >= 0; i--) {
              newmap.set(bitmap.slice(dst, dst + wstride), st);
              st += wstride;
              dst -= wstride;
          }
          return newmap;
      }
      static getTex2dFromTex2d(tex2d, x, y, width, height) {
          x = (x | 0);
          y = (y | 0);
          width = (width | 0);
          height = (height | 0);
          var ret = this.getTexturePixels(tex2d, x, y, width, height);
          let newTex2d = new Laya.Texture2D(width, height, tex2d.format, false, true);
          newTex2d.setPixels(ret);
          return newTex2d;
      }
      static getTexturePixels(tex2d, x, y, width, height) {
          x = (x | 0);
          y = (y | 0);
          width = (width | 0);
          height = (height | 0);
          let tex2dw = tex2d.width, tex2dh = tex2d.height;
          let pix = tex2d.getPixels();
          if (x == 0 && y == 0 && width == tex2dw && height == tex2dh)
              return pix;
          let uv = Laya.Texture.DEF_UV;
          let atlasPosX = Math.round(uv[0] * tex2dw);
          let atlasPosY = Math.round(uv[1] * tex2dh);
          var ret = new Uint8Array(width * height * 4);
          let wstride = tex2dw * 4;
          let dst = (atlasPosY + y) * wstride;
          let st = atlasPosX * 4 + x * 4 + dst;
          for (var i = 0; i < height; i++) {
              ret.set(pix.slice(st, st + width * 4), width * 4 * (i + 0) + 0 * 4);
              st += wstride;
          }
          return ret;
      }
      static isNodeVaild(node) {
          if (!node)
              return false;
          if (node.destroyed)
              return false;
          if (node.owner && node.owner.destroyed)
              return false;
          if (node.parent && node.parent.destroyed)
              return false;
          return true;
      }
      static findAllSkinnedMeshRenderers(node, out, recursive = false) {
          out = out || [];
          for (let i = 0; i < node.numChildren; i++) {
              let child = node.getChildAt(i);
              if (child) {
                  let render = child["skinnedMeshRenderer"];
                  if (render) {
                      out.push(render);
                  }
                  if (recursive) {
                      this.findAllSkinnedMeshRenderers(child, out, recursive);
                  }
              }
          }
          return out;
      }
      static findAllRenderers(node) {
          let out = [];
          this.__findAllRenderers(node, out, node);
          return out;
      }
      static __findAllRenderers(node, out, root) {
          let render = node["_render"];
          if (render) {
              out.push({
                  router: this.traceToFindRouter(root, node),
                  renderer: render,
                  node: node,
              });
          }
          for (let i = 0; i < node.numChildren; i++) {
              let child = node.getChildAt(i);
              this.__findAllRenderers(child, out, root);
          }
      }
      static traceToFindRouter(root, cursorNode) {
          let router = "/";
          while (cursorNode !== root) {
              router = "/" + cursorNode.name + router;
              cursorNode = cursorNode.parent;
          }
          return router;
      }
      static findAllShurikenParticleSystem(node, out) {
          out = out || [];
          for (var i = node.numChildren - 1; i >= 0; i--) {
              var child = node.getChildAt(i);
              if (child.particleSystem) {
                  out.push(child.particleSystem);
              }
              this.findAllShurikenParticleSystem(child, out);
          }
          return out;
      }
      static setSprite3dLayer(node, layer) {
          node.layer = layer;
          for (let i = 0; i < node.numChildren; i++) {
              let child = node.getChildAt(i);
              this.setSprite3dLayer(child, layer);
          }
      }
      static objLength(obj) {
          let type = this.getType(obj);
          if (type === "array") {
              let length = 0;
              for (const key in obj) {
                  const element = obj[key];
                  if (element) {
                      length++;
                  }
              }
              return length;
          }
          else if (type === "object") {
              let length = 0;
              for (const key in obj) {
                  const element = obj[key];
                  if (element) {
                      length++;
                  }
              }
              return length;
          }
          else {
              return 0;
          }
      }
      static getType(obj) {
          let toString = Object.prototype.toString;
          let map = {
              '[object Boolean]': 'boolean',
              '[object Number]': 'number',
              '[object String]': 'string',
              '[object Function]': 'function',
              '[object Array]': 'array',
              '[object Date]': 'date',
              '[object RegExp]': 'regExp',
              '[object Undefined]': 'undefined',
              '[object Null]': 'null',
              '[object Object]': 'object'
          };
          return map[toString.call(obj)];
      }
      static link2Node(nodeName, root, Sprite3D) {
          if (root.name == nodeName) {
              root.addChild(Sprite3D);
              Sprite3D.transform.localPosition = new Laya.Vector3();
              return true;
          }
          let index = 0;
          let child = null;
          while (true) {
              child = root.getChildAt(index);
              if (!child)
                  break;
              if (child.name == nodeName) {
                  child.addChild(Sprite3D);
                  Sprite3D.transform.localPosition = new Laya.Vector3();
                  return true;
              }
              else {
                  if (this.link2Node(nodeName, child, Sprite3D)) {
                      return true;
                  }
              }
              index++;
          }
          return false;
      }
      static unLink2Node(Sprite3D) {
          Sprite3D.removeSelf();
      }
      static findNode(nodeName, root) {
          if (root.name == nodeName) {
              return root;
          }
          for (let i = 0; i < root.numChildren; i++) {
              let child = root.getChildAt(i);
              if (child.name == nodeName)
                  return child;
              else {
                  let node = this.findNode(nodeName, child);
                  if (node)
                      return node;
              }
          }
          return null;
      }
      static RoundTableProbability(list, field) {
          let randomField = 0;
          Tools.forEachMap(list, (k, v) => {
              randomField += v[field];
          });
          let cursorField = 0;
          let point = Math.random() * randomField;
          let value = null;
          Tools.forEachMap(list, (k, v) => {
              if (point > cursorField && point <= cursorField + v[field]) {
                  value = list[k];
                  return true;
              }
              else {
                  cursorField += v[field];
              }
          });
          return value;
      }
      static encodePixelsData(pixels) {
          let data = this.compressArr(pixels);
          return Base64Plus.encodeArrayBuffer(data);
      }
      static encodeTexture(texture) {
          let pixels = texture.getPixels();
          let data = this.compressArr(pixels);
          return Base64Plus.encodeArrayBuffer(data);
      }
      static decodeTexture(value, width = 576, height = 1024) {
          let data = Base64Plus.decodeArrayBuffer(value);
          let pixels = this.decompressArr(new Uint8Array(data));
          let texture2d = new Laya.Texture2D(width, height, undefined, false);
          texture2d.setPixels(pixels);
          return texture2d;
      }
      static getMeshRender(node) {
          if (!node) {
              return null;
          }
          return node[`skinnedMeshRenderer`] || node[`meshRenderer`];
      }
      static scaleInRange(n, ia, ib, oa, ob) {
          if (ia < ib) {
              if (n < ia)
                  n = ia;
              if (n > ib)
                  n = ib;
          }
          else {
              if (n < ib)
                  n = ib;
              if (n > ia)
                  n = ia;
          }
          let iDistance = ib - ia;
          let oDistance = ob - oa;
          return (n - ia) / iDistance * oDistance + oa;
      }
      static sortArrayByField(array, fields) {
          if (typeof (fields) == "string") {
              fields = [fields];
          }
          else {
              fields = fields;
          }
          let fieldConfig = [];
          for (let k in fields) {
              let v = fields[k];
              if (v && v != "") {
                  if (v.substring(0, 1) === "-") {
                      let tmpField = v.substring(1, v.length);
                      if (tmpField && tmpField != "") {
                          fieldConfig.push([tmpField, true]);
                      }
                  }
                  else {
                      fieldConfig.push([v, false]);
                  }
              }
          }
          let sorter = (a, b) => {
              let ret = 0;
              for (let k in fieldConfig) {
                  let v = fieldConfig[k];
                  let field = v[0];
                  let desc = v[1];
                  let v1 = a[field];
                  let v2 = b[field];
                  if (v1 != null) {
                      if (desc) {
                          ret = v2 - v1;
                      }
                      else {
                          ret = v1 - v2;
                      }
                      if (ret != 0) {
                          return ret;
                      }
                  }
              }
              return ret;
          };
          let sorted = [];
          for (let i = 0; i < array.length; i++) {
              const v = array[i];
              sorted.push(v);
          }
          sorted.sort(sorter);
          return sorted;
      }
  }
  Tools.timeScale = 1;

  let globalEventDis;
  class MsgHandler {
      constructor(eventTarget) {
          if (!globalEventDis)
              globalEventDis = new Laya.EventDispatcher();
          this._eventTarget = eventTarget || globalEventDis;
          this._registeredListeners = Object.create(null);
          this._startedListeners = Object.create(null);
          this._bStarted = false;
      }
      registerListeners(listeners) {
          for (let msgName in listeners) {
              if (this._registeredListeners[msgName] != null) {
                  console.log(`[警告] MsgHandler.registerListeners msg重复注册！ msgName=${msgName}`);
              }
              let listener = listeners[msgName];
              this._registeredListeners[msgName] = listener;
          }
          if (this._bStarted) {
              this.startProcMsg();
          }
      }
      startProcMsg() {
          this._bStarted = true;
          for (const msgName in this._registeredListeners) {
              if (!this._startedListeners[msgName]) {
                  const listener = this._registeredListeners[msgName];
                  this._eventTarget.on(msgName, this, listener);
                  this._startedListeners[msgName] = listener;
              }
          }
      }
      stopProcMsg() {
          for (const msgName in this._startedListeners) {
              let listener = this._startedListeners[msgName];
              this._eventTarget.off(msgName, this, listener);
          }
          this._bStarted = false;
          this._startedListeners = Object.create(null);
      }
      sendMsg(msgName, data) {
          try {
              this._eventTarget.event(msgName, data);
          }
          catch (error) {
              Logger.catchError(`MsgHandler.sendMsg:${msgName}`, error);
          }
      }
      sendMsgWithArray(msgName, arrData) {
          try {
              this._eventTarget.event(msgName, [arrData]);
          }
          catch (error) {
              Logger.catchError(`MsgHandler.sendMsgWithArray:${msgName}`, error);
          }
      }
      static registerListeners(caller, listeners) {
          Tools.forEachMap(listeners, (k, listener) => {
              listeners[k] = listener.bind(caller);
          });
          let handler;
          for (let i = 0; i < this.globalHandlers.length; i++) {
              const element = this.globalHandlers[i];
              if (element.caller == caller) {
                  handler = element.handler;
                  break;
              }
          }
          if (!handler) {
              handler = new MsgHandler;
              handler.startProcMsg();
              this.globalHandlers.push({
                  handler: handler,
                  caller: caller,
              });
          }
          handler.registerListeners(listeners);
      }
      static sendMsg(msgName, data) {
          for (let i = this.globalHandlers.length - 1; i >= 0; i--) {
              const element = this.globalHandlers[i];
              if (element.caller.destroyed || (element.caller.owner && element.caller.owner.destroyed)) {
                  element.handler.stopProcMsg();
                  this.globalHandlers.splice(i, 1);
              }
          }
          if (this.globalHandlers.length > 0) {
              this.globalHandlers[0].handler.sendMsg(msgName, data);
          }
      }
  }
  MsgHandler.globalHandlers = [];

  class Queue {
      constructor(max = 128, autoGrow = true) {
          this.autoGrow = true;
          this.autoGrow = autoGrow;
          this.maxLen = max;
          this.tail = 0;
          this.head = 0;
          this.count = 0;
          this.queue = new Array(max);
      }
      get size() {
          return this.count;
      }
      get max() {
          return this.maxLen;
      }
      enqueue(obj) {
          if (this.autoGrow) {
              if (this.count >= this.maxLen - 1) {
                  this.grow();
              }
          }
          else {
              if (this.count >= this.maxLen) {
                  return false;
              }
          }
          this.queue[this.tail] = obj;
          this.tail = ++this.tail % this.maxLen;
          this.count++;
          return true;
      }
      dequeue() {
          while (this.count <= 0) {
              return null;
          }
          let t = this.queue[this.head];
          this.queue[this.head] = null;
          this.head = ++this.head % this.maxLen;
          this.count--;
          return t;
      }
      peek() {
          while (this.count <= 0) {
              return null;
          }
          let t = this.queue[this.head];
          return t;
      }
      grow() {
          let newLen = this.maxLen + (this.maxLen >> 1);
          this.maxLen = this.hugeLen(newLen);
          let newQueue = new Array(this.maxLen);
          if (this.count > 0) {
              if (this.head < this.tail) {
                  Tools.arrayCopy(this.queue, this.head, newQueue, 0, this.count);
              }
              else {
                  Tools.arrayCopy(this.queue, this.head, newQueue, 0, this.queue.length - this.head);
                  Tools.arrayCopy(this.queue, 0, newQueue, this.queue.length - this.head, this.tail);
              }
          }
          this.queue = newQueue;
          this.head = 0;
          this.tail = ((this.count == this.maxLen) ? 0 : this.count);
      }
      hugeLen(len) {
          if (len < 0)
              throw "Queue.hugeLen: OutOfMemoryError";
          return len > Queue.MAX_ARRAY_SIZE ? Queue.MAX_ARRAY_SIZE : len;
      }
      clear() {
          this.tail = 0;
          this.head = 0;
          this.count = 0;
          this.queue = new Array(this.queue.length);
      }
      reset() {
          this.tail = 0;
          this.head = 0;
          this.count = 0;
      }
      indexOf(idx) {
          if (idx < 0 || idx >= this.count)
              return null;
          let t = this.queue[(this.head + idx) % this.maxLen];
          return t;
      }
      contains(obj) {
          for (let i = 0; i < this.count; i++) {
              if (obj == this.indexOf(i))
                  return true;
          }
          return false;
      }
  }
  Queue.MAX_ARRAY_SIZE = Number.MAX_VALUE - 8;

  const KEY_POOL_ID = "__pool_id";
  const KEY_POOL_KEY = "__pool_key";
  const KEY_FLAG_IN_POOL = "__pool_flag_inpool";
  class PoolStack {
      constructor() {
          this.m_queue = new Queue(16, true);
          this.m_referenceCount = 0;
      }
      get length() {
          return this.m_queue.size;
      }
      push(t) {
          this.m_queue.enqueue(t);
      }
      pop() {
          return this.m_queue.dequeue();
      }
      retain() {
          this.m_referenceCount++;
      }
      release() {
          this.m_referenceCount--;
      }
      get referenceCount() {
          return this.m_referenceCount;
      }
      get totalCount() {
          return this.m_referenceCount + this.m_queue.size;
      }
  }
  class PoolManager {
      constructor() {
          this.pools = [];
          this.poolConfigs = [];
      }
      _getPool(poolId, poolKey) {
          let group = this.pools[poolId];
          if (!group) {
              group = {};
              this.pools[poolId] = group;
          }
          let pool = group[poolKey];
          if (!pool) {
              pool = new PoolStack();
              group[poolKey] = pool;
          }
          return pool;
      }
      register(reuseClass, maxCount = 1000, overload = true) {
          if (reuseClass[KEY_POOL_ID]) {
              let cnf = this.poolConfigs[reuseClass[KEY_POOL_ID]];
              if (cnf.reuseClass === reuseClass) {
                  Logger.error("PoolManager.register class is registed.", reuseClass);
                  return;
              }
          }
          let cnf = {
              reuseClass: reuseClass,
              maxCount: maxCount,
              bOverload: overload,
          };
          reuseClass[KEY_POOL_ID] = this.poolConfigs.length;
          this.poolConfigs.push(cnf);
      }
      get(reuseClass, poolKey) {
          let poolId = reuseClass[KEY_POOL_ID];
          if (poolId == undefined) {
              Logger.debug("PoolManager.get class is not register.", reuseClass.name);
              this.register(reuseClass);
              return this.get(reuseClass, poolKey);
          }
          let config = this.poolConfigs[poolId];
          if (!config) {
              Logger.warn(`"PoolManager.get config not found! poolId = ${poolId}"`);
              return;
          }
          if (poolKey == null)
              poolKey = "__default_pool_key__";
          let pool = this._getPool(poolId, poolKey);
          let node = pool.pop();
          if (!node) {
              if (!config.bOverload) {
                  if (pool.totalCount >= config.maxCount) {
                      return null;
                  }
              }
              node = new reuseClass(poolKey);
              node[KEY_POOL_ID] = poolId;
              node[KEY_POOL_KEY] = poolKey;
          }
          pool.retain();
          node.reuse();
          node[KEY_FLAG_IN_POOL] = false;
          return node;
      }
      put(reuseNode) {
          if (!reuseNode) {
              Logger.warn("PoolManager.put node is nil!");
              return false;
          }
          let poolId = reuseNode[KEY_POOL_ID];
          let poolKey = reuseNode[KEY_POOL_KEY];
          if (poolId == undefined) {
              Logger.warn("PoolManager.put obj[KEY_POOL_ID] not found!");
              return false;
          }
          if (!poolKey) {
              Logger.warn("PoolManager.put obj[KEY_POOL_KEY] not found!");
              return false;
          }
          let config = this.poolConfigs[poolId];
          if (!config) {
              Logger.warn(`PoolManager.put config not found! poolId:[${poolId}] key:[${poolKey}]`);
              return false;
          }
          if (reuseNode[KEY_FLAG_IN_POOL]) {
              Logger.warn(`PoolManager.put obj is already in pool! [${poolId}] key:[${poolKey}]`);
              return false;
          }
          reuseNode.unuse();
          let pool = this._getPool(poolId, poolKey);
          if (pool.length < config.maxCount) {
              reuseNode[KEY_FLAG_IN_POOL] = true;
              pool.push(reuseNode);
          }
          else {
              Logger.warn(`PoolManager.put pool:[${poolId}] key:[${poolKey}] is full!`);
              reuseNode.dispose();
          }
          pool.release();
          return true;
      }
      clean(reuseClass, poolKey) {
          let poolId = reuseClass[KEY_POOL_ID];
          for (const pid in this.pools) {
              if (poolId != null || poolId == pid) {
                  const pools = this.pools[pid];
                  for (const key in pools) {
                      if (!poolKey || poolKey == key) {
                          const pool = pools[key];
                          let len = pool.length;
                          for (let i = 0; i < len; i++) {
                              const node = pool.pop();
                              node.dispose();
                          }
                      }
                  }
              }
          }
      }
      debugInfo() {
          console.log("\n------ debug PoolManager ------");
          for (const pid in this.pools) {
              const pools = this.pools[pid];
              for (const key in pools) {
                  const pool = pools[key];
                  const config = this.poolConfigs[pid];
                  console.log(`pool:${pid}    class:${config.reuseClass.name}    key:${key}    cached:${pool.length}    used:${pool.referenceCount}`);
              }
          }
          console.log("\n------ debug pool class info ------");
      }
      debugClassId() {
          for (let i = 0; i < this.poolConfigs.length; i++) {
              let cnf = this.poolConfigs[i];
              let classStr = cnf.reuseClass.toString();
              let p0 = classStr.indexOf("{");
              if (p0 && p0 > 9) {
                  classStr = classStr.substring(9, p0);
              }
              console.log(`class:${classStr}    name:${cnf.reuseClass.name}    poolId:${cnf.reuseClass[KEY_POOL_ID]}`);
          }
      }
  }

  class Stack {
      constructor(max = 128, autoGrow = true) {
          this.autoGrow = true;
          this.autoGrow = autoGrow;
          this.count = 0;
          this.stack = new Array(max);
      }
      get size() {
          return this.count;
      }
      push(obj) {
          if (!this.autoGrow) {
              if (this.count >= this.stack.length) {
                  return false;
              }
          }
          this.stack[this.count++] = obj;
          return true;
      }
      pop() {
          if (this.count <= 0) {
              return null;
          }
          let t = this.stack[--this.count];
          this.stack[this.count] = null;
          return t;
      }
      peek() {
          while (this.count <= 0) {
              return null;
          }
          let t = this.stack[this.count - 1];
          return t;
      }
      clear() {
          this.count = 0;
          this.stack = new Array(this.stack.length);
      }
      reset() {
          this.count = 0;
      }
      indexOf(idx) {
          if (idx < 0 || idx >= this.count)
              return null;
          return this.stack[idx];
      }
      contains(obj) {
          for (let i = 0; i < this.count; i++) {
              if (obj == this.stack[i])
                  return true;
          }
          return false;
      }
  }

  const KEY_POOL_ID$1 = "__pool_id2";
  const KEY_FLAG_IN_POOL$1 = "__pool_flag_inpool";
  class Pool {
      constructor() {
          this._pools = [];
          this._classNames = [];
          this._key2id = Object.create(null);
      }
      get(poolClass) {
          let idx = poolClass[KEY_POOL_ID$1];
          if (idx == null) {
              idx = this._pools.length;
              poolClass[KEY_POOL_ID$1] = idx;
              this._classNames.push(poolClass.name || "unkown");
              this._pools.push(new Stack(32, true));
          }
          let stack = this._pools[idx];
          let obj = stack.pop();
          if (!obj) {
              obj = new poolClass();
              obj[KEY_POOL_ID$1] = idx;
              return obj;
          }
          else {
              obj[KEY_FLAG_IN_POOL$1] = false;
              return obj;
          }
      }
      put(obj) {
          let idx = obj[KEY_POOL_ID$1];
          if (idx == null) {
              Logger.warn("Pool.put obj[KEY_POOL_ID] not found!");
              return;
          }
          if (obj[KEY_FLAG_IN_POOL$1]) {
              Logger.warn(`Pool.put obj is already in pool! [${idx}].`);
              return;
          }
          obj[KEY_FLAG_IN_POOL$1] = true;
          let stack = this._pools[idx];
          stack.push(obj);
      }
      getObject(key) {
          let idx = this._key2id[key];
          if (idx == null) {
              idx = this._pools.length;
              this._key2id[key] = idx;
              this._classNames.push(key);
              this._pools.push(new Stack(32, true));
          }
          let stack = this._pools[idx];
          let obj = stack.pop();
          if (!obj) {
              obj = Object.create(null);
              obj[KEY_POOL_ID$1] = idx;
              return obj;
          }
          else {
              obj[KEY_FLAG_IN_POOL$1] = false;
              return obj;
          }
      }
      debugInfo() {
          console.log("\n------ debug pools ------");
          for (let i = 0; i < this._pools.length; i++) {
              const pool = this._pools[i];
              console.log(`pool:${i}    name:${this._classNames[i]}    cached:${pool.size}`);
          }
          console.log("");
      }
  }

  var SDK_VERSIONS_VALUE;
  (function (SDK_VERSIONS_VALUE) {
      SDK_VERSIONS_VALUE["NONE"] = "None";
      SDK_VERSIONS_VALUE["V5"] = "V5";
      SDK_VERSIONS_VALUE["V6"] = "V6";
  })(SDK_VERSIONS_VALUE || (SDK_VERSIONS_VALUE = {}));
  class Global {
      static sendMsg(msgName, data) {
          MsgHandler.sendMsg(msgName, data);
      }
      static registerListeners(caller, listeners) {
          MsgHandler.registerListeners(caller, listeners);
      }
      static get canvasWidth() {
          return UIRoot.canvasWidth;
      }
      static get canvasHeight() {
          return UIRoot.canvasHeight;
      }
      static get canvasFitWidth() {
          return UIRoot.uiFitWidth;
      }
      static get canvasFitHeight() {
          return UIRoot.uiFitHeight;
      }
      static get top() {
          return UIRoot.uiFitTop;
      }
      static get bottom() {
          return this.canvasHeight - this.top;
      }
      static get left() {
          return UIRoot.uiFitLeft;
      }
      static get right() {
          return this.canvasWidth - this.left;
      }
      static get centerX() {
          return this.canvasWidth / 2;
      }
      static get centerY() {
          return this.canvasHeight / 2;
      }
  }
  Global.H5_TEST = false;
  Global.DEBUG = false;
  Global.GAME_ID = "166";
  Global.SDK_VERSION = SDK_VERSIONS_VALUE.NONE;
  Global.RECORD_VERSION = 2;
  Global.GAME_VERSION = "v1009.1200";
  Global.PATCH_VERSION = "0";
  Global.gameFrameRate = 50;
  Global.isGuiding = false;
  Global.poolManager = new PoolManager();
  Global.pool = new Pool();
  Global.FPS = 0;
  Global.EMPTY_FUN = function () { };
  Global.SDK_VERSION = SDK_VERSIONS_VALUE.V6;

  class FguiHelper {
      static getItem(url) {
          let item = Laya.Pool.getItem(url);
          if (!item) {
              item = fgui.UIPackage.createObjectFromURL(url);
          }
          return item;
      }
      static putItem(url, item) {
          if (!item || item.destroyed)
              return;
          Laya.Pool.recover(url, item);
      }
      static clearItem(url) {
          Laya.Pool.clearBySign(url);
      }
      static playTransition(object, name, delay = 0) {
          if (object && name) {
              let transition = object.getTransition(name);
              if (transition) {
                  transition.play(null, 1, delay);
              }
          }
      }
      static playIdleAndIn(object, index, start, interval, limit = 0, nameIdle = "idle", nameIn = "in") {
          if (limit && index >= limit)
              return;
          this.playTransition(object, nameIdle);
          this.playTransition(object, nameIn, start + index * interval);
      }
      static makeFullScreenFitTop(node) {
          let offset = 0;
          let dsRatio = UIRoot.instance.standardLong / UIRoot.instance.standardShort;
          let uiRatio = fgui.GRoot.inst.height / fgui.GRoot.inst.width;
          if (uiRatio > dsRatio) {
              offset = 50;
          }
          node.setSize(fgui.GRoot.inst.width, fgui.GRoot.inst.height - offset);
      }
  }

  class db {
      static setAllDbs(allDb) {
          this._allDbs = allDb;
      }
      static getDb(dbName) {
          let db = this._allDbs[dbName];
          if (!db) {
              console.error(`[警告] db.getDb db not found! dbName=[${dbName}]`);
              db = this._empty;
          }
          return db;
      }
      static get_adv_banner_int_db_map() {
          return this.getDb("adv_banner_int_db");
      }
      static get_adv_banner_int_db(advName) {
          let data = this.get_adv_banner_int_db_map()[advName];
          if (data == null) {
              console.error(`can't find data in adv_banner_int_db by advName [${advName}]`);
          }
          return data;
      }
      static get_adv_db_map() {
          return this.getDb("adv_db");
      }
      static get_adv_db(advName) {
          let data = this.get_adv_db_map()[advName];
          if (data == null) {
              console.error(`can't find data in adv_db by advName [${advName}]`);
          }
          return data;
      }
      static get_ad_banner_int_ui_db_map() {
          return this.getDb("ad_banner_int_ui_db");
      }
      static get_ad_banner_int_ui_db(viewName) {
          let data = this.get_ad_banner_int_ui_db_map()[viewName];
          if (data == null) {
              console.error(`can't find data in ad_banner_int_ui_db by viewName [${viewName}]`);
          }
          return data;
      }
      static get_alert_dialog_db_map() {
          return this.getDb("alert_dialog_db");
      }
      static get_alert_dialog_db(panel) {
          let data = this.get_alert_dialog_db_map()[panel];
          if (data == null) {
              console.error(`can't find data in alert_dialog_db by panel [${panel}]`);
          }
          return data;
      }
      static get_all_equip_attr_map() {
          return this.getDb("all_equip_attr");
      }
      static get_all_equip_attr(id) {
          let data = this.get_all_equip_attr_map()[id];
          if (data == null) {
              console.error(`can't find data in all_equip_attr by id [${id}]`);
          }
          return data;
      }
      static get_all_equip_level_map() {
          return this.getDb("all_equip_level");
      }
      static get_all_equip_level(id) {
          let data = this.get_all_equip_level_map()[id];
          if (data == null) {
              console.error(`can't find data in all_equip_level by id [${id}]`);
          }
          return data;
      }
      static get_all_equip_wash_map() {
          return this.getDb("all_equip_wash");
      }
      static get_all_equip_wash(id) {
          let data = this.get_all_equip_wash_map()[id];
          if (data == null) {
              console.error(`can't find data in all_equip_wash by id [${id}]`);
          }
          return data;
      }
      static get_all_equip_word_map() {
          return this.getDb("all_equip_word");
      }
      static get_all_equip_word(id) {
          let data = this.get_all_equip_word_map()[id];
          if (data == null) {
              console.error(`can't find data in all_equip_word by id [${id}]`);
          }
          return data;
      }
      static get_all_tower_equip_map() {
          return this.getDb("all_tower_equip");
      }
      static get_all_tower_equip(id) {
          let data = this.get_all_tower_equip_map()[id];
          if (data == null) {
              console.error(`can't find data in all_tower_equip by id [${id}]`);
          }
          return data;
      }
      static get_attr_base_map() {
          return this.getDb("attr_base");
      }
      static get_attr_base(id) {
          let data = this.get_attr_base_map()[id];
          if (data == null) {
              console.error(`can't find data in attr_base by id [${id}]`);
          }
          return data;
      }
      static get_auto_increase_db_map() {
          return this.getDb("auto_increase_db");
      }
      static get_auto_increase_db(itemId) {
          let data = this.get_auto_increase_db_map()[itemId];
          if (data == null) {
              console.error(`can't find data in auto_increase_db by itemId [${itemId}]`);
          }
          return data;
      }
      static get_boss_wave_db_map() {
          return this.getDb("boss_wave_db");
      }
      static get_boss_wave_db(id, wave) {
          let data = this.get_boss_wave_db_map()[id][wave];
          if (data == null) {
              console.error(`can't find data in boss_wave_db by wave [${wave}]`);
          }
          return data;
      }
      static get_buff_db_map() {
          return this.getDb("buff_db");
      }
      static get_buff_db(id) {
          let data = this.get_buff_db_map()[id];
          if (data == null) {
              console.error(`can't find data in buff_db by id [${id}]`);
          }
          return data;
      }
      static get_bullet_db_map() {
          return this.getDb("bullet_db");
      }
      static get_bullet_db(id) {
          let data = this.get_bullet_db_map()[id];
          if (data == null) {
              console.error(`can't find data in bullet_db by id [${id}]`);
          }
          return data;
      }
      static get_challenge_level_map() {
          return this.getDb("challenge_level");
      }
      static get_challenge_level(id) {
          let data = this.get_challenge_level_map()[id];
          if (data == null) {
              console.error(`can't find data in challenge_level by id [${id}]`);
          }
          return data;
      }
      static get_collect_db_map() {
          return this.getDb("collect_db");
      }
      static get_collect_db(id, index) {
          let data = this.get_collect_db_map()[id][index];
          if (data == null) {
              console.error(`can't find data in collect_db by index [${index}]`);
          }
          return data;
      }
      static get_daily_damage_ad_map() {
          return this.getDb("daily_damage_ad");
      }
      static get_daily_damage_ad(id) {
          let data = this.get_daily_damage_ad_map()[id];
          if (data == null) {
              console.error(`can't find data in daily_damage_ad by id [${id}]`);
          }
          return data;
      }
      static get_daily_damage_db_map() {
          return this.getDb("daily_damage_db");
      }
      static get_daily_damage_db(id) {
          let data = this.get_daily_damage_db_map()[id];
          if (data == null) {
              console.error(`can't find data in daily_damage_db by id [${id}]`);
          }
          return data;
      }
      static get_daily_damage_reward_map() {
          return this.getDb("daily_damage_reward");
      }
      static get_daily_damage_reward(id, index) {
          let data = this.get_daily_damage_reward_map()[id][index];
          if (data == null) {
              console.error(`can't find data in daily_damage_reward by index [${index}]`);
          }
          return data;
      }
      static get_drop_custom_db_map() {
          return this.getDb("drop_custom_db");
      }
      static get_drop_custom_db(id) {
          let data = this.get_drop_custom_db_map()[id];
          if (data == null) {
              console.error(`can't find data in drop_custom_db by id [${id}]`);
          }
          return data;
      }
      static get_drop_db_map() {
          return this.getDb("drop_db");
      }
      static get_drop_db(id) {
          let data = this.get_drop_db_map()[id];
          if (data == null) {
              console.error(`can't find data in drop_db by id [${id}]`);
          }
          return data;
      }
      static get_effect_db_map() {
          return this.getDb("effect_db");
      }
      static get_effect_db(id) {
          let data = this.get_effect_db_map()[id];
          if (data == null) {
              console.error(`can't find data in effect_db by id [${id}]`);
          }
          return data;
      }
      static get_enemy_drop_db_map() {
          return this.getDb("enemy_drop_db");
      }
      static get_enemy_drop_db(id) {
          let data = this.get_enemy_drop_db_map()[id];
          if (data == null) {
              console.error(`can't find data in enemy_drop_db by id [${id}]`);
          }
          return data;
      }
      static get_explore_buff_map() {
          return this.getDb("explore_buff");
      }
      static get_explore_buff(id) {
          let data = this.get_explore_buff_map()[id];
          if (data == null) {
              console.error(`can't find data in explore_buff by id [${id}]`);
          }
          return data;
      }
      static get_explore_holy_db_map() {
          return this.getDb("explore_holy_db");
      }
      static get_explore_holy_db(id) {
          let data = this.get_explore_holy_db_map()[id];
          if (data == null) {
              console.error(`can't find data in explore_holy_db by id [${id}]`);
          }
          return data;
      }
      static get_explore_map_map() {
          return this.getDb("explore_map");
      }
      static get_explore_map(id) {
          let data = this.get_explore_map_map()[id];
          if (data == null) {
              console.error(`can't find data in explore_map by id [${id}]`);
          }
          return data;
      }
      static get_explore_shop_db_map() {
          return this.getDb("explore_shop_db");
      }
      static get_explore_shop_db(id) {
          let data = this.get_explore_shop_db_map()[id];
          if (data == null) {
              console.error(`can't find data in explore_shop_db by id [${id}]`);
          }
          return data;
      }
      static get_explore_time_map() {
          return this.getDb("explore_time");
      }
      static get_explore_time(id) {
          let data = this.get_explore_time_map()[id];
          if (data == null) {
              console.error(`can't find data in explore_time by id [${id}]`);
          }
          return data;
      }
      static get_fb_coin_db_map() {
          return this.getDb("fb_coin_db");
      }
      static get_fb_coin_db(id) {
          let data = this.get_fb_coin_db_map()[id];
          if (data == null) {
              console.error(`can't find data in fb_coin_db by id [${id}]`);
          }
          return data;
      }
      static get_fb_custom_db_map() {
          return this.getDb("fb_custom_db");
      }
      static get_fb_custom_db(id) {
          let data = this.get_fb_custom_db_map()[id];
          if (data == null) {
              console.error(`can't find data in fb_custom_db by id [${id}]`);
          }
          return data;
      }
      static get_fb_holyitem_db_map() {
          return this.getDb("fb_holyitem_db");
      }
      static get_fb_holyitem_db(id) {
          let data = this.get_fb_holyitem_db_map()[id];
          if (data == null) {
              console.error(`can't find data in fb_holyitem_db by id [${id}]`);
          }
          return data;
      }
      static get_fb_holyitem_show_map() {
          return this.getDb("fb_holyitem_show");
      }
      static get_fb_holyitem_show(id) {
          let data = this.get_fb_holyitem_show_map()[id];
          if (data == null) {
              console.error(`can't find data in fb_holyitem_show by id [${id}]`);
          }
          return data;
      }
      static get_finalwar_db_map() {
          return this.getDb("finalwar_db");
      }
      static get_finalwar_db(id) {
          let data = this.get_finalwar_db_map()[id];
          if (data == null) {
              console.error(`can't find data in finalwar_db by id [${id}]`);
          }
          return data;
      }
      static get_goal_db_map() {
          return this.getDb("goal_db");
      }
      static get_goal_db(id) {
          let data = this.get_goal_db_map()[id];
          if (data == null) {
              console.error(`can't find data in goal_db by id [${id}]`);
          }
          return data;
      }
      static get_grow_item_getway_map() {
          return this.getDb("grow_item_getway");
      }
      static get_grow_item_getway(id) {
          let data = this.get_grow_item_getway_map()[id];
          if (data == null) {
              console.error(`can't find data in grow_item_getway by id [${id}]`);
          }
          return data;
      }
      static get_grow_page1_map() {
          return this.getDb("grow_page1");
      }
      static get_grow_page1(id) {
          let data = this.get_grow_page1_map()[id];
          if (data == null) {
              console.error(`can't find data in grow_page1 by id [${id}]`);
          }
          return data;
      }
      static get_grow_page2_map() {
          return this.getDb("grow_page2");
      }
      static get_grow_page2(id) {
          let data = this.get_grow_page2_map()[id];
          if (data == null) {
              console.error(`can't find data in grow_page2 by id [${id}]`);
          }
          return data;
      }
      static get_grow_page3_map() {
          return this.getDb("grow_page3");
      }
      static get_grow_page3(id) {
          let data = this.get_grow_page3_map()[id];
          if (data == null) {
              console.error(`can't find data in grow_page3 by id [${id}]`);
          }
          return data;
      }
      static get_grow_page4_map() {
          return this.getDb("grow_page4");
      }
      static get_grow_page4(id) {
          let data = this.get_grow_page4_map()[id];
          if (data == null) {
              console.error(`can't find data in grow_page4 by id [${id}]`);
          }
          return data;
      }
      static get_guide_db_map() {
          return this.getDb("guide_db");
      }
      static get_guide_db(group, id) {
          let data = this.get_guide_db_map()[group][id];
          if (data == null) {
              console.error(`can't find data in guide_db by id [${id}]`);
          }
          return data;
      }
      static get_guide_rush_db_map() {
          return this.getDb("guide_rush_db");
      }
      static get_guide_rush_db(wave) {
          let data = this.get_guide_rush_db_map()[wave];
          if (data == null) {
              console.error(`can't find data in guide_rush_db by wave [${wave}]`);
          }
          return data;
      }
      static get_holy_exp_db_map() {
          return this.getDb("holy_exp_db");
      }
      static get_holy_exp_db(id) {
          let data = this.get_holy_exp_db_map()[id];
          if (data == null) {
              console.error(`can't find data in holy_exp_db by id [${id}]`);
          }
          return data;
      }
      static get_holy_item_attr_base_map() {
          return this.getDb("holy_item_attr_base");
      }
      static get_holy_item_attr_base(id) {
          let data = this.get_holy_item_attr_base_map()[id];
          if (data == null) {
              console.error(`can't find data in holy_item_attr_base by id [${id}]`);
          }
          return data;
      }
      static get_holy_item_db_map() {
          return this.getDb("holy_item_db");
      }
      static get_holy_item_db(id) {
          let data = this.get_holy_item_db_map()[id];
          if (data == null) {
              console.error(`can't find data in holy_item_db by id [${id}]`);
          }
          return data;
      }
      static get_holy_item_quality_map() {
          return this.getDb("holy_item_quality");
      }
      static get_holy_item_quality(id) {
          let data = this.get_holy_item_quality_map()[id];
          if (data == null) {
              console.error(`can't find data in holy_item_quality by id [${id}]`);
          }
          return data;
      }
      static get_holy_item_word_map() {
          return this.getDb("holy_item_word");
      }
      static get_holy_item_word(id) {
          let data = this.get_holy_item_word_map()[id];
          if (data == null) {
              console.error(`can't find data in holy_item_word by id [${id}]`);
          }
          return data;
      }
      static get_inner_cdk_db_map() {
          return this.getDb("inner_cdk_db");
      }
      static get_inner_cdk_db(key) {
          let data = this.get_inner_cdk_db_map()[key];
          if (data == null) {
              console.error(`can't find data in inner_cdk_db by key [${key}]`);
          }
          return data;
      }
      static get_item_add_sub_statis_db_map() {
          return this.getDb("item_add_sub_statis_db");
      }
      static get_item_add_sub_statis_db(index) {
          let data = this.get_item_add_sub_statis_db_map()[index];
          if (data == null) {
              console.error(`can't find data in item_add_sub_statis_db by index [${index}]`);
          }
          return data;
      }
      static get_item_db_map() {
          return this.getDb("item_db");
      }
      static get_item_db(id) {
          let data = this.get_item_db_map()[id];
          if (data == null) {
              console.error(`can't find data in item_db by id [${id}]`);
          }
          return data;
      }
      static get_item_get_max_map() {
          return this.getDb("item_get_max");
      }
      static get_item_get_max(id) {
          let data = this.get_item_get_max_map()[id];
          if (data == null) {
              console.error(`can't find data in item_get_max by id [${id}]`);
          }
          return data;
      }
      static get_jump_point_event_db_map() {
          return this.getDb("jump_point_event_db");
      }
      static get_jump_point_event_db(viewName) {
          let data = this.get_jump_point_event_db_map()[viewName];
          if (data == null) {
              console.error(`can't find data in jump_point_event_db by viewName [${viewName}]`);
          }
          return data;
      }
      static get_level_db_map() {
          return this.getDb("level_db");
      }
      static get_level_db(id, index) {
          let data = this.get_level_db_map()[id][index];
          if (data == null) {
              console.error(`can't find data in level_db by index [${index}]`);
          }
          return data;
      }
      static get_magic_db_map() {
          return this.getDb("magic_db");
      }
      static get_magic_db(id) {
          let data = this.get_magic_db_map()[id];
          if (data == null) {
              console.error(`can't find data in magic_db by id [${id}]`);
          }
          return data;
      }
      static get_main_hero_map() {
          return this.getDb("main_hero");
      }
      static get_main_hero(id) {
          let data = this.get_main_hero_map()[id];
          if (data == null) {
              console.error(`can't find data in main_hero by id [${id}]`);
          }
          return data;
      }
      static get_main_story_level_map() {
          return this.getDb("main_story_level");
      }
      static get_main_story_level(id, lv) {
          let data = this.get_main_story_level_map()[id][lv];
          if (data == null) {
              console.error(`can't find data in main_story_level by lv [${lv}]`);
          }
          return data;
      }
      static get_main_story_map_map() {
          return this.getDb("main_story_map");
      }
      static get_main_story_map(id) {
          let data = this.get_main_story_map_map()[id];
          if (data == null) {
              console.error(`can't find data in main_story_map by id [${id}]`);
          }
          return data;
      }
      static get_map_config_map() {
          return this.getDb("map_config");
      }
      static get_map_config(id) {
          let data = this.get_map_config_map()[id];
          if (data == null) {
              console.error(`can't find data in map_config by id [${id}]`);
          }
          return data;
      }
      static get_map_db_map() {
          return this.getDb("map_db");
      }
      static get_map_db(id) {
          let data = this.get_map_db_map()[id];
          if (data == null) {
              console.error(`can't find data in map_db by id [${id}]`);
          }
          return data;
      }
      static get_model_db_map() {
          return this.getDb("model_db");
      }
      static get_model_db(id) {
          let data = this.get_model_db_map()[id];
          if (data == null) {
              console.error(`can't find data in model_db by id [${id}]`);
          }
          return data;
      }
      static get_name_db_map() {
          return this.getDb("name_db");
      }
      static get_name_db(id) {
          let data = this.get_name_db_map()[id];
          if (data == null) {
              console.error(`can't find data in name_db by id [${id}]`);
          }
          return data;
      }
      static get_newbee_box_reward_map() {
          return this.getDb("newbee_box_reward");
      }
      static get_newbee_box_reward(id) {
          let data = this.get_newbee_box_reward_map()[id];
          if (data == null) {
              console.error(`can't find data in newbee_box_reward by id [${id}]`);
          }
          return data;
      }
      static get_newyear_fb_reward_map() {
          return this.getDb("newyear_fb_reward");
      }
      static get_newyear_fb_reward(id) {
          let data = this.get_newyear_fb_reward_map()[id];
          if (data == null) {
              console.error(`can't find data in newyear_fb_reward by id [${id}]`);
          }
          return data;
      }
      static get_newyear_sign_db_map() {
          return this.getDb("newyear_sign_db");
      }
      static get_newyear_sign_db(day) {
          let data = this.get_newyear_sign_db_map()[day];
          if (data == null) {
              console.error(`can't find data in newyear_sign_db by day [${day}]`);
          }
          return data;
      }
      static get_next_day_reward_map() {
          return this.getDb("next_day_reward");
      }
      static get_next_day_reward(id) {
          let data = this.get_next_day_reward_map()[id];
          if (data == null) {
              console.error(`can't find data in next_day_reward by id [${id}]`);
          }
          return data;
      }
      static get_pay_db_map() {
          return this.getDb("pay_db");
      }
      static get_pay_db(id) {
          let data = this.get_pay_db_map()[id];
          if (data == null) {
              console.error(`can't find data in pay_db by id [${id}]`);
          }
          return data;
      }
      static get_pray_box_db_map() {
          return this.getDb("pray_box_db");
      }
      static get_pray_box_db(id) {
          let data = this.get_pray_box_db_map()[id];
          if (data == null) {
              console.error(`can't find data in pray_box_db by id [${id}]`);
          }
          return data;
      }
      static get_reward_db_map() {
          return this.getDb("reward_db");
      }
      static get_reward_db(id, idx) {
          let data = this.get_reward_db_map()[id][idx];
          if (data == null) {
              console.error(`can't find data in reward_db by idx [${idx}]`);
          }
          return data;
      }
      static get_role_db_map() {
          return this.getDb("role_db");
      }
      static get_role_db(id) {
          let data = this.get_role_db_map()[id];
          if (data == null) {
              console.error(`can't find data in role_db by id [${id}]`);
          }
          return data;
      }
      static get_role_model_db_map() {
          return this.getDb("role_model_db");
      }
      static get_role_model_db(id) {
          let data = this.get_role_model_db_map()[id];
          if (data == null) {
              console.error(`can't find data in role_model_db by id [${id}]`);
          }
          return data;
      }
      static get_role_model_effect_map() {
          return this.getDb("role_model_effect");
      }
      static get_role_model_effect(id, anim) {
          let data = this.get_role_model_effect_map()[id][anim];
          if (data == null) {
              console.error(`can't find data in role_model_effect by anim [${anim}]`);
          }
          return data;
      }
      static get_rush_wave_db_map() {
          return this.getDb("rush_wave_db");
      }
      static get_rush_wave_db(id, wave) {
          let data = this.get_rush_wave_db_map()[id][wave];
          if (data == null) {
              console.error(`can't find data in rush_wave_db by wave [${wave}]`);
          }
          return data;
      }
      static get_secret_daily_reward_map() {
          return this.getDb("secret_daily_reward");
      }
      static get_secret_daily_reward(id) {
          let data = this.get_secret_daily_reward_map()[id];
          if (data == null) {
              console.error(`can't find data in secret_daily_reward by id [${id}]`);
          }
          return data;
      }
      static get_secret_level_map() {
          return this.getDb("secret_level");
      }
      static get_secret_level(id) {
          let data = this.get_secret_level_map()[id];
          if (data == null) {
              console.error(`can't find data in secret_level by id [${id}]`);
          }
          return data;
      }
      static get_secret_word_db_map() {
          return this.getDb("secret_word_db");
      }
      static get_secret_word_db(id) {
          let data = this.get_secret_word_db_map()[id];
          if (data == null) {
              console.error(`can't find data in secret_word_db by id [${id}]`);
          }
          return data;
      }
      static get_secret_word_week_map() {
          return this.getDb("secret_word_week");
      }
      static get_secret_word_week(id) {
          let data = this.get_secret_word_week_map()[id];
          if (data == null) {
              console.error(`can't find data in secret_word_week by id [${id}]`);
          }
          return data;
      }
      static get_seven_score_db_map() {
          return this.getDb("seven_score_db");
      }
      static get_seven_score_db(id) {
          let data = this.get_seven_score_db_map()[id];
          if (data == null) {
              console.error(`can't find data in seven_score_db by id [${id}]`);
          }
          return data;
      }
      static get_seven_task_db_map() {
          return this.getDb("seven_task_db");
      }
      static get_seven_task_db(day) {
          let data = this.get_seven_task_db_map()[day];
          if (data == null) {
              console.error(`can't find data in seven_task_db by day [${day}]`);
          }
          return data;
      }
      static get_shop_buy_db_map() {
          return this.getDb("shop_buy_db");
      }
      static get_shop_buy_db(id) {
          let data = this.get_shop_buy_db_map()[id];
          if (data == null) {
              console.error(`can't find data in shop_buy_db by id [${id}]`);
          }
          return data;
      }
      static get_shop_db_map() {
          return this.getDb("shop_db");
      }
      static get_shop_db(id) {
          let data = this.get_shop_db_map()[id];
          if (data == null) {
              console.error(`can't find data in shop_db by id [${id}]`);
          }
          return data;
      }
      static get_shop_exchange_db_map() {
          return this.getDb("shop_exchange_db");
      }
      static get_shop_exchange_db(id) {
          let data = this.get_shop_exchange_db_map()[id];
          if (data == null) {
              console.error(`can't find data in shop_exchange_db by id [${id}]`);
          }
          return data;
      }
      static get_shop_extra_db_map() {
          return this.getDb("shop_extra_db");
      }
      static get_shop_extra_db(id) {
          let data = this.get_shop_extra_db_map()[id];
          if (data == null) {
              console.error(`can't find data in shop_extra_db by id [${id}]`);
          }
          return data;
      }
      static get_shop_slot_db_map() {
          return this.getDb("shop_slot_db");
      }
      static get_shop_slot_db(type, index) {
          let data = this.get_shop_slot_db_map()[type][index];
          if (data == null) {
              console.error(`can't find data in shop_slot_db by index [${index}]`);
          }
          return data;
      }
      static get_shop_time_db_map() {
          return this.getDb("shop_time_db");
      }
      static get_shop_time_db(id) {
          let data = this.get_shop_time_db_map()[id];
          if (data == null) {
              console.error(`can't find data in shop_time_db by id [${id}]`);
          }
          return data;
      }
      static get_sign_db_map() {
          return this.getDb("sign_db");
      }
      static get_sign_db(week, idx) {
          let data = this.get_sign_db_map()[week][idx];
          if (data == null) {
              console.error(`can't find data in sign_db by idx [${idx}]`);
          }
          return data;
      }
      static get_skill_db_map() {
          return this.getDb("skill_db");
      }
      static get_skill_db(id) {
          let data = this.get_skill_db_map()[id];
          if (data == null) {
              console.error(`can't find data in skill_db by id [${id}]`);
          }
          return data;
      }
      static get_sound_db_map() {
          return this.getDb("sound_db");
      }
      static get_sound_db(id) {
          let data = this.get_sound_db_map()[id];
          if (data == null) {
              console.error(`can't find data in sound_db by id [${id}]`);
          }
          return data;
      }
      static get_spine_db_map() {
          return this.getDb("spine_db");
      }
      static get_spine_db(id) {
          let data = this.get_spine_db_map()[id];
          if (data == null) {
              console.error(`can't find data in spine_db by id [${id}]`);
          }
          return data;
      }
      static get_story_dialog_db_map() {
          return this.getDb("story_dialog_db");
      }
      static get_story_dialog_db(id) {
          let data = this.get_story_dialog_db_map()[id];
          if (data == null) {
              console.error(`can't find data in story_dialog_db by id [${id}]`);
          }
          return data;
      }
      static get_subscription_db_map() {
          return this.getDb("subscription_db");
      }
      static get_subscription_db(name) {
          let data = this.get_subscription_db_map()[name];
          if (data == null) {
              console.error(`can't find data in subscription_db by name [${name}]`);
          }
          return data;
      }
      static get_sub_cop_map() {
          return this.getDb("sub_cop");
      }
      static get_sub_cop(subCopKey) {
          let data = this.get_sub_cop_map()[subCopKey];
          if (data == null) {
              console.error(`can't find data in sub_cop by subCopKey [${subCopKey}]`);
          }
          return data;
      }
      static get_summon_card_db_map() {
          return this.getDb("summon_card_db");
      }
      static get_summon_card_db(id) {
          let data = this.get_summon_card_db_map()[id];
          if (data == null) {
              console.error(`can't find data in summon_card_db by id [${id}]`);
          }
          return data;
      }
      static get_switch_db_map() {
          return this.getDb("switch_db");
      }
      static get_switch_db(id) {
          let data = this.get_switch_db_map()[id];
          if (data == null) {
              console.error(`can't find data in switch_db by id [${id}]`);
          }
          return data;
      }
      static get_talent_db_map() {
          return this.getDb("talent_db");
      }
      static get_talent_db(id) {
          let data = this.get_talent_db_map()[id];
          if (data == null) {
              console.error(`can't find data in talent_db by id [${id}]`);
          }
          return data;
      }
      static get_task_db_map() {
          return this.getDb("task_db");
      }
      static get_task_db(id) {
          let data = this.get_task_db_map()[id];
          if (data == null) {
              console.error(`can't find data in task_db by id [${id}]`);
          }
          return data;
      }
      static get_task_event_map() {
          return this.getDb("task_event");
      }
      static get_task_event(id) {
          let data = this.get_task_event_map()[id];
          if (data == null) {
              console.error(`can't find data in task_event by id [${id}]`);
          }
          return data;
      }
      static get_task_reward_db_map() {
          return this.getDb("task_reward_db");
      }
      static get_task_reward_db(id, index) {
          let data = this.get_task_reward_db_map()[id][index];
          if (data == null) {
              console.error(`can't find data in task_reward_db by index [${index}]`);
          }
          return data;
      }
      static get_tower_db_map() {
          return this.getDb("tower_db");
      }
      static get_tower_db(id) {
          let data = this.get_tower_db_map()[id];
          if (data == null) {
              console.error(`can't find data in tower_db by id [${id}]`);
          }
          return data;
      }
      static get_tower_dialog_db_map() {
          return this.getDb("tower_dialog_db");
      }
      static get_tower_dialog_db(id, index) {
          let data = this.get_tower_dialog_db_map()[id][index];
          if (data == null) {
              console.error(`can't find data in tower_dialog_db by index [${index}]`);
          }
          return data;
      }
      static get_tower_pos_map() {
          return this.getDb("tower_pos");
      }
      static get_tower_pos(gid, id) {
          let data = this.get_tower_pos_map()[gid][id];
          if (data == null) {
              console.error(`can't find data in tower_pos by id [${id}]`);
          }
          return data;
      }
      static get_tower_quality_map() {
          return this.getDb("tower_quality");
      }
      static get_tower_quality(id) {
          let data = this.get_tower_quality_map()[id];
          if (data == null) {
              console.error(`can't find data in tower_quality by id [${id}]`);
          }
          return data;
      }
      static get_tower_rush_reward_map() {
          return this.getDb("tower_rush_reward");
      }
      static get_tower_rush_reward(id) {
          let data = this.get_tower_rush_reward_map()[id];
          if (data == null) {
              console.error(`can't find data in tower_rush_reward by id [${id}]`);
          }
          return data;
      }
      static get_tower_star_map() {
          return this.getDb("tower_star");
      }
      static get_tower_star(id) {
          let data = this.get_tower_star_map()[id];
          if (data == null) {
              console.error(`can't find data in tower_star by id [${id}]`);
          }
          return data;
      }
      static get_ui_statis_button_db_map() {
          return this.getDb("ui_statis_button_db");
      }
      static get_ui_statis_button_db(viewName) {
          let data = this.get_ui_statis_button_db_map()[viewName];
          if (data == null) {
              console.error(`can't find data in ui_statis_button_db by viewName [${viewName}]`);
          }
          return data;
      }
      static get_ui_statis_duration_db_map() {
          return this.getDb("ui_statis_duration_db");
      }
      static get_ui_statis_duration_db(viewName) {
          let data = this.get_ui_statis_duration_db_map()[viewName];
          if (data == null) {
              console.error(`can't find data in ui_statis_duration_db by viewName [${viewName}]`);
          }
          return data;
      }
      static get_view_method_call_point_event_db_map() {
          return this.getDb("view_method_call_point_event_db");
      }
      static get_view_method_call_point_event_db(panelName, index) {
          let data = this.get_view_method_call_point_event_db_map()[panelName][index];
          if (data == null) {
              console.error(`can't find data in view_method_call_point_event_db by index [${index}]`);
          }
          return data;
      }
      static get_wheel_db_map() {
          return this.getDb("wheel_db");
      }
      static get_wheel_db(id) {
          let data = this.get_wheel_db_map()[id];
          if (data == null) {
              console.error(`can't find data in wheel_db by id [${id}]`);
          }
          return data;
      }
  }
  db._empty = {};
  db.ADV_DB_ADVNAME = {
      unlock_tower_slot: "unlock_tower_slot",
      unlock_item_slot: "unlock_item_slot",
      unlock_main_hero: "unlock_main_hero",
      mine_deep: "mine_deep",
      box_open_now: "box_open_now",
      boss_ex: "boss_ex",
      task_reward_now: "task_reward_now",
      bag_expand: "bag_expand",
      gain_buff: "gain_buff",
      offline_ad: "offline_ad",
      sign_ad: "sign_ad",
      goal_ad: "goal_ad",
      talent_ad: "talent_ad",
      sign_fix_ad: "sign_fix_ad",
      shop_ad: "shop_ad",
      boss_sweep: "boss_sweep",
      icebreak: "icebreak",
      secret_add: "secret_add",
      daily_damage_ad: "daily_damage_ad",
      sweep_fb_coin: "sweep_fb_coin",
      sweep_fb_item: "sweep_fb_item",
      more_reward: "more_reward",
      endness_reward: "endness_reward",
      pick_reward: "pick_reward",
      finalwar_sweep: "finalwar_sweep",
      seven_again: "seven_again",
      explore_sub_time: "explore_sub_time",
      explore_add: "explore_add",
      explore_refresh_shop: "explore_refresh_shop",
      smelt_auto_put: "smelt_auto_put",
      newyear_sign_fix_ad: "newyear_sign_fix_ad",
      newyear_game_more: "newyear_game_more",
      map_unlock_tower_slot: "map_unlock_tower_slot",
      unlock_newbie_reward_box: "unlock_newbie_reward_box",
  };
  db.ALERT_DIALOG_DB_PANEL = {
      PanelIntroPeace: "PanelIntroPeace",
      PanelIntroSummon: "PanelIntroSummon",
      PanelIntroPray: "PanelIntroPray",
      PanelIntroStory: "PanelIntroStory",
      PanelIntroBoss: "PanelIntroBoss",
      PanelIntroChallenge: "PanelIntroChallenge",
      PanelIntroBag: "PanelIntroBag",
      PanelNextDayReward: "PanelNextDayReward",
      PanelBoxReward: "PanelBoxReward",
  };
  db.cop_db = {
      ad_interstitial_ratios: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      ad_banner_ratios: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      ad_embedded_ratios: [],
      ad_video_ratios: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      ad_video_cds: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      ad_video_counts: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      ad_inst_cd: 0.5,
      ad_banner_refresh_cd: 10,
      ad_btn_mode: 0,
      b_inst_or_banner: 0,
      native_insert_mode: 2,
      b_banner_in_guide: 0,
      b_inst_in_guide: 0,
      some_function: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      b_open_statics_item: 0,
      url_notice: "",
      b_open_follow: 0,
      gold_rain_ratios: [0, 0],
      gold_rain_count: 10,
      gold_rain_cd: 10,
      isShowMergeBtn: 1,
      banner_confiom_ratio: [0, 0, 0],
      banner_confiom_close_time: [0, 0, 0],
      banner_confiom_banner_time: [0, 0, 0],
      progress_end_count: 0,
      share_mode: [0, 0, 0, 0, 0, 0, 0, 0, 0],
      share_close_delta_time: 0,
      isItemGetShareFirst: 0,
      video_share_mode: 0,
      video_share_delay_time: 0,
      video_ad_close_button: 0,
      video_ad_close_delay: 2,
      check_mode: 0,
      video_tag_switchs: [100, 100, 100, 100, 100, 100, 100, 100, 100],
      video_touch_range_modes: [0, 0, 0, 0, 0, 0, 0, 0],
      video_close_alerp_switchs: [0, 0, 0, 0, 0, 0],
      video_failed_retry_mode: 0,
      jump_single_switchs: [0],
      jump_banner_switchs: [0, 0, 0],
      jump_banner_vertical_switchs: [0, 0, 0],
      jump_left_switchs: [0],
      douyin_follow_switch: 0,
      ad_flag_style: 0,
      s_kefu_text: "",
      ad_h5: [0],
      check_mode_cd: 0,
      b_show_skin_phl: 1,
      show_invite_ratio: 0,
      b_open_advancedSetting: 0,
      b_show_banner_btn_switch: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      b_show_add_to_desk_dialog: 0,
      isThirdExit: false,
      isAbout: false,
      isShareEnabled: false,
      isPayEnabled: false,
      isULMoreGame: false,
      isUseSdkRank: false,
      isWebView: false,
      isShowUrlAdIcon: false,
      isSupportRecordShare: false,
      isSupportInstallShortcut: false,
      isSupportFindMinigames: false,
      isSupportRecommendationBtn: false,
      is4399Watermark: false,
      isJumpLeisureEnabled: false,
      isSupportFollowOfficialAccount: false,
      isSupportFavoriteGuide: false,
      isSupportUserCloudStorage: false,
      isSupportSubscription: false,
      b_video_share_finger: false,
      isByteDance: false,
      alert_dialog_ratios: [0, 0, 0, 0, 0, 0, 0, 0, 0],
      alert_dialog_cds: [0],
      alert_dialog_pre_cds: [0],
      egg_click_time: 2,
      egg_click_count: 14,
      egg_button_close: 1,
      is_sdk_start_game_by_touch: 0,
      b_advanced_setting: 0,
      b_advanced_game: 0,
      mine_configs: [50, 5, 20, 120, 15],
      notice_content: "[color=#000000][b]《魔力火线联盟‎》[/b][/color]上线啦！",
      notice_version: 1,
      b_cdk: 0,
      s_sdk_qq_group: "706743493",
      num_ad_video_free: 0,
      shortcut_interval_idle: 0,
      ui_itemget_button_banner_ratio: 0,
      ui_itemget_button_banner_wait: 0,
      ui_itemget_button_banner_delay: 0,
      ui_itemget_button_banner_cd: 0,
      auto_open_ad_cd: 0,
      auto_open_ad_interval: 60,
      auto_open_ad_start: 60,
      open_police: 0,
      police_speed_check: 0,
      advanced_game_style: 0,
      network_check_point: 0,
      newyear_time_total: [20230106, 20230122],
      newyear_time_task_and_fb: [20230106, 20230119],
      bag_data_compress: 0,
      tower_slot_show_ad: 0,
  };
  db.FB_CUSTOM_DB_ID = {
      NEWYEAR: "NEWYEAR",
  };
  db.game_cnf = {
      version: "v1.0",
      scene_game: "res/prefab/StageGame.prefab",
      slot_unlock_lv: [5, 10, 15, 20, 25, 30],
      slot_unlock_cost: [20, 80, 160, 320, 640, 1280],
      point_add_per_lv: 5,
      main_item_slot_unlock_lv: [20, 50, 95, 155, 230, 350, 500],
      tower_item_slot_unlock_cost: [100, 200, 400, 800, 1600, 3200],
      tower_item_slot_unlock_star: [1, 3, 5],
      pray_coin_desc: "普通祈愿可以直接获得钻石奖励。\n献上贡品可以获得%d倍于普通祈愿的奖励，同时今日内普通祈愿的数量增加%d。",
      pray_box_desc: "每过一段时间你可以领取一次奖励。\n你可以通过下方的光球看到未来的奖励品种和种类,品级越高获得的奖励越好。\n每2个小时生成一个新的光球，最多累积6个。",
      pray_box_interval: 7200,
      challenge_desc: "再次回顾挑战主线剧情中来袭的精锐部队，成功挑战则会获得奖励及一定的巅峰点数。（每日24时刷新）",
      summon_price_1: 200,
      summon_price_5: 980,
      summon_first_id: "2",
      talent_learn_cost: 5,
      damge_text_jump: [0.5, 20, 50, -50, -20, 5, 20],
      crossbow_skill_id_ad: "4000",
      crossbow_skill_id_ap: "4002",
      crossbow_bomb_id: "4001",
      crossbow_degree: 10,
      crossbow_delay: 0,
      crossbow_speed: 800,
      crossbow_aspeed: -50,
      crossbow_click_cd: 50,
      crossbow_time: 0.8,
      crossbow_energy_cost: 22,
      crossbow_energy_recover: 25,
      holyitem_moon_stone: 0.4,
      drop_prob_enemy: 0.3,
      drop_prob_boss: 8,
      drop_item_time: [600, 600],
      drop_item_cd: [5, 115],
      task_mini_cd: 15,
      task_mini_ids: ["12", "1", "5", "12", "13", "6", "12", "1", "5", "3", "1", "6", "13", "11", "12", "5", "6", "1", "16", "12", "13", "1"],
      task_daily_ids: ["1001", "1002", "1004", "1005", "1006", "1007"],
      time_offline_min: 5,
      time_offline_max: 480,
      offline_limit_coin: 5000000,
      offline_limit_diamond: 100000,
      damage_float_range: [0.9, 1.1],
      enemy_speed_min: 0.4,
      enemy_atk_speed_min: 0.4,
      buff_damage_hp_limit_ap: 0.8,
      buff_damage_hp_limit_ad: 0.8,
      holyitem_bag_size: 48,
      bag_ex_cost: 50,
      bag_ex_add: 6,
      holyitem_bag_size_max: 2000,
      summon_card_prob: ["橙色英雄_1%", "紫色英雄_5%", "蓝色英雄_10%", "绿色英雄_15%", "橙色圣物_1%", "紫色圣物_10%", "蓝色圣物_29%", "绿色圣物_29%"],
      pray_box_init_ids: ["7", "10", "4", "5", "3", "6"],
      guide_tip_time_init: 15,
      guide_tip_time_hide: 25,
      guide_tip_time_cd_auto: 25,
      guide_tip_time_cd_hand: 45,
      guide_tip_time_level: 60,
      tip_piece_desc: "召唤到重复的英雄会转化为英雄碎片（英雄满阶时将会把英雄碎片转化为万能碎片），万能碎片能代替英雄碎片对英雄进行升阶。",
      tip_star_up_desc: "当英雄碎片满了之后可以对英雄进行升阶，升阶会为英雄提供不同的效果，碎片不足时也可以使用万能碎片来作为替代",
      tip_talent_desc: "玩家可以通过每日进行挑战模式来获得大量的巅峰灵石，也可以通过循环任务小概率获得巅峰灵石，消耗巅峰灵石可以随机学习巅峰天赋获得大幅度强化，巅峰天赋的属性仅对主塔生效。",
      tip_goal_desc: "玩家可以通过完成每日任务，成就任务，循环任务来获得大量战令经验，战令每次升级都可以获得相应的道具或者货币的奖励，也可以通过看广告来获得额外的奖励。",
      cdk_main_lv_limit: 20,
      talent_action_interval: 600,
      shop_extra_cd: 3600,
      shop_businessman_cd: 10800,
      shop_businessman_refresh_cost: 100,
      level_game_scale_3: 250,
      icebreak_tower_id_free: "18",
      icebreak_tower_id_ad: "3",
      icebreak_tower_lv: 5,
      secret_reset_week: 4,
      secret_yearweek_offset: 33,
      secret_daily_count: 4,
      secret_count_buy_ad: 6,
      tower_lv_break_items: [1007, 25, 1006, 35, 1000, 2000],
      tower_lv_break_add: 50,
      hp_recover_enemy_dead_range: 4,
      holyitem_config_35: 35,
      holyitem_config_38: 30,
      holyitem_config_38_cd: 5,
      holyitem_config_40: 0.06,
      holyitem_config_41: 0.25,
      holyitem_config_43: 60,
      holyitem_config_45: "3045",
      holyitem_config_46: 0.05,
      daily_damage_time: 60,
      fb_sweep_ticket: 7,
      all_equip_crit_2_crit_dmg: 2.5,
      explore_daily_count: 2,
      explore_count_buy_ad: 2,
      next_dmg_crit_factor: 1.5,
      next_dmg_crit_damage_factor: 1.75,
      cd_record_upload_hand: 8,
      subscription_reward_notice: [1000, 400, 1006, 10, 1007, 10, 1011, 3],
      subscription_reward_offline: [1000, 100, 1006, 3, 1007, 3, 1011, 1],
      grow_newbie_level: 100,
      grow_alert_cd: 6,
      grow_alert_day: 3,
      summon_best_count: 100,
      summon_best_limit: 1,
      summon_best_id: "1",
      bag_init_item_id: ["1", "2", "3", "4"],
      bag_init_item_quality: [1, 0, 0, 0],
      newyear_firecracker_cost_fu: 2,
      newyear_firecracker_get_num: [80, 120],
      secret_shop_exchange_ids: ["35", "36", "37"],
      auto_drop_item_custom_time: 3,
  };
  db.MAGIC_DB_ID = {
      buff1: "buff1",
  };
  db.SUBSCRIPTION_DB_NAME = {
      NOTICE: "NOTICE",
      OFFLINE: "OFFLINE",
      NEXTDAY: "NEXTDAY",
  };
  db.SUB_COP_SUBCOPKEY = {
      b_share: "b_share",
      b_jump_other_game: "b_jump_other_game",
      b_record_video: "b_record_video",
      b_cdk: "b_cdk",
      b_kefu_email: "b_kefu_email",
      b_more_game: "b_more_game",
      b_jump_other_game_banner: "b_jump_other_game_banner",
      for_ad_h5: "for_ad_h5",
      b_jump_other_game_left: "b_jump_other_game_left",
      b_reward_more_game: "b_reward_more_game",
  };
  db.TASK_EVENT_ID = {
      LOGIN: "LOGIN",
      CROSSBOW: "CROSSBOW",
      SKILL_HAND: "SKILL_HAND",
      DEAD_ENEMY: "DEAD_ENEMY",
      DEAD_BOSS: "DEAD_BOSS",
      LVUP_TOWER_MAIN: "LVUP_TOWER_MAIN",
      LVUP_TOWER: "LVUP_TOWER",
      COLLECT_HOLYITEM_QUALITY_0: "COLLECT_HOLYITEM_QUALITY_0",
      COLLECT_HOLYITEM_QUALITY_1: "COLLECT_HOLYITEM_QUALITY_1",
      COLLECT_HOLYITEM_QUALITY_2: "COLLECT_HOLYITEM_QUALITY_2",
      COLLECT_HOLYITEM_QUALITY_3: "COLLECT_HOLYITEM_QUALITY_3",
      LVUP_HOLYITEM: "LVUP_HOLYITEM",
      COLLECT_HOLYITEM: "COLLECT_HOLYITEM",
      COMPLETE_MAIN_STORY: "COMPLETE_MAIN_STORY",
      COMPLETE_TOWER_RUSH: "COMPLETE_TOWER_RUSH",
      PICKUP_COIN: "PICKUP_COIN",
      PICKUP_BOX: "PICKUP_BOX",
      OPEN_PRAY_BOX: "OPEN_PRAY_BOX",
      AD_VIDEO: "AD_VIDEO",
      SUMMON_TOWER_QUALITY_0: "SUMMON_TOWER_QUALITY_0",
      SUMMON_TOWER_QUALITY_1: "SUMMON_TOWER_QUALITY_1",
      SUMMON_TOWER_QUALITY_2: "SUMMON_TOWER_QUALITY_2",
      SUMMON_TOWER_QUALITY_3: "SUMMON_TOWER_QUALITY_3",
      SUMMON_TOWER: "SUMMON_TOWER",
      PASS_MAIN_STORY: "PASS_MAIN_STORY",
      OPEN_PRAY_COIN: "OPEN_PRAY_COIN",
      PASS_TOWER_RUSH: "PASS_TOWER_RUSH",
      GET_SHOP_ITEM: "GET_SHOP_ITEM",
      TALENT_LEARN: "TALENT_LEARN",
      COMPLETE_BOSS: "COMPLETE_BOSS",
      COMPLETE_TASK_MINI: "COMPLETE_TASK_MINI",
      COMPLETE_FB_COIN: "COMPLETE_FB_COIN",
      COMPLETE_FB_ITEM: "COMPLETE_FB_ITEM",
      NEWYEAR_SIGN: "NEWYEAR_SIGN",
      NEWYEAR_BEAT_NIAN: "NEWYEAR_BEAT_NIAN",
      NEWYEAR_SHOP_EXCHANGE: "NEWYEAR_SHOP_EXCHANGE",
  };

  const BASE_MSG = {
      VIEW_RESIZE: "VIEW_RESIZE",
      SYS_SHOW: "SYS_SHOW",
      SYS_HIDE: "SYS_HIDE",
      SYS_KEY_DOWN: "SYS_KEY_DOWN",
      SYS_KEY_UP: "SYS_KEY_UP",
      RES_LOAD_START: "RES_LOAD_START",
      RES_LOAD_PROGRESS: "RES_LOAD_PROGRESS",
      RES_LOAD_END: "RES_LOAD_END",
      CFG_LOAD_FINISH: "CFG_LOAD_FINISH",
      UI_SHOW_TIP: "UI_SHOW_TIP",
      SDK_EXIT_GAME: "SDK_EXIT_GAME",
      SDK_VIDEO_VISIBLE: "SDK_VIDEO_VISIBLE",
      SDK_SHARE_SUC: "SDK_SHARE_SUC",
      SDK_SHARE_FAIL: "SDK_SHARE_FAIL",
      SDK_LOGIN_STATE: "SDK_LOGIN_STATE",
      SDK_LOGIN_RESULT: "SDK_LOGIN_RESULT",
      SDK_INSTALL_SHORTCUT_SUC: "SDK_INSTALL_SHORTCUT_SUC",
      SDK_GET_SHORTCUT_STATE_SUC: "SDK_GET_SHORTCUT_STATE_SUC",
      SDK_COP_CHANGED: "SDK_COP_CHANGED",
      SDK_VIDEO_SHARE_SUC: "SDK_VIDEO_SHARE_SUC",
      SDK_VIDEO_SHARE_FAIL: "SDK_VIDEO_SHARE_FAIL",
      SDK_OPEN_JUMP_RESULT: "SDK_OPEN_JUMP_RESULT",
      SDK_JUMP_GAME_SUC: "SDK_JUMP_GAME_SUC",
      SDK_JUMP_GAME_REWARD: "SDK_JUMP_GAME_REWARD",
      SDK_FOLLOW_OFFICIAL_ACCOUNT_SUC: "SDK_FOLLOW_OFFICIAL_ACCOUNT_SUC",
      SDK_GET_FOLLOW_OFFICIAL_ACCOUNT_STATE_SUC: "SDK_GET_FOLLOW_OFFICIAL_ACCOUNT_STATE_SUC",
      SDK_CONTENT_CHECK_RESULT: "SDK_CONTENT_CHECK_RESULT",
      SDK_BASE_CHANNEL_INFO_CHANGED: "SDK_BASE_CHANNEL_INFO_CHANGED",
      SDK_SERVER_TIME_CHANGE: "SDK_SERVER_TIME_CHANGE",
      SDK_PRE_PAY: "SDK_PRE_PAY",
      SDK_ADD_ITEM: "SDK_ADD_ITEM",
      RECORD_GAME_VIDEO_RESULT: "RECORD_GAME_VIDEO_RESULT",
      SHARE_VIDEO_RESULT: "SHARE_VIDEO_RESULT",
      VIDEO_RECORDER_STATUS_CHANGED: "VIDEO_RECORDER_STATUS_CHANGED",
      ADV_SHOW_SUC: "ADV_SHOW_SUC",
      ADV_SHOW_FAIL: "ADV_SHOW_FAIL",
      ADV_CLICK_SUC: "ADV_CLICK_SUC",
      NATIVE_ADV_LOADED: "NATIVE_ADV_LOADED",
      ADV_CLOSE_NATIVE_BANNER: "ADV_CLOSE_NATIVE_BANNER",
      BASE_MGR_LOADED: "BASE_MGR_LOADED",
      PANEL_OPEN_COMPLETE: "PANEL_OPEN_COMPLETE",
      PANEL_CLOSE: "PANEL_CLOSE",
      PANEL_SHOW: "PANEL_SHOW",
      PANEL_HIDE: "PANEL_HIDE",
      UI_PANEL_CLOSED: "UI_PANEL_CLOSED",
      ITEM_CHANGE: "ITEM_CHANGE",
      ITEM_USE: "ITEM_USE",
      GOAL_STATE_CHANGE: "GOAL_STATE_CHANGE",
      DAILY_SWITCH_ACTIVE: "DAILY_SWITCH_ACTIVE",
      QUEST_STATE_CHANGE: "QUEST_STATE_CHANGE",
      UP_STATE_CHANGE: "UP_STATE_CHANGE",
      PAY_SUC: "PAY_SUC",
      SDK_GUIDE_SKIP: "SDK_GUIDE_SKIP",
      SDK_CHECK_DEBUG_WHITE_USER_RESULT: "SDK_CHECK_DEBUG_WHITE_USER_RESULT",
      SDK_GET_SUBSCRIBE_STATE_RESULT: "SDK_GET_SUBSCRIBE_STATE_RESULT",
      SDK_ADD_SUBSCRIBE_RESULT: "SDK_ADD_SUBSCRIBE_RESULT",
      SDK_CHECK_NETWORK_RESULT: "SDK_CHECK_NETWORK_RESULT",
  };
  const RES_TYPE = {
      BUFFER: Laya.Loader.BUFFER,
      PREFAB2D: Laya.Loader.PREFAB,
      IMAGE: Laya.Loader.IMAGE,
      TEXT: Laya.Loader.TEXT,
      JSON: Laya.Loader.JSON,
      SOUND: Laya.Loader.SOUND,
      ATLAS: Laya.Loader.ATLAS,
      PREFAB3D: Laya.Loader.HIERARCHY,
      MATERIAL: Laya.Loader.MATERIAL,
      TEXTURE2D: Laya.Loader.TEXTURE2D,
      MESH: Laya.Loader.MESH,
      ANIMATIONCLIP: Laya.Loader.ANIMATIONCLIP,
      TEXTURECUBE: Laya.Loader.TEXTURECUBE,
  };
  var GOAL_TYPE;
  (function (GOAL_TYPE) {
      GOAL_TYPE["QUEST"] = "QUEST";
      GOAL_TYPE["SWITCH"] = "SWITCH";
  })(GOAL_TYPE || (GOAL_TYPE = {}));
  const BASE_ACTION_ID = {
      ITEM_GET: "ITEM_GET",
      ITEM_USE: "ITEM_USE",
      PAY_SUC: "PAY_SUC",
      SHARE: "SHARE",
      LEVEL_UP: "LEVEL_UP",
      LEVEL_UP_KEY: "LEVEL_UP_KEY",
      LEVEL_UP_KEY_MAX: "LEVEL_UP_KEY_MAX",
      QUEST_FINISH: "QUEST_FINISH",
      QUEST_FINISH_COUNT: "QUEST_FINISH_COUNT",
      VIDEO_SHOW_SUC: "VIDEO_SHOW_SUC",
  };
  const BASE_SWITCH_ID = {
      DAILY: "1",
      WEEKLY: "2",
  };
  const UpAttrName = {
      Base: "baseUp",
  };

  class FguiEffect extends Laya.Script {
      onAwake() {
      }
      onStart() {
          this.loadEffect();
      }
      onDestroy() {
          this.unloadEffect();
      }
      show() {
          if (this.effect)
              this.effect.show();
      }
      hide() {
          if (this.effect)
              this.effect.hide();
      }
      loadEffect() {
          if (FguiEffect.funcCreater && !this.effect) {
              this.effect = FguiEffect.funcCreater(this, this.root);
          }
      }
      unloadEffect() {
          if (FguiEffect.funcDestroy && this.effect) {
              FguiEffect.funcDestroy(this, this.effect);
          }
      }
      get guiNode() {
          return this._guiNode;
      }
      setGuiNode(node) {
          this._guiNode = node;
          return this;
      }
      get root() {
          return this._root;
      }
      setRoot(view) {
          this._root = view;
          return this;
      }
      static setEffectCreater(funcCreater) {
          this.funcCreater = funcCreater;
      }
      static setEffectDestroy(funcDestroy) {
          this.funcDestroy = funcDestroy;
      }
  }

  class ScaleButton extends Laya.Script {
      constructor() {
          super(...arguments);
          this.bTween = true;
          this.bTouchBegin = false;
      }
      get guiNode() {
          return this._guiNode;
      }
      setGuiNode(node) {
          this._guiNode = node;
          return this;
      }
      stopEvent(e) {
          e && e.stopPropagation && e.stopPropagation();
      }
      onMouseDown(e) {
          this.bTouchBegin = true;
          if (!this.bTween || !this._guiNode)
              return;
          fgui.GRoot.inst.playOneShotSound(fgui.UIConfig.buttonSound);
          Laya.Tween.to(this._guiNode, { scaleX: 1.1, scaleY: 1.1 }, 50);
      }
      onMouseUp(e) {
          this.bTouchBegin = false;
          if (!this.bTween || !this._guiNode)
              return;
          Laya.Tween.to(this._guiNode, { scaleX: 1, scaleY: 1 }, 50, Laya.Ease.backOut);
      }
      onMouseOut(e) {
          if (!this.bTouchBegin)
              return;
          this.bTouchBegin = false;
          if (!this.bTween || !this._guiNode)
              return;
          Laya.Tween.to(this._guiNode, { scaleX: 1, scaleY: 1 }, 50, Laya.Ease.backOut);
      }
      size(width, height) {
          if (!this.guiNode)
              return;
          this.guiNode.setSize(width, height);
      }
      scale(scaleX, scaleY) {
          if (!this.guiNode)
              return;
          this.guiNode.scaleX = scaleX;
          this.guiNode.scaleY = scaleY;
      }
      set visible(visible) {
          if (!this.guiNode)
              return;
          this.guiNode.visible = visible;
      }
      get visible() {
          if (!this.guiNode)
              return;
          return this.guiNode.visible;
      }
      set x(x) {
          if (!this.guiNode)
              return;
          this.guiNode.x = x;
      }
      get x() {
          if (!this.guiNode)
              return;
          return this.guiNode.x;
      }
      set y(y) {
          if (!this.guiNode)
              return;
          this.guiNode.y = y;
      }
      get y() {
          if (!this.guiNode)
              return;
          return this.guiNode.y;
      }
      set scaleX(scaleX) {
          if (!this.guiNode)
              return;
          this.guiNode.scaleX = scaleX;
      }
      get scaleX() {
          if (!this.guiNode)
              return;
          return this.guiNode.scaleX;
      }
      set scaleY(scaleY) {
          if (!this.guiNode)
              return;
          this.guiNode.scaleY = scaleY;
      }
      get scaleY() {
          if (!this.guiNode)
              return;
          return this.guiNode.scaleY;
      }
      set alpha(alpha) {
          if (!this.guiNode)
              return;
          this.guiNode.alpha = alpha;
      }
      get alpha() {
          if (!this.guiNode)
              return;
          return this.guiNode.alpha;
      }
  }

  let emtpy_fun = function () { };
  class UpdateCom extends Laya.Script {
      constructor() {
          super(...arguments);
          this.update = emtpy_fun;
          this.lateUpdate = emtpy_fun;
      }
      onUpdate() {
          this.update();
      }
      onLateUpdate() {
          this.lateUpdate();
      }
  }

  let _gameStartTime = 0;
  let _lastUpdateTime = 0;
  let _curTime = 0;
  let _time = 0;
  let _deltaTime = 0;
  let _timeFromGameStart = 0;
  let _timeOffset = 0;
  class Timer {
      constructor(span, repeatCount, callback, caller) {
          this._repeatCount = -1;
          this._span = 1;
          this._callback = null;
          this._count = 0;
          this._bRunning = false;
          this._span = span;
          this._repeatCount = repeatCount;
          this._callback = callback;
          this._caller = caller;
      }
      static get now() {
          return Date.now() / 1000;
      }
      static get time() {
          return _time + _timeOffset;
      }
      static get deltaTime() {
          return _deltaTime;
      }
      static get timeFromGameStart() {
          return _timeFromGameStart;
      }
      static waitTime(value) {
          return new Promise(function (resolve, reject) {
              Timer.callLater(value, function () {
                  resolve();
              });
          });
      }
      static setTimeOffset(offset) {
          _timeOffset = offset;
      }
      static initTime() {
          _gameStartTime = this.now;
          this.updateTime();
      }
      static updateTime() {
          _curTime = this.now;
          _time = _curTime;
          _timeFromGameStart = _curTime - _gameStartTime;
          _deltaTime = _curTime - _lastUpdateTime;
          _lastUpdateTime = _curTime;
      }
      static callLater(span, callback, caller) {
          let timer = new Timer(span, 1, callback, caller);
          timer.start();
          return timer;
      }
      static callLaterFrame(span, callback, caller) {
          let timer = new Timer(span, 1, callback, caller);
          timer.startFrame();
          return timer;
      }
      static callLoop(span, callback, caller) {
          let timer = new Timer(span, -1, callback, caller);
          timer.start(!caller);
          return timer;
      }
      static callLoopFrame(span, callback, caller) {
          let timer = new Timer(span, -1, callback, caller);
          timer.startFrame(!caller);
          return timer;
      }
      _onSpan() {
          this._count++;
          if (this._caller && !Tools.isNodeVaild(this._caller)) {
              this.stop();
              return;
          }
          if (this._callback) {
              try {
                  this._callback(this);
              }
              catch (error) {
                  Logger.error("[警告] Timer._onSpan callback has error", error);
              }
          }
          if (this._repeatCount >= 0 && this._count >= this._repeatCount) {
              this.stop();
          }
      }
      isRunning() {
          return this._bRunning;
      }
      get isDone() {
          return this._repeatCount >= 0 && this._count >= this._repeatCount;
      }
      get count() {
          return this._count;
      }
      get span() {
          return this._span;
      }
      start(bIgnoreForeverWarn = false) {
          this.stop();
          if (!this._callback) {
              Logger.warn("警告] Timer.start callback未设置！");
              return this;
          }
          if (!bIgnoreForeverWarn && this._repeatCount < 0) {
              Logger.warn("警告] Timer.start, this timer will never stop!");
              Logger.warn("警告]     please use startAndBindToNode");
              Logger.warn("警告]     or your can stop timer in callback. use e:stop()");
          }
          this._count = 0;
          Laya.timer.loop(this.span * 1000, this, this._onSpan);
          this._bRunning = true;
          return this;
      }
      startFrame(bIgnoreForeverWarn = false) {
          this.stop();
          if (!this._callback) {
              Logger.warn("警告] Timer.start callback未设置！");
              return this;
          }
          if (!bIgnoreForeverWarn && this._repeatCount < 0) {
              Logger.warn("警告] Timer.start, this timer will never stop!");
              Logger.warn("警告]     please use startAndBindToNode");
              Logger.warn("警告]     or your can stop timer in callback. use e:stop()");
          }
          this._count = 0;
          Laya.timer.frameLoop(this.span, this, this._onSpan);
          this._bRunning = true;
          return this;
      }
      resetCount() {
          this._count = 0;
      }
      stop() {
          if (this._bRunning) {
              Laya.timer.clear(this, this._onSpan);
              this._bRunning = false;
          }
          return this;
      }
  }

  const LOG10 = Math.log(10);
  class Mathf {
      static log(value, newBase) {
          if (newBase == null) {
              return Math.log(value) / LOG10;
          }
          else {
              return Math.log(value) / Math.log(newBase);
          }
      }
      static getDigits(num) {
          return Math.floor(this.log(num));
      }
      static random(min, max) {
          if (min == null) {
              return Math.random();
          }
          else if (max == null) {
              return (Math.random() * min + 1) | 0;
          }
          else {
              return (Math.random() * (max - min + 1) + min) | 0;
          }
      }
      static randomPlusOrMinus() {
          return (this.random(2) - 1) * 2 - 1;
      }
      static trueOrFalse() {
          return Math.random() > 0.5;
      }
      static randomEnable(rate) {
          return this.random(100) <= rate;
      }
      static clamp01(value) {
          if (value > 1)
              return 1;
          else if (value < 0)
              return 0;
          else
              return value;
      }
      static clamp(value, min, max) {
          if (value < min)
              return min;
          else if (value > max)
              return max;
          else
              return value;
      }
      static sign(value) {
          if (value >= 0)
              return 1;
          else
              return -1;
      }
      static fuzzyEquals(value1, value2) {
          return Math.abs(value1 - value2) < this.EPSILON;
      }
      static lerp(min, max, t) {
          return min + (max - min) * this.clamp01(t);
      }
      static inverseLerp(min, max, cur) {
          if (min != max) {
              return this.clamp01((cur - min) / (max - min));
          }
          else {
              return 0;
          }
      }
      static lerpFromInverseLerp(valueMin, valueMax, fromMin, fromMax, fromValue) {
          return this.lerp(valueMin, valueMax, this.inverseLerp(fromMin, fromMax, fromValue));
      }
      static getFitScale(x, y, maxX, maxY) {
          let scaleX = maxX / x;
          let scaleY = maxY / y;
          return Math.min(scaleX, scaleY);
      }
      static round(value, digits) {
          digits = digits || 0;
          let num = this.roundPower10Double[digits];
          value *= num;
          return Math.round(value) / num;
      }
      static loop(value, min, max) {
          if (max == null) {
              max = min;
              min = 0;
          }
          if (value < min) {
              return min;
          }
          else {
              let v = (value - min) % (max - min);
              return min + v;
          }
      }
      static pingPong(value, min, max) {
          if (max == null) {
              max = min;
              min = 0;
          }
          if (value < min) {
              return min;
          }
          else {
              let d = max - min;
              let v1 = value - min;
              let s = Math.floor(v1 / d);
              let v2 = v1 % d;
              if (s % 2 == 0) {
                  return v2 + min;
              }
              else {
                  return max - v2;
              }
          }
      }
      static nextGaussian(mean, std_dev) {
          return mean + (this.uniform2NormalDistribution() * std_dev);
      }
      static uniform2NormalDistribution() {
          var sum = 0.0;
          for (var i = 0; i < 12; i++) {
              sum = sum + Math.random();
          }
          return sum - 6.0;
      }
      static circleRandom(...weights) {
          return this.arrCircleRandom(weights);
      }
      static arrCircleRandom(weights) {
          let sum = 0;
          for (let i = 0; i < weights.length; i++) {
              sum += weights[i];
          }
          if (sum <= 0)
              return -1;
          let random = Mathf.random(sum);
          for (let i = 0; i < weights.length; i++) {
              if (random <= weights[i]) {
                  return i;
              }
              random -= weights[i];
          }
          return -1;
      }
      static makeArray(len, shuffle = true) {
          let arr = new Array(len);
          for (let i = 0; i < len; i++) {
              arr[i] = i;
          }
          shuffle && this.shuffle(arr);
          return arr;
      }
      static randomFromArray(arr, removeIt) {
          if (arr && arr.length) {
              let idx = this.random(arr.length) - 1;
              if (removeIt) {
                  return arr.splice(idx, 1)[0];
              }
              else {
                  return arr[idx];
              }
          }
          else {
              return null;
          }
      }
      static randomArrFromArray(arr, count, removeIt) {
          let result = [];
          if (arr) {
              if (!removeIt) {
                  arr = arr.slice();
              }
              for (let i = Math.min(arr.length, count); i > 0; i--) {
                  result.push(this.randomFromArray(arr, true));
              }
          }
          return result;
      }
      static shuffle(data) {
          let temp;
          let rnd;
          for (let i = data.length - 1; i > 0; i--) {
              rnd = this.random(0, i);
              temp = data[i];
              data[i] = data[rnd];
              data[rnd] = temp;
          }
      }
      static swap(data, i, j) {
          let temp = data[i];
          data[i] = data[j];
          data[j] = temp;
      }
      static minIndex(values) {
          let minValue = Number.MAX_SAFE_INTEGER;
          let index = -1;
          for (let i = values.length - 1; i >= 0; i--) {
              if (values[i] <= minValue) {
                  minValue = values[i];
                  index = i;
              }
          }
          return index;
      }
      static distance(p1, p2) {
          let dx = p1.x - p2.x;
          let dy = p1.y - p2.y;
          return Math.sqrt(dx * dx + dy * dy);
      }
      static distance2(dx, dy) {
          return Math.sqrt(dx * dx + dy * dy);
      }
      static distanceSqr(p1, p2) {
          let dx = p1.x - p2.x;
          let dy = p1.y - p2.y;
          return dx * dx + dy * dy;
      }
      static distanceSqr2(dx, dy) {
          return dx * dx + dy * dy;
      }
      static point2line(a, b, s) {
          let sqrt = Math.sqrt;
          let pow = Math.pow;
          let ab = sqrt(pow((a.x - b.x), 2) + pow((a.y - b.y), 2) + pow((a.z - b.z), 2));
          let as = sqrt(pow((a.x - s.x), 2) + pow((a.y - s.y), 2) + pow((a.z - s.z), 2));
          let bs = sqrt(pow((s.x - b.x), 2) + pow((s.y - b.y), 2) + pow((s.z - b.z), 2));
          let cos_A = (pow(as, 2) + pow(ab, 2) - pow(bs, 2)) / (2 * ab * as);
          let sin_A = sqrt(1 - pow(cos_A, 2));
          return as * sin_A;
      }
      static easeInLogic(val) {
          return 1 - Math.sin(0.5 * Math.PI * (1 - val));
      }
      static easeOutLogic(val) {
          return Math.sin(0.5 * Math.PI * val);
      }
      static easeInOutLogic(val) {
          let pi2 = Math.PI * 2;
          return val - Math.sin(val * pi2) / pi2;
      }
      static bounceLogic(val) {
          if (val < 0.363636) {
              val = 7.5685 * val * val;
          }
          else if (val < 0.727272) {
              val = 7.5625 * (val -= 0.545454) * val + 0.75;
          }
          else if (val < 0.909090) {
              val = 7.5625 * (val -= 0.818181) * val + 0.9375;
          }
          else {
              val = 7.5625 * (val -= 0.9545454) * val + 0.984375;
          }
          return val;
      }
      static calcAngleA2B(A, B) {
          if (!A)
              return 0;
          if (!B)
              return 0;
          let magA = Laya.Vector3.scalarLength(A);
          let magB = Laya.Vector3.scalarLength(B);
          if (!magA)
              return 0;
          if (!magB)
              return 0;
          let cos_angle = Laya.Vector3.dot(A, B) / (magA * magB);
          let angle = Math.acos(cos_angle);
          return angle;
      }
  }
  Mathf.roundPower10Double = [
      1.0,
      10.0,
      100.0,
      1000.0,
      10000.0,
      100000.0,
      1000000.0,
      10000000.0,
      100000000.0,
      1000000000.0,
      10000000000.0,
      100000000000.0,
      1000000000000.0,
      10000000000000.0,
      100000000000000.0,
      1E+15
  ];
  Mathf.PI = 3.14159274;
  Mathf.Deg2Rad = 0.0174532924;
  Mathf.Rad2Deg = 57.295779;
  Mathf.TEMP_POINT = new Laya.Point();
  Mathf.TEMP_POINTS = [
      new Laya.Point(),
      new Laya.Point(),
      new Laya.Point(),
      new Laya.Point(),
  ];
  Mathf.TempRect = Laya.Rectangle.create();
  Mathf.VEC3_UP = new Laya.Vector3(0, 1, 0);
  Mathf.TEMP_VEC3 = new Laya.Vector3();
  Mathf.TEMP_VEC3S = [
      new Laya.Vector3(),
      new Laya.Vector3(),
      new Laya.Vector3(),
      new Laya.Vector3(),
  ];
  Mathf.EPSILON = 1e-6;

  class ResLoader {
      static tryLoadRes(url) {
          return Laya.loader.getRes(url);
      }
      static loadRes(url, type, completeCallback) {
          completeCallback = completeCallback || this.EMPTY_FUN;
          let resource = Laya.loader.getRes(url);
          if (resource != null) {
              completeCallback(resource);
              return;
          }
          if (this.loadingCallback[url]) {
              this.loadingCallback[url].calls.push(completeCallback);
              return;
          }
          else {
              this.loadingCallback[url] = { calls: [completeCallback], loadCount: 1 };
          }
          let loadCallback;
          loadCallback = (res) => {
              let callbacks = this.loadingCallback[url];
              if (callbacks) {
                  if (res) {
                      let calls = callbacks.calls;
                      delete this.loadingCallback[url];
                      for (let i = 0; i < calls.length; i++) {
                          calls[i](res);
                      }
                  }
                  else {
                      Logger.error(`mgrRes.loadRes load [${url}] err.`);
                      if (callbacks.loadCount <= this.retryCount) {
                          callbacks.loadCount++;
                          this._loadRes(url, type, loadCallback);
                      }
                      else {
                          let calls = callbacks.calls;
                          delete this.loadingCallback[url];
                          for (let i = 0; i < calls.length; i++) {
                              calls[i](null);
                          }
                      }
                  }
              }
              else {
                  Logger.warn("mgrRes loadCallback: No Loaded Callback Exists! ", url);
              }
          };
          this._loadRes(url, type, loadCallback);
      }
      static _loadRes(url, type, completeCallback) {
          let handler = Laya.Handler.create(this, function (res) {
              try {
                  completeCallback(res);
              }
              catch (error) {
                  Logger.catchError("mgrRes._loadRes complete", error);
              }
          });
          switch (type) {
              case RES_TYPE.PREFAB2D:
              case RES_TYPE.IMAGE:
              case RES_TYPE.TEXT:
              case RES_TYPE.JSON:
              case RES_TYPE.SOUND:
              case RES_TYPE.ATLAS:
                  Laya.loader.load(url, handler, null, type);
                  return;
              case RES_TYPE.PREFAB3D:
              case RES_TYPE.MATERIAL:
              case RES_TYPE.TEXTURE2D:
              case RES_TYPE.MESH:
              case RES_TYPE.ANIMATIONCLIP:
              case RES_TYPE.TEXTURECUBE:
                  Laya.loader.create(url, handler, null, type);
                  return;
              default:
                  Logger.error("未知资源类型:", type);
                  break;
          }
      }
      static loadImageFromWeb(url, onComplete) {
          if (!url) {
              onComplete(null);
              return;
          }
          if (this.webResCache[url]) {
              onComplete(this.webResCache[url]);
              return;
          }
          Logger.error("本方法暂未实现.");
      }
      static loadImage(url, callback) {
          this.loadRes(url, RES_TYPE.IMAGE, callback);
      }
      static loadText(url, callback) {
          this.loadRes(url, RES_TYPE.TEXT, callback);
      }
      static loadJson(url, callback) {
          this.loadRes(url, RES_TYPE.JSON, callback);
      }
      static loadTexture2D(url, callback) {
          this.loadRes(url, RES_TYPE.TEXTURE2D, callback);
      }
      static loadAnimationClip(url, callback) {
          this.loadRes(url, RES_TYPE.ANIMATIONCLIP, callback);
      }
      static loadTextureCube(url, callback) {
          this.loadRes(url, RES_TYPE.TEXTURECUBE, callback);
      }
      static loadSprite3D(url, callback) {
          this.loadRes(url, RES_TYPE.PREFAB3D, function (res) {
              if (callback) {
                  if (res) {
                      res = Laya.Sprite3D.instantiate(res);
                  }
                  callback(res);
              }
          });
      }
  }
  ResLoader.EMPTY_FUN = function () { };
  ResLoader.retryCount = 0;
  ResLoader.loadingCallback = {};
  ResLoader.webResCache = {};

  class TaskManager {
      constructor(taskName = "", bLog = Logger.isDebugLevel) {
          this.destroyed = false;
          this.isLoaded = false;
          this.isLoading = false;
          this.taskName = "";
          this.urls = [];
          this.urlData = { prefab: [], d3: [], d2: [] };
          this.calls = [];
          this.resStartTime = 0;
          this.callStartTime = 0;
          this.progressCallback = null;
          this.completeCallback = null;
          if (taskName) {
              this.taskName = `(${taskName})`;
          }
          this.bLog = false;
      }
      get resCount() {
          return this.urls.length;
      }
      get totalCallWeight() {
          let value = 0;
          for (var i = this.calls.length - 1; i >= 0; i--) {
              value += this.calls[i].weight;
          }
          return value;
      }
      dispose() {
          this.destroyed = true;
          this.urlData = null;
          this.urls = null;
          this.calls = null;
          this.completeCallback = null;
          this.progressCallback = null;
      }
      setLoadingCallback(completeCallback, progressCallback) {
          this.completeCallback = completeCallback;
          this.progressCallback = progressCallback || Global.EMPTY_FUN;
      }
      addRes(url, type = Laya.Loader.PREFAB) {
          if (!url)
              return;
          if (this.isLoading) {
              Logger.error(`TaskManager${this.taskName} is loading!`);
              return;
          }
          if (this.bLog)
              Logger.log(`TaskManager${this.taskName} add:${url} ${type}`);
          let urlData = this.urls;
          if (url instanceof Array) {
              for (let i = 0; i < url.length; i++) {
                  let item = url[i];
                  if (typeof item == "string") {
                      urlData.push({ url: item, type: type });
                  }
                  else {
                      urlData.push(item);
                  }
              }
          }
          else {
              if (typeof url == "string") {
                  urlData.push({ url: url, type: type });
              }
              else {
                  urlData.push(url);
              }
          }
      }
      addFguiPackage(resKey) {
          this.addCall(function (resolve) {
              fgui.UIPackage.loadPackage(resKey, Laya.Handler.create(this, resolve));
          });
      }
      addCall(call, weight = 1) {
          this.calls.push({ fuc: call, weight: weight });
      }
      clearDuplicateRes() {
          let urls = this.urls;
          let resMap = Object.create(null);
          for (let i = urls.length - 1; i >= 0; i--) {
              let item = urls[i];
              if (Laya.loader.getRes(item.url)) {
                  urls.splice(i, 1);
                  continue;
              }
              if (resMap[item.url]) {
                  urls.splice(i, 1);
              }
              else {
                  resMap[item.url] = true;
              }
          }
      }
      classifyRes() {
          this.clearDuplicateRes();
          if (this.urlData.prefab.length > 0 || this.urlData.d2.length > 0 || this.urlData.d3.length > 0)
              return;
          let urls = this.urls;
          for (let i = urls.length - 1; i >= 0; i--) {
              let item = urls[i];
              switch (item.type) {
                  case RES_TYPE.PREFAB2D:
                      this.urlData.prefab.push(item);
                      break;
                  case RES_TYPE.IMAGE:
                  case RES_TYPE.TEXT:
                  case RES_TYPE.JSON:
                  case RES_TYPE.SOUND:
                  case RES_TYPE.ATLAS:
                  case RES_TYPE.BUFFER:
                      this.urlData.d2.push(item);
                      break;
                  case RES_TYPE.PREFAB3D:
                  case RES_TYPE.MATERIAL:
                  case RES_TYPE.TEXTURE2D:
                  case RES_TYPE.MESH:
                  case RES_TYPE.ANIMATIONCLIP:
                  case RES_TYPE.TEXTURECUBE:
                      this.urlData.d3.push(item);
                      break;
                  default:
                      urls.splice(i, 1);
                      Logger.error(`TaskManager${this.taskName}.classifyRes 未知资源类型:${item.type}`);
                      break;
              }
          }
      }
      get isEmpty() {
          return this.resCount == 0;
      }
      loadAll() {
          if (this.isLoading) {
              Logger.error(`TaskManager${this.taskName} is loading!`);
              return;
          }
          this.isLoading = true;
          this.resStartTime = Timer.time;
          this.classifyRes();
          if (this.resCount == 0) {
              this.onResLoadComplete(true);
              return;
          }
          let countPrefab = this.urlData.prefab.length;
          let count2D = this.urlData.d2.length;
          let count3D = this.urlData.d3.length;
          let countTotal = countPrefab + count2D + count3D + this.totalCallWeight;
          let progressPrefab = 0;
          let progress2D = 0;
          let progress3D = 0;
          let completeState = 0;
          let bError = false;
          let calcProgress = () => {
              var progress = progressPrefab * countPrefab + progress2D * count2D + progress3D * count3D;
              this.onProgress(progress / countTotal);
          };
          let checkComplete = (suc) => {
              completeState++;
              if (!suc)
                  bError = true;
              if (completeState == 3) {
                  if (bError) {
                      this.onResLoadComplete(false);
                      Logger.error(`TaskManager${this.taskName} 资源加载错误.`);
                  }
                  else {
                      this.onResLoadComplete(true);
                  }
              }
          };
          this._loadPrefab(checkComplete, function (p) {
              progressPrefab = p;
              calcProgress();
          });
          this._load2d(checkComplete, function (p) {
              progress2D = p;
              calcProgress();
          });
          this._load3d(checkComplete, function (p) {
              progress3D = p;
              calcProgress();
          });
      }
      _loadPrefab(complete, progress, loadIndex = 0) {
          if (loadIndex < this.urlData.prefab.length) {
              let item = this.urlData.prefab[loadIndex++];
              let onAllLoaded = (res) => {
                  if (res) {
                      progress(loadIndex / this.urlData.prefab.length);
                      this._loadPrefab(complete, progress, loadIndex);
                  }
                  else {
                      this.onComplete(false);
                  }
              };
              let onPrefabLoaded = (prefab) => {
                  if (prefab) {
                      if (prefab.json && prefab.json.loadList && prefab.json.loadList.length > 0) {
                          Laya.loader.load(prefab.json.loadList, Laya.Handler.create(this, onAllLoaded));
                          return;
                      }
                      onAllLoaded(true);
                  }
                  else {
                      onAllLoaded(false);
                  }
              };
              Laya.loader.load(item.url, Laya.Handler.create(this, onPrefabLoaded), null, item.type);
          }
          else {
              complete(true);
          }
      }
      _load2d(complete, progress) {
          if (this.urlData.d2.length > 0) {
              Laya.loader.load(this.urlData.d2, Laya.Handler.create(this, complete), Laya.Handler.create(this, progress));
          }
          else {
              complete(true);
          }
      }
      _load3d(complete, progress) {
          if (this.urlData.d3.length > 0) {
              Laya.loader.create(this.urlData.d3, Laya.Handler.create(this, complete), Laya.Handler.create(this, progress));
          }
          else {
              complete(true);
          }
      }
      loadOneByOne(deltaTime = 1) {
          if (this.isLoading) {
              Logger.error(`TaskManager${this.taskName} is loading!`);
              return;
          }
          this.isLoading = true;
          this.resStartTime = Timer.time;
          this.clearDuplicateRes();
          this._loadOneByOne(deltaTime * 1000);
      }
      _loadOneByOne(deltaTime) {
          if (this.destroyed)
              return;
          let urlData = this.urls.shift();
          if (urlData) {
              ResLoader.loadRes(urlData.url, urlData.type, (res) => {
                  if (res) {
                      Laya.timer.once(deltaTime, this, this._loadOneByOne, [deltaTime]);
                  }
                  else {
                      Logger.error(`TaskManager${this.taskName}.loadOneByOne error, url:${urlData.url}`);
                      this.onResLoadComplete(false);
                  }
              });
          }
          else {
              this.onResLoadComplete(true);
          }
      }
      onResLoadComplete(suc) {
          this.bLog && Logger.log(`TaskManager 资源加载结束:${suc}，耗时：${Mathf.round(Timer.time - this.resStartTime, 2)}`);
          if (suc) {
              this.bLog && Logger.log(`TaskManager${this.taskName} 开始执行call!`);
              this.callStartTime = Timer.time;
              this._processCalls();
          }
          else {
              this.onComplete(false);
          }
      }
      _processCalls(curCallIndex = 0) {
          this.curCallIndex = curCallIndex;
          if (curCallIndex >= this.calls.length) {
              this.onProgress(1);
              this.onComplete(true);
              return;
          }
          this.bLog && Logger.log(`TaskManager${this.taskName} 执行索引：`, curCallIndex);
          let curCompleteWeight = 0;
          for (var i = 0; i < curCallIndex; i++) {
              curCompleteWeight += this.calls[i].weight;
          }
          this.onProgress((curCompleteWeight + this.resCount) / (this.totalCallWeight + this.resCount));
          let callItem = this.calls[curCallIndex];
          try {
              let nextStep = () => {
                  Laya.timer.frameOnce(1, this, this._processCalls, [curCallIndex + 1]);
              };
              callItem.fuc(nextStep);
          }
          catch (error) {
              Logger.catchError(`TaskManager${this.taskName}._processCalls index:${curCallIndex}`, error);
              this.onComplete(false);
          }
      }
      setParent(loader) {
          if (this.parent) {
              Logger.warn(`TaskManager${this.taskName}.setParent: parent already exists.`);
          }
          this.parent = loader;
      }
      setCallProgress(percent) {
          if (this.curCallIndex < this.calls.length) {
              let curCompleteWeight = 0;
              for (var i = 0; i < this.curCallIndex; i++) {
                  curCompleteWeight += this.calls[i].weight;
              }
              curCompleteWeight += this.calls[this.curCallIndex].weight * percent;
              this.onProgress((curCompleteWeight + this.resCount) / (this.totalCallWeight + this.resCount));
          }
      }
      onProgress(percent) {
          if (this.progressCallback) {
              this.progressCallback(percent);
          }
          if (this.parent) {
              this.parent.setCallProgress(percent);
          }
          this.bLog && Logger.log(`TaskManager${this.taskName} 加载进度: [${Mathf.round(percent, 2)}]`);
      }
      onComplete(finish) {
          this.bLog && Logger.log(`TaskManager${this.taskName} 执行完成，耗时：${Mathf.round(Timer.time - this.callStartTime, 2)}`);
          this.bLog && Logger.log(`TaskManager${this.taskName} 总耗时：${Mathf.round(Timer.time - this.resStartTime, 2)}`);
          this.isLoaded = true;
          if (this.completeCallback) {
              try {
                  this.completeCallback(finish);
              }
              catch (error) {
                  Logger.catchError(`TaskManager${this.taskName}.onComplete[${finish}]`, error);
              }
          }
          this.dispose();
      }
  }

  class Manager {
      static loadAllManagers(finishCallback) {
          try {
              let tManager = new TaskManager("Manager");
              for (let i = 0; i < this._managerInstances.length; i++) {
                  let manager = this._managerInstances[i];
                  tManager.addCall((resolve) => {
                      manager.loadedCallback = () => {
                          resolve();
                      };
                      manager.onLoad();
                  });
              }
              tManager.setLoadingCallback(() => {
                  finishCallback();
                  this.startAllManagers();
              });
              tManager.loadAll();
          }
          catch (error) {
              console.warn("Manager.loadAllManager has error", error);
          }
      }
      static startAllManagers() {
          for (let i = 0; i < this._managerInstances.length; i++) {
              this._managerInstances[i].onStart();
          }
      }
      static checkRecord(data, dataDefault) {
          let needSave = false;
          for (let key in dataDefault) {
              let value = data[key];
              if (value == null) {
                  data[key] = dataDefault[key];
                  needSave = true;
              }
          }
          if (needSave) {
              this.saveRecord();
          }
      }
      static __init() {
          Manager._managerInstances.push(this);
      }
      static onLoad() {
          Global.registerListeners(this, {
              "MSG_RECORD_RESET": this.loadRecord,
          });
          if (!this._bNetworkResponseRegistered) {
              this._bNetworkResponseRegistered = true;
              this.onRegisterNetworkResponseListeners();
          }
          this.loadedCallback();
          this.loadRecord();
      }
      static onStart() {
      }
      static loadRecord() {
      }
      static saveRecord() {
      }
      static onRegisterNetworkResponseListeners() {
      }
  }
  Manager._managerInstances = [];
  Manager.loadedCallback = null;
  Manager._bNetworkResponseRegistered = false;

  const CLASS_KEY = "__mgr_class__";
  const FLAG_OPENING = "__mgr_flag_open__";
  const FLAG_LOADED = "__mgr_flag_loaded__";
  class Director {
      static get isSceneOpening() {
          return this._isSceneOpening;
      }
      static init() {
          this.initScene();
          console.log("Director.onLoad");
      }
      static runScene(sceneClass, loadingClass, params) {
          console.log("mgrScene startRun.", sceneClass);
          if (this._isSceneOpening) {
              console.error("mgr scene is busy");
              return;
          }
          this._isSceneOpening = true;
          if (loadingClass) {
              this.initScene();
              Director.openPanelWithSingleton(loadingClass, null, () => {
                  this.startLoading(sceneClass, params);
              });
          }
          else {
              this.startLoading(sceneClass, params);
          }
      }
      static startLoading(sceneClass, params) {
          Global.sendMsg(BASE_MSG.RES_LOAD_START, "收集能量");
          if (this.runningScene) {
              this.runningScene.onExit();
              this.runningScene = null;
          }
          let curScene;
          try {
              curScene = new sceneClass();
          }
          catch (error) {
              console.error("mgrScene.runScene:", error);
              return;
          }
          this.runingSceneClass = sceneClass;
          this.nextScene = curScene;
          this.nextSceneparams = params;
          let taskManager = curScene.getTaskManager();
          if (taskManager == null) {
              this.onTaskComplete(true);
          }
          else {
              taskManager.setLoadingCallback(this.onTaskComplete.bind(this), this.onTaskProgress.bind(this));
              taskManager.loadAll();
              console.log("mgrScene 开始加载.");
          }
      }
      static onTaskProgress(progress) {
          Global.sendMsg(BASE_MSG.RES_LOAD_PROGRESS, progress);
      }
      static onTaskComplete(suc) {
          console.log("mgrScene 加载完成.", suc);
          if (suc) {
              this.runningScene = this.nextScene;
              this.nextScene = null;
              let params = this.nextSceneparams;
              this.nextSceneparams = null;
              this._isSceneOpening = false;
              Global.sendMsg(BASE_MSG.RES_LOAD_END);
              this.runningScene.onEnter(params);
          }
          else {
              console.error("mgrSceen.onResComplete error.");
          }
      }
      static initScene() {
          this.init2DLayer();
      }
      static init2DLayer() {
          if (!this.layers2D) {
              this.layers2D = [];
              Laya.stage.addChild(fgui.GRoot.inst.displayObject);
              for (let i = 0; i <= 8; i++) {
                  let layer = new fgui.GComponent();
                  layer.name = "Layer" + i;
                  layer.displayObject.name = layer.name;
                  layer.makeFullScreen();
                  fgui.GRoot.inst.addChild(layer);
                  this.layers2D.push(layer);
                  this.view_stack.push([]);
              }
          }
      }
      static getTopViewName() {
          let node = fgui.GRoot.inst.getChild("Layer1");
          if (node.numChildren > 0)
              return node.getChildAt(node.numChildren - 1).name;
          else
              return "";
      }
      static getLayer(layer = 2) {
          return this.layers2D[layer];
      }
      static getDialogLayer() {
          return this.getLayer;
      }
      static getTipRoot() {
          return this.getLayer(6);
      }
      static createScene3DLayer(layer) {
          if (this.layerScene3d[layer]) {
              return this.layerScene3d[layer];
          }
          let scene3d = new Laya.Scene3D();
          this.getLayer(layer).displayObject.addChild(scene3d);
          var camera = scene3d.addChild(new Laya.Camera(0, 0.1, 20));
          camera.orthographic = true;
          camera.orthographicVerticalSize *= UIRoot.canvasHeight / 1024;
          camera.transform.position = new Laya.Vector3(0, 0, 10);
          camera.clearFlag = Laya.CameraClearFlags.DepthOnly;
          let data = { scene3d: scene3d, camera: camera };
          this.layerScene3d[layer] = data;
          return data;
      }
      static getScene3DLayer(layer) {
          return this.layerScene3d[layer];
      }
      static destroyScene3DLayer(layer) {
          let data = this.getScene3DLayer(layer);
          if (data) {
              data.scene3d.destroy();
          }
          this.layerScene3d[layer] = null;
      }
      static pushStack(panel, layer) {
          let stack = this.view_stack[layer];
          if (stack) {
              stack.push(panel);
          }
          else {
              console.error(`push panel invalid layer: ${layer}`);
          }
      }
      static peekStack(layer, fromIdx) {
          let stack = this.view_stack[layer];
          if (stack) {
              if (fromIdx == null)
                  return stack[stack.length - 1];
              else {
                  for (var i = fromIdx; i >= 0; i--) {
                      if (stack[i])
                          return stack[i];
                  }
                  return null;
              }
          }
          else {
              console.error(`pop panel invalid layer:${layer}}`);
          }
      }
      static removeAndDispose(panel) {
          if (panel) {
              let stack = this.view_stack[panel.panelLayer];
              let index = -1;
              for (let i = 0; i < stack.length; i++) {
                  if (stack[i] === panel) {
                      panel[CLASS_KEY][FLAG_OPENING] = false;
                      stack.splice(i, 1);
                      index = i;
                      break;
                  }
              }
              if (index < 0)
                  console.error(`can't remove panel:${panel.sourceName} in layer:${panel.panelLayer}`);
              panel.dispose();
              return index;
          }
          return -1;
      }
      static closePanel(panel) {
          if (!panel || !panel.isLoaded)
              return;
          if (panel.isFocus)
              panel.onFocus(false);
          let layer = panel.panelLayer;
          let style = panel.panelStyle;
          let idx = this.removeAndDispose(panel);
          if (idx > 0) {
              let curPanel = this.peekStack(layer, idx - 1);
              if (!curPanel)
                  return;
              if (curPanel.panelStyle == 0) {
              }
              else if (curPanel.panelStyle == style) {
                  curPanel.show();
              }
              else if (style == 1) {
                  curPanel.show();
              }
              if (this.peekStack(layer) === curPanel)
                  curPanel.onFocus(true);
          }
      }
      static hasLoaded(panelClass) {
          return !!panelClass[FLAG_LOADED];
      }
      static getPanelClass(panel) {
          if (typeof panel == "string") {
              return Global.require(panel);
          }
          else {
              return panel;
          }
      }
      static openPanel(panel, context, callback) {
          let panelClass = this.getPanelClass(panel);
          if (!panelClass) {
              callback && callback();
              return;
          }
          var panelInstance = new panelClass(context);
          panelInstance.name = panel;
          return this.openPanelInstance(panelInstance, panelClass, callback);
      }
      static openPanelByClass(panelClass, panelName, context, callback) {
          var panelInstance = new panelClass(context);
          panelInstance.name = panelName;
          return this.openPanelInstance(panelInstance, panelClass, callback);
      }
      static openPanelInstance(panel, panelClass, callback) {
          panel[CLASS_KEY] = panelClass;
          panel.create(function (suc) {
              if (suc)
                  panelClass[FLAG_LOADED] = true;
              callback && callback(suc);
              console.log("打开:" + panel.sourceName, suc);
          });
          return panel;
      }
      static openPanelWithSingleton(panel, context, callback) {
          let panelClass = this.getPanelClass(panel);
          if (!panelClass) {
              callback && callback(false);
              return;
          }
          let view = this.findPanel(panelClass);
          if (view) {
              callback && callback(true);
              view.setContext(context);
              view.setTop();
              view.show();
          }
          else {
              if (panelClass[FLAG_OPENING]) {
                  console.info(`${panelClass} is opening`);
                  return;
              }
              panelClass[FLAG_OPENING] = true;
              this.openPanel(panel, context, function (suc) {
                  panelClass[FLAG_OPENING] = false;
                  callback && callback(suc);
              });
          }
      }
      static openPanelWithSingletonByClass(panelClass, panelName, context, callback) {
          let view = this.findPanel(panelClass);
          if (view) {
              callback && callback(true);
              view.setContext(context);
              view.setTop();
              view.show();
          }
          else {
              if (panelClass[FLAG_OPENING]) {
                  console.info(`${panelClass} is opening`);
                  return;
              }
              panelClass[FLAG_OPENING] = true;
              this.openPanelByClass(panelClass, panelName, context, function (suc) {
                  panelClass[FLAG_OPENING] = false;
                  callback && callback(suc);
              });
          }
      }
      static openPanelByWait(panel, context, callback) {
          this.showWait("open_panel");
          this.openPanel(panel, context, (suc) => {
              this.hideWait("open_panel");
              callback && callback(suc);
          });
      }
      static showWait(router = "default") {
          if (~this.waitRouters.indexOf(router))
              return;
          this.waitRouters.push(router);
          if (!this.waitPanel) {
              this.waitPanel = this.openPanel("PanelWait");
          }
      }
      static hideWait(router = "default") {
          let idx = this.waitRouters.indexOf(router);
          if (idx != -1) {
              this.waitRouters.splice(idx, 1);
          }
          if (this.waitRouters.length == 0) {
              if (this.waitPanel) {
                  this.waitPanel.close();
                  this.waitPanel = null;
              }
          }
      }
      static findPanel(panelClass, layer) {
          for (let layerIdx = 0; layerIdx < this.view_stack.length; layerIdx++) {
              if (layer == null || layer == layerIdx) {
                  const stack = this.view_stack[layerIdx];
                  for (let j = 0; j < stack.length; j++) {
                      const panel = stack[j];
                      if (panel[CLASS_KEY] == panelClass)
                          return panel;
                  }
              }
          }
          return null;
      }
      static findPanelLocalBanner() {
          return this.findPanelByName("PanelLocalBanner");
      }
      static findPanelByName(panelName) {
          for (let layer = 0; layer < this.view_stack.length; layer++) {
              const stack = this.view_stack[layer];
              for (let j = 0; j < stack.length; j++) {
                  const panel = stack[j];
                  let arr = panel.sourceName.split("/");
                  if (arr && arr.length > 0) {
                      if (arr[arr.length - 1] == panelName) {
                          return panel;
                      }
                  }
              }
          }
          return null;
      }
      static addPanel(panel) {
          let layer = panel.panelLayer;
          let style = panel.panelStyle;
          let topPanel = this.peekStack(layer);
          this.pushStack(panel, layer);
          this.getLayer(layer).addChild(panel);
          if (topPanel) {
              if (topPanel.panelStyle == 0) {
              }
              else if (topPanel.panelStyle == style) {
                  topPanel.hide();
              }
              else if (style == 1) {
                  topPanel.hide();
              }
              topPanel.onFocus(false);
          }
          panel.onFocus(true);
      }
      static disposeAllPanel(layerExcept) {
          for (let i = 0; i < this.view_stack.length; i++) {
              if (layerExcept == null || i != layerExcept) {
                  const stack = this.view_stack[i];
                  for (let j = 0; j < stack.length; j++) {
                      const panel = stack[j];
                      panel[CLASS_KEY][FLAG_OPENING] = false;
                      panel.onFocus(false);
                      panel.dispose();
                  }
                  this.view_stack[i] = [];
              }
          }
      }
      static closeTop(layer) {
          if (layer == null) {
              for (let i = this.view_stack.length - 1; i >= 0; i--) {
                  const stack = this.view_stack[i];
                  for (let j = stack.length - 1; j >= 0; j--) {
                      const panel = stack[j];
                      if (panel.visible) {
                          panel.close();
                          console.info("close top:", panel.sourceName);
                          return;
                      }
                  }
              }
          }
          else {
              const stack = this.view_stack[layer];
              for (let j = stack.length - 1; j >= 0; j--) {
                  const panel = stack[j];
                  if (panel.visible) {
                      panel.close();
                      console.info("close top:", panel.sourceName);
                      return;
                  }
              }
          }
      }
      static closeLayer(layer) {
          for (let i = this.view_stack.length - 1; i >= 0; i--) {
              if (layer == null || i == layer) {
                  const stack = this.view_stack[i];
                  for (let j = stack.length - 1; j >= 0; j--) {
                      const panel = stack[j];
                      if (panel.visible) {
                          panel.close();
                      }
                  }
              }
          }
      }
      static debugPanels() {
          console.log("------ debug panels start ------");
          for (let i = 0; i < this.view_stack.length; i++) {
              const stack = this.view_stack[i];
              for (let j = 0; j < stack.length; j++) {
                  const panel = stack[j];
                  console.log(`layer:[${i}]  name:[${panel.sourceName}] visible:[${panel.visible}]`);
              }
          }
          console.log("------ debug panels end ------");
      }
      static isDeviceOverHeight() {
          return Laya.stage.height / Laya.stage.width >= 2;
      }
      static get maxRatio() {
          return 2;
      }
      static get standardRatio() {
          return 1024 / 576;
      }
      static get ratioLerpValue() {
          let cur = Laya.stage.height / Laya.stage.width;
          cur = Mathf.clamp(cur, this.standardRatio, this.maxRatio);
          return (cur - this.standardRatio) / (this.maxRatio - this.standardRatio);
      }
      static get width() {
          return Laya.stage.width;
      }
      static get height() {
          return Laya.stage.height;
      }
      static isSceneRuning(sceneClass) {
          return this.runingSceneClass == sceneClass;
      }
  }
  Director._isSceneOpening = false;
  Director.runingSceneClass = null;
  Director.runningScene = null;
  Director.nextScene = null;
  Director.nextSceneparams = null;
  Director.view_stack = [];
  Director.waitRouters = [];
  Director.layerScene3d = [];

  function logID(id) {
      console.log(id);
  }
  function errorID(id) {
      console.error(id);
  }
  function warnID(id, opt) {
      console.warn(id, opt);
  }

  let ID_COUNTER = 0;
  class HashElement {
      constructor() {
          this.actions = [];
          this.target = null;
          this.actionIndex = 0;
          this.currentAction = null;
          this.paused = false;
          this.lock = false;
      }
  }
  class ActionManager {
      constructor() {
          this._hashTargets = Object.create(null);
          this._arrayTargets = [];
          this._elementPool = [];
      }
      _searchElementByTarget(arr, target) {
          for (var k = 0; k < arr.length; k++) {
              if (target === arr[k].target)
                  return arr[k];
          }
          return null;
      }
      _getElement(target, paused) {
          var element = this._elementPool.pop();
          if (!element) {
              element = new HashElement();
          }
          element.target = target;
          element.paused = !!paused;
          return element;
      }
      _putElement(element) {
          element.actions.length = 0;
          element.actionIndex = 0;
          element.currentAction = null;
          element.paused = false;
          element.target = null;
          element.lock = false;
          this._elementPool.push(element);
      }
      addAction(action, target, paused) {
          if (!action || !target) {
              errorID(1000);
              return;
          }
          var gid = (target["$_GID"] || (target["$_GID"] = Laya.Utils.getGID()));
          var element = this._hashTargets[gid];
          if (!element) {
              element = this._getElement(target, paused);
              this._hashTargets[gid] = element;
              this._arrayTargets.push(element);
          }
          else if (!element.actions) {
              element.actions = [];
          }
          element.actions.push(action);
          action.startWithTarget(target);
      }
      removeAllActions() {
          var locTargets = this._arrayTargets;
          for (var i = 0; i < locTargets.length; i++) {
              var element = locTargets[i];
              if (element)
                  this._putElement(element);
          }
          this._arrayTargets.length = 0;
          this._hashTargets = Object.create(null);
      }
      removeAllActionsFromTarget(target, forceDelete) {
          if (target == null)
              return;
          var element = this._hashTargets[target["$_GID"]];
          if (element) {
              element.actions.length = 0;
              this._deleteHashElement(element);
          }
          if (target instanceof Laya.EventDispatcher) {
              target.offAll("NODE_DESTROYED");
          }
      }
      removeAction(action) {
          if (action == null)
              return;
          var target = action.getOriginalTarget();
          var element = this._hashTargets[target["$_GID"]];
          if (element) {
              for (var i = 0; i < element.actions.length; i++) {
                  if (element.actions[i] === action) {
                      element.actions.splice(i, 1);
                      if (element.actionIndex >= i)
                          element.actionIndex--;
                      break;
                  }
              }
          }
      }
      getNumberOfRunningActionsInTarget(target) {
          var element = this._hashTargets[target["$_GID"]];
          if (element)
              return (element.actions) ? element.actions.length : 0;
          return 0;
      }
      pauseTarget(target) {
          var element = this._hashTargets[target["$_GID"]];
          if (element)
              element.paused = true;
      }
      resumeTarget(target) {
          var element = this._hashTargets[target["$_GID"]];
          if (element)
              element.paused = false;
      }
      pauseAllRunningActions() {
          var idsWithActions = [];
          var locTargets = this._arrayTargets;
          for (var i = 0; i < locTargets.length; i++) {
              var element = locTargets[i];
              if (element && !element.paused) {
                  element.paused = true;
                  idsWithActions.push(element.target);
              }
          }
          return idsWithActions;
      }
      resumeTargets(targetsToResume) {
          if (!targetsToResume)
              return;
          for (var i = 0; i < targetsToResume.length; i++) {
              if (targetsToResume[i])
                  this.resumeTarget(targetsToResume[i]);
          }
      }
      pauseTargets(targetsToPause) {
          if (!targetsToPause)
              return;
          for (var i = 0; i < targetsToPause.length; i++) {
              if (targetsToPause[i])
                  this.pauseTarget(targetsToPause[i]);
          }
      }
      purgeSharedManager() {
          Laya.stage.timer.clearAll(this);
      }
      _removeActionAtIndex(index, element) {
          var action = element.actions[index];
          element.actions.splice(index, 1);
          if (element.actionIndex >= index)
              element.actionIndex--;
          if (element.actions.length === 0) {
              this._deleteHashElement(element);
          }
      }
      _deleteHashElement(element) {
          var ret = false;
          if (element && !element.lock) {
              if (this._hashTargets[element.target["$_GID"]]) {
                  delete this._hashTargets[element.target["$_GID"]];
                  var targets = this._arrayTargets;
                  for (var i = 0, l = targets.length; i < l; i++) {
                      if (targets[i] === element) {
                          targets.splice(i, 1);
                          break;
                      }
                  }
                  this._putElement(element);
                  ret = true;
              }
          }
          return ret;
      }
      update(dt) {
          var locTargets = this._arrayTargets;
          var locCurrTarget;
          for (var elt = 0; elt < locTargets.length; elt++) {
              this._currentTarget = locTargets[elt];
              locCurrTarget = this._currentTarget;
              if (!locCurrTarget.paused && locCurrTarget.actions) {
                  locCurrTarget.lock = true;
                  for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
                      locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
                      if (!locCurrTarget.currentAction)
                          continue;
                      locCurrTarget.currentAction.step(dt * (locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1));
                      if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
                          locCurrTarget.currentAction.stop();
                          var action = locCurrTarget.currentAction;
                          locCurrTarget.currentAction = null;
                          this.removeAction(action);
                      }
                      locCurrTarget.currentAction = null;
                  }
                  locCurrTarget.lock = false;
              }
              if (locCurrTarget.actions.length === 0) {
                  this._deleteHashElement(locCurrTarget) && elt--;
              }
          }
      }
  }
  ;

  class TweenSystem {
      constructor() {
          this.actionMgr = new ActionManager();
      }
      static create() {
          if (!this.instance) {
              let sys = new TweenSystem();
              this.instance = sys;
              let timer = Laya.timer;
              timer.frameLoop(1, this, function TweenSystemLoop() {
                  sys.postUpdate(timer.delta / 1000);
              });
          }
      }
      get ActionManager() {
          return this.actionMgr;
      }
      postUpdate(dt) {
          this.actionMgr.update(dt);
      }
  }
  TweenSystem.ID = 'tween';

  class Action {
      constructor() {
          this.originalTarget = null;
          this.target = null;
          this.tag = Action.TAG_INVALID;
      }
      clone() {
          var action = new Action();
          action.originalTarget = null;
          action.target = null;
          action.tag = this.tag;
          return action;
      }
      isDone() {
          return true;
      }
      startWithTarget(target) {
          this.originalTarget = target;
          this.target = target;
      }
      stop() {
          this.target = null;
      }
      step(dt) {
          logID(1006);
      }
      update(dt) {
          logID(1007);
      }
      getTarget() {
          return this.target;
      }
      setTarget(target) {
          this.target = target;
      }
      getOriginalTarget() {
          return this.originalTarget;
      }
      setOriginalTarget(originalTarget) {
          this.originalTarget = originalTarget;
      }
      getTag() {
          return this.tag;
      }
      setTag(tag) {
          this.tag = tag;
      }
      reverse() {
          logID(1008);
          return null;
      }
      retain() { }
      release() { }
  }
  Action.TAG_INVALID = -1;
  class FiniteTimeAction extends Action {
      constructor() {
          super(...arguments);
          this._duration = 0;
          this._timesForRepeat = 1;
      }
      getDuration() {
          return this._duration * (this._timesForRepeat || 1);
      }
      setDuration(duration) {
          this._duration = duration;
      }
      clone() {
          return new FiniteTimeAction();
      }
  }
  class Speed extends Action {
      constructor(action, speed = 1) {
          super();
          this._speed = 0;
          this._innerAction = null;
          action && this.initWithAction(action, speed);
      }
      getSpeed() {
          return this._speed;
      }
      setSpeed(speed) {
          this._speed = speed;
      }
      initWithAction(action, speed) {
          if (!action) {
              errorID(1021);
              return false;
          }
          this._innerAction = action;
          this._speed = speed;
          return true;
      }
      clone() {
          var action = new Speed();
          action.initWithAction(this._innerAction.clone(), this._speed);
          return action;
      }
      startWithTarget(target) {
          Action.prototype.startWithTarget.call(this, target);
          this._innerAction.startWithTarget(target);
      }
      stop() {
          this._innerAction.stop();
          Action.prototype.stop.call(this);
      }
      step(dt) {
          this._innerAction.step(dt * this._speed);
      }
      isDone() {
          return this._innerAction.isDone();
      }
      reverse() {
          return new Speed(this._innerAction.reverse(), this._speed);
      }
      setInnerAction(action) {
          if (this._innerAction !== action) {
              this._innerAction = action;
          }
      }
      getInnerAction() {
          return this._innerAction;
      }
  }

  class ActionInstant extends FiniteTimeAction {
      isDone() {
          return true;
      }
      step(dt) {
          this.update(1);
      }
      update(dt) {
      }
      reverse() {
          return this.clone();
      }
      clone() {
          return new ActionInstant();
      }
  }
  class Show extends ActionInstant {
      update(dt) {
          this.target.visible = true;
      }
      reverse() {
          return new Hide();
      }
      clone() {
          return new Show();
      }
  }
  function show() {
      return new Show();
  }
  ;
  class Hide extends ActionInstant {
      update(dt) {
          this.target.visible = false;
      }
      reverse() {
          return new Show();
      }
      clone() {
          return new Hide();
      }
  }
  function hide() {
      return new Hide();
  }
  ;
  class RemoveSelf extends ActionInstant {
      constructor(isNeedCleanUp) {
          super();
          this._isNeedCleanUp = true;
          isNeedCleanUp !== undefined && this.init(isNeedCleanUp);
      }
      update(dt) {
          this.target.removeSelf();
          if (this._isNeedCleanUp) {
              this.target.destroy();
          }
      }
      init(isNeedCleanUp) {
          this._isNeedCleanUp = isNeedCleanUp;
          return true;
      }
      reverse() {
          return new RemoveSelf(this._isNeedCleanUp);
      }
      clone() {
          return new RemoveSelf(this._isNeedCleanUp);
      }
  }
  function removeSelf(isNeedCleanUp) {
      return new RemoveSelf(isNeedCleanUp);
  }
  ;
  class CallFunc extends ActionInstant {
      constructor(selector, selectorTarget, data) {
          super();
          this._selectorTarget = null;
          this._function = null;
          this._data = null;
          this.initWithFunction(selector, selectorTarget, data);
      }
      initWithFunction(selector, selectorTarget, data) {
          if (selector) {
              this._function = selector;
          }
          if (selectorTarget) {
              this._selectorTarget = selectorTarget;
          }
          if (data !== undefined) {
              this._data = data;
          }
          return true;
      }
      execute() {
          if (this._function) {
              this._function.call(this._selectorTarget, this.target, this._data);
          }
      }
      update(dt) {
          this.execute();
      }
      getTargetCallback() {
          return this._selectorTarget;
      }
      setTargetCallback(sel) {
          if (sel !== this._selectorTarget) {
              if (this._selectorTarget)
                  this._selectorTarget = null;
              this._selectorTarget = sel;
          }
      }
      clone() {
          var action = new CallFunc();
          action.initWithFunction(this._function, this._selectorTarget, this._data);
          return action;
      }
  }
  function callFunc(selector, selectorTarget, data) {
      return new CallFunc(selector, selectorTarget, data);
  }
  ;

  class ActionInterval extends FiniteTimeAction {
      constructor(d) {
          super();
          this.MAX_VALUE = 2;
          this._elapsed = 0;
          this._firstTick = false;
          this._easeList = [];
          this._speed = 1;
          this._repeatForever = false;
          this._repeatMethod = false;
          this._speedMethod = false;
          if (d !== undefined && !isNaN(d)) {
              this.initWithDuration(d);
          }
      }
      getElapsed() {
          return this._elapsed;
      }
      initWithDuration(d) {
          this._duration = (d === 0) ? 0.0000001192092896 : d;
          this._elapsed = 0;
          this._firstTick = true;
          return true;
      }
      isDone() {
          return (this._elapsed >= this._duration);
      }
      _cloneDecoration(action) {
          action._repeatForever = this._repeatForever;
          action._speed = this._speed;
          action._timesForRepeat = this._timesForRepeat;
          action._easeList = this._easeList;
          action._speedMethod = this._speedMethod;
          action._repeatMethod = this._repeatMethod;
      }
      _reverseEaseList(action) {
          if (this._easeList) {
              action._easeList = [];
              for (var i = 0; i < this._easeList.length; i++) {
                  action._easeList.push(this._easeList[i]);
              }
          }
      }
      clone() {
          var action = new ActionInterval(this._duration);
          this._cloneDecoration(action);
          return action;
      }
      easing(...easeObj) {
          if (this._easeList)
              this._easeList.length = 0;
          else
              this._easeList = [];
          for (var i = 0; i < easeObj.length; i++)
              this._easeList.push(easeObj[i]);
          return this;
      }
      _computeEaseTime(dt) {
          var locList = this._easeList;
          if ((!locList) || (locList.length === 0))
              return dt;
          for (var i = 0, n = locList.length; i < n; i++)
              dt = locList[i](dt);
          return dt;
      }
      step(dt) {
          if (this._firstTick) {
              this._firstTick = false;
              this._elapsed = 0;
          }
          else
              this._elapsed += dt;
          var t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896);
          t = (1 > t ? t : 1);
          this.update(t > 0 ? t : 0);
          if (this._repeatMethod && this._timesForRepeat > 1 && this.isDone()) {
              if (!this._repeatForever) {
                  this._timesForRepeat--;
              }
              this.startWithTarget(this.target);
              this.step(this._elapsed - this._duration);
          }
      }
      startWithTarget(target) {
          Action.prototype.startWithTarget.call(this, target);
          this._elapsed = 0;
          this._firstTick = true;
      }
      reverse() {
          logID(1010);
          return this;
      }
      setAmplitudeRate(amp) {
          logID(1011);
      }
      getAmplitudeRate() {
          logID(1012);
          return 0;
      }
      speed(speed) {
          if (speed <= 0) {
              logID(1013);
              return this;
          }
          this._speedMethod = true;
          this._speed *= speed;
          return this;
      }
      getSpeed() {
          return this._speed;
      }
      setSpeed(speed) {
          this._speed = speed;
          return this;
      }
      repeat(times) {
          times = Math.round(times);
          if (isNaN(times) || times < 1) {
              logID(1014);
              return this;
          }
          this._repeatMethod = true;
          this._timesForRepeat *= times;
          return this;
      }
      repeatForever() {
          this._repeatMethod = true;
          this._timesForRepeat = this.MAX_VALUE;
          this._repeatForever = true;
          return this;
      }
  }
  function actionInterval(d) {
      return new ActionInterval(d);
  }
  class Sequence extends ActionInterval {
      constructor(tempArray) {
          super();
          this._actions = [];
          this._split = 0;
          this._last = 0;
          this._reversed = false;
          var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
          if (paramArray.length === 1) {
              errorID(1019);
              return;
          }
          var last = paramArray.length - 1;
          if ((last >= 0) && (paramArray[last] == null))
              logID(1015);
          if (last >= 0) {
              var prev = paramArray[0], action1;
              for (var i = 1; i < last; i++) {
                  if (paramArray[i]) {
                      action1 = prev;
                      prev = Sequence._actionOneTwo(action1, paramArray[i]);
                  }
              }
              this.initWithTwoActions(prev, paramArray[last]);
          }
      }
      initWithTwoActions(actionOne, actionTwo) {
          if (!actionOne || !actionTwo) {
              errorID(1025);
              return false;
          }
          var durationOne = actionOne._duration, durationTwo = actionTwo._duration;
          durationOne *= actionOne._repeatMethod ? actionOne._timesForRepeat : 1;
          durationTwo *= actionTwo._repeatMethod ? actionTwo._timesForRepeat : 1;
          var d = durationOne + durationTwo;
          this.initWithDuration(d);
          this._actions[0] = actionOne;
          this._actions[1] = actionTwo;
          return true;
      }
      clone() {
          var action = new Sequence();
          this._cloneDecoration(action);
          action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone());
          return action;
      }
      startWithTarget(target) {
          ActionInterval.prototype.startWithTarget.call(this, target);
          this._split = this._actions[0]._duration / this._duration;
          this._split *= this._actions[0]._repeatMethod ? this._actions[0]._timesForRepeat : 1;
          this._last = -1;
      }
      stop() {
          if (this._last !== -1)
              this._actions[this._last].stop();
          Action.prototype.stop.call(this);
      }
      update(dt) {
          if (!this.target || this.target.destroyed) {
              this.stop();
              return;
          }
          var new_t, found = 0;
          var locSplit = this._split;
          var locActions = this._actions;
          var locLast = this._last;
          var actionFound;
          dt = this._computeEaseTime(dt);
          if (dt < locSplit) {
              new_t = (locSplit !== 0) ? dt / locSplit : 1;
              if (found === 0 && locLast === 1 && this._reversed) {
                  locActions[1].update(0);
                  locActions[1].stop();
              }
          }
          else {
              found = 1;
              new_t = (locSplit === 1) ? 1 : (dt - locSplit) / (1 - locSplit);
              if (locLast === -1) {
                  locActions[0].startWithTarget(this.target);
                  locActions[0].update(1);
                  locActions[0].stop();
              }
              if (locLast === 0) {
                  locActions[0].update(1);
                  locActions[0].stop();
              }
          }
          actionFound = locActions[found];
          if (locLast === found && actionFound.isDone())
              return;
          if (locLast !== found)
              actionFound.startWithTarget(this.target);
          new_t = new_t * actionFound._timesForRepeat;
          actionFound.update(new_t > 1 ? new_t % 1 : new_t);
          this._last = found;
      }
      reverse() {
          var action = Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse());
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          action._reversed = true;
          return action;
      }
  }
  Sequence._actionOneTwo = function (actionOne, actionTwo) {
      var sequence = new Sequence();
      sequence.initWithTwoActions(actionOne, actionTwo);
      return sequence;
  };
  function sequence(tempArray) {
      var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
      if (paramArray.length === 1) {
          errorID(1019);
          return null;
      }
      var last = paramArray.length - 1;
      if ((last >= 0) && (paramArray[last] == null))
          logID(1015);
      var result = null;
      if (last >= 0) {
          result = paramArray[0];
          for (var i = 1; i <= last; i++) {
              if (paramArray[i]) {
                  result = Sequence._actionOneTwo(result, paramArray[i]);
              }
          }
      }
      return result;
  }
  ;
  class Repeat extends ActionInterval {
      constructor(action, times) {
          super();
          this._times = 0;
          this._total = 0;
          this._nextDt = 0;
          this._actionInstant = false;
          this._innerAction = null;
          times !== undefined && this.initWithAction(action, times);
      }
      initWithAction(action, times) {
          var duration = action._duration * times;
          if (this.initWithDuration(duration)) {
              this._times = times;
              this._innerAction = action;
              if (action instanceof ActionInstant) {
                  this._actionInstant = true;
                  this._times -= 1;
              }
              this._total = 0;
              return true;
          }
          return false;
      }
      clone() {
          var action = new Repeat();
          this._cloneDecoration(action);
          action.initWithAction(this._innerAction.clone(), this._times);
          return action;
      }
      startWithTarget(target) {
          this._total = 0;
          this._nextDt = this._innerAction._duration / this._duration;
          ActionInterval.prototype.startWithTarget.call(this, target);
          this._innerAction.startWithTarget(target);
      }
      stop() {
          this._innerAction.stop();
          Action.prototype.stop.call(this);
      }
      update(dt) {
          dt = this._computeEaseTime(dt);
          var locInnerAction = this._innerAction;
          var locDuration = this._duration;
          var locTimes = this._times;
          var locNextDt = this._nextDt;
          if (dt >= locNextDt) {
              while (dt > locNextDt && this._total < locTimes) {
                  locInnerAction.update(1);
                  this._total++;
                  locInnerAction.stop();
                  locInnerAction.startWithTarget(this.target);
                  locNextDt += locInnerAction._duration / locDuration;
                  this._nextDt = locNextDt > 1 ? 1 : locNextDt;
              }
              if (dt >= 1.0 && this._total < locTimes) {
                  locInnerAction.update(1);
                  this._total++;
              }
              if (!this._actionInstant) {
                  if (this._total === locTimes) {
                      locInnerAction.stop();
                  }
                  else {
                      locInnerAction.update(dt - (locNextDt - locInnerAction._duration / locDuration));
                  }
              }
          }
          else {
              locInnerAction.update((dt * locTimes) % 1.0);
          }
      }
      isDone() {
          return this._total === this._times;
      }
      reverse() {
          var action = new Repeat(this._innerAction.reverse(), this._times);
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
      setInnerAction(action) {
          if (this._innerAction !== action) {
              this._innerAction = action;
          }
      }
      getInnerAction() {
          return this._innerAction;
      }
  }
  function repeat(action, times) {
      return new Repeat(action, times);
  }
  class RepeatForever extends ActionInterval {
      constructor(action) {
          super();
          this._innerAction = null;
          action && this.initWithAction(action);
      }
      stop() {
          this.bStop = true;
          super.stop();
      }
      initWithAction(action) {
          if (!action) {
              errorID(1026);
              return false;
          }
          this._innerAction = action;
          return true;
      }
      clone() {
          var action = new RepeatForever();
          this._cloneDecoration(action);
          action.initWithAction(this._innerAction.clone());
          return action;
      }
      startWithTarget(target) {
          this.bStop = false;
          ActionInterval.prototype.startWithTarget.call(this, target);
          this._innerAction.startWithTarget(target);
      }
      step(dt) {
          const target = this.target;
          if (!target || target.destroyed) {
              this.stop();
              return;
          }
          var locInnerAction = this._innerAction;
          locInnerAction.step(dt);
          if (locInnerAction.isDone()) {
              locInnerAction.startWithTarget(this.target);
              locInnerAction.step(locInnerAction.getElapsed() - locInnerAction._duration);
          }
      }
      isDone() {
          return this.bStop;
      }
      reverse() {
          var action = new RepeatForever(this._innerAction.reverse());
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
      setInnerAction(action) {
          if (this._innerAction !== action) {
              this._innerAction = action;
          }
      }
      getInnerAction() {
          return this._innerAction;
      }
  }
  function repeatForever(action) {
      return new RepeatForever(action);
  }
  class Spawn extends ActionInterval {
      constructor(tempArray) {
          super();
          this._one = null;
          this._two = null;
          var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
          if (paramArray.length === 1) {
              errorID(1020);
              return;
          }
          var last = paramArray.length - 1;
          if ((last >= 0) && (paramArray[last] == null))
              logID(1015);
          if (last >= 0) {
              var prev = paramArray[0], action1;
              for (var i = 1; i < last; i++) {
                  if (paramArray[i]) {
                      action1 = prev;
                      prev = Spawn._actionOneTwo(action1, paramArray[i]);
                  }
              }
              this.initWithTwoActions(prev, paramArray[last]);
          }
      }
      initWithTwoActions(action1, action2) {
          if (!action1 || !action2) {
              errorID(1027);
              return false;
          }
          var ret = false;
          var d1 = action1._duration;
          var d2 = action2._duration;
          if (this.initWithDuration(Math.max(d1, d2))) {
              this._one = action1;
              this._two = action2;
              if (d1 > d2) {
                  this._two = Sequence._actionOneTwo(action2, delayTime(d1 - d2));
              }
              else if (d1 < d2) {
                  this._one = Sequence._actionOneTwo(action1, delayTime(d2 - d1));
              }
              ret = true;
          }
          return ret;
      }
      clone() {
          var action = new Spawn();
          this._cloneDecoration(action);
          action.initWithTwoActions(this._one.clone(), this._two.clone());
          return action;
      }
      startWithTarget(target) {
          ActionInterval.prototype.startWithTarget.call(this, target);
          this._one.startWithTarget(target);
          this._two.startWithTarget(target);
      }
      stop() {
          this._one.stop();
          this._two.stop();
          Action.prototype.stop.call(this);
      }
      update(dt) {
          dt = this._computeEaseTime(dt);
          if (this._one)
              this._one.update(dt);
          if (this._two)
              this._two.update(dt);
      }
      reverse() {
          var action = Spawn._actionOneTwo(this._one.reverse(), this._two.reverse());
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
  }
  Spawn._actionOneTwo = function (action1, action2) {
      var pSpawn = new Spawn();
      pSpawn.initWithTwoActions(action1, action2);
      return pSpawn;
  };
  function spawn(tempArray) {
      var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
      if (paramArray.length === 1) {
          errorID(1020);
          return null;
      }
      if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null))
          logID(1015);
      var prev = paramArray[0];
      for (var i = 1; i < paramArray.length; i++) {
          if (paramArray[i] != null)
              prev = Spawn._actionOneTwo(prev, paramArray[i]);
      }
      return prev;
  }
  class DelayTime extends ActionInterval {
      update(dt) { }
      reverse() {
          var action = new DelayTime(this._duration);
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
      clone() {
          var action = new DelayTime();
          this._cloneDecoration(action);
          action.initWithDuration(this._duration);
          return action;
      }
  }
  function delayTime(d) {
      return new DelayTime(d);
  }
  ;
  class ReverseTime extends ActionInterval {
      constructor(action) {
          super();
          this._other = null;
          action && this.initWithAction(action);
      }
      initWithAction(action) {
          if (!action) {
              errorID(1028);
              return false;
          }
          if (action === this._other) {
              errorID(1029);
              return false;
          }
          if (ActionInterval.prototype.initWithDuration.call(this, action._duration)) {
              this._other = action;
              return true;
          }
          return false;
      }
      clone() {
          var action = new ReverseTime();
          this._cloneDecoration(action);
          action.initWithAction(this._other.clone());
          return action;
      }
      startWithTarget(target) {
          ActionInterval.prototype.startWithTarget.call(this, target);
          this._other.startWithTarget(target);
      }
      update(dt) {
          dt = this._computeEaseTime(dt);
          if (this._other)
              this._other.update(1 - dt);
      }
      reverse() {
          return this._other.clone();
      }
      stop() {
          this._other.stop();
          Action.prototype.stop.call(this);
      }
  }
  function reverseTime(action) {
      return new ReverseTime(action);
  }

  var Easing;
  (function (Easing) {
      function constant() {
          return 0;
      }
      Easing.constant = constant;
      function linear(k) {
          return k;
      }
      Easing.linear = linear;
      function quadIn(k) {
          return k * k;
      }
      Easing.quadIn = quadIn;
      function quadOut(k) {
          return k * (2 - k);
      }
      Easing.quadOut = quadOut;
      function quadInOut(k) {
          k *= 2;
          if (k < 1) {
              return 0.5 * k * k;
          }
          return -0.5 * (--k * (k - 2) - 1);
      }
      Easing.quadInOut = quadInOut;
      function cubicIn(k) {
          return k * k * k;
      }
      Easing.cubicIn = cubicIn;
      function cubicOut(k) {
          return --k * k * k + 1;
      }
      Easing.cubicOut = cubicOut;
      function cubicInOut(k) {
          k *= 2;
          if (k < 1) {
              return 0.5 * k * k * k;
          }
          return 0.5 * ((k -= 2) * k * k + 2);
      }
      Easing.cubicInOut = cubicInOut;
      function quartIn(k) {
          return k * k * k * k;
      }
      Easing.quartIn = quartIn;
      function quartOut(k) {
          return 1 - (--k * k * k * k);
      }
      Easing.quartOut = quartOut;
      function quartInOut(k) {
          k *= 2;
          if (k < 1) {
              return 0.5 * k * k * k * k;
          }
          return -0.5 * ((k -= 2) * k * k * k - 2);
      }
      Easing.quartInOut = quartInOut;
      function quintIn(k) {
          return k * k * k * k * k;
      }
      Easing.quintIn = quintIn;
      function quintOut(k) {
          return --k * k * k * k * k + 1;
      }
      Easing.quintOut = quintOut;
      function quintInOut(k) {
          k *= 2;
          if (k < 1) {
              return 0.5 * k * k * k * k * k;
          }
          return 0.5 * ((k -= 2) * k * k * k * k + 2);
      }
      Easing.quintInOut = quintInOut;
      function sineIn(k) {
          return 1 - Math.cos(k * Math.PI / 2);
      }
      Easing.sineIn = sineIn;
      function sineOut(k) {
          return Math.sin(k * Math.PI / 2);
      }
      Easing.sineOut = sineOut;
      function sineInOut(k) {
          return 0.5 * (1 - Math.cos(Math.PI * k));
      }
      Easing.sineInOut = sineInOut;
      function expoIn(k) {
          return k === 0 ? 0 : Math.pow(1024, k - 1);
      }
      Easing.expoIn = expoIn;
      function expoOut(k) {
          return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
      }
      Easing.expoOut = expoOut;
      function expoInOut(k) {
          if (k === 0) {
              return 0;
          }
          if (k === 1) {
              return 1;
          }
          k *= 2;
          if (k < 1) {
              return 0.5 * Math.pow(1024, k - 1);
          }
          return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
      }
      Easing.expoInOut = expoInOut;
      function circIn(k) {
          return 1 - Math.sqrt(1 - k * k);
      }
      Easing.circIn = circIn;
      function circOut(k) {
          return Math.sqrt(1 - (--k * k));
      }
      Easing.circOut = circOut;
      function circInOut(k) {
          k *= 2;
          if (k < 1) {
              return -0.5 * (Math.sqrt(1 - k * k) - 1);
          }
          return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
      }
      Easing.circInOut = circInOut;
      function elasticIn(k) {
          let s;
          let a = 0.1;
          const p = 0.4;
          if (k === 0) {
              return 0;
          }
          if (k === 1) {
              return 1;
          }
          if (!a || a < 1) {
              a = 1;
              s = p / 4;
          }
          else {
              s = p * Math.asin(1 / a) / (2 * Math.PI);
          }
          return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
      }
      Easing.elasticIn = elasticIn;
      function elasticOut(k) {
          let s;
          let a = 0.1;
          const p = 0.4;
          if (k === 0) {
              return 0;
          }
          if (k === 1) {
              return 1;
          }
          if (!a || a < 1) {
              a = 1;
              s = p / 4;
          }
          else {
              s = p * Math.asin(1 / a) / (2 * Math.PI);
          }
          return (a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1);
      }
      Easing.elasticOut = elasticOut;
      function elasticInOut(k) {
          let s;
          let a = 0.1;
          const p = 0.4;
          if (k === 0) {
              return 0;
          }
          if (k === 1) {
              return 1;
          }
          if (!a || a < 1) {
              a = 1;
              s = p / 4;
          }
          else {
              s = p * Math.asin(1 / a) / (2 * Math.PI);
          }
          k *= 2;
          if (k < 1) {
              return -0.5 *
                  (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
          }
          return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
      }
      Easing.elasticInOut = elasticInOut;
      function backIn(k) {
          const s = 1.70158;
          return k * k * ((s + 1) * k - s);
      }
      Easing.backIn = backIn;
      function backOut(k) {
          const s = 1.70158;
          return --k * k * ((s + 1) * k + s) + 1;
      }
      Easing.backOut = backOut;
      function backInOut(k) {
          const s = 1.70158 * 1.525;
          k *= 2;
          if (k < 1) {
              return 0.5 * (k * k * ((s + 1) * k - s));
          }
          return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
      }
      Easing.backInOut = backInOut;
      function bounceIn(k) {
          return 1 - bounceOut(1 - k);
      }
      Easing.bounceIn = bounceIn;
      function bounceOut(k) {
          if (k < (1 / 2.75)) {
              return 7.5625 * k * k;
          }
          else if (k < (2 / 2.75)) {
              return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
          }
          else if (k < (2.5 / 2.75)) {
              return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
          }
          else {
              return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
          }
      }
      Easing.bounceOut = bounceOut;
      function bounceInOut(k) {
          if (k < 0.5) {
              return bounceIn(k * 2) * 0.5;
          }
          return bounceOut(k * 2 - 1) * 0.5 + 0.5;
      }
      Easing.bounceInOut = bounceInOut;
      function smooth(k) {
          if (k <= 0) {
              return 0;
          }
          if (k >= 1) {
              return 1;
          }
          return k * k * (3 - 2 * k);
      }
      Easing.smooth = smooth;
      function fade(k) {
          if (k <= 0) {
              return 0;
          }
          if (k >= 1) {
              return 1;
          }
          return k * k * k * (k * (k * 6 - 15) + 10);
      }
      Easing.fade = fade;
      Easing.quadOutIn = _makeOutIn(quadIn, quadOut);
      Easing.cubicOutIn = _makeOutIn(cubicIn, cubicOut);
      Easing.quartOutIn = _makeOutIn(quartIn, quartOut);
      Easing.quintOutIn = _makeOutIn(quintIn, quintOut);
      Easing.sineOutIn = _makeOutIn(sineIn, sineOut);
      Easing.expoOutIn = _makeOutIn(expoIn, expoOut);
      Easing.circOutIn = _makeOutIn(circIn, circOut);
      Easing.elasticOutIn = _makeOutIn(elasticIn, elasticOut);
      Easing.backOutIn = _makeOutIn(backIn, backOut);
      Easing.bounceOutIn = _makeOutIn(bounceIn, bounceOut);
      function _makeOutIn(fnIn, fnOut) {
          return (k) => {
              if (k < 0.5) {
                  return fnOut(k * 2) / 2;
              }
              return fnIn(2 * k - 1) / 2 + 0.5;
          };
      }
  })(Easing || (Easing = {}));

  function TweenEasinAdapter(easingName) {
      let initialChar = easingName.charAt(0);
      if (/[A-Z]/.test(initialChar)) {
          easingName = easingName.replace(initialChar, initialChar.toLowerCase());
          const arr = easingName.split('-');
          if (arr.length == 2) {
              const str0 = arr[0];
              if (str0 == 'linear') {
                  easingName = 'linear';
              }
              else {
                  const str1 = arr[1];
                  switch (str0) {
                      case 'quadratic':
                          easingName = 'quad' + str1;
                          break;
                      case 'quartic':
                          easingName = 'quart' + str1;
                          break;
                      case 'quintic':
                          easingName = 'quint' + str1;
                          break;
                      case 'sinusoidal':
                          easingName = 'sine' + str1;
                          break;
                      case 'exponential':
                          easingName = 'expo' + str1;
                          break;
                      case 'circular':
                          easingName = 'circ' + str1;
                          break;
                      default:
                          easingName = str0 + str1;
                          break;
                  }
              }
          }
      }
      return easingName;
  }
  function TweenOptionChecker(opts) {
      if (true)
          return;
      const header = ' [Tween:] ';
      const message = ' option is not support in v' + -1;
      if (opts['delay']) {
          console.warn(header + 'delay' + message);
      }
      if (opts['repeat']) {
          console.warn(header + 'repeat' + message);
      }
      if (opts['repeatDelay']) {
          console.warn(header + 'repeatDelay' + message);
      }
      if (opts['interpolation']) {
          console.warn(header + 'interpolation' + message);
      }
      if (opts['onStop']) {
          console.warn(header + 'onStop' + message);
      }
  }
  class TweenAction extends ActionInterval {
      constructor(duration, props, opts) {
          super();
          if (opts == null) {
              opts = TweenAction.EMPTY_OPTION;
          }
          else {
              TweenOptionChecker(opts);
              if (opts.easing && typeof opts.easing === 'string') {
                  opts.easing = TweenEasinAdapter(opts.easing);
              }
              if (!opts.progress) {
                  opts.progress = this.progress;
              }
              if (opts.easing && typeof opts.easing === 'string') {
                  let easingName = opts.easing;
                  opts.easing = Easing[easingName];
                  if (!opts.easing) {
                      warnID(1031, easingName);
                  }
              }
          }
          this._opts = opts;
          this._props = Object.create(null);
          for (let name in props) {
              let value = props[name];
              let easing, progress;
              if (value.value !== undefined && (value.easing || value.progress)) {
                  if (typeof value.easing === 'string') {
                      easing = easing[value.easing];
                      !easing && warnID(1031, value.easing);
                  }
                  else {
                      easing = value.easing;
                  }
                  progress = value.progress;
                  value = value.value;
              }
              let prop = Object.create(null);
              prop.value = value;
              prop.easing = easing;
              prop.progress = progress;
              this._props[name] = prop;
          }
          this._originProps = props;
          this.initWithDuration(duration);
      }
      clone() {
          var action = new TweenAction(this._duration, this._originProps, this._opts);
          this._cloneDecoration(action);
          return action;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          const relative = !!this._opts.relative;
          const props = this._props;
          for (var property in props) {
              const _t = target[property];
              if (_t === undefined) {
                  continue;
              }
              const prop = props[property];
              const value = prop.value;
              if (typeof _t === "number") {
                  prop.start = _t;
                  prop.current = _t;
                  prop.end = relative ? _t + value : value;
              }
              else if (typeof _t === "object") {
                  if (prop.start == null) {
                      prop.start = {};
                      prop.current = {};
                      prop.end = {};
                  }
                  for (var k in value) {
                      prop.start[k] = _t[k];
                      prop.current[k] = _t[k];
                      prop.end[k] = relative ? _t[k] + value[k] : value[k];
                  }
              }
          }
          if (this._opts.onStart) {
              this._opts.onStart(this.target);
          }
      }
      update(t) {
          const target = this.target;
          if (!target || target.destroyed) {
              this.stop();
              return;
          }
          const props = this._props;
          const opts = this._opts;
          let easingTime = t;
          if (opts.easing)
              easingTime = opts.easing(t);
          let progress = opts.progress;
          for (const name in props) {
              let prop = props[name];
              let time = prop.easing ? prop.easing(t) : easingTime;
              let interpolation = prop.progress ? prop.progress : progress;
              const start = prop.start;
              const end = prop.end;
              if (typeof start === 'number') {
                  prop.current = interpolation(start, end, prop.current, time);
              }
              else if (typeof start === 'object') {
                  for (const k in start) {
                      prop.current[k] = interpolation(start[k], end[k], prop.current[k], time);
                  }
              }
              target[name] = prop.current;
          }
          if (opts.onUpdate) {
              opts.onUpdate(this.target, t);
          }
          if (t == 1 && opts.onComplete) {
              opts.onComplete(this.target);
          }
      }
      progress(start, end, current, t) {
          return current = start + (end - start) * t;
      }
  }
  TweenAction.EMPTY_OPTION = Object.create(null);

  class SetAction extends ActionInstant {
      constructor(props) {
          super();
          this._props = {};
          props !== undefined && this.init(props);
      }
      init(props) {
          for (let name in props) {
              this._props[name] = props[name];
          }
          return true;
      }
      update() {
          let props = this._props;
          let target = this.target;
          for (let name in props) {
              target[name] = props[name];
          }
      }
      clone() {
          var action = new SetAction();
          action.init(this._props);
          return action;
      }
  }

  let _default_progress = function (start, end, current, t) {
      return current = start + (end - start) * t;
  };
  let DEFAULT_OPT1 = { easing: Easing.linear, progress: _default_progress };
  let DEFAULT_OPT2 = { easing: Easing.linear, progress: _default_progress };
  class Tween {
      constructor(target) {
          this._actions = [];
          this._finalAction = null;
          this._target = null;
          this._target = target === undefined ? null : target;
          if (this._target && this._target instanceof Laya.EventDispatcher) {
              this._target.on("NODE_DESTROYED", this, this._destroy);
          }
      }
      then(other) {
          if (other instanceof Action) {
              this._actions.push(other);
          }
          else {
              this._actions.push(other._union());
          }
          return this;
      }
      target(target) {
          if (this._target && this._target instanceof Laya.EventDispatcher) {
              this._target.off("NODE_DESTROYED", this, this._destroy);
          }
          this._target = target;
          if (this._target && this._target instanceof Laya.EventDispatcher) {
              this._target.on("NODE_DESTROYED", this, this._destroy);
          }
          return this;
      }
      start() {
          if (!this._target) {
              console.warn('Please set target to tween first');
              return this;
          }
          if (this._finalAction) {
              TweenSystem.instance.ActionManager.removeAction(this._finalAction);
          }
          this._finalAction = this._union();
          TweenSystem.instance.ActionManager.addAction(this._finalAction, this._target, false);
          return this;
      }
      stop() {
          if (this._finalAction) {
              TweenSystem.instance.ActionManager.removeAction(this._finalAction);
          }
          return this;
      }
      clone(target) {
          let action = this._union();
          return new Tween(target).then(action.clone());
      }
      union() {
          let action = this._union();
          this._actions.length = 0;
          this._actions.push(action);
          return this;
      }
      to(duration, props, opts) {
          opts = opts || DEFAULT_OPT1;
          opts.relative = false;
          const action = new TweenAction(duration, props, opts);
          this._actions.push(action);
          return this;
      }
      by(duration, props, opts) {
          opts = opts || DEFAULT_OPT2;
          opts.relative = true;
          const action = new TweenAction(duration, props, opts);
          this._actions.push(action);
          return this;
      }
      set(props) {
          const action = new SetAction(props);
          this._actions.push(action);
          return this;
      }
      delay(duration) {
          const action = delayTime(duration);
          this._actions.push(action);
          return this;
      }
      call(callback) {
          const action = callFunc(callback);
          this._actions.push(action);
          return this;
      }
      sequence(...args) {
          const action = Tween._wrappedSequence(...args);
          this._actions.push(action);
          return this;
      }
      parallel(...args) {
          const action = Tween._wrappedParallel(...args);
          this._actions.push(action);
          return this;
      }
      repeat(repeatTimes, embedTween) {
          if (repeatTimes == Infinity) {
              return this.repeatForever(embedTween);
          }
          const actions = this._actions;
          let action;
          if (embedTween) {
              action = embedTween._union();
          }
          else {
              action = actions.pop();
          }
          actions.push(repeat(action, repeatTimes));
          return this;
      }
      repeatForever(embedTween) {
          const actions = this._actions;
          let action;
          if (embedTween) {
              action = embedTween._union();
          }
          else {
              action = actions.pop();
          }
          actions.push(repeatForever(action));
          return this;
      }
      reverseTime(embedTween) {
          const actions = this._actions;
          let action;
          if (embedTween instanceof Tween) {
              action = embedTween._union();
          }
          else {
              action = actions.pop();
          }
          actions.push(reverseTime(action));
          return this;
      }
      hide() {
          let action = hide();
          this._actions.push(action);
          return this;
      }
      show() {
          let action = show();
          this._actions.push(action);
          return this;
      }
      removeSelf(destroy = false) {
          let action = removeSelf(destroy);
          this._actions.push(action);
          return this;
      }
      _union() {
          let actions = this._actions;
          let action;
          if (actions.length === 1) {
              action = actions[0];
          }
          else {
              action = sequence(actions);
          }
          return action;
      }
      _destroy() {
          this.stop();
      }
      static _wrappedSequence(...args) {
          const tmp_args = Tween._tmp_args;
          tmp_args.length = 0;
          for (let l = args.length, i = 0; i < l; i++) {
              let arg = tmp_args[i] = args[i];
              if (arg instanceof Tween) {
                  tmp_args[i] = arg._union();
              }
          }
          return sequence.apply(sequence, tmp_args);
      }
      static _wrappedParallel(...args) {
          const tmp_args = Tween._tmp_args;
          tmp_args.length = 0;
          for (let l = args.length, i = 0; i < l; i++) {
              let arg = tmp_args[i] = args[i];
              if (arg instanceof Tween) {
                  tmp_args[i] = arg._union();
              }
          }
          return spawn.apply(spawn, tmp_args);
      }
  }
  Tween._tmp_args = [];

  class Vec2 {
      constructor(x = 0, y = 0) {
          this.x = 0;
          this.y = 0;
          this.x = x;
          this.y = y;
      }
      static get zero() {
          return new Vec2(0, 0);
      }
      static get one() {
          return new Vec2(1, 1);
      }
      clone() {
          return new Vec2(this.x, this.y);
      }
      setTo(x, y) {
          this.setValue(x, y);
          return this;
      }
      setValue(x, y) {
          this.x = x;
          this.y = y;
      }
      set(newValue) {
          this.x = newValue.x;
          this.y = newValue.y;
          return this;
      }
      equals(other) {
          return other && this.x === other.x && this.y === other.y;
      }
      fuzzyEquals(other, variance) {
          if (this.x - variance <= other.x && other.x <= this.x + variance) {
              if (this.y - variance <= other.y && other.y <= this.y + variance)
                  return true;
          }
          return false;
      }
      lerp(to, ratio, out) {
          out = out || new Vec2();
          let x = this.x;
          let y = this.y;
          out.x = x + (to.x - x) * ratio;
          out.y = y + (to.y - y) * ratio;
          return out;
      }
      clampf(min_inclusive, max_inclusive) {
          this.x = Mathf.clamp(this.x, min_inclusive.x, max_inclusive.x);
          this.y = Mathf.clamp(this.y, min_inclusive.y, max_inclusive.y);
          return this;
      }
      addSelf(vector) {
          this.x += vector.x;
          this.y += vector.y;
          return this;
      }
      add(vector, out) {
          out = out || new Vec2();
          out.x = this.x + vector.x;
          out.y = this.y + vector.y;
          return out;
      }
      subSelf(vector) {
          this.x -= vector.x;
          this.y -= vector.y;
          return this;
      }
      sub(vector, out) {
          out = out || new Vec2();
          out.x = this.x - vector.x;
          out.y = this.y - vector.y;
          return out;
      }
      mulSelf(num) {
          this.x *= num;
          this.y *= num;
          return this;
      }
      mul(num, out) {
          out = out || new Vec2();
          out.x = this.x * num;
          out.y = this.y * num;
          return out;
      }
      scaleSelf(vector) {
          this.x *= vector.x;
          this.y *= vector.y;
          return this;
      }
      scale(vector, out) {
          out = out || new Vec2();
          out.x = this.x * vector.x;
          out.y = this.y * vector.y;
          return out;
      }
      divSelf(divisor) {
          this.x /= divisor;
          this.y /= divisor;
          return this;
      }
      div(divisor, out) {
          out = out || new Vec2();
          out.x = this.x / divisor;
          out.y = this.y / divisor;
          return out;
      }
      negSelf() {
          this.x = -this.x;
          this.y = -this.y;
          return this;
      }
      neg(out) {
          out = out || new Vec2();
          out.x = -this.x;
          out.y = -this.y;
          return out;
      }
      dot(vector) {
          return this.x * vector.x + this.y * vector.y;
      }
      cross(vector) {
          return this.x * vector.y - this.y * vector.x;
      }
      mag() {
          return Math.sqrt(this.x * this.x + this.y * this.y);
      }
      magSqr() {
          return this.x * this.x + this.y * this.y;
      }
      normalizeSelf() {
          var magSqr = this.x * this.x + this.y * this.y;
          if (magSqr === 1.0)
              return this;
          if (magSqr === 0.0) {
              return this;
          }
          var invsqrt = 1.0 / Math.sqrt(magSqr);
          this.x *= invsqrt;
          this.y *= invsqrt;
          return this;
      }
      normalize(out) {
          out = out || new Vec2();
          out.x = this.x;
          out.y = this.y;
          out.normalizeSelf();
          return out;
      }
      angle(vector) {
          var magSqr1 = this.magSqr();
          var magSqr2 = vector.magSqr();
          if (magSqr1 === 0 || magSqr2 === 0) {
              console.warn("Can't get angle between zero vector");
              return 0.0;
          }
          var dot = this.dot(vector);
          var theta = dot / (Math.sqrt(magSqr1 * magSqr2));
          theta = Mathf.clamp(theta, -1.0, 1.0);
          return Math.acos(theta);
      }
      signAngle(vector) {
          let angle = this.angle(vector);
          return this.cross(vector) < 0 ? -angle : angle;
      }
      rotate(radians, out) {
          out = out || new Vec2();
          out.x = this.x;
          out.y = this.y;
          return out.rotateSelf(radians);
      }
      rotateSelf(radians) {
          var sin = Math.sin(radians);
          var cos = Math.cos(radians);
          var x = this.x;
          this.x = cos * x - sin * this.y;
          this.y = sin * x + cos * this.y;
          return this;
      }
      project(vector) {
          return vector.mul(this.dot(vector) / vector.dot(vector));
      }
  }
  Vec2.ZERO = new Vec2(0, 0);
  Vec2.TEMP = new Vec2(0, 0);
  Vec2.TEMPS = [
      new Vec2(0, 0),
      new Vec2(0, 0),
      new Vec2(0, 0),
      new Vec2(0, 0)
  ];

  class JumpBy extends ActionInterval {
      constructor(duration, x, y, height, jumps) {
          super();
          this._previousPosition = new Vec2(0, 0);
          this._startPosition = new Vec2(0, 0);
          this._delta = new Vec2(0, 0);
          this._height = 0;
          this._jumps = 0;
          height !== undefined && this.initWithDuration(duration, x, y, height, jumps);
      }
      initWithDuration(duration, x, y, height, jumps) {
          if (super.initWithDuration(duration)) {
              this._delta.x = x;
              this._delta.y = y;
              this._height = height;
              this._jumps = jumps;
              return true;
          }
          return false;
      }
      clone() {
          var action = new JumpBy();
          this._cloneDecoration(action);
          action.initWithDuration(this._duration, this._delta.x, this._delta.y, this._height, this._jumps);
          return action;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          var locPosX = target.x;
          var locPosY = target.y;
          this._previousPosition.x = locPosX;
          this._previousPosition.y = locPosY;
          this._startPosition.x = locPosX;
          this._startPosition.y = locPosY;
      }
      update(dt) {
          dt = this._computeEaseTime(dt);
          let target = this.target;
          if (target) {
              var frac = dt * this._jumps % 1.0;
              var y = this._height * 4 * frac * (1 - frac);
              y += this._delta.y * dt;
              var x = this._delta.x * dt;
              var locStartPosition = this._startPosition;
              if (false) {
                  var targetX = target.x;
                  var targetY = target.y;
                  var locPreviousPosition = this._previousPosition;
                  locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x;
                  locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
                  x = x + locStartPosition.x;
                  y = y + locStartPosition.y;
                  locPreviousPosition.x = x;
                  locPreviousPosition.y = y;
                  target.setXY(x, y);
              }
              else {
                  target.x = locStartPosition.x + x;
                  target.y = locStartPosition.y + y;
              }
          }
      }
      reverse() {
          var action = new JumpBy(this._duration, -this._delta.x, -this._delta.y, this._height, this._jumps);
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
  }
  class JumpTo extends JumpBy {
      constructor(duration, x, y, height, jumps) {
          super();
          this._endPosition = new Vec2(0, 0);
          height !== undefined && this.initWithDuration(duration, x, y, height, jumps);
      }
      initWithDuration(duration, x, y, height, jumps) {
          if (super.initWithDuration(duration, x, y, height, jumps)) {
              this._endPosition.x = x;
              this._endPosition.y = y;
              return true;
          }
          return false;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          this._delta.x = this._endPosition.x - this._startPosition.x;
          this._delta.y = this._endPosition.y - this._startPosition.y;
      }
      clone() {
          var action = new JumpTo();
          this._cloneDecoration(action);
          action.initWithDuration(this._duration, this._endPosition.x, this._endPosition.y, this._height, this._jumps);
          return action;
      }
  }
  class JumpBy3D extends ActionInterval {
      constructor(duration, delta, height, jumps, bWorld) {
          super();
          this._previousPosition = new Laya.Vector3(0, 0);
          this._startPosition = new Laya.Vector3(0, 0);
          this._delta = new Laya.Vector3(0, 0);
          this._height = new Laya.Vector3(0, 0);
          this._jumps = 0;
          height !== undefined && this.initWithDuration(duration, delta, height, jumps, bWorld);
      }
      initWithDuration(duration, delta, height, jumps, bWorld) {
          if (super.initWithDuration(duration)) {
              delta.cloneTo(this._delta);
              height.cloneTo(this._height);
              this._jumps = jumps;
              this._bWorld = bWorld;
              return true;
          }
          return false;
      }
      clone() {
          var action = new JumpBy3D();
          this._cloneDecoration(action);
          action.initWithDuration(this._duration, this._delta, this._height, this._jumps, this._bWorld);
          return action;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          if (this._bWorld) {
              target.transform.position.cloneTo(this._previousPosition);
          }
          else {
              target.transform.localPosition.cloneTo(this._previousPosition);
          }
          this._previousPosition.cloneTo(this._startPosition);
      }
      update(dt) {
          dt = this._computeEaseTime(dt);
          let target = this.target;
          if (target && !target.destroyed) {
              var frac = dt * this._jumps % 1.0;
              let dh = Mathf.TEMP_VEC3S[0];
              let delta = Mathf.TEMP_VEC3S[1];
              Laya.Vector3.scale(this._height, 4 * frac * (1 - frac), dh);
              Laya.Vector3.scale(this._delta, dt, delta);
              Laya.Vector3.add(delta, dh, delta);
              Laya.Vector3.add(this._startPosition, delta, delta);
              if (this._bWorld) {
                  target.transform.position = delta;
              }
              else {
                  target.transform.localPosition = delta;
              }
          }
      }
      reverse() {
          let delta = this._delta.clone();
          Laya.Vector3.scale(delta, -1, delta);
          var action = new JumpBy3D(this._duration, delta, this._height, this._jumps, this._bWorld);
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
  }
  class JumpTo3D extends JumpBy3D {
      constructor(duration, to, height, jumps, bWorld) {
          super();
          this._endPosition = new Laya.Vector3;
          height !== undefined && this.initWithDuration(duration, to, height, jumps, bWorld);
      }
      initWithDuration(duration, to, height, jumps, bWorld) {
          if (super.initWithDuration(duration, to, height, jumps, bWorld)) {
              to.cloneTo(this._endPosition);
              return true;
          }
          return false;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          Laya.Vector3.subtract(this._endPosition, this._startPosition, this._delta);
      }
      clone() {
          var action = new JumpTo3D();
          this._cloneDecoration(action);
          action.initWithDuration(this._duration, this._endPosition, this._height, this._jumps, this._bWorld);
          return action;
      }
  }
  let default_number_formater = function (value) {
      return (value | 0).toString();
  };
  class NumberTo extends ActionInterval {
      constructor(duration, from, to, formater) {
          super();
          this._from = from;
          this._to = to;
          this._formater = formater || default_number_formater;
          this.initWithDuration(duration);
      }
      clone() {
          var action = new NumberTo(this._duration, this._from, this._to, this._formater);
          this._cloneDecoration(action);
          return action;
      }
      initWithDuration(duration) {
          if (super.initWithDuration(duration)) {
              return true;
          }
          return false;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          this.m_label = target;
      }
      update(t) {
          if (this.m_label) {
              t = this._computeEaseTime(t);
              let cur = this._from + (this._to - this._from) * t;
              this.m_label.text = this._formater(cur);
          }
      }
  }
  class StringOneByOne extends ActionInterval {
      constructor(duration, text) {
          super();
          this._text = text;
          this.initWithDuration(duration);
      }
      clone() {
          var action = new StringOneByOne(this._duration, this._text);
          this._cloneDecoration(action);
          return action;
      }
      update(t) {
          let target = this.target;
          if (target) {
              t = this._computeEaseTime(t);
              let idx = Math.floor(Mathf.lerp(0, this._text.length, t));
              target.text = this._text.substring(0, idx);
          }
      }
  }
  class Follow3DTo2D extends ActionInterval {
      constructor(duration, target, orthographicCamera, offsetX = 0, offsetY = 0) {
          super();
          this._followTarget = target;
          this._orthographicCamera = orthographicCamera;
          this._offsetX = offsetX;
          this._offsetY = offsetY;
          if (duration <= 0)
              duration = 1e8;
          this.initWithDuration(duration);
      }
      clone() {
          var action = new Follow3DTo2D(this._duration, this._followTarget, this._orthographicCamera);
          this._cloneDecoration(action);
          return action;
      }
      update(t) {
          let target = this.target;
          if (target) {
              let followTarge = this._followTarget;
              if (followTarge && !followTarge.destroyed) {
                  let v2 = Laya.Point.TEMP;
                  v2.setTo(this._offsetX + followTarge.pivotX, this._offsetY + followTarge.pivotY);
                  followTarge.localToGlobal(v2, false);
                  let v3 = Mathf.TEMP_VEC3;
                  v3.setValue(v2.x, v2.y, 0);
                  this._orthographicCamera.convertScreenCoordToOrthographicCoord(v3, v3);
                  target.transform.position = v3;
              }
          }
      }
  }
  function bezierAt(a, b, c, d, t) {
      return (Math.pow(1 - t, 3) * a +
          3 * t * (Math.pow(1 - t, 2)) * b +
          3 * Math.pow(t, 2) * (1 - t) * c +
          Math.pow(t, 3) * d);
  }
  class BezierBy extends ActionInterval {
      constructor(duration, points) {
          super();
          this._config = [];
          this._startPosition = new Vec2();
          this._previousPosition = new Vec2();
          points && this.initWithDuration(duration, points);
      }
      initWithDuration(duration, points) {
          if (super.initWithDuration(duration)) {
              this._config = points;
              return true;
          }
          return false;
      }
      clone() {
          var action = new BezierBy();
          this._cloneDecoration(action);
          var newConfigs = [];
          for (var i = 0; i < this._config.length; i++) {
              var selConf = this._config[i];
              newConfigs.push(new Vec2(selConf.x, selConf.y));
          }
          action.initWithDuration(this._duration, newConfigs);
          return action;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          var locPosX = target.x;
          var locPosY = target.y;
          this._previousPosition.x = locPosX;
          this._previousPosition.y = locPosY;
          this._startPosition.x = locPosX;
          this._startPosition.y = locPosY;
      }
      update(t) {
          t = this._computeEaseTime(t);
          if (this.target) {
              var target = this.target;
              var locConfig = this._config;
              var xa = 0;
              var xb = locConfig[0].x;
              var xc = locConfig[1].x;
              var xd = locConfig[2].x;
              var ya = 0;
              var yb = locConfig[0].y;
              var yc = locConfig[1].y;
              var yd = locConfig[2].y;
              var x = bezierAt(xa, xb, xc, xd, t);
              var y = bezierAt(ya, yb, yc, yd, t);
              var locStartPosition = this._startPosition;
              if (false) {
                  var targetX = target.x;
                  var targetY = target.y;
                  var locPreviousPosition = this._previousPosition;
                  locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x;
                  locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
                  x = x + locStartPosition.x;
                  y = y + locStartPosition.y;
                  locPreviousPosition.x = x;
                  locPreviousPosition.y = y;
                  target.setXY(x, y, true);
              }
              else {
                  target.x = locStartPosition.x + x;
                  target.y = locStartPosition.y + y;
              }
          }
      }
      reverse() {
          var locConfig = this._config;
          var x0 = locConfig[0].x, y0 = locConfig[0].y;
          var x1 = locConfig[1].x, y1 = locConfig[1].y;
          var x2 = locConfig[2].x, y2 = locConfig[2].y;
          var r = [
              new Vec2(x1 - x2, y1 - y2),
              new Vec2(x0 - x2, y0 - y2),
              new Vec2(-x2, -y2)
          ];
          var action = new BezierBy(this._duration, r);
          this._cloneDecoration(action);
          this._reverseEaseList(action);
          return action;
      }
  }
  class BezierTo extends ActionInterval {
      constructor(duration, points, pathCount = 5, count = 2) {
          super();
          this.initWithDuration(duration, points, pathCount, count);
      }
      initWithDuration(duration, points, pathCount, count) {
          if (super.initWithDuration(duration)) {
              let path = new Laya.Bezier().getBezierPoints(points, pathCount, count);
              this._path = path;
              let len = 0;
              for (var i = 0; i < path.length - 2; i += 2) {
                  len += Mathf.distance2(path[i] - path[i + 2], path[i + 1] - path[i + 3]);
              }
              return true;
          }
          return false;
      }
      clone() {
          console.error("暂无clone实现，偷懒而已");
          return null;
      }
      startWithTarget(target) {
          super.startWithTarget(target);
      }
      setUpdateCallBack(callback) {
          this.handlerUpdate = callback;
      }
      update(t) {
          t = this._computeEaseTime(t);
          if (this.target) {
              var pos = Vec2.TEMP;
              let ox = this.target.x;
              let oy = this.target.y;
              BezierTo.lerpPath(this._path, t, pos);
              var target = this.target;
              let dx = pos.x - ox;
              let dy = pos.y - oy;
              target.x = pos.x;
              target.y = pos.y;
              if (this.handlerUpdate)
                  this.handlerUpdate.runWith([dx, dy]);
          }
      }
      reverse() {
          console.error("暂无reverse实现，偷懒而已");
          return null;
      }
      static lerpPath(path, t, out) {
          if (path.length == 0) {
              return;
          }
          t = Mathf.clamp01(t);
          if (out == null) {
              out = new Vec2(0, 0);
          }
          if (t == 0) {
              out.setValue(path[0], path[1]);
          }
          else if (t == 1) {
              out.setValue(path[path.length - 2], path[path.length - 1]);
          }
          else {
              let value = (path.length / 2 - 1) * t;
              let min = value | 0;
              let max = Math.ceil(value);
              if (min != max) {
                  out.x = Mathf.lerp(path[min * 2], path[max * 2], value - min);
                  out.y = Mathf.lerp(path[min * 2 + 1], path[max * 2 + 1], value - min);
              }
              else {
                  out.setValue(path[max * 2], path[max * 2 + 1]);
              }
          }
          return out;
      }
  }
  class LookAt extends ActionInterval {
      constructor(duration, target) {
          super();
          this.looAtTarget = target;
          this.lookAtPos = new Laya.Vector3();
          if (duration <= 0)
              duration = 1e8;
          this.initWithDuration(duration);
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          let forward = Mathf.TEMP_VEC3;
          target.transform.getForward(forward);
          Laya.Vector3.normalize(forward, forward);
          let dis = Laya.Vector3.distance(target.transform.position, this.looAtTarget.transform.position);
          Laya.Vector3.scale(forward, dis, forward);
          Laya.Vector3.add(target.transform.position, forward, this.lookAtPos);
      }
      clone() {
          var action = new LookAt(this._duration, this.looAtTarget);
          this._cloneDecoration(action);
          return action;
      }
      update(t) {
          let target = this.target;
          if (target) {
              let lookAtTarge = this.looAtTarget;
              if (lookAtTarge && !lookAtTarge.destroyed) {
                  Laya.Vector3.lerp(this.lookAtPos, lookAtTarge.transform.position, 0.1, this.lookAtPos);
                  target.transform.lookAt(this.lookAtPos, LookAt.UP, false);
              }
          }
      }
  }
  LookAt.UP = new Laya.Vector3(0, 1, 0);
  class Follow3D extends ActionInterval {
      constructor(duration, target, distance = 0) {
          super();
          this.followTarget = target;
          this.distance = distance;
          this.originPos = new Laya.Vector3();
          if (duration <= 0)
              duration = 1e8;
          this.initWithDuration(duration);
      }
      startWithTarget(target) {
          super.startWithTarget(target);
          if (this.distance <= 0) {
              this.distance = Laya.Vector3.distance(target.transform.position, this.followTarget.transform.position);
          }
          target.transform.position.cloneTo(this.originPos);
      }
      clone() {
          var action = new Follow3D(this._duration, this.followTarget, this.distance);
          this._cloneDecoration(action);
          return action;
      }
      update(t) {
          let target = this.target;
          if (target) {
              let followTarge = this.followTarget;
              if (followTarge && !followTarge.destroyed) {
                  Laya.Vector3.lerp(this.originPos, followTarge.transform.position, 0.1, this.originPos);
                  target.transform.position = this.originPos;
              }
          }
      }
  }
  Follow3D.UP = new Laya.Vector3(0, 1, 0);
  class Follow2D extends ActionInterval {
      constructor(duration, target, offset) {
          super();
          this.followTarget = target;
          this.offset = offset || new Laya.Point();
          if (duration <= 0)
              duration = 1e8;
          this.initWithDuration(duration);
      }
      startWithTarget(target) {
          super.startWithTarget(target);
      }
      clone() {
          var action = new Follow2D(this._duration, this.followTarget, this.offset);
          this._cloneDecoration(action);
          return action;
      }
      update(t) {
          let target = this.target;
          if (target) {
              let followTarget = this.followTarget;
              if (followTarget && !followTarget.isDisposed) {
                  let p = Follow2D.temp_point;
                  p.setTo(this.offset.x, this.offset.y);
                  followTarget.localToGlobal(p.x, p.y, p);
                  if (target.parent) {
                      target.parent.globalToLocal(p.x, p.y, p);
                      target.x = Mathf.lerp(target.x, p.x, 0.1);
                      target.y = Mathf.lerp(target.y, p.y, 0.1);
                  }
              }
          }
      }
  }
  Follow2D.temp_point = new Laya.Point();

  var cc$1;
  (function (cc) {
      function tween(target, clearBefore = false) {
          if (clearBefore)
              clearTween(target);
          return new Tween(target);
      }
      cc.tween = tween;
      function clearTween(target) {
          TweenSystem.instance.ActionManager.removeAllActionsFromTarget(target);
      }
      cc.clearTween = clearTween;
      cc.Ease = Easing;
      function jumpBy(duration, x, y, height, jumps) {
          return new JumpBy(duration, x, y, -height, jumps);
      }
      cc.jumpBy = jumpBy;
      function jumpTo(duration, x, y, height, jumps) {
          return new JumpTo(duration, x, y, -height, jumps);
      }
      cc.jumpTo = jumpTo;
      function jumpBy3D(duration, delta, height, jumps, bWorld = false) {
          return new JumpBy3D(duration, delta, height, jumps, bWorld);
      }
      cc.jumpBy3D = jumpBy3D;
      function jumpTo3D(duration, to, height, jumps, bWorld = false) {
          return new JumpTo3D(duration, to, height, jumps, bWorld);
      }
      cc.jumpTo3D = jumpTo3D;
      function numberTo(duration, from, to, formater) {
          return new NumberTo(duration, from, to, formater);
      }
      cc.numberTo = numberTo;
      function stringOneByOne(duration, text) {
          return new StringOneByOne(duration, text);
      }
      cc.stringOneByOne = stringOneByOne;
      function lookAt(duration, target) {
          return new LookAt(duration, target);
      }
      cc.lookAt = lookAt;
      function bezierTo(duration, points, pathCount) {
          return new BezierTo(duration, points, pathCount, points.length / 2 - 1);
      }
      cc.bezierTo = bezierTo;
      function bezierFromTo(duration, from, to, radiusRate = 0.5, pathCount = 10) {
          let r = Mathf.distance(from, to) * radiusRate;
          let rot = Mathf.random(Math.PI * 200) / 100;
          let x = Math.cos(rot) * r;
          let y = Math.sin(rot) * r;
          let points = [from.x, from.y, from.x + x, from.y + y, to.x, to.y];
          return bezierTo(duration, points, pathCount);
      }
      cc.bezierFromTo = bezierFromTo;
      function follow2d(target, duration = 0, offset) {
          return new Follow2D(duration, target, offset);
      }
      cc.follow2d = follow2d;
      function follow3d(target, duration = 0, distance) {
          return new Follow3D(duration, target, distance);
      }
      cc.follow3d = follow3d;
      cc.PROP = {
          EMPTY: {},
          SCALE0: { scaleX: 0, scaleY: 0 },
          SCALE1: { scaleX: 1, scaleY: 1 },
          SCALE1_2: { scaleX: 1.2, scaleY: 1.2 },
          ALPHA0: { alpha: 0 },
          ALPHA1: { alpha: 1 },
          SCALE_ALPHA0: { scaleX: 0, scaleY: 0, alpha: 0 },
          SCALE_ALPHA1: { scaleX: 1, scaleY: 1, alpha: 1 },
      };
      cc.OPTION = {
          BACK_OUT: { easing: Easing.backOut },
          BACK_IN: { easing: Easing.backIn },
          SINE_IN: { easing: Easing.sineIn },
          SINE_OUT: { easing: Easing.sineOut },
          SINE_IN_OUT: { easing: Easing.sineInOut },
          SINE_OUT_IN: { easing: Easing.sineOutIn },
          CIRC_IN: { easing: Easing.circIn },
          CIRC_OUT: { easing: Easing.circOut },
          EXPO_IN: { easing: Easing.expoIn },
          EXPO_OUT: { easing: Easing.expoOut },
          CUBIC_IN: { easing: Easing.cubicIn },
          CUBIC_OUT: { easing: Easing.cubicOut },
      };
  })(cc$1 || (cc$1 = {}));

  class UITools {
      static get MASK_TEXTURE2D() {
          if (!this.maskTexture2d) {
              var pixels = new Uint8Array(4);
              pixels[0] = 0;
              pixels[1] = 0;
              pixels[2] = 0;
              pixels[3] = (255 * 0.7) | 0;
              let tex2d = new Laya.Texture2D(1, 1, Laya.TextureFormat.R8G8B8A8, false, false);
              tex2d.setPixels(pixels);
              tex2d.lock = true;
              this.maskTexture2d = tex2d;
          }
          return this.maskTexture2d;
      }
      static get MASK_TEXTURE() {
          if (!this.maskTexture) {
              this.maskTexture = Laya.Texture.create(this.MASK_TEXTURE2D, 0, 0, 1, 1);
          }
          return this.maskTexture;
      }
      static get WHITE_TEXTURE2D() {
          return Laya.Texture2D.whiteTexture;
      }
      static get WHITE_TEXTURE() {
          if (!this.whiteTexture) {
              this.whiteTexture = Laya.Texture.create(this.WHITE_TEXTURE2D, 0, 0, 1, 1);
          }
          return this.whiteTexture;
      }
      static getChild(node, childPath) {
          if (!childPath)
              return null;
          if (childPath == "/")
              return node;
          if (~childPath.indexOf("/")) {
              let names = childPath.split("/");
              for (let i = 0; i < names.length; i++) {
                  node = node.getChildByName(names[i]);
                  if (!node)
                      return null;
              }
              return node;
          }
          else {
              return node.getChildByName(childPath);
          }
      }
      static findChild(root, childName) {
          if (!childName)
              return null;
          if (root.name == childName)
              return root;
          for (let i = root.numChildren - 1; i >= 0; i--) {
              let child = this.findChild(root.getChildAt(i), childName);
              if (child) {
                  return child;
              }
          }
      }
      static findAllMeshRenderers(node, out, recursive = false) {
          out = out || [];
          for (let i = 0; i < node.numChildren; i++) {
              let child = node.getChildAt(i);
              if (child) {
                  let render = child["meshRenderer"];
                  if (render) {
                      out.push(render);
                  }
                  if (recursive) {
                      this.findAllMeshRenderers(child, out, recursive);
                  }
              }
          }
          return out;
      }
      static findAllSkinnedMeshRenderers(node, out, recursive = false) {
          out = out || [];
          for (let i = 0; i < node.numChildren; i++) {
              let child = node.getChildAt(i);
              if (child) {
                  let render = child["skinnedMeshRenderer"];
                  if (render) {
                      out.push(render);
                  }
                  if (recursive) {
                      this.findAllSkinnedMeshRenderers(child, out, recursive);
                  }
              }
          }
          return out;
      }
      static findMeshRender(model) {
          for (let i = 0; i < model.numChildren; i++) {
              let child = model.getChildAt(i);
              let renderer = child[`skinnedMeshRenderer`] || child[`meshRenderer`];
              if (renderer) {
                  return renderer;
              }
          }
          return null;
      }
      static findAllShurikenParticleSystem(node, out) {
          out = out || [];
          for (var i = node.numChildren - 1; i >= 0; i--) {
              var child = node.getChildAt(i);
              if (child.particleSystem) {
                  out.push(child.particleSystem);
              }
              this.findAllShurikenParticleSystem(child, out);
          }
          return out;
      }
      static setLayer(node, layer) {
          node.layer = layer;
          for (var i = 0; i < node.numChildren; i++) {
              this.setLayer(node.getChildAt(i), layer);
          }
      }
      static cloneSprite(sprite) {
          let newSprite = this._cloneSingleSprite(sprite);
          for (var i = 0; i < sprite.numChildren; i++) {
              var newChild = this.cloneSprite(sprite.getChildAt(i));
              if (newChild) {
                  newSprite.addChild(newChild);
              }
          }
          return newSprite;
      }
      static _cloneSingleSprite(sprite) {
          if (!sprite.name)
              return null;
          let newSprite;
          if (sprite instanceof Laya.Image) {
              let newImage = new Laya.Image(sprite.skin);
              if (sprite.anchorX)
                  newImage.anchorX = sprite.anchorX;
              if (sprite.anchorY)
                  newImage.anchorY = sprite.anchorY;
              newImage.sizeGrid = sprite.sizeGrid;
              newImage.pivot(sprite.pivotX, sprite.pivotY);
              newSprite = newImage;
          }
          else if (sprite instanceof Laya.Label) {
              let newLabel = new Laya.Label();
              newLabel.fontSize = sprite.fontSize;
              newLabel.color = sprite.color;
              newLabel.strokeColor = sprite.strokeColor;
              newLabel.stroke = sprite.stroke;
              if (sprite.anchorX)
                  newLabel.anchorX = sprite.anchorX;
              if (sprite.anchorY)
                  newLabel.anchorY = sprite.anchorY;
              newLabel.align = sprite.align;
              newLabel.wordWrap = sprite.wordWrap;
              newLabel.text = sprite.text;
              newSprite = newLabel;
          }
          else if (sprite instanceof Laya.Text) {
              let newText = new Laya.Label();
              newText.fontSize = sprite.fontSize;
              newText.color = sprite.color;
              newText.strokeColor = sprite.strokeColor;
              newText.stroke = sprite.stroke;
              newText.align = sprite.align;
              newText.wordWrap = sprite.wordWrap;
              newText.text = sprite.text;
              newSprite = newText;
          }
          else if (sprite instanceof Laya.Sprite) {
              newSprite = new Laya.Sprite();
              newSprite.texture = sprite.texture;
              newSprite.pivot(sprite.pivotX, sprite.pivotY);
          }
          if (sprite["_width"])
              newSprite.width = sprite.width;
          if (sprite["_height"])
              newSprite.height = sprite.height;
          newSprite.pos(sprite.x, sprite.y, true)
              .scale(sprite.scaleX, sprite.scaleY).rotation = sprite.rotation;
          newSprite.name = sprite.name;
          return newSprite;
      }
      static local2local(from, toNode, outPos) {
          from.localToGlobal(outPos, false);
          toNode.globalToLocal(outPos, false);
          return outPos;
      }
      static getSelfGlobalPos(obj, outPos) {
          outPos = outPos || new Laya.Point();
          if (obj.parent) {
              outPos.setTo(obj.x, obj.y);
              obj.parent.localToGlobal(obj.x, obj.y, outPos);
          }
          return outPos;
      }
      static node2camera(obj, camera, out) {
          let p = this.getSelfGlobalPos(obj, new Laya.Point());
          return this.global2camera(p, camera, out);
      }
      static global2camera(worldPos, camera, out) {
          out = out || new Laya.Vector3();
          out.x = worldPos.x;
          out.y = worldPos.y;
          out.z = 0;
          camera.convertScreenCoordToOrthographicCoord(out, out);
          return out;
      }
      static worldToScreen(pos, camera, out) {
          out = out || new Laya.Point();
          let point = this.vec4_temp;
          camera.viewport.project(pos, camera.projectionViewMatrix, point);
          out.x = point.x / Laya.stage.clientScaleX;
          out.y = point.y / Laya.stage.clientScaleY;
          return out;
      }
      static screenToWorld(screenPos, camera, distance, out) {
          out = out || new Laya.Vector3();
          this.screenToRay(screenPos, camera, this.ray_temp);
          Laya.Vector3.scale(this.ray_temp.direction, distance, out);
          Laya.Vector3.add(this.ray_temp.origin, out, out);
          return out;
      }
      static screenToRay(screenPos, camera, ray) {
          ray = ray || new Laya.Ray(new Laya.Vector3, new Laya.Vector3);
          this.convertScreenToCanvas(screenPos, this.vec2_temp);
          camera.viewportPointToRay(this.vec2_temp, ray);
          return ray;
      }
      static convertScreenToCanvas(screenPos, out) {
          out = out || new Laya.Vector2();
          out.x = screenPos.x * Laya.stage.clientScaleX;
          out.y = screenPos.y * Laya.stage.clientScaleY;
          return out;
      }
      static clampSpriteSize(sprite, maxSize) {
          let max = Math.max(sprite.width, sprite.height);
          if (max > 0) {
              if (max > maxSize) {
                  let scale = maxSize / max;
                  sprite.scale(scale, scale, true);
              }
          }
          else {
              let texture = sprite.texture;
              if (texture) {
                  let fixSize = function () {
                      if (sprite.destroyed)
                          return;
                      let max = Math.max(texture.width, texture.height);
                      if (max > maxSize) {
                          let scale = maxSize / max;
                          sprite.scale(scale, scale, true);
                      }
                  };
                  if (texture.getIsReady()) {
                      fixSize();
                  }
                  else {
                      texture.once(Laya.Event.READY, sprite, fixSize);
                  }
              }
          }
      }
      static setSpritePosition(sprite3d, x, y, z) {
          let transform = sprite3d.transform;
          transform.position.setValue(x, y, z);
          transform.position = transform.position;
      }
      static setSpriteLocalPosition(sprite3d, x, y, z) {
          let transform = sprite3d.transform;
          transform.localPosition.setValue(x, y, z);
          transform.localPosition = transform.localPosition;
      }
      static setSpriteLocalScale(sprite3d, x, y, z) {
          let transform = sprite3d.transform;
          transform.localScale.setValue(x, y, z);
          transform.localScale = transform.localScale;
      }
      static setTransformVec3Prop(transform, key, x, y, z) {
          let prop = transform[key];
          prop.setValue(x, y, z);
          transform[key] = prop;
      }
      static tweenTransformVec3Prop(transform, key, duration, x, y, z) {
          let prop = transform[key];
          let fromX = prop.x;
          let fromY = prop.y;
          let fromZ = prop.z;
          cc$1.tween(transform).to(duration, cc$1.PROP.EMPTY, {
              onUpdate: function (target, t) {
                  prop.setValue(Mathf.lerp(fromX, x, t), Mathf.lerp(fromY, y, t), Mathf.lerp(fromZ, z, t));
                  transform[key] = prop;
              }
          }).start();
      }
      static linearModel(sprite3D, lineSprite3D, color, keepWorldPos = false) {
          if (sprite3D instanceof Laya.MeshSprite3D) {
              var meshSprite3D = sprite3D;
              var mesh = meshSprite3D.meshFilter.sharedMesh;
              var positions = [];
              mesh.getPositions(positions);
              var indices = mesh.getSubMesh(0).getIndices();
              for (var i = 0; i < indices.length; i += 3) {
                  var vertex0 = positions[indices[i]];
                  var vertex1 = positions[indices[i + 1]];
                  var vertex2 = positions[indices[i + 2]];
                  if (keepWorldPos) {
                      Laya.Vector3.transformCoordinate(vertex0, meshSprite3D.transform.worldMatrix, this.transVertex0);
                      Laya.Vector3.transformCoordinate(vertex1, meshSprite3D.transform.worldMatrix, this.transVertex1);
                      Laya.Vector3.transformCoordinate(vertex2, meshSprite3D.transform.worldMatrix, this.transVertex2);
                      lineSprite3D.addLine(this.transVertex0, this.transVertex1, color, color);
                      lineSprite3D.addLine(this.transVertex1, this.transVertex2, color, color);
                      lineSprite3D.addLine(this.transVertex2, this.transVertex0, color, color);
                  }
                  else {
                      lineSprite3D.addLine(vertex0, vertex1, color, color);
                      lineSprite3D.addLine(vertex1, vertex2, color, color);
                      lineSprite3D.addLine(vertex2, vertex0, color, color);
                  }
              }
          }
          for (var i = 0, n = sprite3D.numChildren; i < n; i++)
              this.linearModel(sprite3D.getChildAt(i), lineSprite3D, color);
      }
      static widgetLeftMC(node) {
          this.widgetLeftTopMC(node, false, true);
      }
      static widgetRightMC(node) {
          this.widgetRightTopMC(node, false, true);
      }
      static widgetTopMC(node) {
          this.widgetLeftTopMC(node, true, false);
      }
      static widgetBottomMC(node) {
          this.widgetLeftBottomMC(node, true, false);
      }
      static widgetLeftTopMC(node, bDisableH = false, bDisableV = false) {
          if (!node[`_originPos_`]) {
              node[`_originPos_`] = new Laya.Point(node.x, node.y);
          }
          let offsetX = (UIRoot.uiFitWidth - UIRoot.designWidth) / 2;
          let offsetY = (UIRoot.uiFitHeight - UIRoot.designHeight) / 2;
          !bDisableH && (node.x = node[`_originPos_`].x - offsetX);
          !bDisableV && (node.y = node[`_originPos_`].y - offsetY);
      }
      static widgetRightTopMC(node, bDisableH = false, bDisableV = false) {
          if (!node[`_originPos_`]) {
              node[`_originPos_`] = new Laya.Point(node.x, node.y);
          }
          let offsetX = (UIRoot.uiFitWidth - UIRoot.designWidth) / 2;
          let offsetY = (UIRoot.uiFitHeight - UIRoot.designHeight) / 2;
          !bDisableH && (node.x = node[`_originPos_`].x + offsetX);
          !bDisableV && (node.y = node[`_originPos_`].y - offsetY);
      }
      static widgetLeftBottomMC(node, bDisableH = false, bDisableV = false) {
          if (!node[`_originPos_`]) {
              node[`_originPos_`] = new Laya.Point(node.x, node.y);
          }
          let offsetX = (UIRoot.uiFitWidth - UIRoot.designWidth) / 2;
          let offsetY = (UIRoot.uiFitHeight - UIRoot.designHeight) / 2;
          !bDisableH && (node.x = node[`_originPos_`].x - offsetX);
          !bDisableV && (node.y = node[`_originPos_`].y + offsetY);
      }
      static widgetRightBottomMC(node, bDisableH = false, bDisableV = false) {
          if (!node[`_originPos_`]) {
              node[`_originPos_`] = new Laya.Point(node.x, node.y);
          }
          let offsetX = (UIRoot.uiFitWidth - UIRoot.designWidth) / 2;
          let offsetY = (UIRoot.uiFitHeight - UIRoot.designHeight) / 2;
          !bDisableH && (node.x = node[`_originPos_`].x + offsetX);
          !bDisableV && (node.y = node[`_originPos_`].y + offsetY);
      }
  }
  UITools.vec2_temp = new Laya.Vector2();
  UITools.vec3_temp = new Laya.Vector3();
  UITools.vec4_temp = new Laya.Vector4();
  UITools.ray_temp = new Laya.Ray(new Laya.Vector3, new Laya.Vector3);
  UITools.transVertex0 = new Laya.Vector3();
  UITools.transVertex1 = new Laya.Vector3();
  UITools.transVertex2 = new Laya.Vector3();

  var AnimLoadState;
  (function (AnimLoadState) {
      AnimLoadState[AnimLoadState["Empty"] = 0] = "Empty";
      AnimLoadState[AnimLoadState["Loading"] = 1] = "Loading";
      AnimLoadState[AnimLoadState["Loaded"] = 2] = "Loaded";
  })(AnimLoadState || (AnimLoadState = {}));
  const DEFAULT_TRANSITION_DURATION = 0.1;
  class AnimStateScript extends Laya.AnimatorStateScript {
      constructor() {
          super(...arguments);
          this._callbackList = [];
      }
      addCallback(callback) {
          this._callbackList.push(callback);
      }
      setEventData(node, animId) {
          this._node = node;
          this._animId = animId;
      }
      onStateEnter() {
          if (this._node.destroyed)
              return;
          this._node.event("Enter", this._animId);
          this._startTime = Timer.time;
      }
      onStateUpdate() {
          let deltaTime = Timer.time - this._startTime;
          for (let i = this._callbackList.length - 1; i >= 0; i--) {
              const callInfo = this._callbackList[i];
              if (callInfo.time <= deltaTime) {
                  callInfo.callback();
                  this._callbackList.splice(i, 1);
              }
          }
      }
      onStateExit() {
          if (this._node.destroyed)
              return;
          this._node.event("Exit", this._animId);
      }
  }
  class Model extends Laya.Sprite3D {
      constructor(modelId) {
          super();
          this.resourceType = RES_TYPE.PREFAB3D;
          this._lastAnimId = "";
          this._curAnimId = "";
          this._animStates = Object.create(null);
          this.delayCalls = [];
          this.aniDelayCalls = {};
          this.modelId = modelId;
          this.modelDb = db.get_model_db(modelId);
          this.sourceName = this.modelDb.resPath;
          this.name = modelId;
          this.create();
      }
      get isLoaded() {
          return this._isLoaded;
      }
      get isLoading() {
          return this._isLoading;
      }
      get lastAnimationId() {
          return this._lastAnimId;
      }
      get curAnimationId() {
          return this._curAnimId;
      }
      create() {
          if (this._isLoaded) {
              return;
          }
          if (this._isLoading) {
              return;
          }
          let pName = this.sourceName;
          if (!pName) {
              console.error("Model.create: can't find resourceName.");
              return;
          }
          this._isLoading = true;
          ResLoader.loadRes(this.sourceName, this.resourceType, (res) => {
              this.onResLoaded(res);
          });
      }
      onResLoaded(res) {
          this._isLoading = false;
          if (res) {
              if (!this.destroyed) {
                  this._isLoaded = true;
                  this.onResourceLoaded(res);
                  if (!this.destroyed && this.scene)
                      this.processDelayCalls();
              }
          }
          else {
              this.onResourceLoadedFail();
          }
      }
      onResourceLoadedFail() {
          console.warn("资源加载失败:", this.sourceName);
      }
      onResourceLoaded(res) {
          this.resNode = Laya.Sprite3D.instantiate(res);
          this._animtor = this.resNode.getComponent(Laya.Animator);
          this.addChild(this.resNode);
          if (this._animtor)
              this.on("Exit", this, this._onAnimComplete);
      }
      tryCreate() {
          if (this.destroyed || this._isLoaded || this._isLoading)
              return;
          this.create();
      }
      reuse() {
          this.tryCreate();
          this.setSpeed(1);
          this.active = true;
      }
      unuse() {
          this._curAnimId = "";
          this._clearAnimList();
          this.setSpeed(0);
          this.removeSelf();
          this.transform.position = new Laya.Vector3(0, 0, 0);
          this.transform.rotationEuler = new Laya.Vector3(0, 0, 0);
          this.transform.localScale = new Laya.Vector3(1, 1, 1);
          this.active = false;
      }
      dispose() {
          this.destroy();
      }
      onDestroy() {
          this._isLoaded = false;
          this.clearDelayCalls();
      }
      initAnimator(createControllerLayer = true, alwaysAnimate = true) {
          if (this._isLoaded) {
              if (!this._animtor) {
                  this._animtor = this.resNode.addComponent(Laya.Animator);
                  this._animtor.cullingMode = alwaysAnimate ? Laya.Animator.CULLINGMODE_ALWAYSANIMATE : Laya.Animator.CULLINGMODE_CULLCOMPLETELY;
                  createControllerLayer && this._animtor.addControllerLayer(new Laya.AnimatorControllerLayer(""));
                  this.on("Exit", this, this._onAnimComplete);
              }
          }
          else {
              this.safeCall(this.initAnimator, createControllerLayer, alwaysAnimate);
          }
      }
      getAnimator() {
          if (this.callable) {
              return this._animtor;
          }
          else {
              this.logNotFinishError();
          }
      }
      logNotFinishError() {
          Logger.error("对象未加载完成");
      }
      getAnimationDuration(animId) {
          let animState = this._animtor.getControllerLayer(0).getAnimatorState(animId);
          if (animState) {
              return animState.clip.duration();
          }
          else {
              return 0;
          }
      }
      playAnim(animId, transitionDuration = DEFAULT_TRANSITION_DURATION, loop) {
          if (!this.callable) {
              this.safeCall(this.playAnim, animId, transitionDuration, loop);
              return;
          }
          this._clearAnimList();
          this._checkAnimAndPlay(animId, transitionDuration, 0, loop);
      }
      _checkAnimAndPlay(animId, transitionDuration, normalizedTime, loop) {
          if (!this._animtor)
              return;
          this._curAnimId = animId;
          this._lastAnimId = animId;
          switch (this._animStates[animId] || AnimLoadState.Empty) {
              case AnimLoadState.Loaded:
                  this._playAnimOnloaded(animId, transitionDuration, normalizedTime, loop);
                  break;
              case AnimLoadState.Empty:
                  if (animId) {
                  }
                  else {
                      this._playAnimOnloaded(null, transitionDuration, normalizedTime, loop);
                  }
                  break;
              case AnimLoadState.Loading:
                  break;
          }
      }
      addAnimatorStateById(animId) {
          if (this._animtor.getControllerLayer(0).getAnimatorState(animId)) {
              return;
          }
      }
      addAnimatorState(animId, clip) {
          if (!this._animtor)
              return;
          if (!clip) {
              console.error(`Model.addAnimatorState: 未知动画:${animId}`);
              return;
          }
          if (this._animtor.getControllerLayer(0).getAnimatorState(animId)) {
              console.log(`Model.addAnimatorState: 重复添加动画:`, animId);
              return;
          }
          let state = new Laya.AnimatorState();
          state.clip = clip;
          state.clipStart = 0;
          state.clipEnd = 1;
          state.name = animId;
          state.addScript(AnimStateScript).setEventData(this, animId);
          if (this.aniDelayCalls[animId]) {
              for (let i = 0; i < this.aniDelayCalls[animId].length; i++) {
                  const element = this.aniDelayCalls[animId][i];
                  state.getScript(AnimStateScript).addCallback(element);
              }
              this.aniDelayCalls[animId] = [];
          }
          this._animtor.getControllerLayer(0).addState(state);
          this._animStates[animId] = AnimLoadState.Loaded;
      }
      addAniCallback(animId, time, callback, aniLayer = 0) {
          if (this.destroyed)
              return;
          if (!this.callable) {
              this.safeCall(this.addAniCallback, animId, time, callback, aniLayer);
              return;
          }
          if (!this._animtor)
              return;
          let layer = this._animtor.getControllerLayer(aniLayer);
          if (!layer) {
              Logger.error(`model: addAniCallback: find layer${aniLayer} failed`);
              return;
          }
          ;
          let state = layer.getAnimatorState(animId);
          if (!state) {
              if (!this.aniDelayCalls[animId])
                  this.aniDelayCalls[animId] = [];
              this.aniDelayCalls[animId].push({
                  time: time,
                  callback: callback,
              });
              return;
          }
          let script = state.getScript(AnimStateScript);
          if (!script)
              return;
          script.addCallback({
              time: time,
              callback: callback,
          });
      }
      _playAnimOnloaded(animId, transitionDuration, normalizedTime, loop) {
          if (this._curAnimId != animId)
              return;
          if (this.destroyed)
              return;
          if (loop != null) {
              this._animtor.getControllerLayer(0).getAnimatorState(animId).clip.islooping = loop;
          }
          if (!transitionDuration) {
              this._animtor.play(animId, 0, normalizedTime);
          }
          else {
              this._animtor.crossFade(animId, transitionDuration, 0, normalizedTime);
          }
      }
      playAnims(transitionDuration = DEFAULT_TRANSITION_DURATION, animIds, loop) {
          if (!this.callable) {
              this.safeCall(this.playAnims, transitionDuration, animIds, loop);
              return;
          }
          this._loop = loop;
          switch (animIds.length) {
              case 0:
                  return;
              case 1:
                  this._checkAnimAndPlay(animIds[0], transitionDuration, 0, loop);
                  break;
              default:
                  this._animPlayList = animIds.slice(1);
                  this._checkAnimAndPlay(animIds[0], transitionDuration, 0, false);
                  break;
          }
      }
      _onAnimComplete(animId) {
          this._curAnimId = "";
          if (this._animPlayList && this._animPlayList.length > 0) {
              let animId = this._animPlayList.shift();
              this._checkAnimAndPlay(animId, 0.1, 0, this._loop);
              if (this._animPlayList.length == 0)
                  this._animPlayList = null;
          }
      }
      _clearAnimList() {
          this._animPlayList = null;
          this._loop = null;
      }
      simulate(animId, normalizedTime) {
          if (!this.callable) {
              this.safeCall(this.simulate, animId, normalizedTime);
              return;
          }
          this._clearAnimList();
          this._checkAnimAndPlay(animId, 0, normalizedTime, false);
      }
      getSpeed() {
          return this._animtor && this._animtor.speed;
      }
      setSpeed(value) {
          if (this.callable) {
              this._animtor && (this._animtor.speed = value);
          }
          else {
              this.safeCall(this.setSpeed, value);
          }
      }
      safeCall(method, ...ps) {
          if (this.destroyed)
              return;
          if (this._isLoaded) {
              method.apply(this, ps);
          }
          else {
              this.pushDelayCall(method, ps);
          }
      }
      processDelayCalls() {
          let calls = this.delayCalls;
          let len = calls.length;
          if (len > 0) {
              this.delayCalls = [];
              for (let i = 0; i < len; i++) {
                  const item = calls[i];
                  item.method.apply(this, item.params);
              }
          }
      }
      clearDelayCalls() {
          if (this.delayCalls.length > 0)
              this.delayCalls.length = 0;
      }
      pushDelayCall(method, params) {
          this.delayCalls.push({ method: method, params: params });
      }
      callIfLoaded(func) {
          if (this.destroyed)
              return;
          if (this.isLoaded) {
              this.callDelayFunc(func);
          }
          else {
              this.pushDelayCall(this.callDelayFunc, [func]);
          }
      }
      callDelayFunc(func) {
          if (func) {
              func();
          }
      }
      get callable() {
          return this._isLoaded && !this.destroyed;
      }
  }

  class Particle extends Model {
      constructor() {
          super(...arguments);
          this.sourceName = null;
          this.resourceType = RES_TYPE.PREFAB3D;
          this._pss = [];
      }
      onResourceLoaded(res) {
          super.onResourceLoaded(res);
          Particle._findPs(this.resNode, this._pss);
      }
      static _findPs(node, out) {
          for (var i = node.numChildren - 1; i >= 0; i--) {
              var child = node.getChildAt(i);
              if (child.particleSystem) {
                  out.push(child.particleSystem);
              }
              this._findPs(child, out);
          }
      }
      reuse() {
          super.reuse();
      }
      unuse() {
          this.stop();
          this.stopFollow();
          super.unuse();
      }
      dispose() {
          this._pss = null;
          super.dispose();
      }
      play(pos, time, stopDelay, layer) {
          if (this.callable) {
              layer && layer.addChild(this.resNode);
              pos && (this.transform.position = pos);
              for (var i = this._pss.length - 1; i >= 0; i--) {
                  this._pss[i].play();
              }
              if (time) {
                  Laya.timer.once(time * 1000, this, this.stopAndPutback, [stopDelay]);
              }
          }
          else {
              this.safeCall(this.play, pos, time, stopDelay, layer);
          }
      }
      stopAndPutback(delay) {
          if (this.callable) {
              this.stop();
              if (delay) {
                  Laya.timer.once(delay * 1000, this, this.putBack);
              }
              else {
                  this.putBack();
              }
          }
          else {
              this.safeCall(this.stopAndPutback, delay);
          }
      }
      stop() {
          if (this.callable) {
              for (var i = this._pss.length - 1; i >= 0; i--) {
                  this._pss[i].stop();
              }
          }
          else {
              this.safeCall(this.stop);
          }
      }
      putBack() {
          if (this.callable) {
              Global.poolManager.put(this);
          }
          else {
              this.safeCall(this.putBack);
          }
      }
      resetTrail(mode) {
          mode = mode || this.resNode;
          if (mode instanceof Laya.TrailSprite3D) {
              let oldTime = mode.trailFilter.time;
              mode.trailFilter.time = 0;
              Laya.timer.frameOnce(1, mode, function () {
                  mode.trailFilter.time = oldTime;
              });
          }
          for (let i = 0; i < mode.numChildren; i++) {
              let child = mode.getChildAt(i);
              this.resetTrail(child);
          }
      }
      setPlayOnAwake(value) {
          if (!this.callable) {
              return this.safeCall(this.setPlayOnAwake, value);
          }
          for (var i = this._pss.length - 1; i >= 0; i--) {
              this._pss[i].playOnAwake = value;
          }
      }
      simulateParticle(time, restart) {
          if (this.callable) {
              for (var i = this._pss.length - 1; i >= 0; i--) {
                  this._pss[i].simulate(time, restart);
              }
          }
          else {
              this.safeCall(this.simulate, time, restart);
          }
      }
      setCurrentTime(time) {
          if (this.callable) {
              for (var i = this._pss.length - 1; i >= 0; i--) {
                  var emitTime = time - this._pss[i]["_currentTime"];
                  this._pss[i]["_updateParticles"](emitTime);
              }
          }
          else {
              this.safeCall(this.setCurrentTime, time);
          }
      }
      followTarget(target, camera, offsetX = 0, offsetY = 0) {
          if (!this.callable) {
              return this.safeCall(this.followTarget, target, camera, offsetX, offsetY);
          }
          if (target instanceof Laya.Sprite3D) {
              this._target3D = target;
          }
          else {
              this._target = target;
              this._camera = camera;
              this._offsetX = offsetX;
              this._offsetY = offsetY;
          }
          Laya.timer.frameLoop(1, this, this.updateFollow, null, true);
          this.updateFollow();
      }
      followScale(value) {
          if (this.callable) {
              this._bScale = value;
          }
          else {
              this.safeCall(this.followScale, value);
          }
      }
      stopFollow() {
          if (!this.callable) {
              return this.safeCall(this.stopFollow);
          }
          this._target = null;
          this._target3D = null;
          this._camera = null;
          this._bScale = false;
          Laya.timer.clearAll(this);
      }
      updateFollow() {
          if (this._target) {
              if (this._target.isDisposed || this._camera.destroyed) {
                  this.stopAndPutback();
              }
              else {
                  this.align(this._target, this._camera);
              }
          }
          else {
              if (this._target3D.destroyed) {
                  this.stopAndPutback();
              }
              else {
                  this.align3D(this._target3D);
              }
          }
      }
      align(target, camera) {
          let p0 = Particle._TEMP_P;
          let p1 = Particle._TEMP_VEC3;
          UITools.getSelfGlobalPos(target, p0);
          p1.setValue(p0.x, p0.y, 0);
          camera.convertScreenCoordToOrthographicCoord(p1, p1);
          this.transform.position = p1;
      }
      align3D(target) {
          let p1 = Particle._TEMP_VEC3;
          target.transform.position.cloneTo(p1);
          this.transform.position = p1;
          if (this._bScale) {
              this.transform.localScale = target.transform.localScale;
          }
      }
  }
  Particle._TEMP_P = new Laya.Point();
  Particle._TEMP_VEC3 = new Laya.Vector3();

  class mgrTip extends Manager {
      static onLoad() {
          Global.require("ViewTipItem").init();
          super.onLoad();
      }
      static playEffect(effectId, pos, time, stopDelay) {
          let effect = Global.poolManager.get(Particle, effectId);
          return effect;
      }
      static showMsgTip(text) {
          Global.sendMsg(BASE_MSG.UI_SHOW_TIP, text);
      }
      static alertPrompt(desc, title, onConfirm, onCancel, confirmText, cancelText) {
          let context;
          if (typeof desc === "string") {
              context = {
                  desc: desc,
                  title: title,
                  confirm: onConfirm,
                  cancel: onCancel,
                  confirmText: confirmText,
                  cancelText: cancelText,
              };
          }
          else {
              context = desc;
          }
          Director.openPanel("PanelDialog", context);
      }
      static alertTip(desc, title, confirmText) {
          Director.openPanelWithSingleton("PanelDialogTip", { title: title || "提示", desc: desc, confirmText: confirmText || "确定" });
      }
      static alertNotEnough(itemId, bShowMsg = true) {
          if (bShowMsg) {
              let itemDb = db.get_item_db(itemId);
              this.showMsgTip(`${itemDb.name}不足~`);
          }
      }
      static alertItemsByText(items, callback) {
          let str = "";
          if (items instanceof Array) {
              for (let i = 0; i < items.length; i++) {
                  const item = items[i];
                  let itemDb = db.get_item_db(item.itemId);
                  if (i == 0) {
                      str = `获得${itemDb.name}x${item.count}`;
                  }
                  else {
                      str = `${str}, 获得${itemDb.name}x${item.count}`;
                  }
              }
          }
          else {
              let itemDb = db.get_item_db(items.itemId);
              str = `获得${itemDb.name}x${items.count}`;
          }
          this.showMsgTip(str);
          callback && callback();
      }
      static alertSingleItem(item, bAdv = true, onClose) {
          Director.openPanelByWait("PanelItemGet", { items: [{ data: item }], bAdv: bAdv, onClose: onClose });
      }
      static alertItems(items, bAdv = true, onClose) {
          if (!items)
              return;
          let item;
          if (items instanceof Array) {
              if (items.length == 0) {
                  onClose && onClose();
                  return;
              }
              if (items.length == 1) {
                  item = items[0];
              }
              else {
                  let idx = 0;
                  var alertItem = () => {
                      this.alertSingleItem(items[idx++], bAdv, function () {
                          Laya.timer.frameOnce(1, this, function () {
                              if (idx < items.length) {
                                  alertItem();
                              }
                              else {
                                  onClose && onClose();
                              }
                          });
                      });
                  };
                  alertItem();
                  return;
              }
          }
          else {
              item = items;
          }
          let itemDb = db.get_item_db(item.itemId);
          switch (itemDb.type) {
              case 2:
                  this.alertSingleItem(item, bAdv, onClose);
                  break;
              case 1:
                  this.alertSingleItem(item, bAdv, onClose);
                  break;
              default:
                  this.alertSingleItem(item, bAdv, onClose);
                  break;
          }
      }
      static alertItemFromNode(items, node) {
          let item;
          if (items instanceof Array) {
              if (items.length == 0)
                  return;
              if (items.length == 1) {
                  item = items[0];
              }
              else {
                  return;
              }
          }
          else {
              item = items;
          }
          let p = UITools.getSelfGlobalPos(node, Laya.Point.TEMP);
          return this.playItemToCurrency(item.itemId, p, 10);
      }
      static initCurrencyIconPosition(coinPos, diamondPos, vitPos) {
          this.uiCoinPos = coinPos;
          this.uiVitPos = vitPos;
          this.uiDiamondPos = diamondPos;
      }
      static playItemToCurrency(itemId, worldPos, count) {
          let itemDb = db.get_item_db(itemId);
          switch (itemId) {
              case 1001:
                  return this.playIconTo(worldPos, count, itemDb.icon, this.uiCoinPos, 0.42, true);
              case 1000:
                  return this.playIconTo(worldPos, count, itemDb.icon, this.uiDiamondPos, 0.42, true);
              case 1002:
                  return this.playIconTo(worldPos, count, itemDb.icon, this.uiVitPos, 0.42, true);
              default:
                  break;
          }
      }
      static playIconTo(worldPos, count = 2, view, toPos, scale = 0.5, rndFly = false) {
      }
  }

  let systemConsole = console;
  var ULLog$1;
  (function (ULLog) {
      class console {
          static info(...data) {
              if (ULLog.console.allowConsole) {
                  systemConsole.info(...data);
              }
          }
          static log(...data) {
              if (ULLog.console.allowConsole) {
                  systemConsole.log(...data);
              }
          }
          static warn(...data) {
              if (ULLog.console.allowConsole) {
                  systemConsole.warn(...data);
              }
          }
          static error(...data) {
              if (ULLog.console.allowConsole) {
                  systemConsole.error(...data);
              }
          }
      }
      console.allowConsole = true;
      ULLog.console = console;
  })(ULLog$1 || (ULLog$1 = {}));
  window["ULLog"] = ULLog$1;

  class ULEventListener {
      constructor(type, priority, callback, bDispatchOnce) {
          this.type = type;
          this.priority = priority;
          this.callback = callback;
          this.bDispatchOnce = bDispatchOnce;
          this.bNeedRemove = false;
      }
      isDispatchOnce() {
          return !!this.bDispatchOnce;
      }
      isNeedRemove() {
          return !!this.bNeedRemove;
      }
      markNeedRemove() {
          this.bNeedRemove = true;
      }
      triggerCallback(event) {
          if (this.callback instanceof Function) {
              try {
                  this.callback(event);
              }
              catch (error) {
                  ULLog.console.error("ULEventListener.triggerCallback has exception!", error.stack);
                  return false;
              }
              return true;
          }
          return false;
      }
  }

  class ULEvent {
      constructor(type, data) {
          this.bPropagationStoped = false;
          this.type = type;
          this.data = data;
          this.bPropagationStoped = false;
          this.returnValue = null;
      }
      stopImmediatePropagation() {
          this.bPropagationStoped = true;
      }
      setReturnValue(value, bDonotStop) {
          if (value != null) {
              this.returnValue = value;
              if (!bDonotStop)
                  this.stopImmediatePropagation();
          }
      }
      getReturnValue() {
          return this.returnValue;
      }
      isPropagationStoped() {
          return !!this.bPropagationStoped;
      }
  }

  class ULConst {
  }
  ULConst.CMD_GET_BASE_CHANNEL_INFO = "/c/getBaseChannelInfo";
  ULConst.CMD_SET_VERSION = "/c/setVersion";
  ULConst.CMD_END_USER_GUIDE = "/c/endUserGuide";
  ULConst.CMD_OPEN_MORE_GAME = "/c/openMoreGame";
  ULConst.CMD_OPEN_UL_MORE_GAME = "/c/openUlMoreGame";
  ULConst.CMD_OPEN_PAY = "/c/openPay";
  ULConst.CMD_OPEN_JF = "/c/openJf";
  ULConst.CMD_OPEN_SHARE = "/c/openShare";
  ULConst.CMD_CALL_PHONE = "/c/callPhone";
  ULConst.CMD_UL_WEB_VIEW = "/c/ulWebView";
  ULConst.CMD_EXIT_GAME = "/c/exitGame";
  ULConst.CMD_MEGADATA_SERVER = "/c/megadataServer";
  ULConst.CMD_POST_MEGADATA = "/c/postMegadata";
  ULConst.CMD_USE_CDKEY = "/c/useCdkey";
  ULConst.CMD_CHECK_TIME_CHANGE = "/c/checkTimeChange";
  ULConst.CMD_OPEN_ADV = "/c/openAdv";
  ULConst.CMD_CLICK_NATIVE_ADV = "/c/clickNativeAdv";
  ULConst.CMD_CLOSE_ADV = "/c/closeAdv";
  ULConst.CMD_CLOSE_NATIVE_ADV = "/c/closeNativeAdv";
  ULConst.CMD_USER_LOGIN = "/c/userLogin";
  ULConst.CMD_USER_LOGIN_REPORT = "/c/userLoginReport";
  ULConst.CMD_USER_IS_LOGIN = "/c/userIsLogin";
  ULConst.CMD_LOGIN_OUT = "/c/loginOut";
  ULConst.CMD_SAVE_RANK_DATA = "/c/saveRankData";
  ULConst.CMD_GET_RANK_DATA = "/c/getRankData";
  ULConst.CMD_GET_HEADLINE_IMRANK_DATA = "/c/getHeadlineIMRankData";
  ULConst.CMD_SET_HEADLINE_IMRANK_DATA = "/c/setHeadlineIMRankData";
  ULConst.CMD_RECORDER_GAME_VIDEO = "/c/recorderGameVideo";
  ULConst.CMD_SHARE_GAME_VIDEO = "/c/shareGameVideo";
  ULConst.CMD_OPEN_JUMP = "/c/openJump";
  ULConst.CMD_JUMP_OTHER_GAME = "/c/jumpOtherGame";
  ULConst.CMD_OPEN_RECOMMENDATION = "/c/openRecommendation";
  ULConst.CMD_CLOSE_RECOMMENDATION = "/c/closeRecommendation";
  ULConst.CMD_SAVE_USER_DATA = "/c/saveUserData";
  ULConst.CMD_GET_USER_DATA = "/c/getUserData";
  ULConst.CMD_ADD_GAME_TO_MY_FAVORITE = "/c/addGameToMyFavorite";
  ULConst.CMD_GET_USER_INFO_MSG = "/c/getUserInfoMsg";
  ULConst.CMD_OPEN_USERINFO_ACCREDIT_BUTTON = "/c/openUserInfoAccreditButton";
  ULConst.CMD_CLOSE_USERINFO_ACCREDIT_BUTTON = "/c/closeUserInfoAccreditButton";
  ULConst.CMD_INSTALL_SHORTCUT = "/c/installShortcut";
  ULConst.CMD_SET_CLIPBOARD_DATA = "/c/setClipboardData";
  ULConst.CMD_GET_CLIPBOARD_DATA = "/c/getClipboardData";
  ULConst.CMD_SET_ULSDKDEMO_DEBUG_MODE = "/c/setUlsdkdemoDebugMode";
  ULConst.CMD_MPSDK_AD_HANDLER = '/c/mpsdkAdHandler';
  ULConst.CMD_CREATE_GAME_ICON = '/c/createGameIcon';
  ULConst.CMD_GAME_ICON_HANDLER = '/c/gameIconHandler';
  ULConst.CMD_OPEN_CHANNEL_MORE_GAME_BOX = '/c/openChannelMoreGameBox';
  ULConst.CMD_OPEN_BLOCK_AD = '/c/openBlockAd';
  ULConst.CMD_CLOSE_BLOCK_AD = '/c/closeBlockAd';
  ULConst.CMD_GET_SHORTCUT_STATE = '/c/getShortcutState';
  ULConst.CMD_GET_SUBSCRIBE_STATE = "/c/getSubscribeState";
  ULConst.CMD_ADD_SUBSCRIBE = "/c/addSubscribe";
  ULConst.CMD_ADD_COLOR_SIGN = '/c/addColorSign';
  ULConst.CMD_OPEN_GRID_AD = '/c/openGridAd';
  ULConst.CMD_CLOSE_GRID_AD = '/c/closeGridAd';
  ULConst.CMD_JUMP_TO_VIDEO_VIEW = '/c/jumpToVideoView';
  ULConst.CMD_FOLLOW_OFFICIAL_ACCOUNT = '/c/followOfficialAccount';
  ULConst.CMD_GET_FOLLOW_OFFICIAL_ACCOUNT_STATE = '/c/getFollowOfficialAccountState';
  ULConst.CMD_CONTENT_SECURITY_CHECK = '/c/contentSecurityCheck';
  ULConst.CMD_JUMP_LEISURE_SUBJECT = '/c/jumpLeisureSubject';
  ULConst.CMD_PHONE_VIBRATE = '/c/phoneVibrate';
  ULConst.CMD_OPEN_URL = '/c/openUrl';
  ULConst.CMD_SHOW_CHANNEL_MASK = '/c/showChannelMask';
  ULConst.CMD_CLOSE_CHANNEL_MASK = '/c/closeChannelMask';
  ULConst.CMD_SHOW_PRIVACY = '/c/showPrivacy';
  ULConst.CMD_OPEN_ADVANCED_SETTING = '/c/openAdvancedSetting';
  ULConst.CMD_GET_OPENDATA_CANVAS = '/c/getOpenDataCanvas';
  ULConst.CMD_SET_USER_CLOUD_STORAGE = '/c/setUserCloudStorage';
  ULConst.CMD_GET_USER_CLOUD_STORAGE = '/c/getUserCloudStorage';
  ULConst.CMD_GET_JOIN_GROUP_NUM = "/c/getJoinGroupNum";
  ULConst.CMD_JOIN_GROUP = "/c/joinGroup";
  ULConst.CMD_RANKLIST_GET_USER_NUM = "/c/getUserNumInRank";
  ULConst.CMD_RANKLIST_GET_USER_INFO_BY_ID = "/c/getUserInfoByIdInRank";
  ULConst.CMD_RANKLIST_GET_USER_INFO_BY_LIST = "/c/getUserInfoListByRankId";
  ULConst.CMD_RANKLIST_REPORT_USER_INFO = "/c/reportUserInfoInRank";
  ULConst.CMD_RANKLIST_MODIFY_SCORE_BY_ARRAY = "/c/modifyScoreByArray";
  ULConst.CMD_CHANNEL_INFO_RESULT = "/c/channelInfoResult";
  ULConst.CMD_GET_BASE_CHANNEL_INFO_RESULT = "/c/getBaseChannelInfoResult";
  ULConst.CMD_PAY_RESULT = "/c/payResult";
  ULConst.CMD_PRE_PAY_RESULT = "/c/prePayResult";
  ULConst.CMD_SHARE_RESULT = "/c/shareResult";
  ULConst.CMD_LIFE_CYCLE_RESULT = "/c/lifeCycle";
  ULConst.CMD_PAUSE_SOUND_RESULT = "/c/pauseSound";
  ULConst.CMD_RESUME_SOUND_RESULT = "/c/resumeSound";
  ULConst.CMD_COP_INFO_RESULT = "/c/copInfoResult";
  ULConst.CMD_MEGADATA_SERVER_RESULT = "/c/megadataServer";
  ULConst.CMD_POST_MEGADATA_RESULT = "/c/postMegadataResult";
  ULConst.CMD_USE_CDKEY_RESULT = "/c/useCdkey";
  ULConst.CMD_CHECK_TIME_CHANGE_RESULT = "/c/checkTimeChangeResult";
  ULConst.CMD_OPEN_ADV_RESULT = "/c/openAdvResult";
  ULConst.CMD_OPEN_NATIVE_ADV_RESULT = "/c/openNativeAdvResult";
  ULConst.CMD_CLICK_NATIVE_ADV_RESULT = "/c/clickNativeAdvResult";
  ULConst.CMD_CLICK_ADV_RESULT = "/c/clickAdvResult";
  ULConst.CMD_CLOSE_ADV_RESULT = "/c/closeAdvResult";
  ULConst.CMD_CLOSE_NATIVE_ADV_RESULT = "/c/closeNativeAdvResult";
  ULConst.CMD_USER_LOGIN_RESULT = "/c/userLoginResult";
  ULConst.CMD_USER_IS_LOGIN_RESULT = "/c/userIsLoginResult";
  ULConst.CMD_USER_LOGIN_REPORT_RESULT = "/c/userLoginReportResult";
  ULConst.CMD_LOGIN_OUT_RESULT = "/c/loginOutResult";
  ULConst.CMD_SHOW_PRIVACY_RESULT = '/c/showPrivacyResult';
  ULConst.CMD_ADV_VALID_COUNT_RESULT = "/c/advValidCountResult";
  ULConst.CMD_SAVE_RANK_DATA_RESULT = "/c/saveRankDataResult";
  ULConst.CMD_GET_RANK_DATA_RESULT = "/c/getRankDataResult";
  ULConst.CMD_GET_HEADLINE_IMRANK_DATA_RESULT = "/c/getHeadlineIMRankDataResult";
  ULConst.CMD_SET_HEADLINE_IMRANK_DATA_RESULT = "/c/setHeadlineIMRankDataResult";
  ULConst.CMD_RECORDER_GAME_VIDEO_RESULT = "/c/recorderGameVideoResult";
  ULConst.CMD_SHARE_GAME_VIDEO_RESULT = "/c/shareGameVideoResult";
  ULConst.CMD_OPEN_JUMP_RESULT = "/c/openJumpResult";
  ULConst.CMD_JUMP_OTHER_GAME_RESULT = "/c/jumpOtherGameResult";
  ULConst.CMD_JUMP_OTHER_GAME_REWARD_RESULT = "/c/jumpOtherGameRewardResult";
  ULConst.CMD_EXTRA_BONUS_RESULT = "/c/extraBonus";
  ULConst.CMD_OPEN_RECOMMENDATION_RESULT = "/c/openRecommendationResult";
  ULConst.CMD_CLOSE_RECOMMENDATION_RESULT = "/c/closeRecommendationResult";
  ULConst.CMD_SAVE_USER_DATA_RESULT = "/c/saveUserDataResult";
  ULConst.CMD_GET_USER_DATA_RESULT = "/c/getUserDataResult";
  ULConst.CMD_ADD_GAME_TO_MY_FAVORITE_RESULT = "/c/addGameToMyFavoriteResult";
  ULConst.CMD_GET_USER_INFO_MSG_RESULT = "/c/getUserInfoMsgResult";
  ULConst.CMD_OPEN_USERINFO_ACCREDIT_BUTTON_RESULT = "/c/openUserInfoAccreditButtonResult";
  ULConst.CMD_CLOSE_USERINFO_ACCREDIT_BUTTON_RESULT = "/c/closeUserInfoAccreditButtonResult";
  ULConst.CMD_APP_SHARE_RESULT = "/c/appShareResult";
  ULConst.CMD_INSTALL_SHORTCUT_RESULT = "/c/installShortcutResult";
  ULConst.CMD_SET_CLIPBOARD_DATA_RESULT = "/c/setClipboardDataResult";
  ULConst.CMD_GET_CLIPBOARD_DATA_RESULT = "/c/getClipboardDataResult";
  ULConst.CMD_MPSDK_AD_HANDLER_RESULT = '/c/mpsdkAdHandlerResult';
  ULConst.CMD_CREATE_GAME_ICON_RESULT = '/c/createGameIconResult';
  ULConst.CMD_GAME_ICON_HANDLER_RESULT = '/c/gameIconHandlerResult';
  ULConst.CMD_OPEN_CHANNEL_MORE_GAME_BOX_RESULT = '/c/openChannelMoreGameBoxResult';
  ULConst.CMD_OPEN_BLOCK_AD_RESULT = '/c/openBlockAdResult';
  ULConst.CMD_CLOSE_BLOCK_AD_RESULT = '/c/closeBlockAdResult';
  ULConst.CMD_GET_SHORTCUT_STATE_RESULT = '/c/getShortcutStateResult';
  ULConst.CMD_GET_SUBSCRIBE_STATE_RESULT = "/c/getSubscribeStateResult";
  ULConst.CMD_ADD_SUBSCRIBE_RESULT = "/c/addSubscribeResult";
  ULConst.CMD_ADD_COLOR_SIGN_RESULT = '/c/addColorSignResult';
  ULConst.CMD_OPEN_GRID_AD_RESULT = '/c/openGridAdResult';
  ULConst.CMD_CLOSE_GRID_AD_RESULT = '/c/closeGridAdResult';
  ULConst.CMD_JUMP_TO_VIDEO_VIEW_RESULT = '/c/jumpToVideoViewResult';
  ULConst.CMD_FOLLOW_OFFICIAL_ACCOUNT_RESULT = '/c/followOfficialAccountResult';
  ULConst.CMD_GET_FOLLOW_OFFICIAL_ACCOUNT_STATE_RESULT = '/c/getFollowOfficialAccountStateResult';
  ULConst.CMD_CONTENT_SECURITY_CHECK_RESULT = '/c/contentSecurityCheckResult';
  ULConst.CMD_JUMP_LEISURE_SUBJECT_RESULT = '/c/jumpLeisureSubjectResult';
  ULConst.CMD_PHONE_VIBRATE_RESULT = '/c/phoneVibrateResult';
  ULConst.CMD_JUMP_NEW_USER_GUIDE = '/c/jumpNewGuide';
  ULConst.CMD_CHECKDEBUG_WHITEUSER_RESULT = '/c/checkDebugWhiteUserResult';
  ULConst.CMD_OPEN_URL_RESULT = '/c/openUrlResult';
  ULConst.CMD_CLEAN_UP_GAME_ARCHIVE = '/c/cleanUpGameArchive';
  ULConst.CMD_SHOW_POINT_DEBUG_INFO = '/c/showPointDebugInfo';
  ULConst.CMD_CHECK_LAUNCH_REWARD = "/sdk/checkLaunchReward";
  ULConst.CMD_SET_USER_CLOUD_STORAGE_RESULT = '/c/setUserCloudStorageResult';
  ULConst.CMD_GET_USER_CLOUD_STORAGE_RESULT = '/c/getUserCloudStorageResult';
  ULConst.CMD_GET_JOIN_GROUP_NUM_RESULT = "/c/getJoinGroupNumResult";
  ULConst.CMD_JOIN_GROUP_RESULT = "/c/joinGroupResult";
  ULConst.CMD_LAUNCH_REWARD_RESULT = "/c/launchRewardResult";
  ULConst.CMD_MOYANG_QQ_NET_EARNED_QUERY = "/c/qqNetEarnedQuery";
  ULConst.CMD_MOYANG_QQ_NET_EARNED_RECHARGE = "/c/qqNetEarnedRecharge";
  ULConst.CMD_MOYANG_QQ_NET_EARNED_CASH = "/c/qqNetEarnedCash";
  ULConst.CMD_MOYANG_QQ_NET_EARNED_QUERY_RESULT = "/c/qqNetEarnedQueryResult";
  ULConst.CMD_MOYANG_QQ_NET_EARNED_RECHARGE_RESULT = "/c/qqNetEarnedRechargeResult";
  ULConst.CMD_MOYANG_QQ_NET_EARNED_CASH_RESULT = "/c/qqNetEarnedCashResult";
  ULConst.CMD_RANKLIST_GET_USER_NUM_RESULT = "/c/getUserNumInRankResult";
  ULConst.CMD_RANKLIST_GET_USER_INFO_BY_ID_RESULT = "/c/getUserInfoByIdInRankResult";
  ULConst.CMD_RANKLIST_GET_USER_INFO_BY_LIST_RESULT = "/c/getUserInfoListByRankIdResult";
  ULConst.CMD_RANKLIST_REPORT_USER_INFO_RESULT = "/c/reportUserInfoInRankResult";
  ULConst.CMD_RANKLIST_MODIFY_SCORE_BY_ARRAY_RESULT = "/c/modifyScoreByArrayResult";
  ULConst.CMD_GET_OPENDATA_CANVAS_RESULT = '/c/getOpenDataCanvasResult';
  ULConst.CMD_SDK_ON_COP_CHANGED = "/sdk/onCopChanged";
  ULConst.CMD_SDK_PREPARE_SHOW_VIDEO_ADV = "/sdk/prepareShowVideoAdv";
  ULConst.CMD_SDK_PREPARE_SHOW_INTER_ADV = "/sdk/prepareShowInterAdv";
  ULConst.CMD_SDK_PREPARE_SHOW_BANNER_ADV = "/sdk/prepareShowBannerAdv";
  ULConst.CMD_SDK_PREPARE_SHOW_EMBEDDED_ADV = "/sdk/prepareShowEmbeddedAdv";
  ULConst.CMD_SDK_PREPARE_SHOW_URL_ADV = "/sdk/prepareShowUrlAdv";
  ULConst.CMD_SDK_PREPARE_SHOW_PASTER_ADV = "/sdk/prepareShowPasterAdv";
  ULConst.CMD_SDK_SHOW_VIDEO_ADV = "/sdk/showVideoAdv";
  ULConst.CMD_SDK_SHOW_INTER_ADV = "/sdk/showInterAdv";
  ULConst.CMD_SDK_SHOW_BANNER_ADV = "/sdk/showBannerAdv";
  ULConst.CMD_SDK_SHOW_EMBEDDED_ADV = "/sdk/showEmbeddedAdv";
  ULConst.CMD_SDK_SHOW_URL_ADV = "/sdk/showUrlAdv";
  ULConst.CMD_SDK_SHOW_PASTER_ADV = "/sdk/showPasterAdv";
  ULConst.CMD_SDK_CLOSE_VIDEO_ADV = "/sdk/closeVideoAdv";
  ULConst.CMD_SDK_CLOSE_INTER_ADV = "/sdk/closeInterAdv";
  ULConst.CMD_SDK_CLOSE_BANNER_ADV = "/sdk/closeBannerAdv";
  ULConst.CMD_SDK_CLOSE_EMBEDDED_ADV = "/sdk/closeEmbeddedAdv";
  ULConst.CMD_SDK_CLOSE_URL_ADV = "/sdk/closeUrlAdv";
  ULConst.CMD_SDK_CLOSE_Paster_ADV = "/sdk/closePasterAdv";
  ULConst.CMD_SDK_CLOSE_NATIVE_ADV = "/sdk/closeNativeAdv";
  ULConst.CMD_SDK_CLICK_NATIVE_ADV = "/sdk/clickNativeAdv";
  ULConst.CMD_SDK_GET_STORAGE = "/sdk/getStorge";
  ULConst.CMD_SDK_SET_STORAGE = "/sdk/setStorge";
  ULConst.CMD_SDK_GET_CLIPBOARD_DATA = "/sdk/getClipboardData";
  ULConst.CMD_SDK_SET_CLIPBOARD_DATA = "/sdk/setClipboardData";
  ULConst.CMD_SDK_IS_SUPPORT_CLIPBOARD = "/sdk/isSupportClipboard";
  ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG = "/sdk/collectionModuleCheckerConfig";
  ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_MORE_GAME_AB_TEST_CONFIG = "/sdk/collectionModuleCheckerMoreGameAbTestConfig";
  ULConst.CMD_SDK_ON_GAME_START = "/sdk/onGameStart";
  ULConst.CMD_SDK_ON_GAME_PAUSE = "/sdk/onGamePause";
  ULConst.CMD_SDK_ON_GAME_RESUME = "/sdk/onGameResume";
  ULConst.CMD_SDK_ON_SHARE_SHOW = "/sdk/onShareShow";
  ULConst.CMD_SDK_ON_SAHRE_APP_MESSAGE = "/sdk/onShareAppMessage";
  ULConst.CMD_SDK_ON_REPORT_ULSDK_EVENT = "/sdk/ulsdkMegadataUpload";
  ULConst.CMD_SDK_OPEN_SHARE_DURING_ADV = "/sdk/openShareDuringAdv";
  ULConst.CMD_SDK_CHANNEL_MEGADATA_POST = "/sdk/channelMegadataPost";
  ULConst.CMD_SDK_SET_UP_WEBVIEW_JAVASCRIPT_BRIDGE = "/sdk/setUpWebViewJavascriptBridge";
  ULConst.CMD_SDK_EXPRESS_NATIVE_ADV_STATUS_CHANGE = "/sdk/expressNativeAdvStatusChange";
  ULConst.CMD_MOYANG_QQ_REWARD_VIDEO_PLAY = "/sdk/moyangQQRewardVideoPlay";
  ULConst.CMD_MOYANG_QQ_REWARD_VIDEO_CLOSE = "/sdk/moyangQQRewardVideoClose";
  ULConst.CMD_FACEBOOK_INIT_COMPLETE = "/sdk/facebookInitComplete";
  ULConst.CMD_WXOCEANENGINE_PAY_SUCCESS = "/sdk/wxOceanEnginePaySuccess";
  ULConst.CMD_HUAWEI_BUYQUANTITY_PLAY_VIDEOAD = "/sdk/HuaweiBuyQuantityPlayVideoAd";
  ULConst.CMD_HUAWEI_BUYQUANTITY_PAY_SUCCESS = "/sdk/HuaweiBuyQuantityPaySuccess";
  ULConst.CMD_WEIXIN_BUYQUANTITY_PLAY_VIDEOAD = "/sdk/weixinBuyQuantityPlayVideoAd";
  ULConst.CMD_WEIXIN_BUYQUANTITY_PAY_SUCCESS = "/sdk/weixinBuyQuantityPaySuccess";
  ULConst.CMD_HEADLINE_BUYQUANTITY_PLAY_VIDEOAD = "/sdk/headlineBuyQuantityPlayVideoAd";
  ULConst.CMD_HEADLINE_BUYQUANTITY_STARTPLAY_VIDEOAD = "/sdk/headlineBuyQuantityStartPlayVideoAd";
  ULConst.CMD_HEADLINE_BUYQUANTITY_PAY_SUCCESS = "/sdk/headlineBuyQuantityPaySuccess";
  ULConst.CMD_SDK_COMMONEVENT_ID_POST = "/sdk/commonEventIdPost";
  ULConst.CMD_SDK_LEVELCOMPLETEEVENT_ID_POST = "/sdk/levelCompleteEventIdPost";
  ULConst.CMD_SDK_INIT_USER_LOGIN = "/sdk/initUserLogin";
  ULConst.CMD_SDK_QM_LOGIN_REPORT = "/qmsdk/loginReport";
  ULConst.CMD_SDK_QM_REPORT_EVENT = "/qmsdk/reportEvent";
  ULConst.CMD_SDK_QM_REPORT_GOLD = "/qmsdk/reportGold";
  ULConst.CMD_SDK_QM_SET_ACCOUNT_INFO = "/qmsdk/setAccountInfo";
  ULConst.CMD_SDK_QM_GET_OPEN_LEVEL = "/qmsdk/getOpenLevel";
  ULConst.CMD_SDK_QM_GET_RECOMMEND_INFO = "/qmsdk/getRecommendInfo";
  ULConst.CMD_SDK_QM_GET_SUGGEST_LIST = "/qmsdk/getSuggestList";
  ULConst.CMD_SDK_QM_GET_EXCITATION_LIST = "/qmsdk/getExcitationList";
  ULConst.CMD_SDK_QM_MPSDK_AD_CLICK = "/qmsdk/mpsdkAdClick";
  ULConst.CMD_SDK_QM_MPSDK_CLICK_SYNC = "/qmsdk/mpsdkClickSync";
  ULConst.CMD_SDK_QM_GET_USER_DATA_VERSION = "/qmsdk/getUserDataVersion";
  ULConst.CMD_SDK_QM_IS_STRONG_FISSION = "/qmsdk/isStrongFission";
  ULConst.CMD_SDK_QM_REPORT_VIDEO_TIME_EVENT = "/qmsdk/reportVideoTimeEvent";
  ULConst.CMD_SDK_OPPOQG_MARK_MANUAL_CLOSE_BANNER_COUNT = "/sdk/oppoqg/markManualCloseBannerCount";
  ULConst.CMD_SDK_OPPOQG_GET_MANUAL_CLOSE_BANNER_COUNT = "/sdk/oppoqg/getManualCloseBannerCount";
  ULConst.CMD_SDK_OPPOQG_HAS_BANNER_SHOWING = "/sdk/oppoqg/hasBannerShowing";
  ULConst.PRIORITY_DISABLE = -2;
  ULConst.PRIORITY_NONE = -1;
  ULConst.CONSOLE_OUTPUT_LEVEL_WARN = 1;
  ULConst.CONSOLE_OUTPUT_LEVEL_ERROR = 1;
  ULConst.CONSOLE_OUTPUT_LEVEL_LOG = 2;
  ULConst.CONSOLE_OUTPUT_LEVEL_INNER_DEBUG = 3;
  ULConst.B_INNER_DEBUG = false;
  ULConst.COP_RETRY_TIME_SEC = 30;
  ULConst.STATIS_TYPE_BASE_INFO = "1";
  ULConst.STATIS_TYPE_PAY_INFO = "2";
  ULConst.STATIS_TYPE_ADV_INFO = "3";
  ULConst.STATIS_TYPE_COP_REQUEST = "4";
  ULConst.STATIS_TYPE_USER_EVENT = "5";
  ULConst.STATIS_TYPE_ONLINE_TIME = "6";
  ULConst.STATIS_TYPE_POINT_EVENT = "7";
  ULConst.STATIS_TYPE_COIN_CHANGE_EVENT = "5";
  ULConst.STATIS_TYPE_COMMON_EVENT = "7";
  ULConst.STATIS_TYPE_LEVEL_START_EVENT = "8";
  ULConst.STATIS_TYPE_LEVEL_COMPLETE_EVENT = "9";
  ULConst.STATIS_TYPE_ITEM_BUY = "10";
  ULConst.STATIS_TYPE_BUY_ACTION = "11";
  ULConst.STATIS_TYPE_VIDEO_POINT_EVENT = "12";
  ULConst.STATIS_TYPE_USER_MESSAGE = "14";
  ULConst.DEFAULT_REFERANCE_BANNER_HEIGHT = 200;
  ULConst.STATIS_USER_EVENT_GAME_LEVEL_START = "gameLevelStart";
  ULConst.STATIS_USER_EVENT_GAME_LEVEL_COMPLETE = "gameLevelComplete";
  ULConst.STATIS_USER_EVENT_GAME_COIN_ADD = "gameCoinAdd";
  ULConst.STATIS_USER_EVENT_GAME_COIN_LOST = "gameCoinLost";
  ULConst.STATIS_USER_EVENT_BUY_ACTION = "buyAction";
  ULConst.STATIS_USER_EVENT_ITEM_BUY = "itemBuy";
  ULConst.STATIS_USER_EVENT_COMMON_EVENT = "commonEvent";
  ULConst.STATIS_USER_EVENT_COMMON_EVENT_MULTI_FIELD = "commonEventMultiField";
  ULConst.STATIS_USER_EVENT_POINT_EVENT = "pointEvent";
  ULConst.STATIS_USER_ACTION_EVENT_LEVEL_START = "levelStart";
  ULConst.STATIS_USER_ACTION_EVENT_LEVEL_COMPLETE = "levelComplete";
  ULConst.STATIS_USER_ACTION_EVENT_COIN_CHANGE = "coinChange";
  ULConst.STATIS_USER_ACTION_EVENT_ITEM_BUY = "itemBuy";
  ULConst.STATIS_USER_ACTION_EVENT_BUY_ACTION = "buyAction";
  ULConst.STATIS_USER_ACTION_EVENT_COMMON_EVENT = "commonEvent";
  ULConst.STATIS_USER_ACTION_EVENT_VIDEO_POINT_EVENT = "videoPointEvent";
  ULConst.STATIS_UPLOAD_SPAN = 60;
  ULConst.STATIS_UPLOAD_SINGLE_REQUEST_MAX_COUNT = 100;
  ULConst.ADV_FAIL_TIP_NOAD = "暂时无法播放广告，请稍后再试";
  ULConst.ADV_FAIL_TIP_BUSY = "广告准备中，请稍后再试";
  ULConst.ENGLISH_ADV_FAIL_TIP_NOAD = "Ad display failed, please retry later.";
  ULConst.ENGLISH_ADV_FAIL_TIP_BUSY = "Ad in preparation, please retry later.";
  ULConst.ADV_ERR_CODE_CONSECUTIVE_FAIL = -100;
  ULConst.ADV_ERR_CODE_CDING = -101;
  ULConst.ADV_ERR_CODE_NATIVE_ID_ERROR = -102;
  ULConst.ADV_ERR_CODE_NATIVE_DATA_ERROR = -102;
  ULConst.ADV_ERR_CODE_CAN_NOT_PLAY = -103;
  ULConst.ADV_ERR_CODE_NOT_INITED = -104;
  ULConst.ADV_ERR_CODE_UNKNOWN = -105;
  ULConst.ADV_ERR_CODE_SHARE_NO_CALLBACK = -106;
  ULConst.ADV_ERR_CODE_SHARE_FAIL = -107;
  ULConst.ADV_ERR_CODE_ADOBJ_NULL = -108;
  ULConst.ADV_ERR_CODE_ADV_TYPE_CD = -109;
  ULConst.ADV_ERR_CODE_ADV_TYPE_DAILY_LIMIT = -110;
  ULConst.ADV_PRELOAD_STATE_READY = 1;
  ULConst.ADV_PRELOAD_STATE_LOADING = 2;
  ULConst.ADV_PRELOAD_STATE_NOAD = 3;
  ULConst.ADV_RESULT_CODE_SUCCESS = 1;
  ULConst.ADV_RESULT_CODE_FAILED = 0;
  ULConst.ADV_RESULT_CODE_OBSOLETE = 2;
  ULConst.ADV_MUST_DEFAULT_WEIGHT = 100;
  ULConst.ADV_RANDOM_DEFAULT_WEIGHT = 1;
  ULConst.ADV_DISABLE_DEFAULT_WEIGHT = 0;
  ULConst.ADV_RESULT_MSG_FAILED = "哎呀,广告走丢啦";
  ULConst.ADV_RESULT_MSG_SUCCESS = "show adv success";
  ULConst.ADV_NATIVE_RESULT_MSG_SUCCESS = "load native data success";
  ULConst.ADV_NATIVE_RESULT_MSG_FAIL = "load native data fail";
  ULConst.ADV_VIDEO_PLAY_FAIL_MSG = "广告提前关闭,无法获得奖励";
  ULConst.ADV_RESULT_MSG_CLICK = "click adv";
  ULConst.ADV_RESULT_MSG_CLOSE = "close adv";
  ULConst.ADV_NATIVE_OBSOLETE_MSG = "广告数据作废";
  ULConst.EXP_ADV_TYPE_CONST = "atype";
  ULConst.EXP_ADV_TEMPLATE_CONST = "tid";
  ULConst.EXP_ADV_POINT_CONST = ".";
  ULConst.UL_EVENT_ONREQUEST = "onRequest";
  ULConst.UL_EVENT_SHOW_PRIVACY_POLICY = "showPrivacyPolicy";
  ULConst.UL_EVENT_SHOW_PRIVACY_POLICY_WAIT = "showPrivacyPolicyWait";
  ULConst.CMD_GET_ADV_STATE_RESULT = "/c/getAdvStateResult";
  ULConst.CMD_CLOSE_ALL_ADV_BY_TYPE_RESULT = "/c/closeAllAdvByTypeResult";
  ULConst.CMD_JUMP_NEW_GUIDE = "/c/jumpNewGuide";
  ULConst.CMD_GET_ADV_STATE = "/c/getAdvState";
  ULConst.CMD_CLOSE_ALL_ADV_BY_TYPE = "/c/closeAllAdvByType";
  ULConst.CMD_REWARD_ADV_RESULT = "/c/rewardAdvResult";
  ULConst.UL_ADV_DEFAULT_TIMEOUT_TIME = 30000;
  ULConst.DEFAULT_TITLE = "广告";
  ULConst.DEFAULT_DESC = "哇!这个实在太棒啦!";
  ULConst.DEFAULT_TARGET_TITLE = "查看广告";
  ULConst.MIN_NATIVE_RESPONSE_CACHE_TIMEOUT = 0;
  ULConst.MAX_NATIVE_RESPONSE_CACHE_TIMEOUT = 30 * 1000;
  ULConst.DEFAULT_NATIVE_RESPONSE_CACHE_TIMEOUT = 15 * 1000;
  ULConst.ADV_LOAD_TYPE_PRELOAD = 1;
  ULConst.ADV_LOAD_TYPE_UNPRELOAD = 0;

  class ULEventDispatcher {
      constructor() {
          this.allListeners = {};
      }
      static getInstance() {
          if (!this._instance) {
              this._instance = new ULEventDispatcher();
          }
          return this._instance;
      }
      addListener(type, priority, callback) {
          return this._addListener(type, priority, callback, false);
      }
      once(type, priority, callback) {
          return this._addListener(type, priority, callback, true);
      }
      _addListener(type, priority, callback, bDispatchOnce) {
          if (priority < ULConst.PRIORITY_NONE) {
              this.removeListenerByCallback(type, callback);
              return;
          }
          ;
          let listeners = this.allListeners[type];
          if (!listeners) {
              listeners = [];
              this.allListeners[type] = listeners;
          }
          let insertIndex = -1;
          for (let i = 0; i < listeners.length; i++) {
              let listener = listeners[i];
              if (listener.callback == callback) {
                  ULLog.console.warn("ULEventDispatcher._addListener callback already exists:", type);
                  return false;
              }
              if (insertIndex == -1 && listener.priority < priority) {
                  insertIndex = i;
              }
          }
          let listener = new ULEventListener(type, priority, callback, bDispatchOnce);
          if (insertIndex != -1) {
              listeners.splice(insertIndex, 0, listener);
          }
          else {
              listeners.push(listener);
          }
          return true;
      }
      removeListenerByCallback(type, callback) {
          let listeners = this.allListeners[type];
          if (!listeners)
              return;
          for (let i = listeners.length - 1; i >= 0; i--) {
              let listener = listeners[i];
              if (listener.callback == callback) {
                  listeners.splice(i, 1);
              }
          }
      }
      removeListenersByType(type) {
          delete this.allListeners[type];
      }
      dispatch(type, data) {
          let event = null;
          if (type instanceof ULEvent) {
              event = type;
          }
          else {
              event = new ULEvent(type, data);
          }
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULEventDispatcher.dispatch", event.type, event.data);
          let ret = this._inner_dispatch(event);
          return ret.bCalled;
      }
      dispatchWithReturn(type, data) {
          let event = null;
          if (type instanceof ULEvent) {
              event = type;
          }
          else {
              event = new ULEvent(type, data);
          }
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULEventDispatcher.dispatchWithReturn", event.type, event.data);
          let ret = this._inner_dispatch(event);
          return ret.returnValue;
      }
      _inner_dispatch(event) {
          let bCalled = false;
          let listeners = this.allListeners[event.type];
          if (!listeners) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("  listeners not found");
              return { bCalled: false, returnValue: null };
          }
          for (let i = 0; i < listeners.length; i++) {
              const listener = listeners[i];
              if (listener.isNeedRemove())
                  continue;
              if (listener.isDispatchOnce()) {
                  listener.markNeedRemove();
              }
              if (listener.triggerCallback(event)) {
                  bCalled = true;
              }
              if (event.isPropagationStoped()) {
                  break;
              }
          }
          for (let i = listeners.length - 1; i >= 0; i--) {
              let listener = listeners[i];
              if (listener.isNeedRemove()) {
                  listeners.splice(i, 1);
              }
          }
          return { bCalled: bCalled, returnValue: event.getReturnValue() };
      }
  }
  ULEventDispatcher._instance = null;

  var cConfig = JSON.parse(`{
    "a_prj_upload_res_dirs": [
        
    ],
    "b_sdk_oppoqg_debug": false,
    "creatorVersion": "",
    "i_channel_info_timeout": 3000,
    "i_game_start_ready_timeout": 10000,
    "i_net_timeout": 5000,
    "i_prj_b2b_mode": 0,
    "i_sdk_adv_banner_cd": 0,
    "i_sdk_adv_banner_timeout": 30000,
    "i_sdk_adv_banner_valid_show_count": 2,
    "i_sdk_adv_custom_valid_show_count": 2,
    "i_sdk_adv_embedded_timeout": 30000,
    "i_sdk_adv_inter_cd": 0,
    "i_sdk_adv_inter_timeout": 30000,
    "i_sdk_adv_native_clicked_report_mode": 0,
    "i_sdk_adv_native_exposure_cd": 0,
    "i_sdk_adv_native_life_time": 15000,
    "i_sdk_adv_native_request_cd": 10000,
    "i_sdk_adv_paster_timeout": 30000,
    "i_sdk_adv_type_banner_cd": 0,
    "i_sdk_adv_type_banner_daily_limit": 0,
    "i_sdk_adv_type_embedded_cd": 0,
    "i_sdk_adv_type_embedded_daily_limit": 0,
    "i_sdk_adv_type_interstitial_cd": 0,
    "i_sdk_adv_type_interstitial_daily_limit": 0,
    "i_sdk_adv_type_paster_cd": 0,
    "i_sdk_adv_type_paster_daily_limit": 0,
    "i_sdk_adv_type_url_cd": 0,
    "i_sdk_adv_type_url_daily_limit": 0,
    "i_sdk_adv_type_video_cd": 0,
    "i_sdk_adv_type_video_daily_limit": 0,
    "i_sdk_adv_url_timeout": 30000,
    "i_sdk_adv_video_timeout": 30000,
    "i_sdk_age_level_info_mode": 1,
    "i_sdk_banner_autoRefresh_mode": 0,
    "i_sdk_banner_refresh_intervals": 30,
    "i_sdk_channel_user_id_mode": 0,
    "i_sdk_common_checktime_deferenceLimit": 300000,
    "i_sdk_compress_res_mode": 1,
    "i_sdk_content_security_check_support": 1,
    "i_sdk_custom_autoRefresh_mode": 0,
    "i_sdk_custom_refresh_intervals": 30,
    "i_sdk_debug_mode": 0,
    "i_sdk_debug_task_mode": 0,
    "i_sdk_find_mini_game_mode": 1,
    "i_sdk_installShortcut_mode": 1,
    "i_sdk_joinGroup_mode": 1,
    "i_sdk_jump_game_resource_mode": 0,
    "i_sdk_jump_single_random_length": 5,
    "i_sdk_jumplist_mode": 1,
    "i_sdk_megadata_encrypt": 1,
    "i_sdk_megadata_mode": 1,
    "i_sdk_megadata_upload_span": 5000,
    "i_sdk_moreWonderful_mode": 0,
    "i_sdk_moregame_mode": 1,
    "i_sdk_native_autoRefresh_intervals": 30,
    "i_sdk_native_autoRefresh_mode": 0,
    "i_sdk_native_valid_show_count": 2,
    "i_sdk_oppoqg_ad_ecd": 0,
    "i_sdk_oppoqg_banner_mode": 0,
    "i_sdk_oppoqg_jump_game_reward_time": 20000,
    "i_sdk_oppoqg_not_show_banner_after_user_close_count_limit": 5,
    "i_sdk_pay_mode": 0,
    "i_sdk_phone_vibrate": 0,
    "i_sdk_sdk_rank_mode": 0,
    "i_sdk_share_mode": 0,
    "i_sdk_subscribe_mode": 1,
    "i_sdk_support_open_url": 0,
    "i_sdk_support_record_share": 1,
    "i_sdk_trim_adv_err_switch": 1,
    "layaVersion": "2.8",
    "n_sdk_adv_video_complete_mode": 1,
    "n_sdk_common_online_time_report_looper_interval": 60,
    "nodejsExePath": "nodejs16.15.1/node.exe",
    "nodejsGitAddr": "ude2/prj.ulnodejs",
    "nodejsGitBranch": "v1",
    "resProcessScriptPath": "",
    "s_game_name": "魔力火线联盟‎",
    "s_game_orientation": "portrait",
    "s_prj_name": "prj.game166",
    "s_sdk_adv_info": {
        "1": {
            "group": [
                "1"
            ],
            "type": "interstitial"
        },
        "2": {
            "group": [
                "2"
            ],
            "type": "banner"
        },
        "3": {
            "group": [
                "3"
            ],
            "type": "embedded"
        },
        "4": {
            "group": [
                "4"
            ],
            "type": "video"
        },
        "5": {
            "group": [
                "5"
            ],
            "type": "url"
        }
    },
    "s_sdk_age_level_info": "游戏中有实名认证系统，认证为未成年人的用户将接受以下管理：未满8周岁的用户不能充值；8周岁以上未满16周岁的未成年人用户，单次充值金额不得超过50元人民币，每月充值金额累计不得超过200元人民币；16周岁以上的未成年人用户，单次充值金额不得超过100元人民币，每月充值金额累计不得超过400元人民币。未成年人用户可以在周五、周六、周日和法定节假日每日晚20时至21时期间登录游戏，其他时间内无法登录游戏。",
    "s_sdk_cdk_app_id": "99",
    "s_sdk_cdk_url": "https://cdkey.ultralisk.cn/commoncdk/usecdk",
    "s_sdk_common_affiche_title": "最新公告",
    "s_sdk_common_affiche_url": "",
    "s_sdk_common_checktime_url": "https://copv7.ultralisk.cn/getservertime",
    "s_sdk_common_copyright_str": " ",
    "s_sdk_common_login_url": "https://sdkserver.ultralisk.cn/userlogin",
    "s_sdk_common_online_pay_url": "https://sdkpay.ultralisk.cn",
    "s_sdk_cop_addr": "https://copv7.ultralisk.cn/h5/getdata/",
    "s_sdk_cop_game_id": "119",
    "s_sdk_jump_game_statis_game_indexes": "",
    "s_sdk_lan_debug_address": "",
    "s_sdk_megadata_close_table_type_ids": "",
    "s_sdk_megadata_game_id": "368",
    "s_sdk_megadata_server_jump_game_type_id": "jumpabtest",
    "s_sdk_megadata_server_type_id": "368",
    "s_sdk_megadata_test_url": "https://megadatav7.ultralisk.cn/batchtestmodedataupload",
    "s_sdk_megadata_url": "https://megadatav7.ultralisk.cn/batchdataupload",
    "s_sdk_oppoqg_app_key": "C96a5e0EnDkC4Wc440k888Wss",
    "s_sdk_oppoqg_appid": "30831905",
    "s_sdk_oppoqg_appsecret": "4B57A7b74aB8054C72C06a1D2873A6Ac",
    "s_sdk_oppoqg_minPlatform_version": "1056",
    "s_sdk_oppoqg_package_name": "com.ultralisk.game166.nearme.gamecenter",
    "s_sdk_oppoqg_preOrder_online_url": "http://sdkpay.ultralisk.cn/preorder",
    "s_sdk_oppoqg_pre_order_url": "https://jits.open.oppomobile.com/jitsopen/api/pay/v1.0/preOrder",
    "s_sdk_oppoqg_private_key": "-----BEGIN RSA PRIVATE KEY-----MIICXgIBAAKBgQC46Giy1S4Zuys/c3QO6VZVWAOo1tussbIpqI0M7edU9OC732leFej2DmG3O9XRh9NlYjoAq4hyt7DxiZ6MyN8IdStZn4b0/e/CZKQA5WaCI5h71hUTwCJTzHZHvO+woDWaE2mOSsBfjAdwTsHUr32eCPzju/1zatys02W7ai4v+wIDAQABAoGAGjbAmRHF3ln9kJpCitajqae3pRkIvZvXgTZnAL09fXrV3WyX2IHMrA1v5vUxo+nYm1foly26Q2EtUaDL/HOBwshbwEtR5TR0g+kZBpA+S4wt/ujZPlALmZiGuQjjqwWFo9OfeskXer7vA5UWYemDMvy7XQ2TWoLNOzI+LaVvEPECQQDpEgY7XmrKeq8qkUFPsDjcEa7SZ2eEEOps0NKmewGvAaiavm7+8yCdS/ZPS7ZD6590TanFWy3gJtugw/vPa2tpAkEAyxlj8u+EYKchPBYehuRjm4W5SlJNAGrABqrJjM50jQ4aRVr1LbS6R0S77kTaZLTV/w8eYk1LS9cTCaY+JB+HwwJBAIXrlmscmG4ZynbCGe4JCtLg0jwRsHhBJAI8hx2jxlbhtBieXbbeypm3YSM1FNi4FdpFGczN1HFcwowAsLsBNSkCQQC9YgywQKYI1m+ILvwCPr+fCt/PrNS+mcw7q0/Lq8xEp6zZlUpgd1DoGfC/6pZXJ8UQVFG5ymd27bOD4O+7EWevAkEAzYHfclV/kP3V1aCR0KoXBHA4WIHKa+JaVuFMIDZqd/SsfsoKDn+Stsajl/e8LAwt9XXctYWNvGsVfCSfZ5Y3tw==-----END RSA PRIVATE KEY-----",
    "s_sdk_oppoqg_tiny_package_server": "https://gamesres.ultralisk.cn/h5_games_res/game166/oppoqg/v1",
    "s_sdk_oppoqg_version_code": "127",
    "s_sdk_oppoqg_version_name": "1.0.27",
    "s_sdk_user_data_get_url": "https://h5gameserver.ultralisk.cn/getuserdata",
    "s_sdk_user_data_save_url": "https://h5gameserver.ultralisk.cn/savealluserdata",
    "s_sdk_version": "f6e824b5e",
    "srcRootPath": "src/script/",
    "t_customer_service_info": [
        "kefu@ultralisk.cn"
    ],
    "t_sdk_adv_banner_tags_style_setting": {
        
    },
    "t_sdk_adv_custom_args_style_setting": {
        
    },
    "t_sdk_common_event_ids": {
        "add_subscrible": "102",
        "click_more_game_channel_system_button": "108",
        "click_more_game_icon_list": "106",
        "click_more_game_icon_reward": "105",
        "click_more_game_icon_single": "104",
        "click_share": "101",
        "click_subscrible": "103",
        "open_cdk": "107",
        "open_share": "100"
    },
    "t_sdk_common_modify_tag_afterBuild": [
        
    ],
    "t_sdk_common_modify_tag_beforeBuild": [
        
    ],
    "t_sdk_compress_json_includes": [
        
    ],
    "t_sdk_compress_json_includes_rem": "",
    "t_sdk_compress_res_config": [
        {
            "cmds": "",
            "rep": ".*fgui///.*"
        },
        {
            "cmds": "jpeg-recompress --strip -t 0.4 --min 80 | guetzil --quality 85",
            "rep": ".*//.jpg"
        },
        {
            "cmds": "autopng --quality 40-80 | optipng -strip all -o7 | zopflipng -y --lossy_8bit --lossy_transparent",
            "rep": ".*//.png"
        }
    ],
    "t_sdk_cop_default_cop": {
        "is_sdk_start_game_by_touch": "1"
    },
    "t_sdk_cop_simulate_city_data": {
        "0": "未知城市",
        "1001": "海南藏族自治州",
        "1002": "西宁",
        "1003": "海东",
        "1004": "黄南藏族自治州",
        "1005": "海西蒙古族藏族自治州",
        "1006": "海北藏族自治州",
        "1007": "果洛藏族自治州",
        "1008": "玉树藏族自治州",
        "101": "北京",
        "1101": "临夏回族自治州",
        "1102": "甘南藏族自治州",
        "1103": "白银",
        "1104": "陇南",
        "1105": "定西",
        "1106": "平凉",
        "1107": "金昌",
        "1108": "酒泉",
        "1109": "张掖",
        "1110": "庆阳",
        "1111": "兰州",
        "1112": "武威",
        "1113": "嘉峪关",
        "1114": "天水",
        "1201": "银川",
        "1202": "固原",
        "1203": "吴忠",
        "1204": "中卫",
        "1205": "石嘴山",
        "1301": "商洛",
        "1302": "安康",
        "1303": "榆林",
        "1304": "铜川",
        "1305": "咸阳",
        "1306": "西安",
        "1307": "渭南",
        "1308": "汉中",
        "1309": "宝鸡",
        "1310": "延安",
        "1401": "长春",
        "1402": "白城",
        "1403": "松原",
        "1404": "白山",
        "1405": "吉林",
        "1406": "延边朝鲜族自治州",
        "1407": "四平",
        "1408": "辽源",
        "1409": "通化",
        "1501": "铜陵",
        "1502": "亳州",
        "1503": "黄山",
        "1504": "池州",
        "1505": "合肥",
        "1506": "淮北",
        "1507": "滁州",
        "1508": "宿州",
        "1509": "淮南",
        "1510": "蚌埠",
        "1511": "六安",
        "1512": "阜阳",
        "1513": "芜湖",
        "1514": "宣城",
        "1515": "安庆",
        "1516": "马鞍山",
        "1601": "恩施土家族苗族自治州",
        "1602": "仙桃",
        "1603": "武汉",
        "1604": "孝感",
        "1605": "咸宁",
        "1606": "十堰",
        "1607": "天门",
        "1608": "黄冈",
        "1609": "宜昌",
        "1610": "襄阳",
        "1611": "黄石",
        "1612": "荆门",
        "1613": "随州",
        "1614": "荆州",
        "1615": "鄂州",
        "1616": "神农架林区",
        "1617": "潜江",
        "1701": "株洲",
        "1702": "邵阳",
        "1703": "岳阳",
        "1704": "张家界",
        "1705": "怀化",
        "1706": "衡阳",
        "1707": "长沙",
        "1708": "常德",
        "1709": "郴州",
        "1710": "永州",
        "1711": "湘西土家族苗族自治州",
        "1712": "湘潭",
        "1713": "益阳",
        "1714": "娄底",
        "1801": "安顺",
        "1802": "黔南布依族苗族自治州",
        "1803": "铜仁",
        "1804": "六盘水",
        "1805": "贵阳",
        "1806": "黔东南苗族侗族自治州",
        "1807": "毕节",
        "1808": "遵义",
        "1809": "黔西南布依族苗族自治州",
        "1901": "太原",
        "1902": "长治",
        "1903": "运城",
        "1904": "晋中",
        "1905": "忻州",
        "1906": "朔州",
        "1907": "晋城",
        "1908": "阳泉",
        "1909": "大同",
        "1910": "临汾",
        "1911": "吕梁",
        "2001": "来宾",
        "2002": "柳州",
        "2003": "崇左",
        "2004": "百色",
        "2005": "河池",
        "2006": "防城港",
        "2007": "贺州",
        "2008": "贵港",
        "2009": "北海",
        "201": "上海",
        "2010": "南宁",
        "2011": "桂林",
        "2012": "玉林",
        "2013": "钦州",
        "2014": "梧州",
        "2101": "凉山彝族自治州",
        "2102": "攀枝花",
        "2103": "乐山",
        "2104": "遂宁",
        "2105": "资阳",
        "2106": "绵阳",
        "2107": "自贡",
        "2108": "德阳",
        "2109": "雅安",
        "2110": "达州",
        "2111": "广元",
        "2112": "广安",
        "2113": "阿坝藏族羌族自治州",
        "2114": "甘孜藏族自治州",
        "2115": "成都",
        "2116": "南充",
        "2117": "泸州",
        "2118": "内江",
        "2119": "宜宾",
        "2120": "巴中",
        "2121": "眉山",
        "2201": "郑州",
        "2202": "三门峡",
        "2203": "洛阳",
        "2204": "开封",
        "2205": "信阳",
        "2206": "焦作",
        "2207": "许昌",
        "2208": "濮阳",
        "2209": "济源",
        "2210": "鹤壁",
        "2211": "安阳",
        "2212": "驻马店",
        "2213": "新乡",
        "2214": "南阳",
        "2215": "漯河",
        "2216": "平顶山",
        "2217": "商丘",
        "2218": "周口",
        "2301": "石家庄",
        "2302": "保定",
        "2303": "沧州",
        "2304": "衡水",
        "2305": "唐山",
        "2306": "邯郸",
        "2307": "廊坊",
        "2308": "秦皇岛",
        "2309": "邢台",
        "2310": "张家口",
        "2311": "承德",
        "2401": "福州",
        "2402": "厦门",
        "2403": "宁德",
        "2404": "莆田",
        "2405": "龙岩",
        "2406": "三明",
        "2407": "南平",
        "2408": "泉州",
        "2409": "漳州",
        "2501": "南昌",
        "2502": "上饶",
        "2503": "赣州",
        "2504": "新余",
        "2505": "鹰潭",
        "2506": "抚州",
        "2507": "萍乡",
        "2508": "宜春",
        "2509": "景德镇",
        "2510": "吉安",
        "2511": "九江",
        "2601": "珠海",
        "2602": "东莞",
        "2603": "江门",
        "2604": "阳江",
        "2605": "惠州",
        "2606": "汕尾",
        "2607": "梅州",
        "2608": "清远",
        "2609": "湛江",
        "2610": "揭阳",
        "2611": "广州",
        "2612": "云浮",
        "2613": "潮州",
        "2614": "汕头",
        "2615": "韶关",
        "2616": "深圳",
        "2617": "佛山",
        "2618": "中山",
        "2619": "肇庆",
        "2620": "茂名",
        "2621": "河源",
        "2701": "呼和浩特",
        "2702": "锡林郭勒盟",
        "2703": "乌兰察布",
        "2704": "通辽",
        "2705": "包头",
        "2706": "阿拉善盟",
        "2707": "巴彦淖尔",
        "2708": "兴安盟",
        "2709": "鄂尔多斯",
        "2710": "乌海",
        "2711": "呼伦贝尔",
        "2712": "赤峰",
        "2801": "鹤岗",
        "2802": "鸡西",
        "2803": "哈尔滨",
        "2804": "黑河",
        "2805": "七台河",
        "2806": "伊春",
        "2807": "大兴安岭地区",
        "2808": "牡丹江",
        "2809": "绥化",
        "2810": "齐齐哈尔",
        "2811": "双鸭山",
        "2812": "大庆",
        "2813": "佳木斯",
        "2901": "葫芦岛",
        "2902": "营口",
        "2903": "丹东",
        "2904": "沈阳",
        "2905": "抚顺",
        "2906": "辽阳",
        "2907": "大连",
        "2908": "鞍山",
        "2909": "盘锦",
        "2910": "阜新",
        "2911": "本溪",
        "2912": "锦州",
        "2913": "铁岭",
        "2914": "朝阳",
        "3001": "淄博",
        "3002": "临沂",
        "3003": "威海",
        "3004": "莱芜",
        "3005": "日照",
        "3006": "济南",
        "3007": "泰安",
        "3008": "烟台",
        "3009": "聊城",
        "301": "天津",
        "3010": "东营",
        "3011": "菏泽",
        "3012": "滨州",
        "3013": "潍坊",
        "3014": "德州",
        "3015": "青岛",
        "3016": "济宁",
        "3017": "枣庄",
        "3101": "南京",
        "3102": "常州",
        "3103": "苏州",
        "3104": "无锡",
        "3105": "盐城",
        "3106": "镇江",
        "3107": "连云港",
        "3108": "宿迁",
        "3109": "南通",
        "3110": "徐州",
        "3111": "淮安",
        "3112": "扬州",
        "3113": "泰州",
        "401": "重庆",
        "501": "宁波",
        "502": "金华",
        "503": "嘉兴",
        "504": "绍兴",
        "505": "湖州",
        "506": "衢州",
        "507": "舟山",
        "508": "杭州",
        "509": "温州",
        "510": "丽水",
        "511": "台州",
        "601": "儋州",
        "602": "定安县",
        "603": "东方",
        "604": "五指山",
        "605": "屯昌县",
        "606": "琼海",
        "607": "澄迈县",
        "608": "琼中黎族苗族自治县",
        "609": "三亚",
        "610": "白沙黎族自治县",
        "611": "文昌",
        "612": "陵水黎族自治县",
        "613": "昌江黎族自治县",
        "614": "保亭黎族苗族自治县",
        "615": "临高县",
        "616": "海口",
        "617": "万宁",
        "618": "乐东黎族自治县",
        "701": "迪庆藏族自治州",
        "702": "西双版纳傣族自治州",
        "703": "临沧",
        "704": "保山",
        "705": "玉溪",
        "706": "德宏傣族景颇族自治州",
        "707": "红河哈尼族彝族自治州",
        "708": "大理白族自治州",
        "709": "丽江",
        "710": "怒江傈僳族自治州",
        "711": "普洱",
        "712": "楚雄彝族自治州",
        "713": "文山壮族苗族自治州",
        "714": "昆明",
        "715": "曲靖",
        "716": "昭通",
        "801": "拉萨",
        "802": "昌都",
        "803": "山南",
        "804": "阿里地区",
        "805": "林芝",
        "806": "日喀则",
        "807": "那曲地区",
        "901": "喀什地区",
        "902": "阿克苏地区",
        "903": "和田地区",
        "904": "哈密",
        "905": "石河子",
        "906": "吐鲁番",
        "907": "博尔塔拉蒙古自治州",
        "908": "巴音郭楞蒙古自治州",
        "909": "昌吉回族自治州",
        "910": "塔城地区",
        "911": "克孜勒苏柯尔克孜自治州",
        "912": "阿勒泰地区",
        "913": "乌鲁木齐",
        "914": "克拉玛依",
        "915": "伊犁哈萨克自治州"
    },
    "t_sdk_cop_strategy_setting": {
        
    },
    "t_sdk_exempt_advType_limit_arrays": [
        
    ],
    "t_sdk_mutuallyExclusive_advType_setting": {
        
    },
    "t_sdk_oppoqg_adv_tag_2_native_index": {
        
    },
    "t_sdk_oppoqg_custom_adv_setting": {
        
    },
    "t_sdk_oppoqg_jump_games": [
        
    ],
    "t_sdk_oppoqg_native_index_2_native_id": {
        
    },
    "t_sdk_oppoqg_pay_code": {
        
    },
    "t_sdk_oppoqg_show_banner_box_adv_tags": [
        
    ],
    "t_sdk_oppoqg_show_drawer_box_adv_tags": {
        
    },
    "t_sdk_oppoqg_show_inter_box_adv_tags": [
        
    ],
    "t_sdk_privacyPolicy_dataArray": [
        {
            "name": "隐私政策",
            "url": "https://gamesres.ultralisk.cn/notice/policy/oppoyiguopolicy.json"
        }
    ],
    "t_sdk_record_duration_limit_object": {
        "*": {
            "max": 300,
            "min": 3
        },
        "2": {
            "max": 300,
            "min": 15
        }
    },
    "t_sdk_show_native_banner_autoRefresh_tags": [
        
    ],
    "t_sdk_show_native_banner_autoRefresh_tags_style_setting": {
        
    },
    "t_sdk_trim_adv_err_object": {
        "*": "广告播放失败了，重新试试看吧！",
        "baidu": {
            "code": {
                "3010003": "您的网络好像不够流畅，请更换到良好的网络环境再播放广告。",
                "3010005||3010006": "正在为您播放广告，请稍等一会儿，不要重复点击。"
            }
        },
        "headline||weixin||qq": {
            "code": {
                "1004": "暂时没有适合您观看的广告，请稍等一会儿再试吧！"
            }
        },
        "oppoqg": {
            "(this.code==1001 || this.code == 1004)&&msg": {
                "/10001/||/10100/||/10101/||/10403/": "您的网络好像不够流畅，请更换到良好的网络环境再播放广告。",
                "/10405/": "您的操作系统版本太低，不能播放广告。",
                "/10406/": "需要连接到 Wifi 网络",
                "/11002/": "这个广告只能在OPPO手机上播放，请确认您的机型。",
                "/11003/": "暂时无法播放广告，请稍等一会儿再试吧1！"
            }
        },
        "vivo": {
            "code": {
                "-100||101||500": "您的网络好像不够流畅，请更换到良好的网络环境再播放广告。",
                "-3||108||30005": "暂时无法播放广告，请稍等一会儿再试吧！",
                "30007": "暂时无法播放广告，请稍等一会儿再试吧！",
                "30010": "广告播放失败了，可能是是由于您经常关闭广告造成的，稍等一会儿再试吧。"
            }
        }
    },
    "targetCreatorBranch": "",
    "targetCreatorExePath": "",
    "targetCreatorGitAddr": "",
    "targetCreatorToolGitAddr": "ude2/prj.ulcocoscreator_tools3.x",
    "targetCreatorToolGitBranch": "v2",
    "targetProjectBranch": "v1_h5_release",
    "targetProjectGitAddr": "ude2/prj.game166",
    "targetProjectPath": "",
    "tempCreatorProjectPaths": [
        [
            ".laya/",
            ".laya/"
        ],
        [
            "bin/",
            "bin/",
            [
                "**/vconsole.*"
            ]
        ],
        [
            "declare/",
            "declare/"
        ],
        [
            "laya/",
            "laya/"
        ],
        [
            "libs/",
            "libs/"
        ],
        [
            "src/",
            "src/"
        ],
        [
            "prj.game166.laya",
            ""
        ],
        [
            "tsconfig.json",
            ""
        ]
    ],
    "tempProjectName": "laya_proj",
    "autoUploadPack": true,
    "B_SHOW_LICENCE_INFO_ON_LOADING": false,
    "build_laya_oppogame_module_config": {
        "bAutoUploadEnabled": true,
        "bNakedPackage": true,
        "compressJs": false,
        "nakedPackageSearchKeys": [
            "res/cfg/",
            "res/scene/vLoadingScene.json"
        ],
        "oppoInfo": {
            "logLevel": "off",
            "name": "魔力火线联盟‎",
            "package": "com.ultralisk.game166.nearme.gamecenter",
            "versionCode": "127",
            "versionName": "1.0.27"
        },
        "title": "魔力火线联盟‎",
        "url_path": "https://gamesres.ultralisk.cn/h5_games_res/game166/oppoqg/v1",
        "useMinJsLibs": false
    },
    "i_sdk_licence_info_mode": 1,
    "i_sdk_start_game_by_touch": 1,
    "s_sdk_cop_channel_id": "146",
    "s_sdk_cop_version": "25098",
    "s_sdk_licence_info": "",
    "t_sdk_increment_fields": [
        "s_sdk_oppoqg_version_code",
        "s_sdk_oppoqg_version_name"
    ],
    "_target_project_branch": "v1_h5_release",
    "_target_project_log": "2023-07-31 11:59:52 +0800-wujun-5dad95c59",
    "_target_last_commit_time": 1690775992,
    "prjVersion": "5dad95c59",
    "rootPath": "D:/ulwork/ulsdk/",
    "rootSdkPath": "D:/ulwork/ulsdk/prj.sdk.html5/",
    "gitRepoPath": "D:/ulwork/ulsdk/h5_games_res/",
    "taskDate": "2023_07_31",
    "taskTick": "2023_07_31_18_41_34",
    "taskTickShort": "0731_184134",
    "taskName": "oppo",
    "configName": "task_game166_ttswz_v1",
    "targetPath": "D:/ulwork/ulsdk/h5_out/66_oppo_0731_184134/",
    "resCachePath": "D:/ulwork/ulsdk/h5_res_cache/prj.game166/",
    "packagePath": "D:/ulwork/ulsdk/prj.games.html5.channels.packages/prj.game166/prj.game166_v1_h5_release_oppo_0731_184134/",
    "buildDisabled": false,
    "creatorExePath": "",
    "nodejsExeAbsPath": "D:/ulwork/ude2/prj.ulnodejs/nodejs16.15.1/node.exe",
    "taskJsonPath": "D:/ulwork/ulsdk/prj.games.html5.channels.tasks/task_game166_ttswz_v1/task.json",
    "buildTempPath": "D://ulwork//ulsdk//prj.sdk.html5//build_system//build_gradle/../../../h5_out/build_temp/",
    "s_sdk_obfuscator_ts_key": "IHY",
    "envCheckResult": [
        {
            "msg": "[警告] taskConfig[t_sdk_oppoqg_show_banner_box_adv_tags]类型错误！当前为[class java.util.ArrayList]，期望[object]",
            "level": 1
        }
    ],
    "b_sdk_obfuscator_mode": false,
    "a_sdk_obfuscator_includes": [
        
    ],
    "o_sdk_obfuscator_config": {
        
    },
    "s_sdk_cocos2x_rootNode_check": "",
    "i_sdk_launchReward_mode": 0,
    "tempProjPath": "D:/ulwork/ulsdk/h5_out/66_oppo_0731_184134/laya_proj/",
    "moduleList": "common,build_laya_oppogame,oppoqg,privacyPolicy"
}`);

  class ULTimer {
      constructor(span, repeatCount, callback) {
          this._repeatCount = -1;
          this._span = 1;
          this._callback = null;
          this._intervalId = null;
          this._count = 0;
          this._beginTime = -1;
          this._usedTime = 0;
          this._span = span;
          this._repeatCount = repeatCount;
          this._callback = callback;
      }
      static callLater(span, callback) {
          let timer = new ULTimer(span, 1, callback);
          timer.start();
      }
      static callLoop(span, callback) {
          let timer = new ULTimer(span, -1, callback);
          timer.start();
      }
      _onSpan() {
          this._count++;
          this._usedTime = ULTools.time() - this._beginTime;
          if (this._callback) {
              try {
                  this._callback(this);
              }
              catch (error) {
                  ULLog.console.warn("警告] ULTimer._onSpan callback has error", error);
              }
          }
          if (this._repeatCount >= 0 && this._count >= this._repeatCount) {
              this.stop();
          }
      }
      isRunning() {
          return this._intervalId != null;
      }
      get count() {
          return this._count;
      }
      get span() {
          return this._span;
      }
      get usedTime() {
          return this._usedTime;
      }
      start() {
          this.stop();
          if (!this._callback) {
              ULLog.console.warn("警告] ULTimer.start callback未设置！");
              return this;
          }
          this._beginTime = ULTools.time();
          this._count = 0;
          this._intervalId = setInterval(this._onSpan.bind(this), this.span * 1000);
          return this;
      }
      stop() {
          if (this._intervalId != null) {
              clearInterval(this._intervalId);
              this._intervalId = null;
          }
          return this;
      }
  }

  class ULStorageManager {
      constructor() {
          this.cacheStorage = {};
      }
      static getInstance() {
          if (!this._instance) {
              this._instance = new ULStorageManager();
          }
          return this._instance;
      }
      getStorage(key) {
          let returnValue = ULEventDispatcher.getInstance().dispatchWithReturn(ULConst.CMD_SDK_GET_STORAGE, { key: key });
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log(ULTools.format("ULStorageManager.getStorage(%s) => [%s]", key, returnValue));
          if (returnValue == null) {
              returnValue = this.cacheStorage[key];
          }
          else {
              this.cacheStorage[key] = returnValue;
          }
          return returnValue;
      }
      setStorage(key, data) {
          this.cacheStorage[key] = data;
          let bCalled = ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_SET_STORAGE, { key: key, data: data });
          if (!bCalled) {
              ULLog.console.warn("ULStorageManager.setStorage 未找到实现！");
          }
      }
  }
  ULStorageManager._instance = null;

  class ULWebSocket {
      constructor(url) {
          this.socketingWS = null;
          this.isOpening = false;
          this.socketMsgCache = [];
          this._isAutoClearCache = false;
          if ("WebSocket" in window) {
              return;
              var address = url;
              var ws = new WebSocket(address);
              this.socketingWS = ws;
              let self = this;
              ws.onopen = function (ev) {
                  self.isOpening = true;
                  self.onopen(ev);
              };
              ws.onmessage = function (evt) {
                  self.onmessage(evt);
              };
              ws.onclose = function (evt) {
                  self.isOpening = false;
                  self.socketingWS = null;
                  self.socketMsgCache = [];
                  self.onclose(evt);
              };
              ws.onerror = function (err) {
                  self.isOpening = false;
                  self.socketingWS = null;
                  self.socketMsgCache = [];
                  self.onerror(err);
              };
          }
      }
      set isAutoClearCache(value) {
          if (value == this._isAutoClearCache) {
              return;
          }
          this._isAutoClearCache = value;
          if (this._isAutoClearCache) {
              this.intervalId = setInterval(() => {
                  this.clearCache();
              }, 30);
          }
          else {
              clearInterval(this.intervalId);
          }
      }
      close(code, reason) {
          if (this.isOpening && this.socketingWS) {
              this.socketingWS.close();
              this.isOpening = false;
              this.socketingWS = null;
          }
      }
      send(msg) {
          if (!this.socketingWS) {
              return;
          }
          let ietm = null;
          try {
              ietm = JSON.stringify(msg);
          }
          catch (error) {
              ietm = JSON.stringify({
                  type: 3,
                  data: error
              });
          }
          finally {
              if (!this.isOpening || this._isAutoClearCache) {
                  this.socketMsgCache.push(ietm);
                  this.isAutoClearCache = true;
              }
              else {
                  this.socketingWS.send(ietm);
              }
          }
      }
      clearCache() {
          if (!this.socketingWS || !this.socketMsgCache.length) {
              this.isAutoClearCache = false;
              return;
          }
          if (this.isOpening) {
              let item = this.socketMsgCache.shift();
              this.socketingWS.send(item);
          }
      }
  }

  class ULTools {
      static time() {
          let time = new Date().getTime() / 1000;
          return time;
      }
      static timeInDay() {
          let time = this.time();
          let todayBeginDate = new Date(time * 1000);
          todayBeginDate.setHours(0);
          todayBeginDate.setMinutes(0);
          todayBeginDate.setSeconds(0);
          todayBeginDate.setMilliseconds(0);
          let todayBeginTime = todayBeginDate.getTime() / 1000;
          return time - todayBeginTime;
      }
      static timeDay(time = this.time()) {
          let todayBeginDate = new Date(time * 1000);
          todayBeginDate.setHours(0);
          todayBeginDate.setMinutes(0);
          todayBeginDate.setSeconds(0);
          todayBeginDate.setMilliseconds(0);
          let todayBeginTime = todayBeginDate.getTime() / 1000;
          return todayBeginTime;
      }
      static timeDayHour(hours = 0, minutes = 0, seconds = 0) {
          let todayBeginDate = new Date();
          todayBeginDate.setHours(hours);
          todayBeginDate.setMinutes(minutes);
          todayBeginDate.setSeconds(seconds);
          todayBeginDate.setMilliseconds(0);
          let todayBeginTime = todayBeginDate.getTime() / 1000;
          if (this.time() > todayBeginTime) {
              todayBeginTime += 60 * 60 * 24;
          }
          return todayBeginTime;
      }
      static isOneDay(seconds1, seconds2) {
          var d1 = new Date(seconds1 * 1000);
          var d2 = new Date(seconds2 * 1000);
          return d1.getFullYear() == d2.getFullYear() && d1.getMonth() == d2.getMonth() && d1.getDate() == d2.getDate();
      }
      static isOneMonth(seconds1, seconds2) {
          var d1 = new Date(seconds1 * 1000);
          var d2 = new Date(seconds2 * 1000);
          return d1.getFullYear() == d2.getFullYear() && d1.getMonth() == d2.getMonth();
      }
      static getObjSize(obj) {
          if (!obj) {
              return 0;
          }
          if (Array.isArray(obj)) {
              return obj.length;
          }
          let count = 0;
          this.forEachMap(obj, (k, v) => {
              count++;
          });
          return count;
      }
      static parseUrl(url) {
          var r = {
              protocol: /([^\/]+:)\/\/(.*)/i,
              host: /(^[^\:\/]+)((?:\/|:|$)?.*)/,
              port: /\:?([^\/]*)(\/?.*)/,
              pathname: /([^\?#]+)(\??[^#]*)(#?.*)/
          };
          var tmp = {};
          var res = {
              href: url,
              protocol: "",
              host: "",
              port: "",
              pathname: "",
              search: "",
              hash: ""
          };
          for (let p in r) {
              tmp = r[p].exec(url);
              res[p] = tmp[1];
              url = tmp[2];
              if (url === "") {
                  url = "/";
              }
              if (p === "pathname") {
                  res.pathname = tmp[1];
                  res.search = tmp[2];
                  res.hash = tmp[3];
              }
          }
          return res;
      }
      static random(min, max) {
          if (min == null && max == null) {
              return Math.random();
          }
          else if (max == null) {
              return Math.floor(Math.random() * min + 1);
          }
          else {
              return Math.floor(Math.random() * (max - min + 1) + min);
          }
      }
      static scaleInRange(n, ia, ib, oa, ob) {
          if (ia < ib) {
              if (n < ia)
                  n = ia;
              if (n > ib)
                  n = ib;
          }
          else {
              if (n < ib)
                  n = ib;
              if (n > ia)
                  n = ia;
          }
          let iDistance = ib - ia;
          let oDistance = ob - oa;
          return (n - ia) / iDistance * oDistance + oa;
      }
      static clampf(n, min, max) {
          if (n < min)
              return min;
          if (n > max)
              return max;
          return n;
      }
      static calcWheelTarget(arr, weightKey) {
          let totalWeight = 0;
          for (let i = 0; i < arr.length; i++) {
              const v = arr[i];
              let w = parseInt(v[weightKey]);
              if (isNaN(w)) {
                  ULLog.console.warn(this.format("Tools.calcWheelTarget weight field not found! key=[%s]", weightKey));
                  return null;
              }
              totalWeight += w;
          }
          let rw = this.random(totalWeight);
          for (let i = 0; i < arr.length; i++) {
              const v = arr[i];
              let w = parseInt(v[weightKey]);
              if (rw <= w) {
                  return v;
              }
              else {
                  rw -= w;
              }
          }
          return null;
      }
      static sortArrayByField(array, fields) {
          if (typeof (fields) == "string") {
              fields = [fields];
          }
          else {
              fields = fields;
          }
          let fieldConfig = [];
          for (let k in fields) {
              let v = fields[k];
              if (v && v != "") {
                  if (v.substring(0, 1) === "-") {
                      let tmpField = v.substring(1, v.length);
                      if (tmpField && tmpField != "") {
                          fieldConfig.push([tmpField, true]);
                      }
                  }
                  else {
                      fieldConfig.push([v, false]);
                  }
              }
          }
          let sorter = (a, b) => {
              let ret = 0;
              for (let k in fieldConfig) {
                  let v = fieldConfig[k];
                  let field = v[0];
                  let desc = v[1];
                  let v1 = a[field];
                  let v2 = b[field];
                  if (v1 != null) {
                      if (desc) {
                          ret = v2 - v1;
                      }
                      else {
                          ret = v1 - v2;
                      }
                      if (ret != 0) {
                          return ret;
                      }
                  }
              }
              return ret;
          };
          let sorted = [];
          for (let i = 0; i < array.length; i++) {
              const v = array[i];
              sorted.push(v);
          }
          sorted.sort(sorter);
          return sorted;
      }
      static bubbleSort(arr, sorter) {
          var len = arr.length;
          for (var i = 0; i < len; i++) {
              for (var j = 0; j < len - 1 - i; j++) {
                  let ret = sorter(arr[j], arr[j + 1]);
                  if (ret > 0) {
                      var temp = arr[j + 1];
                      arr[j + 1] = arr[j];
                      arr[j] = temp;
                  }
              }
          }
          return arr;
      }
      static forEachMap(map, callback) {
          if (!map)
              return;
          let keys = Object.keys(map);
          for (let i = 0; i < keys.length; i++) {
              let key = keys[i];
              let value = map[key];
              if (value != null) {
                  if (callback(key, value))
                      break;
              }
          }
      }
      static formatTime(time, format) {
          let hour = Math.floor(time / 3600);
          let minute = Math.floor(time / 60) % 60;
          let second = Math.ceil(time) % 60;
          if (format.match("%h")) {
              format = format.replace("%h", hour.toString());
          }
          if (format.match("%H")) {
              format = format.replace("%H", this.format("%02d", hour));
          }
          if (format.match("%m")) {
              format = format.replace("%m", minute.toString());
          }
          if (format.match("%M")) {
              format = format.replace("%M", this.format("%02d", minute));
          }
          if (format.match("%s")) {
              format = format.replace("%s", second.toString());
          }
          if (format.match("%S")) {
              format = format.replace("%S", this.format("%02d", second));
          }
          return format;
      }
      static formatDate(date, format) {
          let o = {
              "M+": date.getMonth() + 1,
              "d+": date.getDate(),
              "H+": date.getHours(),
              "m+": date.getMinutes(),
              "s+": date.getSeconds(),
              "q+": Math.floor((date.getMonth() + 3) / 3),
              "S+": date.getMilliseconds()
          };
          let fmt = format;
          if (/(y+)/.test(fmt)) {
              fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
          }
          for (var k in o) {
              if (new RegExp("(" + k + ")").test(fmt)) {
                  fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
              }
          }
          return fmt;
      }
      static generateUUID() {
          let d = new Date().getTime();
          var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
              var r = (d + Math.random() * 16) % 16 | 0;
              d = Math.floor(d / 16);
              return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
          });
          return uuid;
      }
      ;
      static compressUuid(uuid) {
          let hexChars = "0123456789abcdef".split("");
          let hexMap = {};
          for (let i = 0; i < hexChars.length; i++) {
              hexMap[hexChars[i]] = i;
          }
          let base64KeyToChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split("");
          let base64CharToKey = {};
          for (let i = 0; i < base64KeyToChars.length; i++) {
              base64CharToKey[base64KeyToChars[i]] = i;
          }
          uuid = uuid.replace(/-/g, "");
          let arr = uuid.split("");
          let outArr = [];
          outArr.push(arr[0]);
          outArr.push(arr[1]);
          for (let i = 2; i < arr.length; i += 3) {
              let hex1 = hexMap[arr[i]];
              let hex2 = hexMap[arr[i + 1]];
              let hex3 = hexMap[arr[i + 2]];
              outArr.push(base64KeyToChars[(hex1 << 2) | (hex2 >> 2)]);
              outArr.push(base64KeyToChars[((hex2 & 3) << 4) | hex3]);
          }
          return outArr.join("");
      }
      static decompressUuid(uuid) {
          let arr = uuid.split("");
          if (arr.length < 22)
              return uuid;
          let hexChars = "0123456789abcdef".split("");
          let hexMap = {};
          for (let i = 0; i < hexChars.length; i++) {
              hexMap[hexChars[i]] = i;
          }
          let base64KeyToChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split("");
          let base64CharToKey = {};
          for (let i = 0; i < base64KeyToChars.length; i++) {
              base64CharToKey[base64KeyToChars[i]] = i;
          }
          let outArr = [];
          outArr.push(arr[0]);
          outArr.push(arr[1]);
          for (let i = 2; i < arr.length; i += 2) {
              let lhs = base64CharToKey[arr[i]];
              let rhs = base64CharToKey[arr[i + 1]];
              outArr.push(hexChars[lhs >> 2]);
              outArr.push(hexChars[((lhs & 3) << 2) | rhs >> 4]);
              outArr.push(hexChars[rhs & 0xF]);
          }
          outArr.splice(8, 0, "-");
          outArr.splice(13, 0, "-");
          outArr.splice(18, 0, "-");
          outArr.splice(23, 0, "-");
          return outArr.join("");
      }
      static getType(obj) {
          let toString = Object.prototype.toString;
          let map = {
              '[object Boolean]': 'boolean',
              '[object Number]': 'number',
              '[object String]': 'string',
              '[object Function]': 'function',
              '[object Array]': 'array',
              '[object Date]': 'date',
              '[object RegExp]': 'regExp',
              '[object Undefined]': 'undefined',
              '[object Null]': 'null',
              '[object Object]': 'object'
          };
          return map[toString.call(obj)];
      }
      static clone(data) {
          let type = this.getType(data);
          let obj;
          if (window["cc"] && window["cc"].Node && data instanceof window["cc"].Node) {
              return data;
          }
          else if (type === 'object') {
              obj = {};
          }
          else if (type === 'array') {
              obj = [];
          }
          else {
              return data;
          }
          if (type === 'array') {
              for (let i = 0, len = data["length"]; i < len; i++) {
                  obj.push(this.clone(data[i]));
              }
          }
          else if (type === 'object') {
              for (let key in data) {
                  obj[key] = this.clone(data[key]);
              }
          }
          return obj;
      }
      static toArray(arr) {
          if (Array.isArray(arr))
              return arr;
          return [];
      }
      static sumNumberArray(arr) {
          if (!Array.isArray(arr))
              return 0;
          let sum = 0;
          for (let i = 0; i < arr.length; i++) {
              const n = arr[i];
              if (isNaN(n))
                  continue;
              sum += n;
          }
          return sum;
      }
      static getRandomValueInArray(arr) {
          if (!Array.isArray(arr))
              return null;
          return arr[this.random(arr.length) - 1];
      }
      static _convert(match, nosign) {
          if (nosign) {
              match.sign = '';
          }
          else {
              match.sign = match.negative ? '-' : match.sign;
          }
          var l = match.min - match.argument.length + 1 - match.sign.length;
          var pad = new Array(l < 0 ? 0 : l).join(match.pad);
          if (!match.left) {
              if (match.pad == "0" || nosign) {
                  return match.sign + pad + match.argument;
              }
              else {
                  return pad + match.sign + match.argument;
              }
          }
          else {
              if (match.pad == "0" || nosign) {
                  return match.sign + match.argument + pad.replace(/0/g, ' ');
              }
              else {
                  return match.sign + match.argument + pad;
              }
          }
      }
      static format(...args) {
          if (typeof arguments == "undefined") {
              return null;
          }
          if (arguments.length < 1) {
              return null;
          }
          if (typeof arguments[0] != "string") {
              return null;
          }
          if (typeof RegExp == "undefined") {
              return null;
          }
          var string = arguments[0];
          var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
          var matches = new Array();
          var strings = new Array();
          var convCount = 0;
          var stringPosStart = 0;
          var stringPosEnd = 0;
          var matchPosEnd = 0;
          var newString = '';
          var match = null;
          while (match = exp.exec(string)) {
              if (match[9]) {
                  convCount += 1;
              }
              stringPosStart = matchPosEnd;
              stringPosEnd = exp.lastIndex - match[0].length;
              strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
              matchPosEnd = exp.lastIndex;
              matches[matches.length] = {
                  match: match[0],
                  left: match[3] ? true : false,
                  sign: match[4] || '',
                  pad: match[5] || ' ',
                  min: match[6] || 0,
                  precision: match[8],
                  code: match[9] || '%',
                  negative: parseInt(arguments[convCount]) < 0 ? true : false,
                  argument: String(arguments[convCount])
              };
          }
          strings[strings.length] = string.substring(matchPosEnd);
          if (matches.length == 0) {
              return string;
          }
          if ((arguments.length - 1) < convCount) {
              return null;
          }
          var code = null;
          var match = null;
          var substitution = null;
          var i = null;
          for (i = 0; i < matches.length; i++) {
              if (matches[i].code == '%') {
                  substitution = '%';
              }
              else if (matches[i].code == 'b') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
                  substitution = this._convert(matches[i], true);
              }
              else if (matches[i].code == 'c') {
                  matches[i].argument = String(String.fromCharCode(Math.abs(parseInt(matches[i].argument))));
                  substitution = this._convert(matches[i], true);
              }
              else if (matches[i].code == 'd') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
                  substitution = this._convert(matches[i]);
              }
              else if (matches[i].code == 'f') {
                  matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
                  substitution = this._convert(matches[i]);
              }
              else if (matches[i].code == 'o') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
                  substitution = this._convert(matches[i]);
              }
              else if (matches[i].code == 's') {
                  matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length);
                  substitution = this._convert(matches[i], true);
              }
              else if (matches[i].code == 'x') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                  substitution = this._convert(matches[i]);
              }
              else if (matches[i].code == 'X') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                  substitution = this._convert(matches[i]).toUpperCase();
              }
              else {
                  substitution = matches[i].match;
              }
              newString += strings[i];
              newString += substitution;
          }
          newString += strings[i];
          return newString;
      }
      static httpGet(obj) {
          // return;
          // let xhr = new XMLHttpRequest();
          // let timeoutTimer = new ULTimer(obj.timeoutMillisecond / 1000, 1, (timer) => {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // });
          // xhr.onreadystatechange = function (e) {
          //     if (!xhr)
          //         return;
          //     if (xhr.readyState == 4) {
          //         timeoutTimer.stop();
          //         if (xhr.status == 200) {
          //             let responseData = xhr.responseText;
          //             if (obj.success instanceof Function)
          //                 obj.success(responseData);
          //         }
          //         else {
          //             if (xhr) {
          //                 ULLog.console.warn("ULTools.httpGet on error:", xhr.readyState, xhr.status);
          // if (obj.fail instanceof Function)
          //     obj.fail(xhr.status.toString());
          if (obj.fail instanceof Function)
              obj.fail("无网络");
          //                 let temp = xhr;
          //                 xhr = null;
          //                 temp.abort();
          //             }
          //         }
          //     }
          // };
          // xhr.ontimeout = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // };
          // xhr.onerror = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("on error :" + e);
          //     }
          // };
          // timeoutTimer.start();
          // xhr.open('get', obj.url);
          // xhr.send();
      }
      static httpGetJson(obj) {
          let arr = [];
          this.forEachMap(obj.params, (k, v) => {
              arr.push(ULTools.format("%s=%s", encodeURIComponent(k), encodeURIComponent(v)));
          });
          let paramString = arr.join('&');
          let trimUrl = `${obj.url}?${paramString}`;
          ULLog.console.log("ULTools.httpGetJson trimUrl:", trimUrl);
          this.httpGet({
              url: trimUrl,
              timeoutMillisecond: obj.timeoutMillisecond,
              success: obj.success,
              fail: obj.fail
          });
      }
      static httpPost(obj) {
          // return;
          // obj.contentType = obj.contentType || "application/x-www-form-urlencoded;charset=utf-8";
          // let xhr = new XMLHttpRequest();
          // let timeoutTimer = new ULTimer(obj.timeoutMillisecond / 1000, 1, (timer) => {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // });
          // xhr.onreadystatechange = function (e) {
          //     if (!xhr)
          //         return;
          //     if (xhr.readyState == 4) {
          //         timeoutTimer.stop();
          //         if (xhr.status == 200) {
          //             let responseData = xhr.responseText;
          //             if (obj.success instanceof Function)
          //                 obj.success(responseData);
          //         }
          //         else {
          //             ULLog.console.warn("ULTools.httpPost on error:", xhr.readyState, xhr.status);
          // if (obj.fail instanceof Function)
          //     obj.fail(xhr.status.toString());
          if (obj.fail instanceof Function)
              obj.fail("无网络");
          //         }
          //     }
          // };
          // xhr.ontimeout = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // };
          // xhr.onerror = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("on error :" + e);
          //     }
          // };
          // timeoutTimer.start();
          // xhr.open('post', obj.url, true);
          // xhr.setRequestHeader('Content-Type', obj.contentType);
          // xhr.send(obj.postData);
      }
      static httpPostJson(obj) {
          let arr = [];
          this.forEachMap(obj.params, (k, v) => {
              arr.push(ULTools.format("%s=%s", encodeURIComponent(k), encodeURIComponent(v)));
          });
          let paramString = arr.join('&');
          ULLog.console.log("ULTools.httpPostJson paramString:", paramString);
          this.httpPost({
              url: obj.url,
              postData: paramString,
              timeoutMillisecond: obj.timeoutMillisecond,
              success: obj.success,
              fail: obj.fail
          });
      }
      static httpPostFormData(obj) {
          // return;
          // let xhr = new XMLHttpRequest();
          // let timeoutTimer = new ULTimer(obj.timeoutMillisecond / 1000, 1, (timer) => {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // });
          // xhr.onreadystatechange = function (e) {
          //     if (!xhr)
          //         return;
          //     if (xhr.readyState == 4) {
          //         timeoutTimer.stop();
          //         if (xhr.status == 200) {
          //             let responseData = xhr.responseText;
          //             if (obj.success instanceof Function)
          //                 obj.success(responseData);
          //         }
          //         else {
          //             ULLog.console.warn("ULTools.httpPost on error:", xhr.readyState, xhr.status);
          // if (obj.fail instanceof Function)
          //     obj.fail(xhr.status.toString());
          if (obj.fail instanceof Function)
              obj.fail("无网络");
          //         }
          //     }
          // };
          // xhr.ontimeout = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // };
          // xhr.onerror = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("on error :" + e);
          //     }
          // };
          // timeoutTimer.start();
          // xhr.open('post', obj.url, true);
          // xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
          // xhr.send(obj.formData);
      }
      static httpPostEncryption(obj) {
          // return;
          // let xhr = new XMLHttpRequest();
          // let timeoutTimer = new ULTimer(obj.timeoutMillisecond / 1000, 1, (timer) => {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // });
          // xhr.onreadystatechange = function (e) {
          //     if (!xhr)
          //         return;
          //     if (xhr.readyState == 4) {
          //         timeoutTimer.stop();
          //         if (xhr.status == 200) {
          //             let responseData = xhr.responseText;
          //             if (obj.success instanceof Function)
          //                 obj.success(responseData);
          //         }
          //         else {
          //             console.warn("ULTools.httpPost on error:", xhr.readyState, xhr.status);
          // if (obj.fail instanceof Function)
          //     obj.fail(xhr.status.toString());
          if (obj.fail instanceof Function)
              obj.fail("无网络");
          //         }
          //     }
          // };
          // xhr.ontimeout = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("timeout");
          //     }
          // };
          // xhr.onerror = function (e) {
          //     if (xhr) {
          //         let temp = xhr;
          //         xhr = null;
          //         temp.abort();
          //         if (obj.fail instanceof Function)
          //             obj.fail("on error :" + e);
          //     }
          // };
          // let byteArray = this.stringToByte(obj.postString);
          // let key = byteArray.length % 127 || 127;
          // var myArray = new ArrayBuffer(byteArray.length);
          // var longInt8View = new Uint8Array(myArray);
          // for (let i = 0; i < byteArray.length; i++) {
          //     byteArray[i] = byteArray[i] ^ key;
          //     longInt8View[i] = byteArray[i];
          // }
          // timeoutTimer.start();
          // xhr.open('post', obj.url, true);
          // xhr.setRequestHeader('isEncrypt', "1");
          // xhr.setRequestHeader('Content-Type', "application/octet-stream");
          // xhr.send(myArray);
      }
      static httpJsonp(obj) {
          if (!obj || !obj.url) {
              throw new Error("参数不合法");
          }
          let callbackName = ULTools.format("jsonp_%d", ULTools.random(1000000));
          obj.data.callback = callbackName;
          let oHead = document.getElementsByTagName('head')[0];
          let arr = [];
          this.forEachMap(obj.data, (k, v) => {
              arr.push(ULTools.format("%s=%s", encodeURIComponent(k), encodeURIComponent(v)));
          });
          let params = arr.join('&');
          let oS = document.createElement('script');
          oHead.appendChild(oS);
          let timeoutTimer = new ULTimer(obj.timeoutMillisecond / 1000, 1, (timer) => {
              if (!window[callbackName])
                  return;
              window[callbackName] = null;
              oHead.removeChild(oS);
              obj.fail && obj.fail("timeout");
          });
          window[callbackName] = function (json) {
              if (!window[callbackName])
                  return;
              oHead.removeChild(oS);
              timeoutTimer.stop();
              window[callbackName] = null;
              obj.success && obj.success(json);
          };
          oS.src = obj.url + '?' + params;
      }
      static _start_console_print_LAN() {
          if (ULTools.socketingWS) {
              return;
          }
          let lan_debug_address_default = ULConfig.getConfig().s_sdk_lan_debug_address.length > 10 ? ULConfig.getConfig().s_sdk_lan_debug_address : "";
          let lan_id = localStorage.getItem("console_lan_id") || ULStorageManager.getInstance().getStorage("console_lan_id") || lan_debug_address_default;
          ULLog.console.log('console_lan_id:', lan_id);
          // if (lan_id && lan_id.length && "WebSocket" in window) {
          //     ULLog.console.log("支持WebSocket局域网调试");
          //     var address = `ws://${lan_id}:3002/websocket/test`;
          //     var ws = null;
          //     try {
          //         ws = new ULWebSocket(address);
          //         ws.onopen = function () {
          //             ULLog.console.log("Connection open ...");
          //             ULSdkManager.getInstance().moduleCheckerManager.addDebugInfo("console_lan_id", "已开启局域网调试");
          //         };
          //         ws.onmessage = function (evt) {
          //             ULLog.console.log("Received Message:" + evt.data);
          //         };
          //         ws.onclose = function () {
          //             ULLog.console.log("Connection closed");
          //             ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("console_lan_id");
          //             ULTools.socketingWS = null;
          //             ULTools._hack_console_print_method();
          //         };
          //         ws.onerror = function (err) {
          //             ULLog.console.error("Connection onerror:", err);
          //             ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("console_lan_id");
          //             ULTools.socketingWS = null;
          //             ULTools._hack_console_print_method();
          //         };
          //     }
          //     catch (error) {
          //         ws = null;
          //         ULLog.console.log("局域网调试错误:", JSON.stringify(error));
          //     }
          //     finally {
          //         if (ws == null) {
          //             return;
          //         }
          //         ULTools.socketingWS = ws;
          //         ULTools._hack_console_print_method();
          //     }
          // }
          // else {
          ULLog.console.log("不支持WebSocket局域网调试");
          // }
      }
      static _close_console_print_LAN() {
          if (ULTools.socketingWS) {
              ULTools.socketingWS.close();
              ULTools.socketingWS = null;
              ULTools._hack_console_print_method();
          }
      }
      static loadJs(url, fOnSuccess, bCrossOriginAnonymous) {
          let script = document.createElement('script');
          script.type = "text/javascript";
          script.addEventListener('load', (e) => {
              if (fOnSuccess instanceof Function)
                  fOnSuccess();
          });
          script.src = url;
          script.defer = "defer";
          if (bCrossOriginAnonymous) {
              script.crossOrigin = "anonymous";
          }
          let head = document.getElementsByTagName('head')[0];
          head.appendChild(script);
      }
      static stringToByte(str) {
          var bytes = new Array();
          var len, c;
          len = str.length;
          for (var i = 0; i < len; i++) {
              c = str.charCodeAt(i);
              if (c >= 0x010000 && c <= 0x10FFFF) {
                  bytes.push(((c >> 18) & 0x07) | 0xF0);
                  bytes.push(((c >> 12) & 0x3F) | 0x80);
                  bytes.push(((c >> 6) & 0x3F) | 0x80);
                  bytes.push((c & 0x3F) | 0x80);
              }
              else if (c >= 0x000800 && c <= 0x00FFFF) {
                  bytes.push(((c >> 12) & 0x0F) | 0xE0);
                  bytes.push(((c >> 6) & 0x3F) | 0x80);
                  bytes.push((c & 0x3F) | 0x80);
              }
              else if (c >= 0x000080 && c <= 0x0007FF) {
                  bytes.push(((c >> 6) & 0x1F) | 0xC0);
                  bytes.push((c & 0x3F) | 0x80);
              }
              else {
                  bytes.push(c & 0xFF);
              }
          }
          return bytes;
      }
      static byteToString(arr) {
          if (typeof arr === 'string') {
              return arr;
          }
          var str = '', _arr = arr;
          for (var i = 0; i < _arr.length; i++) {
              var one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/);
              if (v && one.length == 8) {
                  var bytesLength = v[0].length;
                  var store = _arr[i].toString(2).slice(7 - bytesLength);
                  for (var st = 1; st < bytesLength; st++) {
                      store += _arr[st + i].toString(2).slice(2);
                  }
                  str += String.fromCharCode(parseInt(store, 2));
                  i += bytesLength - 1;
              }
              else {
                  str += String.fromCharCode(_arr[i]);
              }
          }
          return str;
      }
      static getQueryString(name) {
          var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
          var r = window.location.search.substr(1).match(reg);
          if (r != null) {
              return decodeURI(r[2]);
          }
          return null;
      }
      static createRandomString(len) {
          len = len || 32;
          let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789';
          let maxPos = $chars.length;
          let pwd = '';
          for (let i = 0; i < len; i++) {
              pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
          }
          return pwd;
      }
      static createRandomUserId() {
          let longUuid = this.generateUUID();
          let shortUuid = this.compressUuid(longUuid);
          return shortUuid;
      }
      static createRandomOrderId() {
          let t = new Date().getTime();
          return t + this.createRandomString(7);
      }
      static compareVersion(v1, v2) {
          let arr1 = v1.split('.');
          let arr2 = v2.split('.');
          const len = Math.max(arr1.length, arr2.length);
          while (arr1.length < len) {
              arr1.push('0');
          }
          while (arr2.length < len) {
              arr2.push('0');
          }
          for (let i = 0; i < len; i++) {
              const num1 = parseInt(arr1[i]);
              const num2 = parseInt(arr2[i]);
              if (num1 > num2) {
                  return 1;
              }
              else if (num1 < num2) {
                  return -1;
              }
          }
          return 0;
      }
      static _hack_console_print_method() {
          if (!this._origin_console_log)
              this._origin_console_log = console.log;
          if (!this._origin_console_warn)
              this._origin_console_warn = console.warn;
          if (!this._origin_console_error)
              this._origin_console_error = console.error;
          if (window["cc"] && window["cc"].Node) {
              if (!this._origin_cc_log)
                  this._origin_cc_log = window["cc"]["log"];
              if (!this._origin_cc_warn)
                  this._origin_cc_warn = window["cc"]["warn"];
              if (!this._origin_cc_error)
                  this._origin_cc_error = window["cc"]["error"];
          }
          let trim_console_func = function (type, callback) {
              let trimFunc = function (...data) {
                  callback(...data);
                  if (ULTools.socketingWS) {
                      ULTools.socketingWS.send({
                          type: type,
                          data: data
                      });
                  }
              };
              return trimFunc;
          };
          let config = ULConfig.getConfig();
          console.log = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_LOG ? () => { } : (ULTools.socketingWS ? trim_console_func(1, this._origin_console_log) : this._origin_console_log));
          console.warn = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_WARN ? () => { } : (ULTools.socketingWS ? trim_console_func(2, this._origin_console_warn) : this._origin_console_warn));
          console.error = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_ERROR ? () => { } : (ULTools.socketingWS ? trim_console_func(1, this._origin_console_error) : this._origin_console_error));
          if (window["cc"] && window["cc"].Node) {
              window["cc"]["log"] = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_LOG ? () => { } : (ULTools.socketingWS ? trim_console_func(1, this._origin_cc_log) : this._origin_cc_log));
              window["cc"]["warn"] = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_WARN ? () => { } : (ULTools.socketingWS ? trim_console_func(2, this._origin_cc_warn) : this._origin_cc_warn));
              window["cc"]["error"] = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_ERROR ? () => { } : (ULTools.socketingWS ? trim_console_func(1, this._origin_cc_error) : this._origin_cc_error));
          }
      }
      static jsonValToStr(oldJson) {
          if (!oldJson) {
              return oldJson;
          }
          let targetJson = {};
          let keys = Object.keys(oldJson);
          for (let i = 0; i < keys.length; i++) {
              let key = keys[i];
              let value = oldJson[key];
              if (typeof (value) == "object") {
                  value = JSON.stringify(value);
              }
              else {
                  value = String(value);
              }
              targetJson[key] = value;
          }
          return targetJson;
      }
      static calcWheelTargetByArray(array, maxWeight) {
          let totalWeight = 0;
          for (let i = 0; i < array.length; i++) {
              totalWeight += array[i];
          }
          if (maxWeight != 0) {
              totalWeight = Math.min(totalWeight, maxWeight);
          }
          let random = (Math.random() * totalWeight);
          let sum = 0;
          for (let i = 0; i < array.length; i++) {
              sum += array[i];
              if (sum > random) {
                  return i;
              }
          }
          return null;
      }
      static recordVideoTimeLimit(type, recordDuration) {
          let duration_limit_object = ULConfig.getConfig().t_sdk_record_duration_limit_object || {};
          let tirm_type = (typeof (type) == "string") ? type : (typeof (type) == "number") ? type.toString() : "";
          let type_Object = duration_limit_object[tirm_type] || duration_limit_object["*"] || {};
          let limit_min = type_Object.min || 0;
          let limit_max = type_Object.max || 10000;
          if (limit_min > recordDuration) {
              return { isConform: false, msg: `录屏时间少于${limit_min}秒` };
          }
          else if (limit_max < recordDuration) {
              return { isConform: false, msg: `录屏时间大于${limit_max}秒` };
          }
          return { isConform: true, msg: "" };
      }
      static substrFromByte(str, byteNum) {
          let trimNum = byteNum;
          let trimStrAry = str.split("");
          let cutStr = "";
          while (trimStrAry.length && trimNum > 0) {
              let firstItem = trimStrAry.shift();
              let bytes = ULTools.stringToByte(firstItem);
              trimNum = trimNum - bytes.length;
              if (trimNum >= 0) {
                  cutStr += firstItem;
              }
              else {
                  trimStrAry.unshift(firstItem);
              }
          }
          return { remainStr: trimStrAry.join(""), cutStr: cutStr };
      }
      static isLayaEngine() {
          if (window["Laya"])
              return true;
          return false;
      }
      static startsWith(str, startStr) {
          var sliceStr = str.slice(0, Math.min(str.length, startStr.length));
          return sliceStr == startStr;
      }
      ;
      static isCreator2xEngine() {
          if (window["cc"] && window["cc"].ENGINE_VERSION && this.startsWith(window["cc"].ENGINE_VERSION, "2.")) {
              return true;
          }
          return false;
      }
      static isCreator3xEngine() {
          if (window["cc"] && window["cc"].ENGINE_VERSION && this.startsWith(window["cc"].ENGINE_VERSION, "3.")) {
              return true;
          }
          return false;
      }
      static isString(obj) {
          let type = ULTools.getType(obj);
          return type == "string";
      }
      static isNumber(obj) {
          let type = ULTools.getType(obj);
          return type == "number";
      }
      static isStringOrNumber(obj) {
          let type = ULTools.getType(obj);
          return type == "number" || type == "string";
      }
      static isObject(obj) {
          let type = ULTools.getType(obj);
          return type == "object";
      }
      static isArray(obj) {
          let type = ULTools.getType(obj);
          return type == "array";
      }
      static isFunc(obj) {
          let type = ULTools.getType(obj);
          return type == "function";
      }
      static getStringValue(obj, key, defaultValue = "") {
          if (ULTools.isObject(obj) && ULTools.isString(key)) {
              let value = obj[key];
              if (ULTools.isStringOrNumber(value))
                  return value.toString();
          }
          else if (ULTools.isArray(obj) && ULTools.isNumber(key)) {
              let trimObj = obj;
              if (trimObj.length > Number(key)) {
                  let value = trimObj[key];
                  if (ULTools.isStringOrNumber(value))
                      return value.toString();
              }
          }
          return defaultValue;
      }
      static getNumberValue(obj, key, defaultValue = 0) {
          if (ULTools.isObject(obj) && ULTools.isString(key)) {
              let value = obj[key];
              if (ULTools.isStringOrNumber(value))
                  return !isNaN(Number(value)) ? Number(value) : defaultValue;
          }
          else if (ULTools.isArray(obj) && ULTools.isNumber(key)) {
              let trimObj = obj;
              if (trimObj.length > Number(key)) {
                  let value = obj[key];
                  if (ULTools.isStringOrNumber(value))
                      return !isNaN(Number(value)) ? Number(value) : defaultValue;
              }
          }
          return defaultValue;
      }
      static getArrayValue(obj, key, defaultValue = []) {
          if (ULTools.isObject(obj) && ULTools.isString(key)) {
              let value = obj[key];
              if (ULTools.isArray(value))
                  return value;
          }
          else if (ULTools.isArray(obj) && ULTools.isNumber(key)) {
              let trimObj = obj;
              if (trimObj.length > Number(key)) {
                  let value = trimObj[key];
                  if (ULTools.isArray(value))
                      return value;
              }
          }
          return defaultValue;
      }
      static getObjectValue(obj, key, defaultValue = {}) {
          if (ULTools.isObject(obj) && ULTools.isString(key)) {
              let value = obj[key];
              if (ULTools.isObject(value))
                  return value;
          }
          else if (ULTools.isArray(obj) && ULTools.isNumber(key)) {
              let trimObj = obj;
              if (trimObj.length > Number(key)) {
                  let value = trimObj[key];
                  if (ULTools.isObject(value))
                      return value;
              }
          }
          return defaultValue;
      }
      static randomChinese(length = 10) {
          const randomLength = Math.floor(Math.random() * length) + 1;
          let result = '';
          for (let i = 0; i < randomLength; i++) {
              const random = Math.floor(Math.random() * (0x9fa5 - 0x4e00 + 1)) + 0x4e00;
              result += String.fromCharCode(random);
          }
          return result;
      }
      static getCommonHost() {
          let result = "u";
          result += "l";
          result += "t";
          result += "r";
          result += "a";
          result += "l";
          result += "i";
          result += "s";
          result += "k";
          return result;
      }
  }
  ULTools.socketingWS = null;

  class ULConfig {
      static init() {
          this.bInit = true;
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, ULConst.PRIORITY_NONE, this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
      }
      static getConfig() {
          if (!this.bInit) {
              this.init();
          }
          if (!this.currConfig) {
              this.currConfig = ULTools.clone(cConfig);
          }
          return this.currConfig;
      }
      static get(key) {
          let config = this.getConfig();
          let value = config[key];
          return value;
      }
      static updateValueByCop(cop) {
          let newConfig = ULTools.clone(cConfig);
          ULTools.forEachMap(cop, (k, v) => {
              if (v == "nil")
                  v = "";
              newConfig[k] = v;
          });
          this.currConfig = newConfig;
          ULConst.B_INNER_DEBUG = this.getConfig().i_sdk_debug_mode >= ULConst.CONSOLE_OUTPUT_LEVEL_INNER_DEBUG;
      }
      static onCmdSdkCollectionModuleCheckerConfig(e) {
          let config = e.getReturnValue() || [];
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "cConfig:" });
          config.push({
              type: "button",
              text: "显示cConfig",
              onClick: () => {
                  let data = this.currConfig;
                  let keys = Object.keys(data);
                  keys.sort();
                  let conf = [];
                  for (let i = 0; i < keys.length; i++) {
                      const key = keys[i];
                      let value = JSON.stringify(data[key]);
                      let text = ULTools.format("[%s] = [%s]\n", key, value);
                      if (text.length >= 64) {
                          text = text.substr(0, 64 - 2) + "..";
                      }
                      conf.push({ text: text, value: { k: key, v: value } });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("cConfig", conf, (value) => {
                      ULSdkManager.getInstance().moduleCheckerManager.alertPrompt(value.k, value.v, "关闭", null);
                  }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({
              type: "label",
              text: ULTools.format("i_sdk_debug_mode=[%s]", this.getConfig().i_sdk_debug_mode),
              name: "labelDebugMode",
          });
          config.push({
              type: "button",
              text: "切换调试模式",
              onClick: () => {
                  let conf = [
                      { text: "0: 全关", value: 0 },
                      { text: "1: warn + error", value: 1 },
                      { text: "2: log + warn + error", value: 2 },
                      { text: "3: 开启各模块的DEBUG + log + warn + error", value: 3 },
                  ];
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("选择调试模式", conf, (value) => {
                      cConfig.i_sdk_debug_mode = value;
                      this.currConfig.i_sdk_debug_mode = value;
                      ULTools._hack_console_print_method();
                      ULConst.B_INNER_DEBUG = this.getConfig().i_sdk_debug_mode >= ULConst.CONSOLE_OUTPUT_LEVEL_INNER_DEBUG;
                      ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelDebugMode", ULTools.format("i_sdk_debug_mode=[%s]", this.getConfig().i_sdk_debug_mode));
                  });
              },
          });
          config.push({ type: "newLine" });
          config.push({
              type: "label",
              text: "局域网调试：",
              name: "labelSocketDebugMode",
          });
          config.push({
              type: "inputBox",
              text: ULStorageManager.getInstance().getStorage("console_lan_id"),
              name: "console_lan_id"
          });
          config.push({
              type: "button",
              text: "切换局域网调试模式",
              onClick: () => {
                  let console_lan_id = ULSdkManager.getInstance().moduleCheckerManager.getItemText("console_lan_id");
                  let conf = [
                      { text: "关闭调试", value: 0 },
                      { text: "开启调试: " + console_lan_id, value: 1 },
                  ];
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("选择调试模式", conf, (value) => {
                      if (value == 0) {
                          ULStorageManager.getInstance().setStorage("console_lan_id", null);
                          ULTools._close_console_print_LAN();
                      }
                      else {
                          ULStorageManager.getInstance().setStorage("console_lan_id", console_lan_id);
                          ULTools._start_console_print_LAN();
                      }
                  });
              },
          });
          config.push({ type: "newLine" });
          config.push({
              type: "label",
              text: `SDK log 开关：(${this.sdkLogSwitch ? "已开启" : "已关闭"})`,
              name: "SDK_LOG_MODE",
          });
          config.push({
              type: "button",
              text: `切换状态`,
              onClick: () => {
                  if (this.sdkLogSwitch) {
                      this.sdkLogSwitch = false;
                      ULLog.console.allowConsole = false;
                  }
                  else {
                      this.sdkLogSwitch = true;
                      ULLog.console.allowConsole = true;
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.setItemText("SDK_LOG_MODE", `SDK log 开关：(${this.sdkLogSwitch ? "已开启" : "已关闭"})`);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "显示sdk通信记录:" });
          config.push({
              type: "button",
              text: "查看...",
              onClick: () => {
                  let log = ULSdkManager.getInstance().getSdkCommunicationLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const v = log[i];
                      try {
                          let data = JSON.parse(v);
                          ULLog.console.log(i, v, data);
                          conf.push({
                              text: ULTools.format("%d: %s", i, data.cmd),
                              value: v,
                          });
                      }
                      catch (error) {
                      }
                  }
                  ULLog.console.log("conf", conf);
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("sdk通信记录（最近100条）", conf, (v) => {
                      ULSdkManager.getInstance().moduleCheckerManager.showBigTextWithPickerDialog("详情", v, 40);
                  }, true);
              },
          });
          config.push({ type: "newLine" });
          e.setReturnValue(config, true);
      }
  }
  ULConfig.bInit = false;
  ULConfig.sdkLogSwitch = true;

  class ULModuleBase {
      constructor() {
          ULLog.console.log("ULModuleBase-constructor");
      }
      init() {
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, this.getCollectionModuleCheckerPriority(), this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
      }
      onDisposeModule() {
          ULLog.console.log("ULModuleBase-onDisposeModule");
      }
      loadSubModules() {
          return [];
      }
      getSubAdModuleClassName() {
          return [];
      }
      getAdMainClassName() {
          return "";
      }
      createSubAdObj(className, param) {
          return null;
      }
      createMainAdObj() {
          return null;
      }
      loadModuleCheckerConfig() {
          return [];
      }
      onCmdSdkCollectionModuleCheckerConfig(e) {
          let config = e.getReturnValue() || [];
          let ret = this.loadModuleCheckerConfig();
          for (let i = 0; i < ret.length; i++) {
              const v = ret[i];
              config.push(v);
          }
          e.setReturnValue(config, true);
      }
      getCollectionModuleCheckerPriority() {
          return ULConst.PRIORITY_NONE;
      }
  }

  class ULModuleCdk extends ULModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModuleCdk";
      }
      init() {
          super.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_USE_CDKEY, 1, this.onCmdUseCdkey.bind(this));
      }
      requestUseCdk(userId, cdkStr, channelId) {
          let config = ULConfig.getConfig();
          let appId = config.s_sdk_cdk_app_id;
          let timeout = config.i_net_timeout;
          let url = ULTools.format("%s?userId=%s&cdkStr=%s&appId=%s&channelId=%s", config.s_sdk_cdk_url, userId, cdkStr, appId, channelId);
          ULLog.console.log("ULModuleCdk.requestUseCdk", url);
          // ULTools.httpGet({
          //     url: url,
          //     timeoutMillisecond: timeout,
          //     success: (responseText) => {
          //         responseText = responseText.replace("\"[", "[");
          //         responseText = responseText.replace("]\"", "]");
          //         responseText = responseText.replace("\"0\"", "\"1\"");
          //         responseText = responseText.replace("message", "data");
          //         let data = JSON.parse(responseText);
          //         ULSdkManager.getInstance().statisManager.reportOpenCdk(data.code);
          //         if (data.code == 1) {
          //             ULSdkManager.getInstance().response(ULConst.CMD_USE_CDKEY_RESULT, {
          //                 code: 1,
          //                 data: data.data,
          //                 message: "兑换成功",
          //             });
          //         }
          //         else {
          //             ULSdkManager.getInstance().response(ULConst.CMD_USE_CDKEY_RESULT, {
          //                 code: 0,
          //                 data: [],
          //                 message: data.data,
          //             });
          //         }
          //     },
          //     fail: () => {
          ULSdkManager.getInstance().statisManager.reportOpenCdk(0);
          ULSdkManager.getInstance().response(ULConst.CMD_USE_CDKEY_RESULT, {
              code: 0,
              message: "请求超时",
          });
          //     },
          // });
      }
      onCmdUseCdkey(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          let userId = data.userId;
          let cdkStr = data.cdkStr;
          let channelId = config.s_sdk_cop_channel_id;
          this.requestUseCdk(userId, cdkStr, channelId);
      }
  }

  class ULModuleMegadata extends ULModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModuleMegadata";
      }
      init() {
          super.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_MEGADATA_SERVER, 1, this.onCmdMegadataServer.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_POST_MEGADATA, 1, this.onCmdPostMegadata.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_RESUME, ULConst.PRIORITY_NONE, this.onCmdSdkOnGameResume.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_PAUSE, ULConst.PRIORITY_NONE, this.onCmdSdkOnGamePause.bind(this));
          this.gameLevelStartMsgList = {};
      }
      onCmdMegadataServer(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          if (Array.isArray(data) && data.length > 0) {
              ULSdkManager.getInstance().response(ULConst.CMD_MEGADATA_SERVER_RESULT, {
                  code: 1,
                  message: "上报成功",
              });
          }
          else {
              ULSdkManager.getInstance().response(ULConst.CMD_MEGADATA_SERVER_RESULT, {
                  code: 0,
                  message: "数据异常",
              });
          }
          let statisticsAddr = config.s_sdk_megadata_url;
          if (!!ULSdkManager.getInstance().statisManager.getPostMegadataMode()) {
              statisticsAddr = config.s_sdk_megadata_test_url;
          }
          if (statisticsAddr.search(/megadatav7/gi) != -1) {
              ULLog.console.warn("应用确定使用v7版本统计，/c/megadataServer接口数据不再进行上报");
              return;
          }
          let rawDatas = ULTools.clone(data);
          let actionType = rawDatas[0];
          if (actionType == ULConst.STATIS_USER_EVENT_POINT_EVENT) {
              ULSdkManager.getInstance().statisManager.reportPointEvent(rawDatas[1], rawDatas[2]);
              return;
          }
          if (actionType == ULConst.STATIS_USER_EVENT_GAME_LEVEL_START) {
              let gameLevelStartTime = ULTools.time();
              let levelName = rawDatas[1] + "";
              this.gameLevelStartMsgList[levelName] = gameLevelStartTime;
          }
          if (actionType == ULConst.STATIS_USER_EVENT_GAME_LEVEL_COMPLETE) {
              let levelName = rawDatas[1] + "";
              let usedTime = ULTools.time() - this.gameLevelStartMsgList[levelName];
              this.gameLevelStartMsgList[levelName] = undefined;
              delete this.gameLevelStartMsgList[levelName];
              if (isNaN(usedTime))
                  usedTime = 0;
              if (usedTime < 0 || usedTime > 10000) {
                  usedTime = 0;
              }
              rawDatas.push(Math.floor(usedTime).toString());
          }
          ULSdkManager.getInstance().statisManager.reportUserEvent(rawDatas);
      }
      onCmdPostMegadata(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          if (Array.isArray(data) && data.length > 0) {
              ULSdkManager.getInstance().response(ULConst.CMD_POST_MEGADATA_RESULT, {
                  code: 1,
                  message: "上报成功",
              });
          }
          else {
              ULSdkManager.getInstance().response(ULConst.CMD_POST_MEGADATA_RESULT, {
                  code: 0,
                  message: "数据异常",
              });
          }
          let rawDatas = ULTools.clone(data);
          let actionType = rawDatas[0];
          let typeId = "";
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_LEVEL_START) {
              let gameLevelStartTime = ULTools.time();
              let levelName = rawDatas[1] + "";
              this.gameLevelStartMsgList[levelName] = gameLevelStartTime;
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_LEVEL_START_EVENT);
          }
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_LEVEL_COMPLETE) {
              let levelName = rawDatas[1] + "";
              let usedTime = ULTools.time() - this.gameLevelStartMsgList[levelName];
              this.gameLevelStartMsgList[levelName] = undefined;
              delete this.gameLevelStartMsgList[levelName];
              if (isNaN(usedTime))
                  usedTime = 0;
              if (usedTime < 0 || usedTime > 10000) {
                  usedTime = 0;
              }
              rawDatas.push(Math.floor(usedTime).toString());
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_LEVEL_COMPLETE_EVENT);
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, ["levelComplete", levelName]);
          }
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_COIN_CHANGE) {
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_COIN_CHANGE_EVENT);
          }
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_ITEM_BUY) {
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_ITEM_BUY);
          }
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_BUY_ACTION) {
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_BUY_ACTION);
          }
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_COMMON_EVENT) {
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_COMMON_EVENT);
              let postData = ULTools.clone(rawDatas);
              postData.shift();
              ULLog.console.log("ULModuleMegadta.onCmdPostMegadatapostData postData:", postData);
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, postData);
          }
          if (actionType == ULConst.STATIS_USER_ACTION_EVENT_VIDEO_POINT_EVENT) {
              typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_VIDEO_POINT_EVENT);
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, ["videoPointShow", rawDatas[1]]);
          }
          if (typeId != "") {
              rawDatas.shift();
              ULLog.console.log("ULModuleMegadta.onCmdPostMegadatapostData typeId:", typeId, " rawDatas:", rawDatas);
              ULSdkManager.getInstance().statisManager.reportUserActionEvent(rawDatas, typeId);
          }
      }
      onCmdSdkOnGameResume(e) {
          let config = ULConfig.getConfig();
          for (let key in this.gameLevelStartMsgList) {
              this.gameLevelStartMsgList[key] = ULTools.time();
          }
          ULLog.console.log("ULModuleMegadta.onCmdSdkOnGameResume gameLevelStartTime:", this.gameLevelStartMsgList);
      }
      onCmdSdkOnGamePause(e) {
          let config = ULConfig.getConfig();
          for (let key in this.gameLevelStartMsgList) {
              ULLog.console.log("ULModuleMegadta.onCmdSdkOnGamePause currentGameLevelName:", key);
              let usedTime = ULTools.time() - this.gameLevelStartMsgList[key];
              if (isNaN(usedTime))
                  usedTime = 0;
              if (usedTime < 0 || usedTime > 10000) {
                  usedTime = 0;
              }
              let rawDatas = new Array();
              rawDatas.push(key);
              rawDatas.push("2");
              rawDatas.push("pause");
              rawDatas.push("0");
              rawDatas.push("0");
              rawDatas.push("0");
              rawDatas.push("0");
              rawDatas.push("0");
              rawDatas.push("0");
              rawDatas.push(Math.floor(usedTime).toString());
              let typeId = ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_LEVEL_COMPLETE_EVENT);
              ULSdkManager.getInstance().statisManager.reportUserActionEvent(rawDatas, typeId);
          }
      }
  }

  class ULModuleUserData extends ULModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModuleUserData";
      }
      init() {
          super.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SAVE_USER_DATA, ULConst.PRIORITY_DISABLE, this.onCmdSaveUserData.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_GET_USER_DATA, ULConst.PRIORITY_DISABLE, this.onCmdGetUserData.bind(this));
      }
      requestUploadUserData(userId, userData) {
          let config = ULConfig.getConfig();
          let url = config.s_sdk_user_data_save_url;
          let postData = {
              userId: userId,
              data: userData,
          };
          ULTools.httpPost({
              url: url,
              postData: postData,
              timeoutMillisecond: config.i_net_timeout,
              success: (responseText) => {
                  let responseData = JSON.parse(responseText);
                  if (responseData && responseData.code == 0) {
                      ULSdkManager.getInstance().response(ULConst.CMD_SAVE_USER_DATA_RESULT, {
                          code: 1,
                          msg: "存档成功",
                      });
                  }
                  else {
                      ULSdkManager.getInstance().response(ULConst.CMD_SAVE_USER_DATA_RESULT, {
                          code: 0,
                          msg: "存档失败",
                      });
                  }
              },
              fail: () => {
                  ULSdkManager.getInstance().response(ULConst.CMD_SAVE_USER_DATA_RESULT, {
                      code: 0,
                      msg: "存档超时",
                  });
              },
          });
      }
      requestDownloadUserData(userId) {
          let config = ULConfig.getConfig();
          let url = ULTools.format("%s?userId=%s", config.s_sdk_user_data_get_url, userId);
          ULLog.console.log("ULModuleUserData.requestDownloadUserData", userId);
          ULLog.console.log("  url", url);
          // ULTools.httpGet({
          //     url: url,
          //     timeoutMillisecond: config.i_net_timeout,
          //     success: (responseText) => {
          //         let responseData = JSON.parse(responseText);
          //         ULLog.console.log("  ULModuleUserData.requestDownloadUserData success", responseText);
          //         if (responseData && responseData.code == 0) {
          //             ULSdkManager.getInstance().response(ULConst.CMD_GET_USER_DATA_RESULT, {
          //                 code: 1,
          //                 userData: responseData.data,
          //                 msg: "模拟成功",
          //             });
          //         }
          //         else {
          ULSdkManager.getInstance().response(ULConst.CMD_GET_USER_DATA_RESULT, {
              code: 0,
              userData: {},
              msg: "读取存档失败",
          });
          //         }
          //     },
          //     fail: (err) => {
          //         ULLog.console.log("  ULModuleUserData.requestDownloadUserData fail", err);
          //         ULSdkManager.getInstance().response(ULConst.CMD_GET_USER_DATA_RESULT, {
          //             code: 0,
          //             userData: {},
          //             msg: "读取存档超时",
          //         });
          //     },
          // });
      }
      onCmdSaveUserData(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let data = e.data;
          let userId = channelInfo.uuid;
          let userData = data.userData;
          if (!userId) {
              ULLog.console.log("ULModuleUserData.onCmdSaveUserData userId not found!");
              return;
          }
          this.requestUploadUserData(userId, userData);
      }
      onCmdGetUserData(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let data = e.data;
          let userId = channelInfo.uuid;
          this.requestDownloadUserData(userId);
      }
  }

  class ULClipboardManager {
      static getInstance() {
          if (!this._instance) {
              this._instance = new ULClipboardManager();
          }
          return this._instance;
      }
      getClipboardData(finishCallback) {
          if (!(finishCallback instanceof Function)) {
              ULLog.console.warn("ULClipboardManager.getClipboardData finishCallback not a function");
              return;
          }
          let bCalled = ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_GET_CLIPBOARD_DATA, {
              finishCallback: finishCallback,
          });
          if (!bCalled) {
              finishCallback(null);
          }
      }
      setClipboardData(data, finishCallback) {
          if (!(finishCallback instanceof Function)) {
              ULLog.console.warn("ULClipboardManager.setClipboardData finishCallback not a function");
              return;
          }
          let bCalled = ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_SET_CLIPBOARD_DATA, {
              data: data,
              finishCallback: finishCallback,
          });
          if (!bCalled) {
              finishCallback(false);
          }
      }
      isSupport() {
          let bSupport = !!ULEventDispatcher.getInstance().dispatchWithReturn(ULConst.CMD_SDK_IS_SUPPORT_CLIPBOARD, {});
          return bSupport;
      }
  }
  ULClipboardManager._instance = null;

  class ULModuleClipboard extends ULModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModuleClipboard";
      }
      init() {
          super.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SET_CLIPBOARD_DATA, 1, this.onCmdSetClipboardData.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_GET_CLIPBOARD_DATA, 1, this.onCmdGetClipboardData.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SET_VERSION, 1, this.onCmdSetVersion.bind(this));
      }
      onCmdSetClipboardData(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          let clipboardData = data.clipboardData;
          let userData = data.userData;
          ULClipboardManager.getInstance().setClipboardData(clipboardData, (bSuccess) => {
              if (bSuccess) {
                  ULSdkManager.getInstance().response(ULConst.CMD_SET_CLIPBOARD_DATA_RESULT, {
                      code: 1,
                      msg: "保存成功",
                      clipboardData: clipboardData,
                      userData: userData,
                  });
              }
              else {
                  ULSdkManager.getInstance().response(ULConst.CMD_SET_CLIPBOARD_DATA_RESULT, {
                      code: 0,
                      msg: "保存失败",
                      clipboardData: clipboardData,
                      userData: userData,
                  });
              }
          });
      }
      onCmdGetClipboardData(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          let userData = data.userData;
          ULClipboardManager.getInstance().getClipboardData((clipboardData) => {
              if (clipboardData) {
                  ULSdkManager.getInstance().response(ULConst.CMD_GET_CLIPBOARD_DATA_RESULT, {
                      code: 1,
                      msg: "获取成功",
                      clipboardData: clipboardData,
                      userData: userData,
                  });
              }
              else {
                  ULSdkManager.getInstance().response(ULConst.CMD_GET_CLIPBOARD_DATA_RESULT, {
                      code: 0,
                      msg: "获取失败",
                      clipboardData: null,
                      userData: userData,
                  });
              }
          });
      }
      onCmdSetVersion(e) {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          channelInfo.isSupportClipboardData = ULClipboardManager.getInstance().isSupport();
          ULLog.console.log(ULTools.format("ULModuleClipboard.onCmdSetVersion mark isSupportClipboardData = %s", channelInfo.isSupportClipboardData));
      }
  }

  class ULModuleDefault extends ULModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModuleDefault";
          this.hadShowAffiche = false;
      }
      init() {
          super.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SET_VERSION, 1, this.onCmdSetVersion.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_CHECK_TIME_CHANGE, 1, (e) => {
              this.checkTimeChange((bChange, serverTime, timeDeferenceLimit) => {
                  ULSdkManager.getInstance().response(ULConst.CMD_CHECK_TIME_CHANGE_RESULT, {
                      bChange: bChange,
                      serverTime: serverTime,
                      timeDeferenceLimit: timeDeferenceLimit
                  }, true);
              });
          });
      }
      checkTimeChange(callback) {
          let config = ULConfig.getConfig();
          let url = config.s_sdk_common_checktime_url;
          let timeout = config.i_net_timeout;
          let deferenceLimit = config.i_sdk_common_checktime_deferenceLimit;
          deferenceLimit = !isNaN(Number(deferenceLimit)) ? Number(deferenceLimit) : 300000;
          // if (url) {
          //     ULTools.httpGet({
          //         url: url,
          //         timeoutMillisecond: timeout,
          //         success: (responseText) => {
          //             let serviceTime = !isNaN(Number(responseText)) ? Number(responseText) : 0;
          //             let difference = Math.abs(serviceTime - new Date().getTime());
          //             console.log("now:", new Date().getTime());
          //             console.log("serviceTime:", serviceTime);
          //             console.log("difference:", difference);
          //             callback(difference > deferenceLimit, serviceTime, deferenceLimit);
          //         },
          //         fail: () => {
          //             callback(true, 0, deferenceLimit);
          //         },
          //     });
          // }
          // else {
          Promise.resolve().then(() => {
              callback(false, new Date().getTime(), deferenceLimit);
          });
          // }
      }
      onCmdSetVersion(e) {
          if (!this.hadShowAffiche) {
              this.hadShowAffiche = true;
              let config = ULConfig.getConfig();
              let affiche_url = config.s_sdk_common_affiche_url;
              if (affiche_url.length > 5) {
                  let title = config.s_sdk_common_affiche_title || "最新公告";
                  ULSdkManager.getInstance().moduleCheckerManager.showPrivacyContent(title, affiche_url);
              }
          }
      }
  }

  let hbs = window["hbs"];
  let qg$1 = window["qg"];
  let tt = window["tt"];
  let wx = window["wx"];
  let qq = window["qq"];
  class ULModulePrivacyPolicy extends ULModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModulePrivacyPolicy";
      }
      get isAgreePrivacyPolicy() {
          let value = ULStorageManager.getInstance().getStorage("hadSurePrivacy") || "0";
          return value == "1";
      }
      agreePrivacyPolicy() {
          ULStorageManager.getInstance().setStorage("hadSurePrivacy", "1");
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          channelInfo.isAgreePrivacyPolicy = true;
      }
      init() {
          super.init();
          this.initSdk();
      }
      initSdk() {
          ULLog.console.info("ULModulePrivacyPolicy-initSdk");
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          channelInfo.isAgreePrivacyPolicy = this.isAgreePrivacyPolicy;
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SHOW_PRIVACY, 1000, this.onCmdShowPrivacy.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_OPEN_ADVANCED_SETTING, 1000, this.onCmdOpenAdvancedSetting.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SET_VERSION, 1, this.onCmdSetVersion.bind(this));
      }
      onCmdOpenAdvancedSetting(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let items = [];
          items.push({
              name: `注销账户`,
              handle: () => {
                  ULSdkManager.getInstance().moduleCheckerManager.alertPrompt2("温馨提示", "注销账户会导致该账户不可用", "知道了", "再想想", () => {
                      localStorage.clear();
                      this.exitGame();
                      localStorage.clear();
                  }, () => {
                  });
              }
          });
          items.push({
              name: `隐私政策界面`,
              handle: () => {
                  // ULSdkManager.getInstance().moduleCheckerManager.alertPrivacy("温馨提示", config.t_sdk_privacyPolicy_dataArray, ["返回"], [() => {
                  // }]);
                  UIConfig.closeDialogOnSide = false;
                  Laya.Dialog.open("ads/HuaweiMsg.json", false, null, Laya.Handler.create(this, (view) => {
                      view.panel.vScrollBarSkin = "";
                      view.btnCancel.on(Laya.Event.CLICK, view, () => {
                          view.close();
                          qg$1.exitApplication({
                              success: function () {
                                  console.log("exitApplication success");
                              },
                              fail: function () {
                                  console.log("exitApplication fail");
                              },
                              complete: function () {
                                  console.log("exitApplication complete");
                              }
                          });
                      });
                      view.btnConfirm.on(Laya.Event.CLICK, view, () => {
                          Laya.LocalStorage.setItem("huaweiMsg", "6666");
                          view.close();
                          // YYGMiniGames.showBanner()
                      });
                  }));
                  }
          });
          for (let item of config.t_sdk_privacyPolicy_dataArray) {
              items.push({
                  name: `《${item.name}》`,
                  handle: () => {
                      UIConfig.closeDialogOnSide = false;
                      Laya.Dialog.open("ads/HuaweiMsg.json", false, null, Laya.Handler.create(this, (view) => {
                          view.panel.vScrollBarSkin = "";
                          view.btnCancel.on(Laya.Event.CLICK, view, () => {
                              view.close();
                              qg$1.exitApplication({
                                  success: function () {
                                      console.log("exitApplication success");
                                  },
                                  fail: function () {
                                      console.log("exitApplication fail");
                                  },
                                  complete: function () {
                                      console.log("exitApplication complete");
                                  }
                              });
                          });
                          view.btnConfirm.on(Laya.Event.CLICK, view, () => {
                              Laya.LocalStorage.setItem("huaweiMsg", "6666");
                              view.close();
                              // YYGMiniGames.showBanner()
                          });
                      }));
                      // ULSdkManager.getInstance().moduleCheckerManager.showPrivacyContent(item.name, item.url, item["replaceParam"] || {});
                  }
              });
          }
          ULSdkManager.getInstance().moduleCheckerManager.showSettingView("高级设置", items);
      }
      onCmdSetVersion(e) {
          const msg = Laya.LocalStorage.getItem("huaweiMsg");
          if (!msg) {
              this.showPrivacyPolicy();
          }
      }
      onCmdShowPrivacy(e) {
          e.stopImmediatePropagation();
          let data = e.data || {};
          let type = data.type || "0";
          let userData = data.userData || "";
          let callback = (code, msg) => {
              ULSdkManager.getInstance().response(ULConst.CMD_SHOW_PRIVACY_RESULT, {
                  code: code,
                  msg: msg,
                  type: type,
                  userData: userData,
              });
          };
          if (!type) {
              callback(0, "type 值错误");
              return;
          }
          let config = ULConfig.getConfig();
          let dataArray = config.t_sdk_privacyPolicy_dataArray || [];
          let index = Math.max(0, Number(type));
          if (index < dataArray.length) {
              let content = dataArray[index];
              ULSdkManager.getInstance().moduleCheckerManager.showPrivacyContent(content.name, content.url, content["replaceParam"] || {});
              callback(1, "执行成功");
          }
          else {
              callback(0, "未找到对应配置");
          }
      }
      showPrivacyPolicy() {
          
              UIConfig.closeDialogOnSide = false;
              Laya.Dialog.open("ads/HuaweiMsg.json", false, null, Laya.Handler.create(this, (view) => {
                  view.panel.vScrollBarSkin = "";
                  view.btnCancel.on(Laya.Event.CLICK, view, () => {
                      view.close();
                      qg$1.exitApplication({
                          success: function () {
                              console.log("exitApplication success");
                          },
                          fail: function () {
                              console.log("exitApplication fail");
                          },
                          complete: function () {
                              console.log("exitApplication complete");
                          }
                      });
                  });
                  view.btnConfirm.on(Laya.Event.CLICK, view, () => {
                      Laya.LocalStorage.setItem("huaweiMsg", "6666");
                      view.close();
                      // YYGMiniGames.showBanner()
                  });
              }));
          // }
          // if (!this.isAgreePrivacyPolicy) {
          //     let config = ULConfig.getConfig();
          //     ULSdkManager.getInstance().moduleCheckerManager.alertPrivacy("温馨提示", config.t_sdk_privacyPolicy_dataArray, ["拒绝", "同意"], [() => {
          //         this.exitGame();
          //         return true;
          //     }, () => {
          //         this.agreePrivacyPolicy();
          //         ULSdkManager.getInstance().waits.removeCondition("privacy_agree");
          //     }]);
          // }
          // else {
          //     ULSdkManager.getInstance().waits.removeCondition("privacy_agree");
          // }
      }
      exitGame() {
          let modeArray = [hbs, qg$1, tt, wx, qq];
          while (modeArray.length) {
              let mode = modeArray.pop();
              if (mode && mode != 'undefined' && mode.exitApplication) {
                  mode.exitApplication({
                      success: function () {
                          ULLog.console.log("exitApplication success");
                      },
                      fail: function () {
                          ULLog.console.log("exitApplication fail");
                      },
                      complete: function () {
                          ULLog.console.log("exitApplication complete");
                      }
                  });
              }
              else if (mode && mode != 'undefined' && mode.exitMiniProgram) {
                  mode.exitMiniProgram({
                      success: function () {
                          ULLog.console.log("exitMiniProgram success");
                      },
                      fail: function () {
                          ULLog.console.log("exitMiniProgram fail");
                      },
                      complete: function () {
                          ULLog.console.log("exitMiniProgram complete");
                      }
                  });
              }
          }
          ULLog.console.log("未配置 退出游戏 渠道");
      }
  }

  function pkcs1unpad2(d, n) {
      var b = d.toByteArray();
      var i = 0;
      while (i < b.length && b[i] == 0) ++i;
      if (b.length - i != n - 1 || b[i] != 2)
          return null;
      ++i;
      while (b[i] != 0)
          if (++i >= b.length) return null;
      var ret = "";
      while (++i < b.length) {
          var c = b[i] & 255;
          if (c < 128) { // utf-8 decode
              ret += String.fromCharCode(c);
          }
          else if ((c > 191) && (c < 224)) {
              ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
              ++i;
          }
          else {
              ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
              i += 2;
          }
      }
      return ret;
  }

  // PKCS#1 (OAEP) mask generation function
  function oaep_mgf1_str(seed, len, hash) {
      var mask = '', i = 0;

      while (mask.length < len) {
          mask += hash(seed + String.fromCharCode.apply(String, [
              (i & 0xff000000) >> 24,
              (i & 0x00ff0000) >> 16,
              (i & 0x0000ff00) >> 8,
              i & 0x000000ff]));
          i += 1;
      }

      return mask;
  }

  function oaep_unpad(d, n, hash, hashLen) {
      var MD = KJUR.crypto.MessageDigest;
      var Util = KJUR.crypto.Util;
      var algName = null;

      if (!hash) hash = "sha1";

      if (typeof hash === "string") {
          algName = MD.getCanonicalAlgName(hash);
          hashLen = MD.getHashLength(algName);
          hash = function (s) {
              return hextorstr(Util.hashHex(rstrtohex(s), algName));
          };
      }

      d = d.toByteArray();

      var i;

      for (i = 0; i < d.length; i += 1) {
          d[i] &= 0xff;
      }

      while (d.length < n) {
          d.unshift(0);
      }

      d = String.fromCharCode.apply(String, d);

      if (d.length < 2 * hashLen + 2) {
          throw "Cipher too short";
      }

      var maskedSeed = d.substr(1, hashLen);
      var maskedDB = d.substr(hashLen + 1);

      var seedMask = oaep_mgf1_str(maskedDB, hashLen, hash);
      var seed = [], i;

      for (i = 0; i < maskedSeed.length; i += 1) {
          seed[i] = maskedSeed.charCodeAt(i) ^ seedMask.charCodeAt(i);
      }

      var dbMask = oaep_mgf1_str(String.fromCharCode.apply(String, seed),
          d.length - hashLen, hash);

      var DB = [];

      for (i = 0; i < maskedDB.length; i += 1) {
          DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i);
      }

      DB = String.fromCharCode.apply(String, DB);

      if (DB.substr(0, hashLen) !== hash('')) {
          throw "Hash mismatch";
      }

      DB = DB.substr(hashLen);

      var first_one = DB.indexOf('\x01');
      var last_zero = (first_one != -1) ? DB.substr(0, first_one).lastIndexOf('\x00') : -1;

      if (last_zero + 1 != first_one) {
          throw "Malformed data";
      }

      return DB.substr(first_one + 1);
  }

  // Set the private key fields N, e, and d from hex strings
  function RSASetPrivate(N, E, D) {
      this.isPrivate = true;
      if (typeof N !== "string") {
          this.n = N;
          this.e = E;
          this.d = D;
      }
      else if (N != null && E != null && N.length > 0 && E.length > 0) {
          this.n = parseBigInt(N, 16);
          this.e = parseInt(E, 16);
          this.d = parseBigInt(D, 16);
      }
      else
          throw "Invalid RSA private key";
  }

  // Set the private key fields N, e, d and CRT params from hex strings
  function RSASetPrivateEx(N, E, D, P, Q, DP, DQ, C) {
      this.isPrivate = true;
      this.isPublic = false;
      if (N == null) throw "RSASetPrivateEx N == null";
      if (E == null) throw "RSASetPrivateEx E == null";
      if (N.length == 0) throw "RSASetPrivateEx N.length == 0";
      if (E.length == 0) throw "RSASetPrivateEx E.length == 0";

      if (N != null && E != null && N.length > 0 && E.length > 0) {
          this.n = parseBigInt(N, 16);
          this.e = parseInt(E, 16);
          this.d = parseBigInt(D, 16);
          this.p = parseBigInt(P, 16);
          this.q = parseBigInt(Q, 16);
          this.dmp1 = parseBigInt(DP, 16);
          this.dmq1 = parseBigInt(DQ, 16);
          this.coeff = parseBigInt(C, 16);
      } else {
          throw "Invalid RSA private key in RSASetPrivateEx";
      }
  }

  // Generate a new random private key B bits long, using public expt E
  function RSAGenerate(B, E) {
      var rng = new SecureRandom();
      var qs = B >> 1;
      this.e = parseInt(E, 16);
      var ee = new BigInteger(E, 16);
      for (; ;) {
          for (; ;) {
              this.p = new BigInteger(B - qs, 1, rng);
              if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
          }
          for (; ;) {
              this.q = new BigInteger(qs, 1, rng);
              if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
          }
          if (this.p.compareTo(this.q) <= 0) {
              var t = this.p;
              this.p = this.q;
              this.q = t;
          }
          var p1 = this.p.subtract(BigInteger.ONE); // p1 = p - 1
          var q1 = this.q.subtract(BigInteger.ONE); // q1 = q - 1
          var phi = p1.multiply(q1);
          if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
              this.n = this.p.multiply(this.q); // this.n = p * q
              this.d = ee.modInverse(phi);  // this.d = 
              this.dmp1 = this.d.mod(p1); // this.dmp1 = d mod (p - 1)
              this.dmq1 = this.d.mod(q1); // this.dmq1 = d mod (q - 1)
              this.coeff = this.q.modInverse(this.p); // this.coeff = (q ^ -1) mod p
              break;
          }
      }
      this.isPrivate = true;
  }

  // Perform raw private operation on "x": return x^d (mod n)
  function RSADoPrivate(x) {
      if (this.p == null || this.q == null)
          return x.modPow(this.d, this.n);

      // TODO: re-calculate any missing CRT params
      var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?
      var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?

      while (xp.compareTo(xq) < 0)
          xp = xp.add(this.p);
      return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
  }

  function RSADecrypt(ctext) {
      var c = parseBigInt(ctext, 16);
      var m = this.doPrivate(c);
      if (m == null) return null;
      return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
  }

  function RSADecryptOAEP(ctext, hash, hashLen) {
      var c = parseBigInt(ctext, 16);
      var m = this.doPrivate(c);
      if (m == null) return null;
      return oaep_unpad(m, (this.n.bitLength() + 7) >> 3, hash, hashLen);
  }

  // protected
  RSAKey.prototype.doPrivate = RSADoPrivate;

  // public
  RSAKey.prototype.setPrivate = RSASetPrivate;
  RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
  RSAKey.prototype.generate = RSAGenerate;
  RSAKey.prototype.decrypt = RSADecrypt;
  RSAKey.prototype.decryptOAEP = RSADecryptOAEP;
  //RSAKey.prototype.b64_decrypt = RSAB64Decrypt;

  // (public)
  function bnClone() { var r = nbi(); this.copyTo(r); return r; }

  // (public) return value as integer
  function bnIntValue() {
      if (this.s < 0) {
          if (this.t == 1) return this[0] - this.DV;
          else if (this.t == 0) return -1;
      }
      else if (this.t == 1) return this[0];
      else if (this.t == 0) return 0;
      // assumes 16 < DB < 32
      return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
  }

  // (public) return value as byte
  function bnByteValue() { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; }

  // (public) return value as short (assumes DB>=16)
  function bnShortValue() { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; }

  // (protected) return x s.t. r^x < DV
  function bnpChunkSize(r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); }

  // (public) 0 if this == 0, 1 if this > 0
  function bnSigNum() {
      if (this.s < 0) return -1;
      else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
      else return 1;
  }

  // (protected) convert to radix string
  function bnpToRadix(b) {
      if (b == null) b = 10;
      if (this.signum() == 0 || b < 2 || b > 36) return "0";
      var cs = this.chunkSize(b);
      var a = Math.pow(b, cs);
      var d = nbv(a), y = nbi(), z = nbi(), r = "";
      this.divRemTo(d, y, z);
      while (y.signum() > 0) {
          r = (a + z.intValue()).toString(b).substr(1) + r;
          y.divRemTo(d, y, z);
      }
      return z.intValue().toString(b) + r;
  }

  // (protected) convert from radix string
  function bnpFromRadix(s, b) {
      this.fromInt(0);
      if (b == null) b = 10;
      var cs = this.chunkSize(b);
      var d = Math.pow(b, cs), mi = false, j = 0, w = 0;
      for (var i = 0; i < s.length; ++i) {
          var x = intAt(s, i);
          if (x < 0) {
              if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
              continue;
          }
          w = b * w + x;
          if (++j >= cs) {
              this.dMultiply(d);
              this.dAddOffset(w, 0);
              j = 0;
              w = 0;
          }
      }
      if (j > 0) {
          this.dMultiply(Math.pow(b, j));
          this.dAddOffset(w, 0);
      }
      if (mi) BigInteger.ZERO.subTo(this, this);
  }

  // (protected) alternate constructor
  function bnpFromNumber(a, b, c) {
      if ("number" == typeof b) {
          // new BigInteger(int,int,RNG)
          if (a < 2) this.fromInt(1);
          else {
              this.fromNumber(a, c);
              if (!this.testBit(a - 1))  // force MSB set
                  this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
              if (this.isEven()) this.dAddOffset(1, 0); // force odd
              while (!this.isProbablePrime(b)) {
                  this.dAddOffset(2, 0);
                  if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
              }
          }
      }
      else {
          // new BigInteger(int,RNG)
          var x = new Array(), t = a & 7;
          x.length = (a >> 3) + 1;
          b.nextBytes(x);
          if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0;
          this.fromString(x, 256);
      }
  }

  // (public) convert to bigendian byte array
  function bnToByteArray() {
      var i = this.t, r = new Array();
      r[0] = this.s;
      var p = this.DB - (i * this.DB) % 8, d, k = 0;
      if (i-- > 0) {
          if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p)
              r[k++] = d | (this.s << (this.DB - p));
          while (i >= 0) {
              if (p < 8) {
                  d = (this[i] & ((1 << p) - 1)) << (8 - p);
                  d |= this[--i] >> (p += this.DB - 8);
              }
              else {
                  d = (this[i] >> (p -= 8)) & 0xff;
                  if (p <= 0) { p += this.DB; --i; }
              }
              if ((d & 0x80) != 0) d |= -256;
              if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k;
              if (k > 0 || d != this.s) r[k++] = d;
          }
      }
      return r;
  }

  function bnEquals(a) { return (this.compareTo(a) == 0); }
  function bnMin(a) { return (this.compareTo(a) < 0) ? this : a; }
  function bnMax(a) { return (this.compareTo(a) > 0) ? this : a; }

  // (protected) r = this op a (bitwise)
  function bnpBitwiseTo(a, op, r) {
      var i, f, m = Math.min(a.t, this.t);
      for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]);
      if (a.t < this.t) {
          f = a.s & this.DM;
          for (i = m; i < this.t; ++i) r[i] = op(this[i], f);
          r.t = this.t;
      }
      else {
          f = this.s & this.DM;
          for (i = m; i < a.t; ++i) r[i] = op(f, a[i]);
          r.t = a.t;
      }
      r.s = op(this.s, a.s);
      r.clamp();
  }

  // (public) this & a
  function op_and(x, y) { return x & y; }
  function bnAnd(a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; }

  // (public) this | a
  function op_or(x, y) { return x | y; }
  function bnOr(a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; }

  // (public) this ^ a
  function op_xor(x, y) { return x ^ y; }
  function bnXor(a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; }

  // (public) this & ~a
  function op_andnot(x, y) { return x & ~y; }
  function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; }

  // (public) ~this
  function bnNot() {
      var r = nbi();
      for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i];
      r.t = this.t;
      r.s = ~this.s;
      return r;
  }

  // (public) this << n
  function bnShiftLeft(n) {
      var r = nbi();
      if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r);
      return r;
  }

  // (public) this >> n
  function bnShiftRight(n) {
      var r = nbi();
      if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r);
      return r;
  }

  // return index of lowest 1-bit in x, x < 2^31
  function lbit(x) {
      if (x == 0) return -1;
      var r = 0;
      if ((x & 0xffff) == 0) { x >>= 16; r += 16; }
      if ((x & 0xff) == 0) { x >>= 8; r += 8; }
      if ((x & 0xf) == 0) { x >>= 4; r += 4; }
      if ((x & 3) == 0) { x >>= 2; r += 2; }
      if ((x & 1) == 0) ++r;
      return r;
  }

  // (public) returns index of lowest 1-bit (or -1 if none)
  function bnGetLowestSetBit() {
      for (var i = 0; i < this.t; ++i)
          if (this[i] != 0) return i * this.DB + lbit(this[i]);
      if (this.s < 0) return this.t * this.DB;
      return -1;
  }

  // return number of 1 bits in x
  function cbit(x) {
      var r = 0;
      while (x != 0) { x &= x - 1; ++r; }
      return r;
  }

  // (public) return number of set bits
  function bnBitCount() {
      var r = 0, x = this.s & this.DM;
      for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x);
      return r;
  }

  // (public) true iff nth bit is set
  function bnTestBit(n) {
      var j = Math.floor(n / this.DB);
      if (j >= this.t) return (this.s != 0);
      return ((this[j] & (1 << (n % this.DB))) != 0);
  }

  // (protected) this op (1<<n)
  function bnpChangeBit(n, op) {
      var r = BigInteger.ONE.shiftLeft(n);
      this.bitwiseTo(r, op, r);
      return r;
  }

  // (public) this | (1<<n)
  function bnSetBit(n) { return this.changeBit(n, op_or); }

  // (public) this & ~(1<<n)
  function bnClearBit(n) { return this.changeBit(n, op_andnot); }

  // (public) this ^ (1<<n)
  function bnFlipBit(n) { return this.changeBit(n, op_xor); }

  // (protected) r = this + a
  function bnpAddTo(a, r) {
      var i = 0, c = 0, m = Math.min(a.t, this.t);
      while (i < m) {
          c += this[i] + a[i];
          r[i++] = c & this.DM;
          c >>= this.DB;
      }
      if (a.t < this.t) {
          c += a.s;
          while (i < this.t) {
              c += this[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
          }
          c += this.s;
      }
      else {
          c += this.s;
          while (i < a.t) {
              c += a[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
          }
          c += a.s;
      }
      r.s = (c < 0) ? -1 : 0;
      if (c > 0) r[i++] = c;
      else if (c < -1) r[i++] = this.DV + c;
      r.t = i;
      r.clamp();
  }

  // (public) this + a
  function bnAdd(a) { var r = nbi(); this.addTo(a, r); return r; }

  // (public) this - a
  function bnSubtract(a) { var r = nbi(); this.subTo(a, r); return r; }

  // (public) this * a
  function bnMultiply(a) { var r = nbi(); this.multiplyTo(a, r); return r; }

  // (public) this^2
  function bnSquare() { var r = nbi(); this.squareTo(r); return r; }

  // (public) this / a
  function bnDivide(a) { var r = nbi(); this.divRemTo(a, r, null); return r; }

  // (public) this % a
  function bnRemainder(a) { var r = nbi(); this.divRemTo(a, null, r); return r; }

  // (public) [this/a,this%a]
  function bnDivideAndRemainder(a) {
      var q = nbi(), r = nbi();
      this.divRemTo(a, q, r);
      return new Array(q, r);
  }

  // (protected) this *= n, this >= 0, 1 < n < DV
  function bnpDMultiply(n) {
      this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
      ++this.t;
      this.clamp();
  }

  // (protected) this += n << w words, this >= 0
  function bnpDAddOffset(n, w) {
      if (n == 0) return;
      while (this.t <= w) this[this.t++] = 0;
      this[w] += n;
      while (this[w] >= this.DV) {
          this[w] -= this.DV;
          if (++w >= this.t) this[this.t++] = 0;
          ++this[w];
      }
  }

  // A "null" reducer
  function NullExp() { }
  function nNop(x) { return x; }
  function nMulTo(x, y, r) { x.multiplyTo(y, r); }
  function nSqrTo(x, r) { x.squareTo(r); }

  NullExp.prototype.convert = nNop;
  NullExp.prototype.revert = nNop;
  NullExp.prototype.mulTo = nMulTo;
  NullExp.prototype.sqrTo = nSqrTo;

  // (public) this^e
  function bnPow(e) { return this.exp(e, new NullExp()); }

  // (protected) r = lower n words of "this * a", a.t <= n
  // "this" should be the larger one if appropriate.
  function bnpMultiplyLowerTo(a, n, r) {
      var i = Math.min(this.t + a.t, n);
      r.s = 0; // assumes a,this >= 0
      r.t = i;
      while (i > 0) r[--i] = 0;
      var j;
      for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
      for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i);
      r.clamp();
  }

  // (protected) r = "this * a" without lower n words, n > 0
  // "this" should be the larger one if appropriate.
  function bnpMultiplyUpperTo(a, n, r) {
      --n;
      var i = r.t = this.t + a.t - n;
      r.s = 0; // assumes a,this >= 0
      while (--i >= 0) r[i] = 0;
      for (i = Math.max(n - this.t, 0); i < a.t; ++i)
          r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
      r.clamp();
      r.drShiftTo(1, r);
  }

  // Barrett modular reduction
  function Barrett(m) {
      // setup Barrett
      this.r2 = nbi();
      this.q3 = nbi();
      BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
      this.mu = this.r2.divide(m);
      this.m = m;
  }

  function barrettConvert(x) {
      if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
      else if (x.compareTo(this.m) < 0) return x;
      else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
  }

  function barrettRevert(x) { return x; }

  // x = x mod m (HAC 14.42)
  function barrettReduce(x) {
      x.drShiftTo(this.m.t - 1, this.r2);
      if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); }
      this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
      this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
      while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1);
      x.subTo(this.r2, x);
      while (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
  }

  // r = x^2 mod m; x != r
  function barrettSqrTo(x, r) { x.squareTo(r); this.reduce(r); }

  // r = x*y mod m; x,y != r
  function barrettMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); }

  Barrett.prototype.convert = barrettConvert;
  Barrett.prototype.revert = barrettRevert;
  Barrett.prototype.reduce = barrettReduce;
  Barrett.prototype.mulTo = barrettMulTo;
  Barrett.prototype.sqrTo = barrettSqrTo;

  // (public) this^e % m (HAC 14.85)
  function bnModPow(e, m) {
      var i = e.bitLength(), k, r = nbv(1), z;
      if (i <= 0) return r;
      else if (i < 18) k = 1;
      else if (i < 48) k = 3;
      else if (i < 144) k = 4;
      else if (i < 768) k = 5;
      else k = 6;
      if (i < 8)
          z = new Classic(m);
      else if (m.isEven())
          z = new Barrett(m);
      else
          z = new Montgomery(m);

      // precomputation
      var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1;
      g[1] = z.convert(this);
      if (k > 1) {
          var g2 = nbi();
          z.sqrTo(g[1], g2);
          while (n <= km) {
              g[n] = nbi();
              z.mulTo(g2, g[n - 2], g[n]);
              n += 2;
          }
      }

      var j = e.t - 1, w, is1 = true, r2 = nbi(), t;
      i = nbits(e[j]) - 1;
      while (j >= 0) {
          if (i >= k1) w = (e[j] >> (i - k1)) & km;
          else {
              w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
              if (j > 0) w |= e[j - 1] >> (this.DB + i - k1);
          }

          n = k;
          while ((w & 1) == 0) { w >>= 1; --n; }
          if ((i -= n) < 0) { i += this.DB; --j; }
          if (is1) { // ret == 1, don't bother squaring or multiplying it
              g[w].copyTo(r);
              is1 = false;
          }
          else {
              while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; }
              if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; }
              z.mulTo(r2, g[w], r);
          }

          while (j >= 0 && (e[j] & (1 << i)) == 0) {
              z.sqrTo(r, r2); t = r; r = r2; r2 = t;
              if (--i < 0) { i = this.DB - 1; --j; }
          }
      }
      return z.revert(r);
  }

  // (public) gcd(this,a) (HAC 14.54)
  function bnGCD(a) {
      var x = (this.s < 0) ? this.negate() : this.clone();
      var y = (a.s < 0) ? a.negate() : a.clone();
      if (x.compareTo(y) < 0) { var t = x; x = y; y = t; }
      var i = x.getLowestSetBit(), g = y.getLowestSetBit();
      if (g < 0) return x;
      if (i < g) g = i;
      if (g > 0) {
          x.rShiftTo(g, x);
          y.rShiftTo(g, y);
      }
      while (x.signum() > 0) {
          if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
          if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
          if (x.compareTo(y) >= 0) {
              x.subTo(y, x);
              x.rShiftTo(1, x);
          }
          else {
              y.subTo(x, y);
              y.rShiftTo(1, y);
          }
      }
      if (g > 0) y.lShiftTo(g, y);
      return y;
  }

  // (protected) this % n, n < 2^26
  function bnpModInt(n) {
      if (n <= 0) return 0;
      var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0;
      if (this.t > 0)
          if (d == 0) r = this[0] % n;
          else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n;
      return r;
  }

  // (public) 1/this % m (HAC 14.61)
  function bnModInverse(m) {
      var ac = m.isEven();
      if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
      var u = m.clone(), v = this.clone();
      var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
      while (u.signum() != 0) {
          while (u.isEven()) {
              u.rShiftTo(1, u);
              if (ac) {
                  if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); }
                  a.rShiftTo(1, a);
              }
              else if (!b.isEven()) b.subTo(m, b);
              b.rShiftTo(1, b);
          }
          while (v.isEven()) {
              v.rShiftTo(1, v);
              if (ac) {
                  if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); }
                  c.rShiftTo(1, c);
              }
              else if (!d.isEven()) d.subTo(m, d);
              d.rShiftTo(1, d);
          }
          if (u.compareTo(v) >= 0) {
              u.subTo(v, u);
              if (ac) a.subTo(c, a);
              b.subTo(d, b);
          }
          else {
              v.subTo(u, v);
              if (ac) c.subTo(a, c);
              d.subTo(b, d);
          }
      }
      if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
      if (d.compareTo(m) >= 0) return d.subtract(m);
      if (d.signum() < 0) d.addTo(m, d); else return d;
      if (d.signum() < 0) return d.add(m); else return d;
  }

  var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
  var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];

  // (public) test primality with certainty >= 1-.5^t
  function bnIsProbablePrime(t) {
      var i, x = this.abs();
      if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
          for (i = 0; i < lowprimes.length; ++i)
              if (x[0] == lowprimes[i]) return true;
          return false;
      }
      if (x.isEven()) return false;
      i = 1;
      while (i < lowprimes.length) {
          var m = lowprimes[i], j = i + 1;
          while (j < lowprimes.length && m < lplim) m *= lowprimes[j++];
          m = x.modInt(m);
          while (i < j) if (m % lowprimes[i++] == 0) return false;
      }
      return x.millerRabin(t);
  }

  // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
  function bnpMillerRabin(t) {
      var n1 = this.subtract(BigInteger.ONE);
      var k = n1.getLowestSetBit();
      if (k <= 0) return false;
      var r = n1.shiftRight(k);
      t = (t + 1) >> 1;
      if (t > lowprimes.length) t = lowprimes.length;
      var a = nbi();
      for (var i = 0; i < t; ++i) {
          //Pick bases at random, instead of starting at 2
          a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
          var y = a.modPow(r, this);
          if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
              var j = 1;
              while (j++ < k && y.compareTo(n1) != 0) {
                  y = y.modPowInt(2, this);
                  if (y.compareTo(BigInteger.ONE) == 0) return false;
              }
              if (y.compareTo(n1) != 0) return false;
          }
      }
      return true;
  }

  // protected
  BigInteger.prototype.chunkSize = bnpChunkSize;
  BigInteger.prototype.toRadix = bnpToRadix;
  BigInteger.prototype.fromRadix = bnpFromRadix;
  BigInteger.prototype.fromNumber = bnpFromNumber;
  BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
  BigInteger.prototype.changeBit = bnpChangeBit;
  BigInteger.prototype.addTo = bnpAddTo;
  BigInteger.prototype.dMultiply = bnpDMultiply;
  BigInteger.prototype.dAddOffset = bnpDAddOffset;
  BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
  BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
  BigInteger.prototype.modInt = bnpModInt;
  BigInteger.prototype.millerRabin = bnpMillerRabin;

  // public
  BigInteger.prototype.clone = bnClone;
  BigInteger.prototype.intValue = bnIntValue;
  BigInteger.prototype.byteValue = bnByteValue;
  BigInteger.prototype.shortValue = bnShortValue;
  BigInteger.prototype.signum = bnSigNum;
  BigInteger.prototype.toByteArray = bnToByteArray;
  BigInteger.prototype.equals = bnEquals;
  BigInteger.prototype.min = bnMin;
  BigInteger.prototype.max = bnMax;
  BigInteger.prototype.and = bnAnd;
  BigInteger.prototype.or = bnOr;
  BigInteger.prototype.xor = bnXor;
  BigInteger.prototype.andNot = bnAndNot;
  BigInteger.prototype.not = bnNot;
  BigInteger.prototype.shiftLeft = bnShiftLeft;
  BigInteger.prototype.shiftRight = bnShiftRight;
  BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
  BigInteger.prototype.bitCount = bnBitCount;
  BigInteger.prototype.testBit = bnTestBit;
  BigInteger.prototype.setBit = bnSetBit;
  BigInteger.prototype.clearBit = bnClearBit;
  BigInteger.prototype.flipBit = bnFlipBit;
  BigInteger.prototype.add = bnAdd;
  BigInteger.prototype.subtract = bnSubtract;
  BigInteger.prototype.multiply = bnMultiply;
  BigInteger.prototype.divide = bnDivide;
  BigInteger.prototype.remainder = bnRemainder;
  BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
  BigInteger.prototype.modPow = bnModPow;
  BigInteger.prototype.modInverse = bnModInverse;
  BigInteger.prototype.pow = bnPow;
  BigInteger.prototype.gcd = bnGCD;
  BigInteger.prototype.isProbablePrime = bnIsProbablePrime;

  // JSBN-specific extension
  BigInteger.prototype.square = bnSquare;



  if (YAHOO === undefined) { var YAHOO = {}; }
  YAHOO.lang = {
      /**
       * Utility to set up the prototype, constructor and superclass properties to
       * support an inheritance strategy that can chain constructors and methods.
       * Static members will not be inherited.
       *
       * @method extend
       * @static
       * @param {Function} subc   the object to modify
       * @param {Function} superc the object to inherit
       * @param {Object} overrides  additional properties/methods to add to the
       *                              subclass prototype.  These will override the
       *                              matching items obtained from the superclass
       *                              if present.
       */
      extend: function (subc, superc, overrides) {
          if (!superc || !subc) {
              throw new Error("YAHOO.lang.extend failed, please check that " +
                  "all dependencies are included.");
          }

          var F = function () { };
          F.prototype = superc.prototype;
          subc.prototype = new F();
          subc.prototype.constructor = subc;
          subc.superclass = superc.prototype;

          if (superc.prototype.constructor == Object.prototype.constructor) {
              superc.prototype.constructor = superc;
          }

          if (overrides) {
              var i;
              for (i in overrides) {
                  subc.prototype[i] = overrides[i];
              }

              var _IEEnumFix = function () { },
                  ADD = ["toString", "valueOf"];
              try {
                  if (/MSIE/.test(navigator.userAgent)) {
                      _IEEnumFix = function (r, s) {
                          for (i = 0; i < ADD.length; i = i + 1) {
                              var fname = ADD[i], f = s[fname];
                              if (typeof f === 'function' && f != Object.prototype[fname]) {
                                  r[fname] = f;
                              }
                          }
                      };
                  }
              } catch (ex) { };
              _IEEnumFix(subc.prototype, overrides);
          }
      }
  };

  if (typeof KJUR == "undefined" || !KJUR) KJUR = {};

  if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};

  /**
   * ASN1 utilities class
   * @name KJUR.asn1.ASN1Util
   * @class ASN1 utilities class
   * @since asn1 1.0.2
   */
  KJUR.asn1.ASN1Util = new function () {
      this.integerToByteHex = function (i) {
          var h = i.toString(16);
          if ((h.length % 2) == 1) h = '0' + h;
          return h;
      };
      this.bigIntToMinTwosComplementsHex = function (bigIntegerValue) {
          var h = bigIntegerValue.toString(16);
          if (h.substr(0, 1) != '-') {
              if (h.length % 2 == 1) {
                  h = '0' + h;
              } else {
                  if (!h.match(/^[0-7]/)) {
                      h = '00' + h;
                  }
              }
          } else {
              var hPos = h.substr(1);
              var xorLen = hPos.length;
              if (xorLen % 2 == 1) {
                  xorLen += 1;
              } else {
                  if (!h.match(/^[0-7]/)) {
                      xorLen += 2;
                  }
              }
              var hMask = '';
              for (var i = 0; i < xorLen; i++) {
                  hMask += 'f';
              }
              var biMask = new BigInteger(hMask, 16);
              var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);
              h = biNeg.toString(16).replace(/^-/, '');
          }
          return h;
      };

      this.getPEMStringFromHex = function (dataHex, pemHeader) {
          return hextopem(dataHex, pemHeader);
      };

      this.newObject = function (param) {
          var _KJUR = KJUR,
              _KJUR_asn1 = _KJUR.asn1,
              _DERBoolean = _KJUR_asn1.DERBoolean,
              _DERInteger = _KJUR_asn1.DERInteger,
              _DERBitString = _KJUR_asn1.DERBitString,
              _DEROctetString = _KJUR_asn1.DEROctetString,
              _DERNull = _KJUR_asn1.DERNull,
              _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
              _DEREnumerated = _KJUR_asn1.DEREnumerated,
              _DERUTF8String = _KJUR_asn1.DERUTF8String,
              _DERNumericString = _KJUR_asn1.DERNumericString,
              _DERPrintableString = _KJUR_asn1.DERPrintableString,
              _DERTeletexString = _KJUR_asn1.DERTeletexString,
              _DERIA5String = _KJUR_asn1.DERIA5String,
              _DERUTCTime = _KJUR_asn1.DERUTCTime,
              _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
              _DERSequence = _KJUR_asn1.DERSequence,
              _DERSet = _KJUR_asn1.DERSet,
              _DERTaggedObject = _KJUR_asn1.DERTaggedObject,
              _newObject = _KJUR_asn1.ASN1Util.newObject;

          var keys = Object.keys(param);
          if (keys.length != 1)
              throw "key of param shall be only one.";
          var key = keys[0];

          if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1)
              throw "undefined key: " + key;

          if (key == "bool") return new _DERBoolean(param[key]);
          if (key == "int") return new _DERInteger(param[key]);
          if (key == "bitstr") return new _DERBitString(param[key]);
          if (key == "octstr") return new _DEROctetString(param[key]);
          if (key == "null") return new _DERNull(param[key]);
          if (key == "oid") return new _DERObjectIdentifier(param[key]);
          if (key == "enum") return new _DEREnumerated(param[key]);
          if (key == "utf8str") return new _DERUTF8String(param[key]);
          if (key == "numstr") return new _DERNumericString(param[key]);
          if (key == "prnstr") return new _DERPrintableString(param[key]);
          if (key == "telstr") return new _DERTeletexString(param[key]);
          if (key == "ia5str") return new _DERIA5String(param[key]);
          if (key == "utctime") return new _DERUTCTime(param[key]);
          if (key == "gentime") return new _DERGeneralizedTime(param[key]);

          if (key == "seq") {
              var paramList = param[key];
              var a = [];
              for (var i = 0; i < paramList.length; i++) {
                  var asn1Obj = _newObject(paramList[i]);
                  a.push(asn1Obj);
              }
              return new _DERSequence({ 'array': a });
          }

          if (key == "set") {
              var paramList = param[key];
              var a = [];
              for (var i = 0; i < paramList.length; i++) {
                  var asn1Obj = _newObject(paramList[i]);
                  a.push(asn1Obj);
              }
              return new _DERSet({ 'array': a });
          }

          if (key == "tag") {
              var tagParam = param[key];
              if (Object.prototype.toString.call(tagParam) === '[object Array]' &&
                  tagParam.length == 3) {
                  var obj = _newObject(tagParam[2]);
                  return new _DERTaggedObject({
                      tag: tagParam[0],
                      explicit: tagParam[1],
                      obj: obj
                  });
              } else {
                  var newParam = {};
                  if (tagParam.explicit !== undefined)
                      newParam.explicit = tagParam.explicit;
                  if (tagParam.tag !== undefined)
                      newParam.tag = tagParam.tag;
                  if (tagParam.obj === undefined)
                      throw "obj shall be specified for 'tag'.";
                  newParam.obj = _newObject(tagParam.obj);
                  return new _DERTaggedObject(newParam);
              }
          }
      };

      this.jsonToASN1HEX = function (param) {
          var asn1Obj = this.newObject(param);
          return asn1Obj.getEncodedHex();
      };
  };

  KJUR.asn1.ASN1Util.oidHexToInt = function (hex) {
      var s = "";
      var i01 = parseInt(hex.substr(0, 2), 16);
      var i0 = Math.floor(i01 / 40);
      var i1 = i01 % 40;
      var s = i0 + "." + i1;

      var binbuf = "";
      for (var i = 2; i < hex.length; i += 2) {
          var value = parseInt(hex.substr(i, 2), 16);
          var bin = ("00000000" + value.toString(2)).slice(- 8);
          binbuf = binbuf + bin.substr(1, 7);
          if (bin.substr(0, 1) == "0") {
              var bi = new BigInteger(binbuf, 2);
              s = s + "." + bi.toString(10);
              binbuf = "";
          }
      };

      return s;
  };


  KJUR.asn1.ASN1Util.oidIntToHex = function (oidString) {
      var itox = function (i) {
          var h = i.toString(16);
          if (h.length == 1) h = '0' + h;
          return h;
      };

      var roidtox = function (roid) {
          var h = '';
          var bi = new BigInteger(roid, 10);
          var b = bi.toString(2);
          var padLen = 7 - b.length % 7;
          if (padLen == 7) padLen = 0;
          var bPad = '';
          for (var i = 0; i < padLen; i++) bPad += '0';
          b = bPad + b;
          for (var i = 0; i < b.length - 1; i += 7) {
              var b8 = b.substr(i, 7);
              if (i != b.length - 7) b8 = '1' + b8;
              h += itox(parseInt(b8, 2));
          }
          return h;
      };

      if (!oidString.match(/^[0-9.]+$/)) {
          throw "malformed oid string: " + oidString;
      }
      var h = '';
      var a = oidString.split('.');
      var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
      h += itox(i0);
      a.splice(0, 2);
      for (var i = 0; i < a.length; i++) {
          h += roidtox(a[i]);
      }
      return h;
  };


  KJUR.asn1.ASN1Object = function () {
      var isModified = true;
      var hTLV = null;
      var hT = '00';
      var hL = '00';
      var hV = '';

      this.getLengthHexFromValue = function () {
          if (typeof this.hV == "undefined" || this.hV == null) {
              throw "this.hV is null or undefined.";
          }
          if (this.hV.length % 2 == 1) {
              throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV;
          }
          var n = this.hV.length / 2;
          var hN = n.toString(16);
          if (hN.length % 2 == 1) {
              hN = "0" + hN;
          }
          if (n < 128) {
              return hN;
          } else {
              var hNlen = hN.length / 2;
              if (hNlen > 15) {
                  throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16);
              }
              var head = 128 + hNlen;
              return head.toString(16) + hN;
          }
      };


      this.getEncodedHex = function () {
          if (this.hTLV == null || this.isModified) {
              this.hV = this.getFreshValueHex();
              this.hL = this.getLengthHexFromValue();
              this.hTLV = this.hT + this.hL + this.hV;
              this.isModified = false;
              //alert("first time: " + this.hTLV);
          }
          return this.hTLV;
      };

      this.getValueHex = function () {
          this.getEncodedHex();
          return this.hV;
      };

      this.getFreshValueHex = function () {
          return '';
      };
  };

  KJUR.asn1.DERAbstractString = function (params) {
      KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
      var s = null;
      var hV = null;


      this.getString = function () {
          return this.s;
      };


      this.setString = function (newS) {
          this.hTLV = null;
          this.isModified = true;
          this.s = newS;
          this.hV = utf8tohex(this.s).toLowerCase();
      };

      this.setStringHex = function (newHexString) {
          this.hTLV = null;
          this.isModified = true;
          this.s = null;
          this.hV = newHexString;
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };

      if (typeof params != "undefined") {
          if (typeof params == "string") {
              this.setString(params);
          } else if (typeof params['str'] != "undefined") {
              this.setString(params['str']);
          } else if (typeof params['hex'] != "undefined") {
              this.setStringHex(params['hex']);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);

  KJUR.asn1.DERAbstractTime = function (params) {
      KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
      var s = null;
      var date = null;

      // --- PRIVATE METHODS --------------------
      this.localDateToUTC = function (d) {
          utc = d.getTime() + (d.getTimezoneOffset() * 60000);
          var utcDate = new Date(utc);
          return utcDate;
      };


      this.formatDate = function (dateObject, type, withMillis) {
          var pad = this.zeroPadding;
          var d = this.localDateToUTC(dateObject);
          var year = String(d.getFullYear());
          if (type == 'utc') year = year.substr(2, 2);
          var month = pad(String(d.getMonth() + 1), 2);
          var day = pad(String(d.getDate()), 2);
          var hour = pad(String(d.getHours()), 2);
          var min = pad(String(d.getMinutes()), 2);
          var sec = pad(String(d.getSeconds()), 2);
          var s = year + month + day + hour + min + sec;
          if (withMillis === true) {
              var millis = d.getMilliseconds();
              if (millis != 0) {
                  var sMillis = pad(String(millis), 3);
                  sMillis = sMillis.replace(/[0]+$/, "");
                  s = s + "." + sMillis;
              }
          }
          return s + "Z";
      };

      this.zeroPadding = function (s, len) {
          if (s.length >= len) return s;
          return new Array(len - s.length + 1).join('0') + s;
      };

      this.getString = function () {
          return this.s;
      };


      this.setString = function (newS) {
          this.hTLV = null;
          this.isModified = true;
          this.s = newS;
          this.hV = stohex(newS);
      };


      this.setByDateValue = function (year, month, day, hour, min, sec) {
          var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
          this.setByDate(dateObject);
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };
  };
  YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);

  KJUR.asn1.DERAbstractStructured = function (params) {
      KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
      var asn1Array = null;


      this.setByASN1ObjectArray = function (asn1ObjectArray) {
          this.hTLV = null;
          this.isModified = true;
          this.asn1Array = asn1ObjectArray;
      };

      this.appendASN1Object = function (asn1Object) {
          this.hTLV = null;
          this.isModified = true;
          this.asn1Array.push(asn1Object);
      };

      this.asn1Array = new Array();
      if (typeof params != "undefined") {
          if (typeof params['array'] != "undefined") {
              this.asn1Array = params['array'];
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);


  KJUR.asn1.DERBoolean = function () {
      KJUR.asn1.DERBoolean.superclass.constructor.call(this);
      this.hT = "01";
      this.hTLV = "0101ff";
  };
  YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);


  KJUR.asn1.DERInteger = function (params) {
      KJUR.asn1.DERInteger.superclass.constructor.call(this);
      this.hT = "02";


      this.setByBigInteger = function (bigIntegerValue) {
          this.hTLV = null;
          this.isModified = true;
          this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
      };


      this.setByInteger = function (intValue) {
          var bi = new BigInteger(String(intValue), 10);
          this.setByBigInteger(bi);
      };

      this.setValueHex = function (newHexString) {
          this.hV = newHexString;
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };

      if (typeof params != "undefined") {
          if (typeof params['bigint'] != "undefined") {
              this.setByBigInteger(params['bigint']);
          } else if (typeof params['int'] != "undefined") {
              this.setByInteger(params['int']);
          } else if (typeof params == "number") {
              this.setByInteger(params);
          } else if (typeof params['hex'] != "undefined") {
              this.setValueHex(params['hex']);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);


  KJUR.asn1.DERBitString = function (params) {
      if (params !== undefined && typeof params.obj !== "undefined") {
          var o = KJUR.asn1.ASN1Util.newObject(params.obj);
          params.hex = "00" + o.getEncodedHex();
      }
      KJUR.asn1.DERBitString.superclass.constructor.call(this);
      this.hT = "03";


      this.setHexValueIncludingUnusedBits = function (newHexStringIncludingUnusedBits) {
          this.hTLV = null;
          this.isModified = true;
          this.hV = newHexStringIncludingUnusedBits;
      };


      this.setUnusedBitsAndHexValue = function (unusedBits, hValue) {
          if (unusedBits < 0 || 7 < unusedBits) {
              throw "unused bits shall be from 0 to 7: u = " + unusedBits;
          }
          var hUnusedBits = "0" + unusedBits;
          this.hTLV = null;
          this.isModified = true;
          this.hV = hUnusedBits + hValue;
      };


      this.setByBinaryString = function (binaryString) {
          binaryString = binaryString.replace(/0+$/, '');
          var unusedBits = 8 - binaryString.length % 8;
          if (unusedBits == 8) unusedBits = 0;
          for (var i = 0; i <= unusedBits; i++) {
              binaryString += '0';
          }
          var h = '';
          for (var i = 0; i < binaryString.length - 1; i += 8) {
              var b = binaryString.substr(i, 8);
              var x = parseInt(b, 2).toString(16);
              if (x.length == 1) x = '0' + x;
              h += x;
          }
          this.hTLV = null;
          this.isModified = true;
          this.hV = '0' + unusedBits + h;
      };


      this.setByBooleanArray = function (booleanArray) {
          var s = '';
          for (var i = 0; i < booleanArray.length; i++) {
              if (booleanArray[i] == true) {
                  s += '1';
              } else {
                  s += '0';
              }
          }
          this.setByBinaryString(s);
      };


      this.newFalseArray = function (nLength) {
          var a = new Array(nLength);
          for (var i = 0; i < nLength; i++) {
              a[i] = false;
          }
          return a;
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };

      if (typeof params != "undefined") {
          if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
              this.setHexValueIncludingUnusedBits(params);
          } else if (typeof params['hex'] != "undefined") {
              this.setHexValueIncludingUnusedBits(params['hex']);
          } else if (typeof params['bin'] != "undefined") {
              this.setByBinaryString(params['bin']);
          } else if (typeof params['array'] != "undefined") {
              this.setByBooleanArray(params['array']);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);


  KJUR.asn1.DEROctetString = function (params) {
      if (params !== undefined && typeof params.obj !== "undefined") {
          var o = KJUR.asn1.ASN1Util.newObject(params.obj);
          params.hex = o.getEncodedHex();
      }
      KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
      this.hT = "04";
  };
  YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);


  KJUR.asn1.DERNull = function () {
      KJUR.asn1.DERNull.superclass.constructor.call(this);
      this.hT = "05";
      this.hTLV = "0500";
  };
  YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);


  KJUR.asn1.DERObjectIdentifier = function (params) {
      var itox = function (i) {
          var h = i.toString(16);
          if (h.length == 1) h = '0' + h;
          return h;
      };
      var roidtox = function (roid) {
          var h = '';
          var bi = new BigInteger(roid, 10);
          var b = bi.toString(2);
          var padLen = 7 - b.length % 7;
          if (padLen == 7) padLen = 0;
          var bPad = '';
          for (var i = 0; i < padLen; i++) bPad += '0';
          b = bPad + b;
          for (var i = 0; i < b.length - 1; i += 7) {
              var b8 = b.substr(i, 7);
              if (i != b.length - 7) b8 = '1' + b8;
              h += itox(parseInt(b8, 2));
          }
          return h;
      };

      KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
      this.hT = "06";


      this.setValueHex = function (newHexString) {
          this.hTLV = null;
          this.isModified = true;
          this.s = null;
          this.hV = newHexString;
      };


      this.setValueOidString = function (oidString) {
          if (!oidString.match(/^[0-9.]+$/)) {
              throw "malformed oid string: " + oidString;
          }
          var h = '';
          var a = oidString.split('.');
          var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
          h += itox(i0);
          a.splice(0, 2);
          for (var i = 0; i < a.length; i++) {
              h += roidtox(a[i]);
          }
          this.hTLV = null;
          this.isModified = true;
          this.s = null;
          this.hV = h;
      };

      this.setValueName = function (oidName) {
          var oid = KJUR.asn1.x509.OID.name2oid(oidName);
          if (oid !== '') {
              this.setValueOidString(oid);
          } else {
              throw "DERObjectIdentifier oidName undefined: " + oidName;
          }
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };

      if (params !== undefined) {
          if (typeof params === "string") {
              if (params.match(/^[0-2].[0-9.]+$/)) {
                  this.setValueOidString(params);
              } else {
                  this.setValueName(params);
              }
          } else if (params.oid !== undefined) {
              this.setValueOidString(params.oid);
          } else if (params.hex !== undefined) {
              this.setValueHex(params.hex);
          } else if (params.name !== undefined) {
              this.setValueName(params.name);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);


  KJUR.asn1.DEREnumerated = function (params) {
      KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
      this.hT = "0a";


      this.setByBigInteger = function (bigIntegerValue) {
          this.hTLV = null;
          this.isModified = true;
          this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
      };


      this.setByInteger = function (intValue) {
          var bi = new BigInteger(String(intValue), 10);
          this.setByBigInteger(bi);
      };


      this.setValueHex = function (newHexString) {
          this.hV = newHexString;
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };

      if (typeof params != "undefined") {
          if (typeof params['int'] != "undefined") {
              this.setByInteger(params['int']);
          } else if (typeof params == "number") {
              this.setByInteger(params);
          } else if (typeof params['hex'] != "undefined") {
              this.setValueHex(params['hex']);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);


  KJUR.asn1.DERUTF8String = function (params) {
      KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
      this.hT = "0c";
  };
  YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);


  KJUR.asn1.DERNumericString = function (params) {
      KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
      this.hT = "12";
  };
  YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);


  KJUR.asn1.DERPrintableString = function (params) {
      KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
      this.hT = "13";
  };
  YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);


  KJUR.asn1.DERTeletexString = function (params) {
      KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
      this.hT = "14";
  };
  YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);


  KJUR.asn1.DERIA5String = function (params) {
      KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
      this.hT = "16";
  };
  YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);


  KJUR.asn1.DERUTCTime = function (params) {
      KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
      this.hT = "17";


      this.setByDate = function (dateObject) {
          this.hTLV = null;
          this.isModified = true;
          this.date = dateObject;
          this.s = this.formatDate(this.date, 'utc');
          this.hV = stohex(this.s);
      };

      this.getFreshValueHex = function () {
          if (typeof this.date == "undefined" && typeof this.s == "undefined") {
              this.date = new Date();
              this.s = this.formatDate(this.date, 'utc');
              this.hV = stohex(this.s);
          }
          return this.hV;
      };

      if (params !== undefined) {
          if (params.str !== undefined) {
              this.setString(params.str);
          } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
              this.setString(params);
          } else if (params.hex !== undefined) {
              this.setStringHex(params.hex);
          } else if (params.date !== undefined) {
              this.setByDate(params.date);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);


  KJUR.asn1.DERGeneralizedTime = function (params) {
      KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
      this.hT = "18";
      this.withMillis = false;


      this.setByDate = function (dateObject) {
          this.hTLV = null;
          this.isModified = true;
          this.date = dateObject;
          this.s = this.formatDate(this.date, 'gen', this.withMillis);
          this.hV = stohex(this.s);
      };

      this.getFreshValueHex = function () {
          if (this.date === undefined && this.s === undefined) {
              this.date = new Date();
              this.s = this.formatDate(this.date, 'gen', this.withMillis);
              this.hV = stohex(this.s);
          }
          return this.hV;
      };

      if (params !== undefined) {
          if (params.str !== undefined) {
              this.setString(params.str);
          } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
              this.setString(params);
          } else if (params.hex !== undefined) {
              this.setStringHex(params.hex);
          } else if (params.date !== undefined) {
              this.setByDate(params.date);
          }
          if (params.millis === true) {
              this.withMillis = true;
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);


  KJUR.asn1.DERSequence = function (params) {
      KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
      this.hT = "30";
      this.getFreshValueHex = function () {
          var h = '';
          for (var i = 0; i < this.asn1Array.length; i++) {
              var asn1Obj = this.asn1Array[i];
              h += asn1Obj.getEncodedHex();
          }
          this.hV = h;
          return this.hV;
      };
  };
  YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);


  KJUR.asn1.DERSet = function (params) {
      KJUR.asn1.DERSet.superclass.constructor.call(this, params);
      this.hT = "31";
      this.sortFlag = true; // item shall be sorted only in ASN.1 DER
      this.getFreshValueHex = function () {
          var a = new Array();
          for (var i = 0; i < this.asn1Array.length; i++) {
              var asn1Obj = this.asn1Array[i];
              a.push(asn1Obj.getEncodedHex());
          }
          if (this.sortFlag == true) a.sort();
          this.hV = a.join('');
          return this.hV;
      };

      if (typeof params != "undefined") {
          if (typeof params.sortflag != "undefined" &&
              params.sortflag == false)
              this.sortFlag = false;
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);


  KJUR.asn1.DERTaggedObject = function (params) {
      KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
      this.hT = "a0";
      this.hV = '';
      this.isExplicit = true;
      this.asn1Object = null;


      this.setASN1Object = function (isExplicitFlag, tagNoHex, asn1Object) {
          this.hT = tagNoHex;
          this.isExplicit = isExplicitFlag;
          this.asn1Object = asn1Object;
          if (this.isExplicit) {
              this.hV = this.asn1Object.getEncodedHex();
              this.hTLV = null;
              this.isModified = true;
          } else {
              this.hV = null;
              this.hTLV = asn1Object.getEncodedHex();
              this.hTLV = this.hTLV.replace(/^../, tagNoHex);
              this.isModified = false;
          }
      };

      this.getFreshValueHex = function () {
          return this.hV;
      };

      if (typeof params != "undefined") {
          if (typeof params['tag'] != "undefined") {
              this.hT = params['tag'];
          }
          if (typeof params['explicit'] != "undefined") {
              this.isExplicit = params['explicit'];
          }
          if (typeof params['obj'] != "undefined") {
              this.asn1Object = params['obj'];
              this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
          }
      }
  };
  YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);


  var dbits;

  // JavaScript engine analysis
  var canary = 0xdeadbeefcafe;
  var j_lm = ((canary & 0xffffff) == 0xefcafe);

  // (public) Constructor
  function BigInteger(a, b, c) {
      if (a != null)
          if ("number" == typeof a) this.fromNumber(a, b, c);
          else if (b == null && "string" != typeof a) this.fromString(a, 256);
          else this.fromString(a, b);
  }

  // return new, unset BigInteger
  function nbi() { return new BigInteger(null); }


  function am1(i, x, w, j, c, n) {
      while (--n >= 0) {
          var v = x * this[i++] + w[j] + c;
          c = Math.floor(v / 0x4000000);
          w[j++] = v & 0x3ffffff;
      }
      return c;
  }

  function am2(i, x, w, j, c, n) {
      var xl = x & 0x7fff, xh = x >> 15;
      while (--n >= 0) {
          var l = this[i] & 0x7fff;
          var h = this[i++] >> 15;
          var m = xh * l + h * xl;
          l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
          c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
          w[j++] = l & 0x3fffffff;
      }
      return c;
  }
  // Alternately, set max digit bits to 28 since some
  // browsers slow down when dealing with 32-bit numbers.
  function am3(i, x, w, j, c, n) {
      var xl = x & 0x3fff, xh = x >> 14;
      while (--n >= 0) {
          var l = this[i] & 0x3fff;
          var h = this[i++] >> 14;
          var m = xh * l + h * xl;
          l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
          c = (l >> 28) + (m >> 14) + xh * h;
          w[j++] = l & 0xfffffff;
      }
      return c;
  }
  if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
      BigInteger.prototype.am = am2;
      dbits = 30;
  }
  else if (j_lm && (navigator.appName != "Netscape")) {
      BigInteger.prototype.am = am1;
      dbits = 26;
  }
  else { // Mozilla/Netscape seems to prefer am3
      BigInteger.prototype.am = am3;
      dbits = 28;
  }

  BigInteger.prototype.DB = dbits;
  BigInteger.prototype.DM = ((1 << dbits) - 1);
  BigInteger.prototype.DV = (1 << dbits);

  var BI_FP = 52;
  BigInteger.prototype.FV = Math.pow(2, BI_FP);
  BigInteger.prototype.F1 = BI_FP - dbits;
  BigInteger.prototype.F2 = 2 * dbits - BI_FP;

  // Digit conversions
  var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
  var BI_RC = new Array();
  var rr, vv;
  rr = "0".charCodeAt(0);
  for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
  rr = "a".charCodeAt(0);
  for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
  rr = "A".charCodeAt(0);
  for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;

  function int2char(n) { return BI_RM.charAt(n); }
  function intAt(s, i) {
      var c = BI_RC[s.charCodeAt(i)];
      return (c == null) ? -1 : c;
  }

  // (protected) copy this to r
  function bnpCopyTo(r) {
      for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];
      r.t = this.t;
      r.s = this.s;
  }

  // (protected) set from integer value x, -DV <= x < DV
  function bnpFromInt(x) {
      this.t = 1;
      this.s = (x < 0) ? -1 : 0;
      if (x > 0) this[0] = x;
      else if (x < -1) this[0] = x + this.DV;
      else this.t = 0;
  }

  // return bigint initialized to value
  function nbv(i) { var r = nbi(); r.fromInt(i); return r; }

  // (protected) set from string and radix
  function bnpFromString(s, b) {
      var k;
      if (b == 16) k = 4;
      else if (b == 8) k = 3;
      else if (b == 256) k = 8; // byte array
      else if (b == 2) k = 1;
      else if (b == 32) k = 5;
      else if (b == 4) k = 2;
      else { this.fromRadix(s, b); return; }
      this.t = 0;
      this.s = 0;
      var i = s.length, mi = false, sh = 0;
      while (--i >= 0) {
          var x = (k == 8) ? s[i] & 0xff : intAt(s, i);
          if (x < 0) {
              if (s.charAt(i) == "-") mi = true;
              continue;
          }
          mi = false;
          if (sh == 0)
              this[this.t++] = x;
          else if (sh + k > this.DB) {
              this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
              this[this.t++] = (x >> (this.DB - sh));
          }
          else
              this[this.t - 1] |= x << sh;
          sh += k;
          if (sh >= this.DB) sh -= this.DB;
      }
      if (k == 8 && (s[0] & 0x80) != 0) {
          this.s = -1;
          if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
      }
      this.clamp();
      if (mi) BigInteger.ZERO.subTo(this, this);
  }

  // (protected) clamp off excess high words
  function bnpClamp() {
      var c = this.s & this.DM;
      while (this.t > 0 && this[this.t - 1] == c) --this.t;
  }

  // (public) return string representation in given radix
  function bnToString(b) {
      if (this.s < 0) return "-" + this.negate().toString(b);
      var k;
      if (b == 16) k = 4;
      else if (b == 8) k = 3;
      else if (b == 2) k = 1;
      else if (b == 32) k = 5;
      else if (b == 4) k = 2;
      else return this.toRadix(b);
      var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
      var p = this.DB - (i * this.DB) % k;
      if (i-- > 0) {
          if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); }
          while (i >= 0) {
              if (p < k) {
                  d = (this[i] & ((1 << p) - 1)) << (k - p);
                  d |= this[--i] >> (p += this.DB - k);
              }
              else {
                  d = (this[i] >> (p -= k)) & km;
                  if (p <= 0) { p += this.DB; --i; }
              }
              if (d > 0) m = true;
              if (m) r += int2char(d);
          }
      }
      return m ? r : "0";
  }

  // (public) -this
  function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; }

  // (public) |this|
  function bnAbs() { return (this.s < 0) ? this.negate() : this; }

  // (public) return + if this > a, - if this < a, 0 if equal
  function bnCompareTo(a) {
      var r = this.s - a.s;
      if (r != 0) return r;
      var i = this.t;
      r = i - a.t;
      if (r != 0) return (this.s < 0) ? -r : r;
      while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;
      return 0;
  }

  // returns bit length of the integer x
  function nbits(x) {
      var r = 1, t;
      if ((t = x >>> 16) != 0) { x = t; r += 16; }
      if ((t = x >> 8) != 0) { x = t; r += 8; }
      if ((t = x >> 4) != 0) { x = t; r += 4; }
      if ((t = x >> 2) != 0) { x = t; r += 2; }
      if ((t = x >> 1) != 0) { x = t; r += 1; }
      return r;
  }

  // (public) return the number of bits in "this"
  function bnBitLength() {
      if (this.t <= 0) return 0;
      return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
  }

  // (protected) r = this << n*DB
  function bnpDLShiftTo(n, r) {
      var i;
      for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];
      for (i = n - 1; i >= 0; --i) r[i] = 0;
      r.t = this.t + n;
      r.s = this.s;
  }

  // (protected) r = this >> n*DB
  function bnpDRShiftTo(n, r) {
      for (var i = n; i < this.t; ++i) r[i - n] = this[i];
      r.t = Math.max(this.t - n, 0);
      r.s = this.s;
  }

  // (protected) r = this << n
  function bnpLShiftTo(n, r) {
      var bs = n % this.DB;
      var cbs = this.DB - bs;
      var bm = (1 << cbs) - 1;
      var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i;
      for (i = this.t - 1; i >= 0; --i) {
          r[i + ds + 1] = (this[i] >> cbs) | c;
          c = (this[i] & bm) << bs;
      }
      for (i = ds - 1; i >= 0; --i) r[i] = 0;
      r[ds] = c;
      r.t = this.t + ds + 1;
      r.s = this.s;
      r.clamp();
  }

  // (protected) r = this >> n
  function bnpRShiftTo(n, r) {
      r.s = this.s;
      var ds = Math.floor(n / this.DB);
      if (ds >= this.t) { r.t = 0; return; }
      var bs = n % this.DB;
      var cbs = this.DB - bs;
      var bm = (1 << bs) - 1;
      r[0] = this[ds] >> bs;
      for (var i = ds + 1; i < this.t; ++i) {
          r[i - ds - 1] |= (this[i] & bm) << cbs;
          r[i - ds] = this[i] >> bs;
      }
      if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
      r.t = this.t - ds;
      r.clamp();
  }

  // (protected) r = this - a
  function bnpSubTo(a, r) {
      var i = 0, c = 0, m = Math.min(a.t, this.t);
      while (i < m) {
          c += this[i] - a[i];
          r[i++] = c & this.DM;
          c >>= this.DB;
      }
      if (a.t < this.t) {
          c -= a.s;
          while (i < this.t) {
              c += this[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
          }
          c += this.s;
      }
      else {
          c += this.s;
          while (i < a.t) {
              c -= a[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
          }
          c -= a.s;
      }
      r.s = (c < 0) ? -1 : 0;
      if (c < -1) r[i++] = this.DV + c;
      else if (c > 0) r[i++] = c;
      r.t = i;
      r.clamp();
  }

  // (protected) r = this * a, r != this,a (HAC 14.12)
  // "this" should be the larger one if appropriate.
  function bnpMultiplyTo(a, r) {
      var x = this.abs(), y = a.abs();
      var i = x.t;
      r.t = i + y.t;
      while (--i >= 0) r[i] = 0;
      for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
      r.s = 0;
      r.clamp();
      if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
  }

  // (protected) r = this^2, r != this (HAC 14.16)
  function bnpSquareTo(r) {
      var x = this.abs();
      var i = r.t = 2 * x.t;
      while (--i >= 0) r[i] = 0;
      for (i = 0; i < x.t - 1; ++i) {
          var c = x.am(i, x[i], r, 2 * i, 0, 1);
          if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
              r[i + x.t] -= x.DV;
              r[i + x.t + 1] = 1;
          }
      }
      if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
      r.s = 0;
      r.clamp();
  }

  // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
  // r != q, this != m.  q or r may be null.
  function bnpDivRemTo(m, q, r) {
      var pm = m.abs();
      if (pm.t <= 0) return;
      var pt = this.abs();
      if (pt.t < pm.t) {
          if (q != null) q.fromInt(0);
          if (r != null) this.copyTo(r);
          return;
      }
      if (r == null) r = nbi();
      var y = nbi(), ts = this.s, ms = m.s;
      var nsh = this.DB - nbits(pm[pm.t - 1]);  // normalize modulus
      if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); }
      else { pm.copyTo(y); pt.copyTo(r); }
      var ys = y.t;
      var y0 = y[ys - 1];
      if (y0 == 0) return;
      var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
      var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
      var i = r.t, j = i - ys, t = (q == null) ? nbi() : q;
      y.dlShiftTo(j, t);
      if (r.compareTo(t) >= 0) {
          r[r.t++] = 1;
          r.subTo(t, r);
      }
      BigInteger.ONE.dlShiftTo(ys, t);
      t.subTo(y, y); // "negative" y so we can replace sub with am later
      while (y.t < ys) y[y.t++] = 0;
      while (--j >= 0) {
          // Estimate quotient digit
          var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
          if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {  // Try it out
              y.dlShiftTo(j, t);
              r.subTo(t, r);
              while (r[i] < --qd) r.subTo(t, r);
          }
      }
      if (q != null) {
          r.drShiftTo(ys, q);
          if (ts != ms) BigInteger.ZERO.subTo(q, q);
      }
      r.t = ys;
      r.clamp();
      if (nsh > 0) r.rShiftTo(nsh, r);  // Denormalize remainder
      if (ts < 0) BigInteger.ZERO.subTo(r, r);
  }

  // (public) this mod a
  function bnMod(a) {
      var r = nbi();
      this.abs().divRemTo(a, null, r);
      if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
      return r;
  }

  // Modular reduction using "classic" algorithm
  function Classic(m) { this.m = m; }
  function cConvert(x) {
      if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
      else return x;
  }
  function cRevert(x) { return x; }
  function cReduce(x) { x.divRemTo(this.m, null, x); }
  function cMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); }
  function cSqrTo(x, r) { x.squareTo(r); this.reduce(r); }

  Classic.prototype.convert = cConvert;
  Classic.prototype.revert = cRevert;
  Classic.prototype.reduce = cReduce;
  Classic.prototype.mulTo = cMulTo;
  Classic.prototype.sqrTo = cSqrTo;


  function bnpInvDigit() {
      if (this.t < 1) return 0;
      var x = this[0];
      if ((x & 1) == 0) return 0;
      var y = x & 3;    // y == 1/x mod 2^2
      y = (y * (2 - (x & 0xf) * y)) & 0xf;  // y == 1/x mod 2^4
      y = (y * (2 - (x & 0xff) * y)) & 0xff;  // y == 1/x mod 2^8
      y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
      // last step - calculate inverse mod DV directly;
      // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
      y = (y * (2 - x * y % this.DV)) % this.DV;    // y == 1/x mod 2^dbits
      // we really want the negative inverse, and -DV < y < DV
      return (y > 0) ? this.DV - y : -y;
  }

  // Montgomery reduction
  function Montgomery(m) {
      this.m = m;
      this.mp = m.invDigit();
      this.mpl = this.mp & 0x7fff;
      this.mph = this.mp >> 15;
      this.um = (1 << (m.DB - 15)) - 1;
      this.mt2 = 2 * m.t;
  }

  // xR mod m
  function montConvert(x) {
      var r = nbi();
      x.abs().dlShiftTo(this.m.t, r);
      r.divRemTo(this.m, null, r);
      if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
      return r;
  }

  // x/R mod m
  function montRevert(x) {
      var r = nbi();
      x.copyTo(r);
      this.reduce(r);
      return r;
  }

  // x = x/R mod m (HAC 14.32)
  function montReduce(x) {
      while (x.t <= this.mt2)  // pad x so am has enough room later
          x[x.t++] = 0;
      for (var i = 0; i < this.m.t; ++i) {
          // faster way of calculating u0 = x[i]*mp mod DV
          var j = x[i] & 0x7fff;
          var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
          // use am to combine the multiply-shift-add into one call
          j = i + this.m.t;
          x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
          // propagate carry
          while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
      }
      x.clamp();
      x.drShiftTo(this.m.t, x);
      if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
  }

  // r = "x^2/R mod m"; x != r
  function montSqrTo(x, r) { x.squareTo(r); this.reduce(r); }

  // r = "xy/R mod m"; x,y != r
  function montMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); }

  Montgomery.prototype.convert = montConvert;
  Montgomery.prototype.revert = montRevert;
  Montgomery.prototype.reduce = montReduce;
  Montgomery.prototype.mulTo = montMulTo;
  Montgomery.prototype.sqrTo = montSqrTo;

  // (protected) true iff this is even
  function bnpIsEven() { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; }

  // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
  function bnpExp(e, z) {
      if (e > 0xffffffff || e < 1) return BigInteger.ONE;
      var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
      g.copyTo(r);
      while (--i >= 0) {
          z.sqrTo(r, r2);
          if ((e & (1 << i)) > 0) z.mulTo(r2, g, r);
          else { var t = r; r = r2; r2 = t; }
      }
      return z.revert(r);
  }

  // (public) this^e % m, 0 <= e < 2^32
  function bnModPowInt(e, m) {
      var z;
      if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
      return this.exp(e, z);
  }

  // protected
  BigInteger.prototype.copyTo = bnpCopyTo;
  BigInteger.prototype.fromInt = bnpFromInt;
  BigInteger.prototype.fromString = bnpFromString;
  BigInteger.prototype.clamp = bnpClamp;
  BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
  BigInteger.prototype.drShiftTo = bnpDRShiftTo;
  BigInteger.prototype.lShiftTo = bnpLShiftTo;
  BigInteger.prototype.rShiftTo = bnpRShiftTo;
  BigInteger.prototype.subTo = bnpSubTo;
  BigInteger.prototype.multiplyTo = bnpMultiplyTo;
  BigInteger.prototype.squareTo = bnpSquareTo;
  BigInteger.prototype.divRemTo = bnpDivRemTo;
  BigInteger.prototype.invDigit = bnpInvDigit;
  BigInteger.prototype.isEven = bnpIsEven;
  BigInteger.prototype.exp = bnpExp;

  // public
  BigInteger.prototype.toString = bnToString;
  BigInteger.prototype.negate = bnNegate;
  BigInteger.prototype.abs = bnAbs;
  BigInteger.prototype.compareTo = bnCompareTo;
  BigInteger.prototype.bitLength = bnBitLength;
  BigInteger.prototype.mod = bnMod;
  BigInteger.prototype.modPowInt = bnModPowInt;

  // "constants"
  BigInteger.ZERO = nbv(0);
  BigInteger.ONE = nbv(1);



  /*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/
   */
  var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var b64pad = "=";

  function hex2b64(h) {
      var i;
      var c;
      var ret = "";
      for (i = 0; i + 3 <= h.length; i += 3) {
          c = parseInt(h.substring(i, i + 3), 16);
          ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
      }
      if (i + 1 == h.length) {
          c = parseInt(h.substring(i, i + 1), 16);
          ret += b64map.charAt(c << 2);
      }
      else if (i + 2 == h.length) {
          c = parseInt(h.substring(i, i + 2), 16);
          ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
      }
      if (b64pad) while ((ret.length & 3) > 0) ret += b64pad;
      return ret;
  }

  // convert a base64 string to hex
  function b64tohex(s) {
      var ret = "";
      var i;
      var k = 0; // b64 state, 0-3
      var slop;
      var v;
      for (i = 0; i < s.length; ++i) {
          if (s.charAt(i) == b64pad) break;
          v = b64map.indexOf(s.charAt(i));
          if (v < 0) continue;
          if (k == 0) {
              ret += int2char(v >> 2);
              slop = v & 3;
              k = 1;
          }
          else if (k == 1) {
              ret += int2char((slop << 2) | (v >> 4));
              slop = v & 0xf;
              k = 2;
          }
          else if (k == 2) {
              ret += int2char(slop);
              ret += int2char(v >> 2);
              slop = v & 3;
              k = 3;
          }
          else {
              ret += int2char((slop << 2) | (v >> 4));
              ret += int2char(v & 0xf);
              k = 0;
          }
      }
      if (k == 1)
          ret += int2char(slop << 2);
      return ret;
  }

  // convert a base64 string to a byte/number array
  function b64toBA(s) {
      //piggyback on b64tohex for now, optimize later
      var h = b64tohex(s);
      var i;
      var a = new Array();
      for (i = 0; 2 * i < h.length; ++i) {
          a[i] = parseInt(h.substring(2 * i, 2 * i + 2), 16);
      }
      return a;
  }


  /*
  -------------------------------------------------------------------------------------------------
   */
  function Arcfour() {
      this.i = 0;
      this.j = 0;
      this.S = new Array();
  }

  // Initialize arcfour context from key, an array of ints, each from [0..255]
  function ARC4init(key) {
      var i, j, t;
      for (i = 0; i < 256; ++i)
          this.S[i] = i;
      j = 0;
      for (i = 0; i < 256; ++i) {
          j = (j + this.S[i] + key[i % key.length]) & 255;
          t = this.S[i];
          this.S[i] = this.S[j];
          this.S[j] = t;
      }
      this.i = 0;
      this.j = 0;
  }

  function ARC4next() {
      var t;
      this.i = (this.i + 1) & 255;
      this.j = (this.j + this.S[this.i]) & 255;
      t = this.S[this.i];
      this.S[this.i] = this.S[this.j];
      this.S[this.j] = t;
      return this.S[(t + this.S[this.i]) & 255];
  }

  Arcfour.prototype.init = ARC4init;
  Arcfour.prototype.next = ARC4next;

  // Plug in your RNG constructor here
  function prng_newstate() {
      return new Arcfour();
  }

  // Pool size must be a multiple of 4 and greater than 32.
  // An array of bytes the size of the pool will be passed to init()
  var rng_psize = 256;

  /*
  ---------------------------------------SecureRandom----------------------------------------------------------
   */
  var rng_state;
  var rng_pool;
  var rng_pptr;

  // Mix in a 32-bit integer into the pool
  function rng_seed_int(x) {
      rng_pool[rng_pptr++] ^= x & 255;
      rng_pool[rng_pptr++] ^= (x >> 8) & 255;
      rng_pool[rng_pptr++] ^= (x >> 16) & 255;
      rng_pool[rng_pptr++] ^= (x >> 24) & 255;
      if (rng_pptr >= rng_psize) rng_pptr -= rng_psize;
  }

  // Mix in the current time (w/milliseconds) into the pool
  function rng_seed_time() {
      rng_seed_int(new Date().getTime());
  }

  // Initialize the pool with junk if needed.
  if (rng_pool == null) {
      rng_pool = new Array();
      rng_pptr = 0;
      var t;
      if (window !== undefined &&
          (window.crypto !== undefined ||
              window.msCrypto !== undefined)) {
          var crypto = window.crypto || window.msCrypto;
          if (crypto.getRandomValues) {
              // Use webcrypto if available
              var ua = new Uint8Array(32);
              crypto.getRandomValues(ua);
              for (t = 0; t < 32; ++t)
                  rng_pool[rng_pptr++] = ua[t];
          } else if (navigator.appName == "Netscape" && navigator.appVersion < "5") {
              // Extract entropy (256 bits) from NS4 RNG if available
              var z = window.crypto.random(32);
              for (t = 0; t < z.length; ++t)
                  rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
          }
      }
      while (rng_pptr < rng_psize) {  // extract some randomness from Math.random()
          t = Math.floor(65536 * Math.random());
          rng_pool[rng_pptr++] = t >>> 8;
          rng_pool[rng_pptr++] = t & 255;
      }
      rng_pptr = 0;
      rng_seed_time();
      //rng_seed_int(window.screenX);
      //rng_seed_int(window.screenY);
  }

  function rng_get_byte() {
      if (rng_state == null) {
          rng_seed_time();
          rng_state = prng_newstate();
          rng_state.init(rng_pool);
          for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
              rng_pool[rng_pptr] = 0;
          rng_pptr = 0;
          //rng_pool = null;
      }
      // TODO: allow reseeding after first request
      return rng_state.next();
  }

  function rng_get_bytes(ba) {
      var i;
      for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
  }

  function SecureRandom() { }

  SecureRandom.prototype.nextBytes = rng_get_bytes;


  /*
  ---------------------------------------CryptoJS----------------------------------------------------------
   */

  var CryptoJS = CryptoJS || (function (Math, undefined$1) {
      /**
       * CryptoJS namespace.
       */
      var C = {};

      /**
       * Library namespace.
       */
      var C_lib = C.lib = {};

      /**
       * Base object for prototypal inheritance.
       */
      var Base = C_lib.Base = (function () {
          function F() { }

          return {

              extend: function (overrides) {
                  // Spawn
                  F.prototype = this;
                  var subtype = new F();

                  // Augment
                  if (overrides) {
                      subtype.mixIn(overrides);
                  }

                  // Create default initializer
                  if (!subtype.hasOwnProperty('init')) {
                      subtype.init = function () {
                          subtype.$super.init.apply(this, arguments);
                      };
                  }

                  // Initializer's prototype is the subtype object
                  subtype.init.prototype = subtype;

                  // Reference supertype
                  subtype.$super = this;

                  return subtype;
              },


              create: function () {
                  var instance = this.extend();
                  instance.init.apply(instance, arguments);

                  return instance;
              },


              init: function () {
              },


              mixIn: function (properties) {
                  for (var propertyName in properties) {
                      if (properties.hasOwnProperty(propertyName)) {
                          this[propertyName] = properties[propertyName];
                      }
                  }

                  // IE won't copy toString using the loop above
                  if (properties.hasOwnProperty('toString')) {
                      this.toString = properties.toString;
                  }
              },


              clone: function () {
                  return this.init.prototype.extend(this);
              }
          };
      }());


      var WordArray = C_lib.WordArray = Base.extend({

          init: function (words, sigBytes) {
              words = this.words = words || [];

              if (sigBytes != undefined$1) {
                  this.sigBytes = sigBytes;
              } else {
                  this.sigBytes = words.length * 4;
              }
          },


          toString: function (encoder) {
              return (encoder || Hex).stringify(this);
          },


          concat: function (wordArray) {
              // Shortcuts
              var thisWords = this.words;
              var thatWords = wordArray.words;
              var thisSigBytes = this.sigBytes;
              var thatSigBytes = wordArray.sigBytes;

              // Clamp excess bits
              this.clamp();

              // Concat
              if (thisSigBytes % 4) {
                  // Copy one byte at a time
                  for (var i = 0; i < thatSigBytes; i++) {
                      var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
                      thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
                  }
              } else {
                  // Copy one word at a time
                  for (var i = 0; i < thatSigBytes; i += 4) {
                      thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
                  }
              }
              this.sigBytes += thatSigBytes;

              // Chainable
              return this;
          },


          clamp: function () {
              // Shortcuts
              var words = this.words;
              var sigBytes = this.sigBytes;

              // Clamp
              words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
              words.length = Math.ceil(sigBytes / 4);
          },


          clone: function () {
              var clone = Base.clone.call(this);
              clone.words = this.words.slice(0);

              return clone;
          },


          random: function (nBytes) {
              var words = [];
              for (var i = 0; i < nBytes; i += 4) {
                  words.push((Math.random() * 0x100000000) | 0);
              }

              return new WordArray.init(words, nBytes);
          }
      });


      var C_enc = C.enc = {};


      var Hex = C_enc.Hex = {

          stringify: function (wordArray) {
              // Shortcuts
              var words = wordArray.words;
              var sigBytes = wordArray.sigBytes;

              // Convert
              var hexChars = [];
              for (var i = 0; i < sigBytes; i++) {
                  var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
                  hexChars.push((bite >>> 4).toString(16));
                  hexChars.push((bite & 0x0f).toString(16));
              }

              return hexChars.join('');
          },


          parse: function (hexStr) {
              // Shortcut
              var hexStrLength = hexStr.length;

              // Convert
              var words = [];
              for (var i = 0; i < hexStrLength; i += 2) {
                  words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
              }

              return new WordArray.init(words, hexStrLength / 2);
          }
      };

      /**
       * Latin1 encoding strategy.
       */
      var Latin1 = C_enc.Latin1 = {

          stringify: function (wordArray) {
              // Shortcuts
              var words = wordArray.words;
              var sigBytes = wordArray.sigBytes;

              // Convert
              var latin1Chars = [];
              for (var i = 0; i < sigBytes; i++) {
                  var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
                  latin1Chars.push(String.fromCharCode(bite));
              }

              return latin1Chars.join('');
          },


          parse: function (latin1Str) {
              // Shortcut
              var latin1StrLength = latin1Str.length;

              // Convert
              var words = [];
              for (var i = 0; i < latin1StrLength; i++) {
                  words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
              }

              return new WordArray.init(words, latin1StrLength);
          }
      };


      var Utf8 = C_enc.Utf8 = {

          stringify: function (wordArray) {
              try {
                  return decodeURIComponent(escape(Latin1.stringify(wordArray)));
              } catch (e) {
                  throw new Error('Malformed UTF-8 data');
              }
          },


          parse: function (utf8Str) {
              return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
          }
      };


      var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({

          reset: function () {
              // Initial values
              this._data = new WordArray.init();
              this._nDataBytes = 0;
          },


          _append: function (data) {
              // Convert string to WordArray, else assume WordArray already
              if (typeof data == 'string') {
                  data = Utf8.parse(data);
              }

              // Append
              this._data.concat(data);
              this._nDataBytes += data.sigBytes;
          },

          _process: function (doFlush) {
              // Shortcuts
              var data = this._data;
              var dataWords = data.words;
              var dataSigBytes = data.sigBytes;
              var blockSize = this.blockSize;
              var blockSizeBytes = blockSize * 4;

              // Count blocks ready
              var nBlocksReady = dataSigBytes / blockSizeBytes;
              if (doFlush) {
                  // Round up to include partial blocks
                  nBlocksReady = Math.ceil(nBlocksReady);
              } else {
                  // Round down to include only full blocks,
                  // less the number of blocks that must remain in the buffer
                  nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
              }

              // Count words ready
              var nWordsReady = nBlocksReady * blockSize;

              // Count bytes ready
              var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);

              // Process blocks
              if (nWordsReady) {
                  for (var offset = 0; offset < nWordsReady; offset += blockSize) {
                      // Perform concrete-algorithm logic
                      this._doProcessBlock(dataWords, offset);
                  }

                  // Remove processed words
                  var processedWords = dataWords.splice(0, nWordsReady);
                  data.sigBytes -= nBytesReady;
              }

              // Return processed words
              return new WordArray.init(processedWords, nBytesReady);
          },


          clone: function () {
              var clone = Base.clone.call(this);
              clone._data = this._data.clone();

              return clone;
          },

          _minBufferSize: 0
      });


      var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
          /**
           * Configuration options.
           */
          cfg: Base.extend(),


          init: function (cfg) {
              // Apply config defaults
              this.cfg = this.cfg.extend(cfg);

              // Set initial values
              this.reset();
          },


          reset: function () {
              // Reset data buffer
              BufferedBlockAlgorithm.reset.call(this);

              // Perform concrete-hasher logic
              this._doReset();
          },


          update: function (messageUpdate) {
              // Append
              this._append(messageUpdate);

              // Update the hash
              this._process();

              // Chainable
              return this;
          },


          finalize: function (messageUpdate) {
              // Final message update
              if (messageUpdate) {
                  this._append(messageUpdate);
              }

              // Perform concrete-hasher logic
              var hash = this._doFinalize();

              return hash;
          },

          blockSize: 512 / 32,


          _createHelper: function (hasher) {
              return function (message, cfg) {
                  return new hasher.init(cfg).finalize(message);
              };
          },


          _createHmacHelper: function (hasher) {
              return function (message, key) {
                  return new C_algo.HMAC.init(hasher, key).finalize(message);
              };
          }
      });


      var C_algo = C.algo = {};

      return C;
  }(Math));






  (function () {
      // Shortcuts
      var C = CryptoJS;
      var C_lib = C.lib;
      var WordArray = C_lib.WordArray;
      var Hasher = C_lib.Hasher;
      var C_algo = C.algo;

      // Reusable object
      var W = [];

      /**
       * SHA-1 hash algorithm.
       */
      var SHA1 = C_algo.SHA1 = Hasher.extend({
          _doReset: function () {
              this._hash = new WordArray.init([
                  0x67452301, 0xefcdab89,
                  0x98badcfe, 0x10325476,
                  0xc3d2e1f0
              ]);
          },

          _doProcessBlock: function (M, offset) {
              // Shortcut
              var H = this._hash.words;

              // Working variables
              var a = H[0];
              var b = H[1];
              var c = H[2];
              var d = H[3];
              var e = H[4];

              // Computation
              for (var i = 0; i < 80; i++) {
                  if (i < 16) {
                      W[i] = M[offset + i] | 0;
                  } else {
                      var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
                      W[i] = (n << 1) | (n >>> 31);
                  }

                  var t = ((a << 5) | (a >>> 27)) + e + W[i];
                  if (i < 20) {
                      t += ((b & c) | (~b & d)) + 0x5a827999;
                  } else if (i < 40) {
                      t += (b ^ c ^ d) + 0x6ed9eba1;
                  } else if (i < 60) {
                      t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
                  } else /* if (i < 80) */ {
                      t += (b ^ c ^ d) - 0x359d3e2a;
                  }

                  e = d;
                  d = c;
                  c = (b << 30) | (b >>> 2);
                  b = a;
                  a = t;
              }

              // Intermediate hash value
              H[0] = (H[0] + a) | 0;
              H[1] = (H[1] + b) | 0;
              H[2] = (H[2] + c) | 0;
              H[3] = (H[3] + d) | 0;
              H[4] = (H[4] + e) | 0;
          },

          _doFinalize: function () {
              // Shortcuts
              var data = this._data;
              var dataWords = data.words;

              var nBitsTotal = this._nDataBytes * 8;
              var nBitsLeft = data.sigBytes * 8;

              // Add padding
              dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
              dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
              dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
              data.sigBytes = dataWords.length * 4;

              // Hash final blocks
              this._process();

              // Return final computed hash
              return this._hash;
          },

          clone: function () {
              var clone = Hasher.clone.call(this);
              clone._hash = this._hash.clone();

              return clone;
          }
      });

      C.SHA1 = Hasher._createHelper(SHA1);
      C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
  }());




  (function (Math) {
      // Shortcuts
      var C = CryptoJS;
      var C_lib = C.lib;
      var WordArray = C_lib.WordArray;
      var Hasher = C_lib.Hasher;
      var C_algo = C.algo;

      // Initialization and round constants tables
      var H = [];
      var K = [];

      // Compute constants
      (function () {
          function isPrime(n) {
              var sqrtN = Math.sqrt(n);
              for (var factor = 2; factor <= sqrtN; factor++) {
                  if (!(n % factor)) {
                      return false;
                  }
              }

              return true;
          }

          function getFractionalBits(n) {
              return ((n - (n | 0)) * 0x100000000) | 0;
          }

          var n = 2;
          var nPrime = 0;
          while (nPrime < 64) {
              if (isPrime(n)) {
                  if (nPrime < 8) {
                      H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
                  }
                  K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));

                  nPrime++;
              }

              n++;
          }
      }());

      // Reusable object
      var W = [];

      /**
       * SHA-256 hash algorithm.
       */
      var SHA256 = C_algo.SHA256 = Hasher.extend({
          _doReset: function () {
              this._hash = new WordArray.init(H.slice(0));
          },

          _doProcessBlock: function (M, offset) {
              // Shortcut
              var H = this._hash.words;

              // Working variables
              var a = H[0];
              var b = H[1];
              var c = H[2];
              var d = H[3];
              var e = H[4];
              var f = H[5];
              var g = H[6];
              var h = H[7];

              // Computation
              for (var i = 0; i < 64; i++) {
                  if (i < 16) {
                      W[i] = M[offset + i] | 0;
                  } else {
                      var gamma0x = W[i - 15];
                      var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
                          ((gamma0x << 14) | (gamma0x >>> 18)) ^
                          (gamma0x >>> 3);

                      var gamma1x = W[i - 2];
                      var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
                          ((gamma1x << 13) | (gamma1x >>> 19)) ^
                          (gamma1x >>> 10);

                      W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
                  }

                  var ch = (e & f) ^ (~e & g);
                  var maj = (a & b) ^ (a & c) ^ (b & c);

                  var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
                  var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));

                  var t1 = h + sigma1 + ch + K[i] + W[i];
                  var t2 = sigma0 + maj;

                  h = g;
                  g = f;
                  f = e;
                  e = (d + t1) | 0;
                  d = c;
                  c = b;
                  b = a;
                  a = (t1 + t2) | 0;
              }

              // Intermediate hash value
              H[0] = (H[0] + a) | 0;
              H[1] = (H[1] + b) | 0;
              H[2] = (H[2] + c) | 0;
              H[3] = (H[3] + d) | 0;
              H[4] = (H[4] + e) | 0;
              H[5] = (H[5] + f) | 0;
              H[6] = (H[6] + g) | 0;
              H[7] = (H[7] + h) | 0;
          },

          _doFinalize: function () {
              // Shortcuts
              var data = this._data;
              var dataWords = data.words;

              var nBitsTotal = this._nDataBytes * 8;
              var nBitsLeft = data.sigBytes * 8;

              // Add padding
              dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
              dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
              dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
              data.sigBytes = dataWords.length * 4;

              // Hash final blocks
              this._process();

              // Return final computed hash
              return this._hash;
          },

          clone: function () {
              var clone = Hasher.clone.call(this);
              clone._hash = this._hash.clone();

              return clone;
          }
      });

      C.SHA256 = Hasher._createHelper(SHA256);


      C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
  }(Math));


  /*

  --------------------------------------------------asn1hex-1.1-------------------------------------------------------
  */
  var ASN1HEX = new function () {
  };

  ASN1HEX.getLblen = function (s, idx) {
      if (s.substr(idx + 2, 1) != '8') return 1;
      var i = parseInt(s.substr(idx + 3, 1));
      if (i == 0) return -1;             // length octet '80' indefinite length
      if (0 < i && i < 10) return i + 1; // including '8?' octet;
      return -2;                         // malformed format
  };

  ASN1HEX.getL = function (s, idx) {
      var len = ASN1HEX.getLblen(s, idx);
      if (len < 1) return '';
      return s.substr(idx + 2, len * 2);
  };

  ASN1HEX.getVblen = function (s, idx) {
      var hLen, bi;
      hLen = ASN1HEX.getL(s, idx);
      if (hLen == '') return -1;
      if (hLen.substr(0, 1) === '8') {
          bi = new BigInteger(hLen.substr(2), 16);
      } else {
          bi = new BigInteger(hLen, 16);
      }
      //  console.log("bi---",bi, BigInteger)
      return bi.intValue();
  };


  ASN1HEX.getVidx = function (s, idx) {
      var l_len = ASN1HEX.getLblen(s, idx);
      if (l_len < 0) return l_len;
      return idx + (l_len + 1) * 2;
  };


  ASN1HEX.getV = function (s, idx) {
      var idx1 = ASN1HEX.getVidx(s, idx);
      var blen = ASN1HEX.getVblen(s, idx);
      return s.substr(idx1, blen * 2);
  };

  ASN1HEX.getTLV = function (s, idx) {
      return s.substr(idx, 2) + ASN1HEX.getL(s, idx) + ASN1HEX.getV(s, idx);
  };

  // ========== sibling methods ================================

  ASN1HEX.getNextSiblingIdx = function (s, idx) {
      var idx1 = ASN1HEX.getVidx(s, idx);
      var blen = ASN1HEX.getVblen(s, idx);
      return idx1 + blen * 2;
  };

  // ========== children methods ===============================

  ASN1HEX.getChildIdx = function (h, pos) {
      var _ASN1HEX = ASN1HEX;
      var a = new Array();
      var p0 = _ASN1HEX.getVidx(h, pos);
      if (h.substr(pos, 2) == "03") {
          a.push(p0 + 2); // BITSTRING value without unusedbits
      } else {
          a.push(p0);
      }

      var blen = _ASN1HEX.getVblen(h, pos);
      var p = p0;
      var k = 0;
      while (1) {
          var pNext = _ASN1HEX.getNextSiblingIdx(h, p);
          if (pNext == null || (pNext - p0 >= (blen * 2))) break;
          if (k >= 200) break;

          a.push(pNext);
          p = pNext;

          k++;
      }

      return a;
  };


  ASN1HEX.getNthChildIdx = function (h, idx, nth) {
      var a = ASN1HEX.getChildIdx(h, idx);
      return a[nth];
  };

  // ========== decendant methods ==============================

  ASN1HEX.getIdxbyList = function (h, currentIndex, nthList, checkingTag) {
      var _ASN1HEX = ASN1HEX;
      var firstNth, a;
      if (nthList.length == 0) {
          if (checkingTag !== undefined) {
              if (h.substr(currentIndex, 2) !== checkingTag) {
                  throw "checking tag doesn't match: " +
                  h.substr(currentIndex, 2) + "!=" + checkingTag;
              }
          }
          return currentIndex;
      }
      firstNth = nthList.shift();
      a = _ASN1HEX.getChildIdx(h, currentIndex);
      return _ASN1HEX.getIdxbyList(h, a[firstNth], nthList, checkingTag);
  };


  ASN1HEX.getTLVbyList = function (h, currentIndex, nthList, checkingTag) {
      var _ASN1HEX = ASN1HEX;
      var idx = _ASN1HEX.getIdxbyList(h, currentIndex, nthList);
      if (idx === undefined) {
          throw "can't find nthList object";
      }
      if (checkingTag !== undefined) {
          if (h.substr(idx, 2) != checkingTag) {
              throw "checking tag doesn't match: " +
              h.substr(idx, 2) + "!=" + checkingTag;
          }
      }
      return _ASN1HEX.getTLV(h, idx);
  };


  ASN1HEX.getVbyList = function (h, currentIndex, nthList, checkingTag, removeUnusedbits) {
      var _ASN1HEX = ASN1HEX;
      var idx, v;
      idx = _ASN1HEX.getIdxbyList(h, currentIndex, nthList, checkingTag);

      if (idx === undefined) {
          throw "can't find nthList object";
      }

      v = _ASN1HEX.getV(h, idx);
      if (removeUnusedbits === true) v = v.substr(2);
      return v;
  };


  ASN1HEX.hextooidstr = function (hex) {
      var zeroPadding = function (s, len) {
          if (s.length >= len) return s;
          return new Array(len - s.length + 1).join('0') + s;
      };

      var a = [];

      // a[0], a[1]
      var hex0 = hex.substr(0, 2);
      var i0 = parseInt(hex0, 16);
      a[0] = new String(Math.floor(i0 / 40));
      a[1] = new String(i0 % 40);

      // a[2]..a[n]
      var hex1 = hex.substr(2);
      var b = [];
      for (var i = 0; i < hex1.length / 2; i++) {
          b.push(parseInt(hex1.substr(i * 2, 2), 16));
      }
      var c = [];
      var cbin = "";
      for (var i = 0; i < b.length; i++) {
          if (b[i] & 0x80) {
              cbin = cbin + zeroPadding((b[i] & 0x7f).toString(2), 7);
          } else {
              cbin = cbin + zeroPadding((b[i] & 0x7f).toString(2), 7);
              c.push(new String(parseInt(cbin, 2)));
              cbin = "";
          }
      }

      var s = a.join(".");
      if (c.length > 0) s = s + "." + c.join(".");
      return s;
  };

  ASN1HEX.dump = function (hexOrObj, flags, idx, indent) {
      var _ASN1HEX = ASN1HEX;
      var _getV = _ASN1HEX.getV;
      var _dump = _ASN1HEX.dump;
      var _getChildIdx = _ASN1HEX.getChildIdx;

      var hex = hexOrObj;
      if (hexOrObj instanceof KJUR.asn1.ASN1Object)
          hex = hexOrObj.getEncodedHex();

      var _skipLongHex = function (hex, limitNumOctet) {
          if (hex.length <= limitNumOctet * 2) {
              return hex;
          } else {
              var s = hex.substr(0, limitNumOctet) +
                  "..(total " + hex.length / 2 + "bytes).." +
                  hex.substr(hex.length - limitNumOctet, limitNumOctet);
              return s;
          };
      };

      if (flags === undefined) flags = { "ommit_long_octet": 32 };
      if (idx === undefined) idx = 0;
      if (indent === undefined) indent = "";
      var skipLongHex = flags.ommit_long_octet;

      if (hex.substr(idx, 2) == "01") {
          var v = _getV(hex, idx);
          if (v == "00") {
              return indent + "BOOLEAN FALSE\n";
          } else {
              return indent + "BOOLEAN TRUE\n";
          }
      }
      if (hex.substr(idx, 2) == "02") {
          var v = _getV(hex, idx);
          return indent + "INTEGER " + _skipLongHex(v, skipLongHex) + "\n";
      }
      if (hex.substr(idx, 2) == "03") {
          var v = _getV(hex, idx);
          return indent + "BITSTRING " + _skipLongHex(v, skipLongHex) + "\n";
      }
      if (hex.substr(idx, 2) == "04") {
          var v = _getV(hex, idx);
          if (_ASN1HEX.isASN1HEX(v)) {
              var s = indent + "OCTETSTRING, encapsulates\n";
              s = s + _dump(v, flags, 0, indent + "  ");
              return s;
          } else {
              return indent + "OCTETSTRING " + _skipLongHex(v, skipLongHex) + "\n";
          }
      }
      if (hex.substr(idx, 2) == "05") {
          return indent + "NULL\n";
      }
      if (hex.substr(idx, 2) == "06") {
          var hV = _getV(hex, idx);
          var oidDot = KJUR.asn1.ASN1Util.oidHexToInt(hV);
          var oidName = KJUR.asn1.x509.OID.oid2name(oidDot);
          var oidSpc = oidDot.replace(/\./g, ' ');
          if (oidName != '') {
              return indent + "ObjectIdentifier " + oidName + " (" + oidSpc + ")\n";
          } else {
              return indent + "ObjectIdentifier (" + oidSpc + ")\n";
          }
      }
      if (hex.substr(idx, 2) == "0c") {
          return indent + "UTF8String '" + hextoutf8(_getV(hex, idx)) + "'\n";
      }
      if (hex.substr(idx, 2) == "13") {
          return indent + "PrintableString '" + hextoutf8(_getV(hex, idx)) + "'\n";
      }
      if (hex.substr(idx, 2) == "14") {
          return indent + "TeletexString '" + hextoutf8(_getV(hex, idx)) + "'\n";
      }
      if (hex.substr(idx, 2) == "16") {
          return indent + "IA5String '" + hextoutf8(_getV(hex, idx)) + "'\n";
      }
      if (hex.substr(idx, 2) == "17") {
          return indent + "UTCTime " + hextoutf8(_getV(hex, idx)) + "\n";
      }
      if (hex.substr(idx, 2) == "18") {
          return indent + "GeneralizedTime " + hextoutf8(_getV(hex, idx)) + "\n";
      }
      if (hex.substr(idx, 2) == "30") {
          if (hex.substr(idx, 4) == "3000") {
              return indent + "SEQUENCE {}\n";
          }

          var s = indent + "SEQUENCE\n";
          var aIdx = _getChildIdx(hex, idx);

          var flagsTemp = flags;

          if ((aIdx.length == 2 || aIdx.length == 3) &&
              hex.substr(aIdx[0], 2) == "06" &&
              hex.substr(aIdx[aIdx.length - 1], 2) == "04") { // supposed X.509v3 extension
              var oidName = _ASN1HEX.oidname(_getV(hex, aIdx[0]));
              var flagsClone = JSON.parse(JSON.stringify(flags));
              flagsClone.x509ExtName = oidName;
              flagsTemp = flagsClone;
          }

          for (var i = 0; i < aIdx.length; i++) {
              s = s + _dump(hex, flagsTemp, aIdx[i], indent + "  ");
          }
          return s;
      }
      if (hex.substr(idx, 2) == "31") {
          var s = indent + "SET\n";
          var aIdx = _getChildIdx(hex, idx);
          for (var i = 0; i < aIdx.length; i++) {
              s = s + _dump(hex, flags, aIdx[i], indent + "  ");
          }
          return s;
      }
      var tag = parseInt(hex.substr(idx, 2), 16);
      if ((tag & 128) != 0) { // context specific 
          var tagNumber = tag & 31;
          if ((tag & 32) != 0) { // structured tag
              var s = indent + "[" + tagNumber + "]\n";
              var aIdx = _getChildIdx(hex, idx);
              for (var i = 0; i < aIdx.length; i++) {
                  s = s + _dump(hex, flags, aIdx[i], indent + "  ");
              }
              return s;
          } else { // primitive tag
              var v = _getV(hex, idx);
              if (v.substr(0, 8) == "68747470") { // http
                  v = hextoutf8(v);
              }
              if (flags.x509ExtName === "subjectAltName" &&
                  tagNumber == 2) {
                  v = hextoutf8(v);
              }

              var s = indent + "[" + tagNumber + "] " + v + "\n";
              return s;
          }
      }
      return indent + "UNKNOWN(" + hex.substr(idx, 2) + ") " +
          _getV(hex, idx) + "\n";
  };


  ASN1HEX.isASN1HEX = function (hex) {
      var _ASN1HEX = ASN1HEX;
      if (hex.length % 2 == 1) return false;

      var intL = _ASN1HEX.getVblen(hex, 0);
      var tV = hex.substr(0, 2);
      var lV = _ASN1HEX.getL(hex, 0);
      var hVLength = hex.length - tV.length - lV.length;
      if (hVLength == intL * 2) return true;

      return false;
  };

  ASN1HEX.oidname = function (oidDotOrHex) {
      var _KJUR_asn1 = KJUR.asn1;
      if (KJUR.lang.String.isHex(oidDotOrHex))
          oidDotOrHex = _KJUR_asn1.ASN1Util.oidHexToInt(oidDotOrHex);
      var name = _KJUR_asn1.x509.OID.oid2name(oidDotOrHex);
      if (name === "") name = oidDotOrHex;
      return name;
  };


  /*

  --------------------------------------------------base64x-1.1-------------------------------------------------------
  */
  var KJUR;
  if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
  if (typeof KJUR.lang == "undefined" || !KJUR.lang) KJUR.lang = {};


  KJUR.lang.String = function () { };


  function Base64x() {
  }


  function stoBA(s) {
      var a = new Array();
      for (var i = 0; i < s.length; i++) {
          a[i] = s.charCodeAt(i);
      }
      return a;
  }


  function BAtos(a) {
      var s = "";
      for (var i = 0; i < a.length; i++) {
          s = s + String.fromCharCode(a[i]);
      }
      return s;
  }


  function BAtohex(a) {
      var s = "";
      for (var i = 0; i < a.length; i++) {
          var hex1 = a[i].toString(16);
          if (hex1.length == 1) hex1 = "0" + hex1;
          s = s + hex1;
      }
      return s;
  }


  function stohex(s) {
      return BAtohex(stoBA(s));
  }

  function stob64(s) {
      return hex2b64(stohex(s));
  }

  function stob64u(s) {
      return b64tob64u(hex2b64(stohex(s)));
  }

  function b64utos(s) {
      return BAtos(b64toBA(b64utob64(s)));
  }

  function b64tob64u(s) {
      s = s.replace(/\=/g, "");
      s = s.replace(/\+/g, "-");
      s = s.replace(/\//g, "_");
      return s;
  }

  function b64utob64(s) {
      if (s.length % 4 == 2) s = s + "==";
      else if (s.length % 4 == 3) s = s + "=";
      s = s.replace(/-/g, "+");
      s = s.replace(/_/g, "/");
      return s;
  }

  function hextob64u(s) {
      if (s.length % 2 == 1) s = "0" + s;
      return b64tob64u(hex2b64(s));
  }

  function b64utohex(s) {
      return b64tohex(b64utob64(s));
  }

  var utf8tob64u, b64utoutf8;

  if (typeof Buffer === 'function') {
      utf8tob64u = function (s) {
          return b64tob64u(new Buffer(s, 'utf8').toString('base64'));
      };

      b64utoutf8 = function (s) {
          return new Buffer(b64utob64(s), 'base64').toString('utf8');
      };
  } else {
      utf8tob64u = function (s) {
          return hextob64u(uricmptohex(encodeURIComponentAll(s)));
      };

      b64utoutf8 = function (s) {
          return decodeURIComponent(hextouricmp(b64utohex(s)));
      };
  }

  function utf8tob64(s) {
      return hex2b64(uricmptohex(encodeURIComponentAll(s)));
  }

  function b64toutf8(s) {
      return decodeURIComponent(hextouricmp(b64tohex(s)));
  }

  function utf8tohex(s) {
      return uricmptohex(encodeURIComponentAll(s));
  }

  function hextoutf8(s) {
      return decodeURIComponent(hextouricmp(s));
  }

  function hextorstr(sHex) {
      var s = "";
      for (var i = 0; i < sHex.length - 1; i += 2) {
          s += String.fromCharCode(parseInt(sHex.substr(i, 2), 16));
      }
      return s;
  }

  function rstrtohex(s) {
      var result = "";
      for (var i = 0; i < s.length; i++) {
          result += ("0" + s.charCodeAt(i).toString(16)).slice(-2);
      }
      return result;
  }

  function hextob64(s) {
      return hex2b64(s);
  }

  function hextob64nl(s) {
      var b64 = hextob64(s);
      var b64nl = b64.replace(/(.{64})/g, "$1\r\n");
      b64nl = b64nl.replace(/\r\n$/, '');
      return b64nl;
  }


  function b64nltohex(s) {
      var b64 = s.replace(/[^0-9A-Za-z\/+=]*/g, '');
      var hex = b64tohex(b64);
      return hex;
  }

  function hextopem(dataHex, pemHeader) {
      var pemBody = hextob64nl(dataHex);
      return "-----BEGIN " + pemHeader + "-----\r\n" +
          pemBody +
          "\r\n-----END " + pemHeader + "-----\r\n";
  }

  function pemtohex(s, sHead) {
      if (s.indexOf("-----BEGIN ") == -1)
          throw "can't find PEM header: " + sHead;

      if (sHead !== undefined) {
          s = s.replace("-----BEGIN " + sHead + "-----", "");
          s = s.replace("-----END " + sHead + "-----", "");
      } else {
          s = s.replace(/-----BEGIN [^-]+-----/, '');
          s = s.replace(/-----END [^-]+-----/, '');
      }
      return b64nltohex(s);
  }

  function hextoArrayBuffer(hex) {
      if (hex.length % 2 != 0) throw "input is not even length";
      if (hex.match(/^[0-9A-Fa-f]+$/) == null) throw "input is not hexadecimal";

      var buffer = new ArrayBuffer(hex.length / 2);
      var view = new DataView(buffer);

      for (var i = 0; i < hex.length / 2; i++) {
          view.setUint8(i, parseInt(hex.substr(i * 2, 2), 16));
      }

      return buffer;
  }

  function ArrayBuffertohex(buffer) {
      var hex = "";
      var view = new DataView(buffer);

      for (var i = 0; i < buffer.byteLength; i++) {
          hex += ("00" + view.getUint8(i).toString(16)).slice(-2);
      }

      return hex;
  }

  function zulutomsec(s) {
      var year, month, day, hour, min, sec, msec, d;
      var sYear, sFrac, sMsec, matchResult;

      matchResult = s.match(/^(\d{2}|\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(|\.\d+)Z$/);

      if (matchResult) {
          sYear = matchResult[1];
          year = parseInt(sYear);
          if (sYear.length === 2) {
              if (50 <= year && year < 100) {
                  year = 1900 + year;
              } else if (0 <= year && year < 50) {
                  year = 2000 + year;
              }
          }
          month = parseInt(matchResult[2]) - 1;
          day = parseInt(matchResult[3]);
          hour = parseInt(matchResult[4]);
          min = parseInt(matchResult[5]);
          sec = parseInt(matchResult[6]);
          msec = 0;

          sFrac = matchResult[7];
          if (sFrac !== "") {
              sMsec = (sFrac.substr(1) + "00").substr(0, 3); // .12 -> 012
              msec = parseInt(sMsec);
          }
          return Date.UTC(year, month, day, hour, min, sec, msec);
      }
      throw "unsupported zulu format: " + s;
  }

  function zulutosec(s) {
      var msec = zulutomsec(s);
      return ~~(msec / 1000);
  }

  function zulutodate(s) {
      return new Date(zulutomsec(s));
  }

  function datetozulu(d, flagUTCTime, flagMilli) {
      var s;
      var year = d.getUTCFullYear();
      if (flagUTCTime) {
          if (year < 1950 || 2049 < year)
              throw "not proper year for UTCTime: " + year;
          s = ("" + year).slice(-2);
      } else {
          s = ("000" + year).slice(-4);
      }
      s += ("0" + (d.getUTCMonth() + 1)).slice(-2);
      s += ("0" + d.getUTCDate()).slice(-2);
      s += ("0" + d.getUTCHours()).slice(-2);
      s += ("0" + d.getUTCMinutes()).slice(-2);
      s += ("0" + d.getUTCSeconds()).slice(-2);
      if (flagMilli) {
          var milli = d.getUTCMilliseconds();
          if (milli !== 0) {
              milli = ("00" + milli).slice(-3);
              milli = milli.replace(/0+$/g, "");
              s += "." + milli;
          }
      }
      s += "Z";
      return s;
  }

  function uricmptohex(s) {
      return s.replace(/%/g, "");
  }

  function hextouricmp(s) {
      return s.replace(/(..)/g, "%$1");
  }

  function ipv6tohex(s) {
      var msgMalformedAddress = "malformed IPv6 address";
      if (!s.match(/^[0-9A-Fa-f:]+$/))
          throw msgMalformedAddress;

      // 1. downcase
      s = s.toLowerCase();

      // 2. expand ::
      var num_colon = s.split(':').length - 1;
      if (num_colon < 2) throw msgMalformedAddress;
      var colon_replacer = ':'.repeat(7 - num_colon + 2);
      s = s.replace('::', colon_replacer);

      // 3. fill zero
      var a = s.split(':');
      if (a.length != 8) throw msgMalformedAddress;
      for (var i = 0; i < 8; i++) {
          a[i] = ("0000" + a[i]).slice(-4);
      }
      return a.join('');
  }

  function hextoipv6(s) {
      if (!s.match(/^[0-9A-Fa-f]{32}$/))
          throw "malformed IPv6 address octet";

      // 1. downcase
      s = s.toLowerCase();

      // 2. split 4
      var a = s.match(/.{1,4}/g);

      // 3. trim leading 0
      for (var i = 0; i < 8; i++) {
          a[i] = a[i].replace(/^0+/, "");
          if (a[i] == '') a[i] = '0';
      }
      s = ":" + a.join(":") + ":";

      // 4. find shrinkables :0:0:...
      var aZero = s.match(/:(0:){2,}/g);

      // 5. no shrinkable
      if (aZero === null) return s.slice(1, -1);

      // 6. find max length :0:0:...
      var item = '';
      for (var i = 0; i < aZero.length; i++) {
          if (aZero[i].length > item.length) item = aZero[i];
      }

      // 7. shrink
      s = s.replace(item, '::');
      return s.slice(1, -1);
  }

  function hextoip(s) {
      var malformedMsg = "malformed hex value";
      if (!s.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/))
          throw malformedMsg;
      if (s.length == 8) { // ipv4
          var ip;
          try {
              ip = parseInt(s.substr(0, 2), 16) + "." +
                  parseInt(s.substr(2, 2), 16) + "." +
                  parseInt(s.substr(4, 2), 16) + "." +
                  parseInt(s.substr(6, 2), 16);
              return ip;
          } catch (ex) {
              throw malformedMsg;
          }
      } else if (s.length == 32) {
          return hextoipv6(s);
      } else {
          return s;
      }
  }

  function iptohex(s) {
      var malformedMsg = "malformed IP address";
      s = s.toLowerCase(s);

      if (s.match(/^[0-9.]+$/)) {
          var a = s.split(".");
          if (a.length !== 4) throw malformedMsg;
          var hex = "";
          try {
              for (var i = 0; i < 4; i++) {
                  var d = parseInt(a[i]);
                  hex += ("0" + d.toString(16)).slice(-2);
              }
              return hex;
          } catch (ex) {
              throw malformedMsg;
          }
      } else if (s.match(/^[0-9a-f:]+$/) && s.indexOf(":") !== -1) {
          return ipv6tohex(s);
      } else {
          throw malformedMsg;
      }
  }

  function encodeURIComponentAll(u8) {
      var s = encodeURIComponent(u8);
      var s2 = "";
      for (var i = 0; i < s.length; i++) {
          if (s[i] == "%") {
              s2 = s2 + s.substr(i, 3);
              i = i + 2;
          } else {
              s2 = s2 + "%" + stohex(s[i]);
          }
      }
      return s2;
  }

  // ==== new lines ================================
  function newline_toUnix(s) {
      s = s.replace(/\r\n/mg, "\n");
      return s;
  }

  function newline_toDos(s) {
      s = s.replace(/\r\n/mg, "\n");
      s = s.replace(/\n/mg, "\r\n");
      return s;
  }


  KJUR.lang.String.isInteger = function (s) {
      if (s.match(/^[0-9]+$/)) {
          return true;
      } else if (s.match(/^-[0-9]+$/)) {
          return true;
      } else {
          return false;
      }
  };

  KJUR.lang.String.isHex = function (s) {
      if (s.length % 2 == 0 &&
          (s.match(/^[0-9a-f]+$/) || s.match(/^[0-9A-F]+$/))) {
          return true;
      } else {
          return false;
      }
  };

  KJUR.lang.String.isBase64 = function (s) {
      s = s.replace(/\s+/g, "");
      if (s.match(/^[0-9A-Za-z+\/]+={0,3}$/) && s.length % 4 == 0) {
          return true;
      } else {
          return false;
      }
  };

  KJUR.lang.String.isBase64URL = function (s) {
      if (s.match(/[+/=]/)) return false;
      s = b64utob64(s);
      return KJUR.lang.String.isBase64(s);
  };

  KJUR.lang.String.isIntegerArray = function (s) {
      s = s.replace(/\s+/g, "");
      if (s.match(/^\[[0-9,]+\]$/)) {
          return true;
      } else {
          return false;
      }
  };


  function hextoposhex(s) {
      if (s.length % 2 == 1) return "0" + s;
      if (s.substr(0, 1) > "7") return "00" + s;
      return s;
  }

  function intarystrtohex(s) {
      s = s.replace(/^\s*\[\s*/, '');
      s = s.replace(/\s*\]\s*$/, '');
      s = s.replace(/\s*/g, '');
      try {
          var hex = s.split(/,/).map(function (element, index, array) {
              var i = parseInt(element);
              if (i < 0 || 255 < i) throw "integer not in range 0-255";
              var hI = ("00" + i.toString(16)).slice(-2);
              return hI;
          }).join('');
          return hex;
      } catch (ex) {
          throw "malformed integer array string: " + ex;
      }
  }

  var strdiffidx = function (s1, s2) {
      var n = s1.length;
      if (s1.length > s2.length) n = s2.length;
      for (var i = 0; i < n; i++) {
          if (s1.charCodeAt(i) != s2.charCodeAt(i)) return i;
      }
      if (s1.length != s2.length) return n;
      return -1; // same
  };




  /*

  --------------------------------------------------crypto-1.1-------------------------------------------------------
  */

  if (typeof KJUR == "undefined" || !KJUR) KJUR = {};

  if (typeof KJUR.crypto == "undefined" || !KJUR.crypto) KJUR.crypto = {};


  KJUR.crypto.Util = new function () {
      this.DIGESTINFOHEAD = {
          'sha1': "3021300906052b0e03021a05000414",
          'sha224': "302d300d06096086480165030402040500041c",
          'sha256': "3031300d060960864801650304020105000420",
          'sha384': "3041300d060960864801650304020205000430",
          'sha512': "3051300d060960864801650304020305000440",
          'md2': "3020300c06082a864886f70d020205000410",
          'md5': "3020300c06082a864886f70d020505000410",
          'ripemd160': "3021300906052b2403020105000414",
      };

      /*
       * @since crypto 1.1.1
       */
      this.DEFAULTPROVIDER = {
          'md5': 'cryptojs',
          'sha1': 'cryptojs',
          'sha224': 'cryptojs',
          'sha256': 'cryptojs',
          'sha384': 'cryptojs',
          'sha512': 'cryptojs',
          'ripemd160': 'cryptojs',
          'hmacmd5': 'cryptojs',
          'hmacsha1': 'cryptojs',
          'hmacsha224': 'cryptojs',
          'hmacsha256': 'cryptojs',
          'hmacsha384': 'cryptojs',
          'hmacsha512': 'cryptojs',
          'hmacripemd160': 'cryptojs',

          'MD5withRSA': 'cryptojs/jsrsa',
          'SHA1withRSA': 'cryptojs/jsrsa',
          'SHA224withRSA': 'cryptojs/jsrsa',
          'SHA256withRSA': 'cryptojs/jsrsa',
          'SHA384withRSA': 'cryptojs/jsrsa',
          'SHA512withRSA': 'cryptojs/jsrsa',
          'RIPEMD160withRSA': 'cryptojs/jsrsa',

          'MD5withECDSA': 'cryptojs/jsrsa',
          'SHA1withECDSA': 'cryptojs/jsrsa',
          'SHA224withECDSA': 'cryptojs/jsrsa',
          'SHA256withECDSA': 'cryptojs/jsrsa',
          'SHA384withECDSA': 'cryptojs/jsrsa',
          'SHA512withECDSA': 'cryptojs/jsrsa',
          'RIPEMD160withECDSA': 'cryptojs/jsrsa',

          'SHA1withDSA': 'cryptojs/jsrsa',
          'SHA224withDSA': 'cryptojs/jsrsa',
          'SHA256withDSA': 'cryptojs/jsrsa',

          'MD5withRSAandMGF1': 'cryptojs/jsrsa',
          'SHA1withRSAandMGF1': 'cryptojs/jsrsa',
          'SHA224withRSAandMGF1': 'cryptojs/jsrsa',
          'SHA256withRSAandMGF1': 'cryptojs/jsrsa',
          'SHA384withRSAandMGF1': 'cryptojs/jsrsa',
          'SHA512withRSAandMGF1': 'cryptojs/jsrsa',
          'RIPEMD160withRSAandMGF1': 'cryptojs/jsrsa',
      };

      this.CRYPTOJSMESSAGEDIGESTNAME = {
          'md5': CryptoJS.algo.MD5,
          'sha1': CryptoJS.algo.SHA1,
          'sha224': CryptoJS.algo.SHA224,
          'sha256': CryptoJS.algo.SHA256,
          'sha384': CryptoJS.algo.SHA384,
          'sha512': CryptoJS.algo.SHA512,
          'ripemd160': CryptoJS.algo.RIPEMD160
      };

      this.getDigestInfoHex = function (hHash, alg) {
          if (typeof this.DIGESTINFOHEAD[alg] == "undefined")
              throw "alg not supported in Util.DIGESTINFOHEAD: " + alg;
          return this.DIGESTINFOHEAD[alg] + hHash;
      };

      this.getPaddedDigestInfoHex = function (hHash, alg, keySize) {
          var hDigestInfo = this.getDigestInfoHex(hHash, alg);
          var pmStrLen = keySize / 4; // minimum PM length

          if (hDigestInfo.length + 22 > pmStrLen) // len(0001+ff(*8)+00+hDigestInfo)=22
              throw "key is too short for SigAlg: keylen=" + keySize + "," + alg;

          var hHead = "0001";
          var hTail = "00" + hDigestInfo;
          var hMid = "";
          var fLen = pmStrLen - hHead.length - hTail.length;
          for (var i = 0; i < fLen; i += 2) {
              hMid += "ff";
          }
          var hPaddedMessage = hHead + hMid + hTail;
          return hPaddedMessage;
      };

      this.hashString = function (s, alg) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': alg });
          return md.digestString(s);
      };

      this.hashHex = function (sHex, alg) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': alg });
          return md.digestHex(sHex);
      };

      this.sha1 = function (s) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': 'sha1', 'prov': 'cryptojs' });
          return md.digestString(s);
      };

      this.sha256 = function (s) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': 'sha256', 'prov': 'cryptojs' });
          return md.digestString(s);
      };

      this.sha256Hex = function (s) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': 'sha256', 'prov': 'cryptojs' });
          return md.digestHex(s);
      };

      this.sha512 = function (s) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': 'sha512', 'prov': 'cryptojs' });
          return md.digestString(s);
      };

      this.sha512Hex = function (s) {
          var md = new KJUR.crypto.MessageDigest({ 'alg': 'sha512', 'prov': 'cryptojs' });
          return md.digestHex(s);
      };

  };

  KJUR.crypto.Util.md5 = function (s) {
      var md = new KJUR.crypto.MessageDigest({ 'alg': 'md5', 'prov': 'cryptojs' });
      return md.digestString(s);
  };

  KJUR.crypto.Util.ripemd160 = function (s) {
      var md = new KJUR.crypto.MessageDigest({ 'alg': 'ripemd160', 'prov': 'cryptojs' });
      return md.digestString(s);
  };

  KJUR.crypto.Util.SECURERANDOMGEN = new SecureRandom();

  KJUR.crypto.Util.getRandomHexOfNbytes = function (n) {
      var ba = new Array(n);
      KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(ba);
      return BAtohex(ba);
  };

  KJUR.crypto.Util.getRandomBigIntegerOfNbytes = function (n) {
      return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbytes(n), 16);
  };


  KJUR.crypto.Util.getRandomHexOfNbits = function (n) {
      var n_remainder = n % 8;
      var n_quotient = (n - n_remainder) / 8;
      var ba = new Array(n_quotient + 1);
      KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(ba);
      ba[0] = (((255 << n_remainder) & 255) ^ 255) & ba[0];
      return BAtohex(ba);
  };

  KJUR.crypto.Util.getRandomBigIntegerOfNbits = function (n) {
      return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbits(n), 16);
  };

  KJUR.crypto.Util.getRandomBigIntegerZeroToMax = function (biMax) {
      var bitLenMax = biMax.bitLength();
      while (1) {
          var biRand = KJUR.crypto.Util.getRandomBigIntegerOfNbits(bitLenMax);
          if (biMax.compareTo(biRand) != -1) return biRand;
      }
  };

  KJUR.crypto.Util.getRandomBigIntegerMinToMax = function (biMin, biMax) {
      var flagCompare = biMin.compareTo(biMax);
      if (flagCompare == 1) throw "biMin is greater than biMax";
      if (flagCompare == 0) return biMin;

      var biDiff = biMax.subtract(biMin);
      var biRand = KJUR.crypto.Util.getRandomBigIntegerZeroToMax(biDiff);
      return biRand.add(biMin);
  };

  KJUR.crypto.MessageDigest = function (params) {
      var md = null;
      var algName = null;
      var provName = null;

      this.setAlgAndProvider = function (alg, prov) {
          alg = KJUR.crypto.MessageDigest.getCanonicalAlgName(alg);

          if (alg !== null && prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];

          // for cryptojs
          if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(alg) != -1 &&
              prov == 'cryptojs') {
              try {
                  console.log('KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg]--', KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME, alg, "-----:", CryptoJS);
                  this.md = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg].create();
              } catch (ex) {
                  throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex;
              }
              this.updateString = function (str) {
                  this.md.update(str);
              };
              this.updateHex = function (hex) {
                  var wHex = CryptoJS.enc.Hex.parse(hex);
                  this.md.update(wHex);
              };
              this.digest = function () {
                  var hash = this.md.finalize();
                  return hash.toString(CryptoJS.enc.Hex);
              };
              this.digestString = function (str) {
                  this.updateString(str);
                  return this.digest();
              };
              this.digestHex = function (hex) {
                  this.updateHex(hex);
                  return this.digest();
              };
          }
          if (':sha256:'.indexOf(alg) != -1 &&
              prov == 'sjcl') {
              try {
                  this.md = new sjcl.hash.sha256();
              } catch (ex) {
                  throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex;
              }
              this.updateString = function (str) {
                  this.md.update(str);
              };
              this.updateHex = function (hex) {
                  var baHex = sjcl.codec.hex.toBits(hex);
                  this.md.update(baHex);
              };
              this.digest = function () {
                  var hash = this.md.finalize();
                  return sjcl.codec.hex.fromBits(hash);
              };
              this.digestString = function (str) {
                  this.updateString(str);
                  return this.digest();
              };
              this.digestHex = function (hex) {
                  this.updateHex(hex);
                  return this.digest();
              };
          }
      };

      this.updateString = function (str) {
          throw "updateString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName;
      };

      this.updateHex = function (hex) {
          throw "updateHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName;
      };

      this.digest = function () {
          throw "digest() not supported for this alg/prov: " + this.algName + "/" + this.provName;
      };

      this.digestString = function (str) {
          throw "digestString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName;
      };

      this.digestHex = function (hex) {
          throw "digestHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName;
      };

      if (params !== undefined) {
          if (params['alg'] !== undefined) {
              this.algName = params['alg'];
              if (params['prov'] === undefined)
                  this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
              this.setAlgAndProvider(this.algName, this.provName);
          }
      }
  };

  KJUR.crypto.MessageDigest.getCanonicalAlgName = function (alg) {
      if (typeof alg === "string") {
          alg = alg.toLowerCase();
          alg = alg.replace(/-/, '');
      }
      return alg;
  };

  KJUR.crypto.MessageDigest.getHashLength = function (alg) {
      var MD = KJUR.crypto.MessageDigest;
      var alg2 = MD.getCanonicalAlgName(alg);
      if (MD.HASHLENGTH[alg2] === undefined)
          throw "not supported algorithm: " + alg;
      return MD.HASHLENGTH[alg2];
  };

  // described in KJUR.crypto.MessageDigest class (since jsrsasign 6.2.0 crypto 1.1.10)
  KJUR.crypto.MessageDigest.HASHLENGTH = {
      'md5': 16,
      'sha1': 20,
      'sha224': 28,
      'sha256': 32,
      'sha384': 48,
      'sha512': 64,
      'ripemd160': 20
  };

  KJUR.crypto.Mac = function (params) {
      var mac = null;
      var pass = null;
      var algName = null;
      var provName = null;
      var algProv = null;

      this.setAlgAndProvider = function (alg, prov) {
          alg = alg.toLowerCase();

          if (alg == null) alg = "hmacsha1";

          alg = alg.toLowerCase();
          if (alg.substr(0, 4) != "hmac") {
              throw "setAlgAndProvider unsupported HMAC alg: " + alg;
          }

          if (prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];
          this.algProv = alg + "/" + prov;

          var hashAlg = alg.substr(4);

          // for cryptojs
          if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(hashAlg) != -1 &&
              prov == 'cryptojs') {
              try {
                  var mdObj = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[hashAlg];
                  this.mac = CryptoJS.algo.HMAC.create(mdObj, this.pass);
              } catch (ex) {
                  throw "setAlgAndProvider hash alg set fail hashAlg=" + hashAlg + "/" + ex;
              }
              this.updateString = function (str) {
                  this.mac.update(str);
              };
              this.updateHex = function (hex) {
                  var wHex = CryptoJS.enc.Hex.parse(hex);
                  this.mac.update(wHex);
              };
              this.doFinal = function () {
                  var hash = this.mac.finalize();
                  return hash.toString(CryptoJS.enc.Hex);
              };
              this.doFinalString = function (str) {
                  this.updateString(str);
                  return this.doFinal();
              };
              this.doFinalHex = function (hex) {
                  this.updateHex(hex);
                  return this.doFinal();
              };
          }
      };

      this.updateString = function (str) {
          throw "updateString(str) not supported for this alg/prov: " + this.algProv;
      };

      this.updateHex = function (hex) {
          throw "updateHex(hex) not supported for this alg/prov: " + this.algProv;
      };

      this.doFinal = function () {
          throw "digest() not supported for this alg/prov: " + this.algProv;
      };

      this.doFinalString = function (str) {
          throw "digestString(str) not supported for this alg/prov: " + this.algProv;
      };

      this.doFinalHex = function (hex) {
          throw "digestHex(hex) not supported for this alg/prov: " + this.algProv;
      };

      this.setPassword = function (pass) {

          if (typeof pass == 'string') {
              var hPass = pass;
              if (pass.length % 2 == 1 || !pass.match(/^[0-9A-Fa-f]+$/)) { // raw str
                  hPass = rstrtohex(pass);
              }
              this.pass = CryptoJS.enc.Hex.parse(hPass);
              return;
          }

          if (typeof pass != 'object')
              throw "KJUR.crypto.Mac unsupported password type: " + pass;

          var hPass = null;
          if (pass.hex !== undefined) {
              if (pass.hex.length % 2 != 0 || !pass.hex.match(/^[0-9A-Fa-f]+$/))
                  throw "Mac: wrong hex password: " + pass.hex;
              hPass = pass.hex;
          }
          if (pass.utf8 !== undefined) hPass = utf8tohex(pass.utf8);
          if (pass.rstr !== undefined) hPass = rstrtohex(pass.rstr);
          if (pass.b64 !== undefined) hPass = b64tohex(pass.b64);
          if (pass.b64u !== undefined) hPass = b64utohex(pass.b64u);

          if (hPass == null)
              throw "KJUR.crypto.Mac unsupported password type: " + pass;

          this.pass = CryptoJS.enc.Hex.parse(hPass);
      };

      if (params !== undefined) {
          if (params.pass !== undefined) {
              this.setPassword(params.pass);
          }
          if (params.alg !== undefined) {
              this.algName = params.alg;
              if (params['prov'] === undefined)
                  this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
              this.setAlgAndProvider(this.algName, this.provName);
          }
      }
  };

  KJUR.crypto.Signature = function (params) {
      var prvKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for signing
      var pubKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for verifying

      var md = null; // KJUR.crypto.MessageDigest object
      var sig = null;
      var algName = null;
      var provName = null;
      var algProvName = null;
      var mdAlgName = null;
      var pubkeyAlgName = null;   // rsa,ecdsa,rsaandmgf1(=rsapss)
      var state = null;
      var pssSaltLen = -1;
      var initParams = null;

      var sHashHex = null; // hex hash value for hex
      var hDigestInfo = null;
      var hPaddedDigestInfo = null;
      var hSign = null;

      this._setAlgNames = function () {
          var matchResult = this.algName.match(/^(.+)with(.+)$/);
          if (matchResult) {
              this.mdAlgName = matchResult[1].toLowerCase();
              this.pubkeyAlgName = matchResult[2].toLowerCase();
          }
      };

      this._zeroPaddingOfSignature = function (hex, bitLength) {
          var s = "";
          var nZero = bitLength / 4 - hex.length;
          for (var i = 0; i < nZero; i++) {
              s = s + "0";
          }
          return s + hex;
      };

      this.setAlgAndProvider = function (alg, prov) {
          this._setAlgNames();
          if (prov != 'cryptojs/jsrsa')
              throw "provider not supported: " + prov;

          if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(this.mdAlgName) != -1) {
              try {
                  this.md = new KJUR.crypto.MessageDigest({ 'alg': this.mdAlgName });
              } catch (ex) {
                  throw "setAlgAndProvider hash alg set fail alg=" +
                  this.mdAlgName + "/" + ex;
              }

              this.init = function (keyparam, pass) {
                  var keyObj = null;
                  try {
                      if (pass === undefined) {
                          keyObj = KEYUTIL.getKey(keyparam);
                      } else {
                          keyObj = KEYUTIL.getKey(keyparam, pass);
                      }
                  } catch (ex) {
                      throw "init failed:" + ex;
                  }

                  if (keyObj.isPrivate === true) {
                      this.prvKey = keyObj;
                      this.state = "SIGN";
                  } else if (keyObj.isPublic === true) {
                      this.pubKey = keyObj;
                      this.state = "VERIFY";
                  } else {
                      throw "init failed.:" + keyObj;
                  }
              };

              this.updateString = function (str) {
                  this.md.updateString(str);
              };

              this.updateHex = function (hex) {
                  this.md.updateHex(hex);
              };

              this.sign = function () {
                  this.sHashHex = this.md.digest();
                  if (typeof this.ecprvhex != "undefined" &&
                      typeof this.eccurvename != "undefined") {
                      var ec = new KJUR.crypto.ECDSA({ 'curve': this.eccurvename });
                      this.hSign = ec.signHex(this.sHashHex, this.ecprvhex);
                  } else if (this.prvKey instanceof RSAKey &&
                      this.pubkeyAlgName === "rsaandmgf1") {
                      this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex,
                          this.mdAlgName,
                          this.pssSaltLen);
                  } else if (this.prvKey instanceof RSAKey &&
                      this.pubkeyAlgName === "rsa") {
                      this.hSign = this.prvKey.signWithMessageHash(this.sHashHex,
                          this.mdAlgName);
                  } else if (this.prvKey instanceof KJUR.crypto.ECDSA) {
                      this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);
                  } else if (this.prvKey instanceof KJUR.crypto.DSA) {
                      this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);
                  } else {
                      throw "Signature: unsupported private key alg: " + this.pubkeyAlgName;
                  }
                  return this.hSign;
              };
              this.signString = function (str) {
                  this.updateString(str);
                  return this.sign();
              };
              this.signHex = function (hex) {
                  this.updateHex(hex);
                  return this.sign();
              };
              this.verify = function (hSigVal) {
                  this.sHashHex = this.md.digest();
                  if (typeof this.ecpubhex != "undefined" &&
                      typeof this.eccurvename != "undefined") {
                      var ec = new KJUR.crypto.ECDSA({ curve: this.eccurvename });
                      return ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex);
                  } else if (this.pubKey instanceof RSAKey &&
                      this.pubkeyAlgName === "rsaandmgf1") {
                      return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, hSigVal,
                          this.mdAlgName,
                          this.pssSaltLen);
                  } else if (this.pubKey instanceof RSAKey &&
                      this.pubkeyAlgName === "rsa") {
                      return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
                  } else if (KJUR.crypto.ECDSA !== undefined &&
                      this.pubKey instanceof KJUR.crypto.ECDSA) {
                      return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
                  } else if (KJUR.crypto.DSA !== undefined &&
                      this.pubKey instanceof KJUR.crypto.DSA) {
                      return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);
                  } else {
                      throw "Signature: unsupported public key alg: " + this.pubkeyAlgName;
                  }
              };
          }
      };

      this.init = function (key, pass) {
          throw "init(key, pass) not supported for this alg:prov=" +
          this.algProvName;
      };

      this.updateString = function (str) {
          throw "updateString(str) not supported for this alg:prov=" + this.algProvName;
      };

      this.updateHex = function (hex) {
          throw "updateHex(hex) not supported for this alg:prov=" + this.algProvName;
      };

      this.sign = function () {
          throw "sign() not supported for this alg:prov=" + this.algProvName;
      };

      this.signString = function (str) {
          throw "digestString(str) not supported for this alg:prov=" + this.algProvName;
      };

      this.signHex = function (hex) {
          throw "digestHex(hex) not supported for this alg:prov=" + this.algProvName;
      };

      this.verify = function (hSigVal) {
          throw "verify(hSigVal) not supported for this alg:prov=" + this.algProvName;
      };

      this.initParams = params;

      if (params !== undefined) {
          if (params.alg !== undefined) {
              this.algName = params.alg;
              if (params.prov === undefined) {
                  this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];
              } else {
                  this.provName = params.prov;
              }
              this.algProvName = this.algName + ":" + this.provName;
              this.setAlgAndProvider(this.algName, this.provName);
              this._setAlgNames();
          }

          if (params['psssaltlen'] !== undefined) this.pssSaltLen = params['psssaltlen'];

          if (params.prvkeypem !== undefined) {
              if (params.prvkeypas !== undefined) {
                  throw "both prvkeypem and prvkeypas parameters not supported";
              } else {
                  try {
                      var prvKey = KEYUTIL.getKey(params.prvkeypem);
                      this.init(prvKey);
                  } catch (ex) {
                      throw "fatal error to load pem private key: " + ex;
                  }
              }
          }
      }
  };

  KJUR.crypto.Cipher = function (params) {
  };

  KJUR.crypto.Cipher.encrypt = function (s, keyObj, algName) {
      if (keyObj instanceof RSAKey && keyObj.isPublic) {
          var algName2 = KJUR.crypto.Cipher.getAlgByKeyAndName(keyObj, algName);
          if (algName2 === "RSA") return keyObj.encrypt(s);
          if (algName2 === "RSAOAEP") return keyObj.encryptOAEP(s, "sha1");

          var a = algName2.match(/^RSAOAEP(\d+)$/);
          if (a !== null) return keyObj.encryptOAEP(s, "sha" + a[1]);

          throw "Cipher.encrypt: unsupported algorithm for RSAKey: " + algName;
      } else {
          throw "Cipher.encrypt: unsupported key or algorithm";
      }
  };

  KJUR.crypto.Cipher.decrypt = function (hex, keyObj, algName) {
      if (keyObj instanceof RSAKey && keyObj.isPrivate) {
          var algName2 = KJUR.crypto.Cipher.getAlgByKeyAndName(keyObj, algName);
          if (algName2 === "RSA") return keyObj.decrypt(hex);
          if (algName2 === "RSAOAEP") return keyObj.decryptOAEP(hex, "sha1");

          var a = algName2.match(/^RSAOAEP(\d+)$/);
          if (a !== null) return keyObj.decryptOAEP(hex, "sha" + a[1]);

          throw "Cipher.decrypt: unsupported algorithm for RSAKey: " + algName;
      } else {
          throw "Cipher.decrypt: unsupported key or algorithm";
      }
  };

  KJUR.crypto.Cipher.getAlgByKeyAndName = function (keyObj, algName) {
      if (keyObj instanceof RSAKey) {
          if (":RSA:RSAOAEP:RSAOAEP224:RSAOAEP256:RSAOAEP384:RSAOAEP512:".indexOf(algName) != -1)
              return algName;
          if (algName === null || algName === undefined) return "RSA";
          throw "getAlgByKeyAndName: not supported algorithm name for RSAKey: " + algName;
      }
      throw "getAlgByKeyAndName: not supported algorithm name: " + algName;
  };

  KJUR.crypto.OID = new function () {
      this.oidhex2name = {
          '2a864886f70d010101': 'rsaEncryption',
          '2a8648ce3d0201': 'ecPublicKey',
          '2a8648ce380401': 'dsa',
          '2a8648ce3d030107': 'secp256r1',
          '2b8104001f': 'secp192k1',
          '2b81040021': 'secp224r1',
          '2b8104000a': 'secp256k1',
          '2b81040023': 'secp521r1',
          '2b81040022': 'secp384r1',
          '2a8648ce380403': 'SHA1withDSA', // 1.2.840.10040.4.3
          '608648016503040301': 'SHA224withDSA', // 2.16.840.1.101.3.4.3.1
          '608648016503040302': 'SHA256withDSA', // 2.16.840.1.101.3.4.3.2
      };
  };


  /*

  --------------------------------------------------rsa-------------------------------------------------------
  */

  function parseBigInt(str, r) {
      return new BigInteger(str, r);
  }

  function linebrk(s, n) {
      var ret = "";
      var i = 0;
      while (i + n < s.length) {
          ret += s.substring(i, i + n) + "\n";
          i += n;
      }
      return ret + s.substring(i, s.length);
  }

  function byte2Hex(b) {
      if (b < 0x10)
          return "0" + b.toString(16);
      else
          return b.toString(16);
  }

  // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
  function pkcs1pad2(s, n) {
      if (n < s.length + 11) { // TODO: fix for utf-8
          throw "Message too long for RSA";
          return null;
      }
      var ba = new Array();
      var i = s.length - 1;
      while (i >= 0 && n > 0) {
          var c = s.charCodeAt(i--);
          if (c < 128) { // encode using utf-8
              ba[--n] = c;
          }
          else if ((c > 127) && (c < 2048)) {
              ba[--n] = (c & 63) | 128;
              ba[--n] = (c >> 6) | 192;
          }
          else {
              ba[--n] = (c & 63) | 128;
              ba[--n] = ((c >> 6) & 63) | 128;
              ba[--n] = (c >> 12) | 224;
          }
      }
      ba[--n] = 0;
      var rng = new SecureRandom();
      var x = new Array();
      while (n > 2) { // random non-zero pad
          x[0] = 0;
          while (x[0] == 0) rng.nextBytes(x);
          ba[--n] = x[0];
      }
      ba[--n] = 2;
      ba[--n] = 0;
      return new BigInteger(ba);
  }

  // PKCS#1 (OAEP) mask generation function
  function oaep_mgf1_arr(seed, len, hash) {
      var mask = '', i = 0;

      while (mask.length < len) {
          mask += hash(String.fromCharCode.apply(String, seed.concat([
              (i & 0xff000000) >> 24,
              (i & 0x00ff0000) >> 16,
              (i & 0x0000ff00) >> 8,
              i & 0x000000ff])));
          i += 1;
      }

      return mask;
  }

  function oaep_pad(s, n, hash, hashLen) {
      var MD = KJUR.crypto.MessageDigest;
      var Util = KJUR.crypto.Util;
      var algName = null;

      if (!hash) hash = "sha1";

      if (typeof hash === "string") {
          algName = MD.getCanonicalAlgName(hash);
          hashLen = MD.getHashLength(algName);
          hash = function (s) {
              return hextorstr(Util.hashHex(rstrtohex(s), algName));
          };
      }

      if (s.length + 2 * hashLen + 2 > n) {
          throw "Message too long for RSA";
      }

      var PS = '', i;

      for (i = 0; i < n - s.length - 2 * hashLen - 2; i += 1) {
          PS += '\x00';
      }

      var DB = hash('') + PS + '\x01' + s;
      var seed = new Array(hashLen);
      new SecureRandom().nextBytes(seed);

      var dbMask = oaep_mgf1_arr(seed, DB.length, hash);
      var maskedDB = [];

      for (i = 0; i < DB.length; i += 1) {
          maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i);
      }

      var seedMask = oaep_mgf1_arr(maskedDB, seed.length, hash);
      var maskedSeed = [0];

      for (i = 0; i < seed.length; i += 1) {
          maskedSeed[i + 1] = seed[i] ^ seedMask.charCodeAt(i);
      }

      return new BigInteger(maskedSeed.concat(maskedDB));
  }

  // "empty" RSA key constructor
  function RSAKey() {
      this.n = null;
      this.e = 0;
      this.d = null;
      this.p = null;
      this.q = null;
      this.dmp1 = null;
      this.dmq1 = null;
      this.coeff = null;
  }

  // Set the public key fields N and e from hex strings
  function RSASetPublic(N, E) {
      this.isPublic = true;
      this.isPrivate = false;
      if (typeof N !== "string") {
          this.n = N;
          this.e = E;
      } else if (N != null && E != null && N.length > 0 && E.length > 0) {
          this.n = parseBigInt(N, 16);
          this.e = parseInt(E, 16);
      } else {
          throw "Invalid RSA public key";
      }
  }

  // Perform raw public operation on "x": return x^e (mod n)
  function RSADoPublic(x) {
      return x.modPowInt(this.e, this.n);
  }

  // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
  function RSAEncrypt(text) {
      var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3);
      if (m == null) return null;
      var c = this.doPublic(m);
      if (c == null) return null;
      var h = c.toString(16);
      if ((h.length & 1) == 0) return h; else return "0" + h;
  }

  // Return the PKCS#1 OAEP RSA encryption of "text" as an even-length hex string
  function RSAEncryptOAEP(text, hash, hashLen) {
      var m = oaep_pad(text, (this.n.bitLength() + 7) >> 3, hash, hashLen);
      if (m == null) return null;
      var c = this.doPublic(m);
      if (c == null) return null;
      var h = c.toString(16);
      if ((h.length & 1) == 0) return h; else return "0" + h;
  }

  // protected
  RSAKey.prototype.doPublic = RSADoPublic;

  // public
  RSAKey.prototype.setPublic = RSASetPublic;
  RSAKey.prototype.encrypt = RSAEncrypt;
  RSAKey.prototype.encryptOAEP = RSAEncryptOAEP;
  //RSAKey.prototype.encrypt_b64 = RSAEncryptB64;

  RSAKey.prototype.type = "RSA";




  /*

  --------------------------------------------------rsapem-1.1-------------------------------------------------------
  */

  RSAKey.getPosArrayOfChildrenFromHex = function (hPrivateKey) {
      return ASN1HEX.getChildIdx(hPrivateKey, 0);
  };

  RSAKey.getHexValueArrayOfChildrenFromHex = function (hPrivateKey) {
      var _ASN1HEX = ASN1HEX;
      var _getV = _ASN1HEX.getV;
      var a = RSAKey.getPosArrayOfChildrenFromHex(hPrivateKey);
      var h_v = _getV(hPrivateKey, a[0]);
      var h_n = _getV(hPrivateKey, a[1]);
      var h_e = _getV(hPrivateKey, a[2]);
      var h_d = _getV(hPrivateKey, a[3]);
      var h_p = _getV(hPrivateKey, a[4]);
      var h_q = _getV(hPrivateKey, a[5]);
      var h_dp = _getV(hPrivateKey, a[6]);
      var h_dq = _getV(hPrivateKey, a[7]);
      var h_co = _getV(hPrivateKey, a[8]);
      var a = new Array();
      a.push(h_v, h_n, h_e, h_d, h_p, h_q, h_dp, h_dq, h_co);
      return a;
  };

  RSAKey.prototype.readPrivateKeyFromPEMString = function (keyPEM) {
      var keyHex = pemtohex(keyPEM);
      var a = RSAKey.getHexValueArrayOfChildrenFromHex(keyHex);
      this.setPrivateEx(a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
  };

  RSAKey.prototype.readPKCS5PrvKeyHex = function (h) {
      var a = RSAKey.getHexValueArrayOfChildrenFromHex(h);
      this.setPrivateEx(a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
  };

  RSAKey.prototype.readPKCS8PrvKeyHex = function (h) {
      var hN, hE, hD, hP, hQ, hDP, hDQ, hCO;
      var _ASN1HEX = ASN1HEX;
      var _getVbyList = _ASN1HEX.getVbyList;

      if (_ASN1HEX.isASN1HEX(h) === false)
          throw "not ASN.1 hex string";

      try {
          hN = _getVbyList(h, 0, [2, 0, 1], "02");
          hE = _getVbyList(h, 0, [2, 0, 2], "02");
          hD = _getVbyList(h, 0, [2, 0, 3], "02");
          hP = _getVbyList(h, 0, [2, 0, 4], "02");
          hQ = _getVbyList(h, 0, [2, 0, 5], "02");
          hDP = _getVbyList(h, 0, [2, 0, 6], "02");
          hDQ = _getVbyList(h, 0, [2, 0, 7], "02");
          hCO = _getVbyList(h, 0, [2, 0, 8], "02");
      } catch (ex) {
          throw "malformed PKCS#8 plain RSA private key";
      }

      this.setPrivateEx(hN, hE, hD, hP, hQ, hDP, hDQ, hCO);
  };

  RSAKey.prototype.readPKCS5PubKeyHex = function (h) {
      var _ASN1HEX = ASN1HEX;
      var _getV = _ASN1HEX.getV;

      if (_ASN1HEX.isASN1HEX(h) === false)
          throw "keyHex is not ASN.1 hex string";
      var aIdx = _ASN1HEX.getChildIdx(h, 0);
      if (aIdx.length !== 2 ||
          h.substr(aIdx[0], 2) !== "02" ||
          h.substr(aIdx[1], 2) !== "02")
          throw "wrong hex for PKCS#5 public key";
      var hN = _getV(h, aIdx[0]);
      var hE = _getV(h, aIdx[1]);
      this.setPublic(hN, hE);
  };

  RSAKey.prototype.readPKCS8PubKeyHex = function (h) {
      var _ASN1HEX = ASN1HEX;
      if (_ASN1HEX.isASN1HEX(h) === false)
          throw "not ASN.1 hex string";

      // 06092a864886f70d010101: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
      if (_ASN1HEX.getTLVbyList(h, 0, [0, 0]) !== "06092a864886f70d010101")
          throw "not PKCS8 RSA public key";

      var p5hex = _ASN1HEX.getTLVbyList(h, 0, [1, 0]);
      this.readPKCS5PubKeyHex(p5hex);
  };

  RSAKey.prototype.readCertPubKeyHex = function (h, nthPKI) {
      var x, hPub;
      x = new X509();
      x.readCertHex(h);
      hPub = x.getPublicKeyHex();
      this.readPKCS8PubKeyHex(hPub);
  };




  /*

  ---------------------------------------------rsasign-1.2------------------------------------------------------------
  */

  var _RE_HEXDECONLY = new RegExp("");
  _RE_HEXDECONLY.compile("[^0-9a-f]", "gi");

  function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
      var hashFunc = function (s) { return KJUR.crypto.Util.hashString(s, hashAlg); };
      var sHashHex = hashFunc(s);

      return KJUR.crypto.Util.getPaddedDigestInfoHex(sHashHex, hashAlg, keySize);
  }

  function _zeroPaddingOfSignature(hex, bitLength) {
      var s = "";
      var nZero = bitLength / 4 - hex.length;
      for (var i = 0; i < nZero; i++) {
          s = s + "0";
      }
      return s + hex;
  }

  RSAKey.prototype.sign = function (s, hashAlg) {
      var hashFunc = function (s) { return KJUR.crypto.Util.hashString(s, hashAlg); };
      var sHashHex = hashFunc(s);

      return this.signWithMessageHash(sHashHex, hashAlg);
  };

  RSAKey.prototype.signWithMessageHash = function (sHashHex, hashAlg) {
      var hPM = KJUR.crypto.Util.getPaddedDigestInfoHex(sHashHex, hashAlg, this.n.bitLength());
      var biPaddedMessage = parseBigInt(hPM, 16);
      var biSign = this.doPrivate(biPaddedMessage);
      var hexSign = biSign.toString(16);
      return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
  };

  // PKCS#1 (PSS) mask generation function
  function pss_mgf1_str(seed, len, hash) {
      var mask = '', i = 0;

      while (mask.length < len) {
          mask += hextorstr(hash(rstrtohex(seed + String.fromCharCode.apply(String, [
              (i & 0xff000000) >> 24,
              (i & 0x00ff0000) >> 16,
              (i & 0x0000ff00) >> 8,
              i & 0x000000ff]))));
          i += 1;
      }

      return mask;
  }

  RSAKey.prototype.signPSS = function (s, hashAlg, sLen) {
      var hashFunc = function (sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };
      var hHash = hashFunc(rstrtohex(s));

      if (sLen === undefined) sLen = -1;
      return this.signWithMessageHashPSS(hHash, hashAlg, sLen);
  };

  RSAKey.prototype.signWithMessageHashPSS = function (hHash, hashAlg, sLen) {
      var mHash = hextorstr(hHash);
      var hLen = mHash.length;
      var emBits = this.n.bitLength() - 1;
      var emLen = Math.ceil(emBits / 8);
      var i;
      var hashFunc = function (sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };

      if (sLen === -1 || sLen === undefined) {
          sLen = hLen; // same as hash length
      } else if (sLen === -2) {
          sLen = emLen - hLen - 2; // maximum
      } else if (sLen < -2) {
          throw "invalid salt length";
      }

      if (emLen < (hLen + sLen + 2)) {
          throw "data too long";
      }

      var salt = '';

      if (sLen > 0) {
          salt = new Array(sLen);
          new SecureRandom().nextBytes(salt);
          salt = String.fromCharCode.apply(String, salt);
      }

      var H = hextorstr(hashFunc(rstrtohex('\x00\x00\x00\x00\x00\x00\x00\x00' + mHash + salt)));
      var PS = [];

      for (i = 0; i < emLen - sLen - hLen - 2; i += 1) {
          PS[i] = 0x00;
      }

      var DB = String.fromCharCode.apply(String, PS) + '\x01' + salt;
      var dbMask = pss_mgf1_str(H, DB.length, hashFunc);
      var maskedDB = [];

      for (i = 0; i < DB.length; i += 1) {
          maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i);
      }

      var mask = (0xff00 >> (8 * emLen - emBits)) & 0xff;
      maskedDB[0] &= ~mask;

      for (i = 0; i < hLen; i++) {
          maskedDB.push(H.charCodeAt(i));
      }

      maskedDB.push(0xbc);

      return _zeroPaddingOfSignature(this.doPrivate(new BigInteger(maskedDB)).toString(16),
          this.n.bitLength());
  };

  function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
      var rsa = new RSAKey();
      rsa.setPublic(hN, hE);
      var biDecryptedSig = rsa.doPublic(biSig);
      return biDecryptedSig;
  }

  function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
      var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
      var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
      return hDigestInfo;
  }

  function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
      for (var algName in KJUR.crypto.Util.DIGESTINFOHEAD) {
          var head = KJUR.crypto.Util.DIGESTINFOHEAD[algName];
          var len = head.length;
          if (hDigestInfo.substring(0, len) == head) {
              var a = [algName, hDigestInfo.substring(len)];
              return a;
          }
      }
      return [];
  }

  RSAKey.prototype.verify = function (sMsg, hSig) {
      hSig = hSig.replace(_RE_HEXDECONLY, '');
      hSig = hSig.replace(/[ \n]+/g, "");
      var biSig = parseBigInt(hSig, 16);
      if (biSig.bitLength() > this.n.bitLength()) return 0;
      var biDecryptedSig = this.doPublic(biSig);
      var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
      var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);

      if (digestInfoAry.length == 0) return false;
      var algName = digestInfoAry[0];
      var diHashValue = digestInfoAry[1];
      var ff = function (s) { return KJUR.crypto.Util.hashString(s, algName); };
      var msgHashValue = ff(sMsg);
      return (diHashValue == msgHashValue);
  };

  RSAKey.prototype.verifyWithMessageHash = function (sHashHex, hSig) {
      hSig = hSig.replace(_RE_HEXDECONLY, '');
      hSig = hSig.replace(/[ \n]+/g, "");
      var biSig = parseBigInt(hSig, 16);
      if (biSig.bitLength() > this.n.bitLength()) return 0;
      var biDecryptedSig = this.doPublic(biSig);
      var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
      var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);

      if (digestInfoAry.length == 0) return false;
      var algName = digestInfoAry[0];
      var diHashValue = digestInfoAry[1];
      return (diHashValue == sHashHex);
  };

  RSAKey.prototype.verifyPSS = function (sMsg, hSig, hashAlg, sLen) {
      var hashFunc = function (sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };
      var hHash = hashFunc(rstrtohex(sMsg));

      if (sLen === undefined) sLen = -1;
      return this.verifyWithMessageHashPSS(hHash, hSig, hashAlg, sLen);
  };

  RSAKey.prototype.verifyWithMessageHashPSS = function (hHash, hSig, hashAlg, sLen) {
      var biSig = new BigInteger(hSig, 16);

      if (biSig.bitLength() > this.n.bitLength()) {
          return false;
      }

      var hashFunc = function (sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };
      var mHash = hextorstr(hHash);
      var hLen = mHash.length;
      var emBits = this.n.bitLength() - 1;
      var emLen = Math.ceil(emBits / 8);
      var i;

      if (sLen === -1 || sLen === undefined) {
          sLen = hLen; // same as hash length
      } else if (sLen === -2) {
          sLen = emLen - hLen - 2; // recover
      } else if (sLen < -2) {
          throw "invalid salt length";
      }

      if (emLen < (hLen + sLen + 2)) {
          throw "data too long";
      }

      var em = this.doPublic(biSig).toByteArray();

      for (i = 0; i < em.length; i += 1) {
          em[i] &= 0xff;
      }

      while (em.length < emLen) {
          em.unshift(0);
      }

      if (em[emLen - 1] !== 0xbc) {
          throw "encoded message does not end in 0xbc";
      }

      em = String.fromCharCode.apply(String, em);

      var maskedDB = em.substr(0, emLen - hLen - 1);
      var H = em.substr(maskedDB.length, hLen);

      var mask = (0xff00 >> (8 * emLen - emBits)) & 0xff;

      if ((maskedDB.charCodeAt(0) & mask) !== 0) {
          throw "bits beyond keysize not zero";
      }

      var dbMask = pss_mgf1_str(H, maskedDB.length, hashFunc);
      var DB = [];

      for (i = 0; i < maskedDB.length; i += 1) {
          DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i);
      }

      DB[0] &= ~mask;

      var checkLen = emLen - hLen - sLen - 2;

      for (i = 0; i < checkLen; i += 1) {
          if (DB[i] !== 0x00) {
              throw "leftmost octets not zero";
          }
      }

      if (DB[checkLen] !== 0x01) {
          throw "0x01 marker not found";
      }

      return H === hextorstr(hashFunc(rstrtohex('\x00\x00\x00\x00\x00\x00\x00\x00' + mHash +
          String.fromCharCode.apply(String, DB.slice(-sLen)))));
  };

  RSAKey.SALT_LEN_HLEN = -1;
  RSAKey.SALT_LEN_MAX = -2;
  RSAKey.SALT_LEN_RECOVER = -2;

  class ULAdvBase extends ULModuleBase {
      constructor() {
          super();
          this._initState = false;
          this.onInitModule();
      }
      get initState() {
          return this._initState;
      }
      set initState(v) {
          this._initState = v;
      }
  }

  let qg$1$1 = window["qg"];
  class ULAdvOppoQg extends ULAdvBase {
      constructor() {
          super();
          this.className = "ULAdvOppoQg";
      }
      onInitModule() {
          return;
          qg$1$1.getSystemInfoSync().platformVersion;
          let platformVersionCode = qg$1$1.getSystemInfoSync().platformVersionCode;
          if (platformVersionCode >= 1051) {
              this.initState = true;
              this.notifyInitState(this.initState);
          }
          else {
              this.initAdv();
          }
      }
      notifyInitState(initState) {
          let templateItemObjectArray = ULSdkManager.getInstance().advManager.getAdvObjectsByName("ULAdvOppoQg");
          if (!templateItemObjectArray) {
              return;
          }
          for (const baseObj of templateItemObjectArray) {
              baseObj.receiveMainClassInitState(initState);
          }
      }
      initAdv() {
          return;
          let config = ULConfig.getConfig();
          let appId = config.s_sdk_oppoqg_appid;
          qg$1$1.initAdService({
              appId: appId,
              isDebug: false,
              success: (res) => {
                  ULLog.console.log("ULAdvOppoQg.init success");
                  this.initState = true;
                  this.notifyInitState(this.initState);
              },
              fail: (res) => {
                  console.warn("ULAdvOppoQg.init fail", res.code, res.msg);
                  this.initState = false;
                  this.notifyInitState(this.initState);
              },
              complete: (res) => {
                  ULLog.console.log("ULAdvOppoQg.init complete");
              }
          });
      }
  }
  ULAdvOppoQg.NORMAL_ADVERTISER = "ULAdvOppoQg";
  ULAdvOppoQg.NATIVE_ADVERTISER = "ULAdvOppoQgNative";

  class ULChannelModuleBase extends ULModuleBase {
      constructor() {
          super();
          ULLog.console.log("ULChannelModuleBase-constructor");
      }
      init() {
          super.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_GET_STORAGE, ULConst.PRIORITY_NONE, this.onCmdSdkGetStorage.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_SET_STORAGE, ULConst.PRIORITY_NONE, this.onCmdSdkSetStorage.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_GET_CLIPBOARD_DATA, ULConst.PRIORITY_NONE, this.onCmdSdkGetClipboardData.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_SET_CLIPBOARD_DATA, ULConst.PRIORITY_NONE, this.onCmdSdkSetClipboardData.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_IS_SUPPORT_CLIPBOARD, ULConst.PRIORITY_NONE, this.onCmdSdkIsSupportClipboard.bind(this));
          this.genSdkUserId();
          ULSdkManager.getInstance().channelInfo._sdkUserId = this.sdkUserId;
          ULSdkManager.getInstance().channelInfo.isNewUser = this.isNewUser;
          ULLog.console.log("ULChannelModuleBase.init isNewUser:", this.isNewUser);
      }
      genSdkUserId() {
          let config = ULConfig.getConfig();
          let key = ULTools.format("mUserId_%s", config.s_sdk_megadata_game_id);
          this.isNewUser = false;
          this.sdkUserId = ULStorageManager.getInstance().getStorage(key);
          if (!this.sdkUserId) {
              this.sdkUserId = ULTools.format("%s_%s_%s", config.s_sdk_cop_game_id, ULTools.createRandomUserId(), config.s_sdk_cop_channel_id);
              ULStorageManager.getInstance().setStorage(key, this.sdkUserId);
              this.isNewUser = true;
          }
      }
      onCmdSdkGetStorage(e) {
          let data = e.data;
          let key = data.key;
          e.setReturnValue(this._hook_getStorage(key));
      }
      onCmdSdkSetStorage(e) {
          let key = e.data.key;
          let data = e.data.data;
          this._hook_setStorage(key, data);
          e.stopImmediatePropagation();
      }
      onCmdSdkGetClipboardData(e) {
          let data = e.data;
          let finishCallback = data.finishCallback;
          this._hook_getClipboardData(finishCallback);
          e.stopImmediatePropagation();
      }
      onCmdSdkSetClipboardData(e) {
          let clipboardData = e.data.data;
          let finishCallback = e.data.finishCallback;
          this._hook_setClipboardData(clipboardData, finishCallback);
          e.stopImmediatePropagation();
      }
      onCmdSdkIsSupportClipboard(e) {
          let data = e.data;
          e.setReturnValue(this._hook_isSupportClipboard());
          e.stopImmediatePropagation();
      }
  }

  class ULAdvObjectBase extends ULModuleBase {
      constructor(arg, advType, advKey) {
          super();
          this._preLoadState = ULConst.ADV_PRELOAD_STATE_NOAD;
          this.onLoadFailErr = { code: "", msg: "" };
          this._statisticsAdvertiser = "";
          this._statisticsType = "";
          this.advKey_2_lastRequestTime = {};
          this._supportLoadType = [];
          this._loadType = undefined;
          this.isReportLoading = false;
          this.isDispose = false;
          this._arg = arg;
          this._advType = advType;
          this._advKey = advKey;
      }
      onDisposeModule() {
          super.onDisposeModule();
          this.isDispose = true;
          ULLog.console.log("ULAdvObjectBase-onDisposeModule arg:", this.arg);
      }
      get arg() {
          return this._arg;
      }
      get advKey() {
          return this._advKey;
      }
      get preLoadState() {
          return this._preLoadState;
      }
      set preLoadState(preLoadState) {
          if (this._preLoadState == preLoadState)
              return;
          this._preLoadState = preLoadState;
          ULSdkManager.getInstance().advManager.onAdvObjectPreloadStateChanged(this.advKey);
      }
      get advType() {
          return this._advType;
      }
      get isOpened() {
          return this._isOpened;
      }
      set isOpened(opened) {
          this._isOpened = opened;
      }
      get showData() {
          return this._mShowData;
      }
      set showData(mShowData) {
          this._mShowData = mShowData;
      }
      getMainClassNameString() {
          return this.getMainClassName();
      }
      receiveMainClassInitState(initState) {
          this.receiveInitState(initState);
      }
      preLoadAdv() {
          this.onLoadFailErr.code = "";
          this.onLoadFailErr.msg = "";
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_LOADING;
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          let rcd = ULSdkManager.getInstance().advManager.getRcdByAdvKey(this.advKey);
          if (rcd) {
              let lastRequestTime = this.advKey_2_lastRequestTime[this.advKey];
              let now = (new Date()).valueOf();
              if (lastRequestTime) {
                  if ((now - lastRequestTime) < rcd) {
                      console.warn(`${this.className}-preLoadAdv:模块[ + ${this.advKey} + ]in cd`);
                      this.preLoadState = ULConst.ADV_PRELOAD_STATE_NOAD;
                      this.reLoadAdv();
                      return;
                  }
                  else {
                      this.advKey_2_lastRequestTime[this.advKey] = now;
                  }
              }
              else {
                  this.advKey_2_lastRequestTime[this.advKey] = now;
              }
          }
          this.loadAdv();
      }
      reLoadAdv() {
          ULTimer.callLater(ULSdkManager.getInstance().advManager.getAdvReloadTime() / 1000, () => {
              if (!this.isDispose) {
                  this.preLoadAdv();
              }
          });
      }
      advSkip(data, info) {
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleSkip(this.advKey, info, data);
      }
      get statisticsAdvertiser() {
          return this._statisticsAdvertiser;
      }
      set statisticsAdvertiser(statisticsAdvertiser) {
          this._statisticsAdvertiser = statisticsAdvertiser;
      }
      get statisticsType() {
          return this._statisticsType;
      }
      set statisticsType(statisticsType) {
          this._statisticsType = statisticsType;
      }
      set setSupportLoadType(types) {
          this._supportLoadType = types;
      }
      get getSupportLoadType() {
          return this._supportLoadType;
      }
      set setLoadType(type) {
          if (type == undefined) {
              return;
          }
          this._loadType = type;
      }
      get getLoadType() {
          return this._loadType;
      }
  }

  class ULAdvNativeObjectBase extends ULAdvObjectBase {
      constructor(arg, advType, templateItemName) {
          super(arg, advType, templateItemName);
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_CLICK_NATIVE_ADV, ULConst.PRIORITY_NONE, this.clickNativeAdv.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_CLOSE_NATIVE_ADV, ULConst.PRIORITY_NONE, this.closeNativeAdv.bind(this));
      }
      get nativeShowState() {
          return this._nativeShowState;
      }
      set nativeShowState(nativeShowState) {
          this._nativeShowState = nativeShowState;
      }
      get nativeData() {
          return this._nativeData;
      }
      set nativeData(nativeData) {
          this._nativeData = nativeData;
      }
  }

  const EvalSYMBOL = {
      ",": { order: -2, argCount: 1, handler: (args) => { return args[0]; } },
      "*": { order: 3, argCount: 2, handler: (args) => { return args[0] * args[1]; } },
      "/": { order: 3, argCount: 2, handler: (args) => { return args[0] / args[1]; } },
      "+": { order: 2, argCount: 2, handler: (args) => { return args[0] + args[1]; } },
      "-": {
          order: 2, argCount: 2, handler: (args) => {
              if (args.length == 1)
                  return 0 - args[0];
              return args[0] - args[1];
          }
      },
      ">=": { order: 1, argCount: 2, handler: (args) => { return args[0] >= args[1]; } },
      ">": { order: 1, argCount: 2, handler: (args) => { return args[0] > args[1]; } },
      "<=": { order: 1, argCount: 2, handler: (args) => { return args[0] <= args[1]; } },
      "<": { order: 1, argCount: 2, handler: (args) => { return args[0] < args[1]; } },
      "==": { order: 0, argCount: 2, handler: (args) => { return args[0] == args[1]; } },
      "!=": { order: 0, argCount: 2, handler: (args) => { return args[0] != args[1]; } },
      "&&": { order: -1, argCount: 2, handler: (args) => { return args[0] && args[1]; } },
      "||": { order: -1, argCount: 2, handler: (args) => { return args[0] || args[1]; } },
      "[": { order: 4, argChar: "]", handler: (args) => { let a = args[0]; let b = args[1]; return a[b]; } },
      "(": {
          order: 4, argChar: ')', handler: (args) => {
              let a = args[0];
              if (Object.prototype.toString.call(a) === "[object Function]") {
                  args.shift();
                  return a(...args);
              }
              else {
                  return a;
              }
          }
      },
      ".": {
          order: 5, argCount: 2, handler: (args) => {
              if (typeof (args[1]) == "number") {
                  return Number(`${args[0]}.${args[1]}`);
              }
              else {
                  let item = args[0][args[1]];
                  if (Object.prototype.toString.call(item) === "[object Function]") {
                      return item.bind(args[0]);
                  }
                  else {
                      return item;
                  }
              }
          }
      },
      "\"\"": { order: 6, argCount: 1, handler: (args) => { return args[0].toString(); } },
      "\'\'": { order: 6, argCount: 1, handler: (args) => { return args[0].toString(); } },
      "undefined": { order: 5, argCount: 0, handler: (args) => { return undefined; } },
      "window": { order: 5, argCount: 0, handler: (args) => { return window; } },
      "ULConfig": { order: 5, argCount: 0, handler: (args) => { return ULConfig; } },
      "ULTools": { order: 5, argCount: 0, handler: (args) => { return ULTools; } },
      "true": { order: 5, argCount: 0, handler: (args) => { return true; } },
      "false": { order: 5, argCount: 0, handler: (args) => { return false; } },
  };
  let EvalSYMBOL_keys = Object.keys(EvalSYMBOL);
  let EvalSYMBOLKeysDic = {};
  EvalSYMBOL_keys.forEach((value) => {
      EvalSYMBOLKeysDic[value.length] = true;
  });
  let EvalSYMBOLKeys = Object.keys(EvalSYMBOLKeysDic).map(a => {
      return Number(a);
  }).sort((a, b) => {
      return b - a;
  });
  class ULEvalExp {
      static trimCalcExp(exp) {
          exp = exp.replace(/\s/g, "");
          let expArray = exp.split("");
          var expSignCache = [];
          var expSignSetting = {
              ")": {
                  cut: [")", "\'", "\""],
                  end: "(",
                  symbol: "(",
                  handle: (str) => {
                      let expCache = this.trimCalcExp(str);
                      expCache.push("\")\"");
                      return expCache;
                  }
              },
              "]": {
                  cut: [")", "\'", "\""],
                  end: "[",
                  symbol: "[",
                  handle: (str) => {
                      let expCache = this.trimCalcExp(str);
                      expCache.push("\"]\"");
                      return expCache;
                  }
              },
              "\"": {
                  cut: [],
                  end: "\"",
                  handle: (str) => {
                      return [`"${str}"`];
                  }
              },
              "\'": {
                  cut: [],
                  end: "\'",
                  handle: (str) => {
                      return [`'${str}'`];
                  }
              }
          };
          let value = "";
          let expCache = [];
          let symbolCache = [];
          let expCacheString = "";
          while (expArray.length) {
              let char = expArray.pop();
              let lastExpChar = expSignCache.length ? expSignCache[expSignCache.length - 1] : null;
              if (lastExpChar) {
                  let cut = expSignSetting[lastExpChar].cut;
                  let end = expSignSetting[lastExpChar].end;
                  let symbol = expSignSetting[lastExpChar].symbol;
                  let handle = expSignSetting[lastExpChar].handle;
                  if (char == end) {
                      expSignCache.pop();
                      if (expSignCache.length == 0) {
                          expCache = expCache.concat(handle(expCacheString).reverse());
                          symbol && symbolCache.push(symbol);
                          expCacheString = "";
                          continue;
                      }
                  }
                  else if (cut.indexOf(char) >= 0) {
                      expSignCache.push(char);
                  }
                  expCacheString = char + expCacheString;
              }
              else {
                  if (expSignSetting[char]) {
                      if (value.length) {
                          expCache.push(value);
                          value = "";
                      }
                      expSignCache.push(char);
                      continue;
                  }
                  let symbol = null;
                  for (let i = 0; i < EvalSYMBOLKeys.length; i++) {
                      let length = EvalSYMBOLKeys[i] - 1;
                      if (expArray.length > length) {
                          let key = expArray.slice(expArray.length - length, expArray.length) + char;
                          if (EvalSYMBOL[key]) {
                              char = key;
                              symbol = EvalSYMBOL[key];
                              expArray = expArray.slice(0, expArray.length - length);
                              break;
                          }
                      }
                  }
                  if (symbol) {
                      if (value.length) {
                          expCache.push(value);
                          value = "";
                      }
                      if (symbolCache.length) {
                          for (let i = symbolCache.length - 1; i >= 0; i--) {
                              let lastKey = symbolCache.pop();
                              let lastSymbol = EvalSYMBOL[lastKey];
                              if (lastSymbol && lastSymbol.order > symbol.order) {
                                  expCache.push(lastKey);
                              }
                              else {
                                  symbolCache.push(lastKey);
                                  break;
                              }
                          }
                      }
                      symbolCache.push(char);
                      continue;
                  }
                  value = char + value;
              }
          }
          if (value.length) {
              expCache.push(value);
              value = "";
          }
          expCache = expCache.filter((element, index, array) => {
              return (element != "");
          });
          expCache = expCache.concat(symbolCache.reverse()).reverse();
          return expCache;
      }
      static getCalcExpArray(exp, getObjCallback = null) {
          exp = exp.split(".").join(".^");
          let expCache = this.trimCalcExp(exp);
          let trimExpCache = expCache.map((item, index, arr) => {
              if (EvalSYMBOL[item])
                  return item;
              let char = item.charAt(0);
              if (char == '"' || char == "'") {
                  let trimItem = item.substring(1, item.length - 1);
                  return trimItem.split(".^").join(".");
              }
              else if (char == '^') {
                  let trimItem = item.substring(1, item.length);
                  char = trimItem.charAt(0);
                  if (char <= '9' && char >= '0') {
                      return Number(trimItem);
                  }
                  return trimItem;
              }
              else if (!isNaN(Number(item))) {
                  return Number(item);
              }
              else {
                  let value = getObjCallback ? getObjCallback(item) : undefined;
                  if (!value)
                      ULLog.console.warn(`ULEvalExp item:${item} value:${value}`);
                  return value;
              }
          });
          return trimExpCache;
      }
      static evalExpResults(exp, getObjCallback = null) {
          var result = true;
          try {
              let expArray = this.getCalcExpArray(exp, getObjCallback);
              ULLog.console.log(expArray);
              result = this.evalExpArrayResults(expArray);
              ULLog.console.log("ULEvalExp result:", result);
          }
          catch (error) {
              ULLog.console.log("ULEvalExp exp规则错误:", error.stack);
              result = false;
          }
          return result;
      }
      static evalExpArrayResults(expArray) {
          if (expArray.length == 0)
              return true;
          let argCountDefalutHandler = (resultArray, argChar, argCount) => {
              let args = [];
              while (resultArray.length > 0) {
                  if (argChar) {
                      let arg = resultArray.pop();
                      if (arg == argChar)
                          break;
                      args.push(arg);
                  }
                  else {
                      if (argCount-- <= 0)
                          break;
                      args.push(resultArray.pop());
                  }
              }
              return args;
          };
          let resultArray = [];
          while (expArray.length) {
              let key = expArray.pop();
              if (EvalSYMBOL_keys.indexOf(key) > -1) {
                  let value = EvalSYMBOL[key];
                  let argChar = value.argChar;
                  let argCount = value.argCount;
                  let args = argCountDefalutHandler(resultArray, argChar, argCount);
                  let result = value.handler(args);
                  resultArray.push(result);
              }
              else {
                  resultArray.push(key);
              }
          }
          return resultArray[0];
      }
  }

  class ULAdvExpManager {
      constructor() {
          this.availableExpKeyArray = [];
          this.updateValue = 10;
      }
      static getInstance() {
          if (this.instance == null) {
              this.instance = new ULAdvExpManager();
              this.instance.addListern();
          }
          return this.instance;
      }
      get expValueCache() {
          if (!this._expValueCache) {
              let recordExpKey = this._getRecordKey();
              let recordStr = ULStorageManager.getInstance().getStorage(recordExpKey) || "{}";
              let record;
              try {
                  record = JSON.parse(recordStr);
              }
              catch (error) {
                  record = {};
              }
              for (const key in record) {
                  let timeString = this.getKeyTimeString(key);
                  let expValueItem = record[key];
                  if (timeString != expValueItem.exp_time) {
                      delete record[key];
                  }
              }
              this._expValueCache = record;
          }
          return this._expValueCache;
      }
      addListern() {
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_PAUSE, ULConst.PRIORITY_NONE, this.onCmdSdkOnGamePause.bind(this));
      }
      onCmdSdkOnGamePause(e) {
          this.saveStoreValue();
      }
      static updateExpKeys(expKeyArray) {
          ULAdvExpManager.getInstance().availableExpKeyArray = expKeyArray.slice(0);
      }
      static calcExp(exp) {
          return ULAdvExpManager.getInstance().calcExpResults(exp);
      }
      static updateExpValue(expKey) {
          ULAdvExpManager.getInstance().setStoreValue(expKey);
      }
      calcExpResults(exp) {
          if (!exp)
              return true;
          ULLog.console.log("ULAdvExpManager calcExp:", exp);
          let trimExp = exp.replace(/\s/g, "");
          trimExp = trimExp.split(".").join("^");
          return ULEvalExp.evalExpResults(trimExp, (key) => {
              let trimKey = key.split("^").join(".");
              return this.getCalcExpValue(trimKey);
          });
      }
      _getRecordKey() {
          let config = ULConfig.getConfig();
          return ULTools.format("ULAdvExpManager_record_%d", config.s_sdk_megadata_game_id);
      }
      getCalcExpValue(anyObject) {
          if (typeof (anyObject) == "string" && this.availableExpKeyArray.indexOf(anyObject) != -1) {
              return this.getStoreValue(anyObject);
          }
          return anyObject;
      }
      getStoreValue(key) {
          let expValueItem = this.expValueCache[key];
          if (!expValueItem) {
              return 0;
          }
          let timeString = this.getKeyTimeString(key);
          if (timeString != expValueItem.exp_time) {
              expValueItem.exp_time = timeString;
              expValueItem.exp_value = 0;
          }
          return expValueItem.exp_value;
      }
      setStoreValue(key) {
          if (typeof (key) != "string" || this.availableExpKeyArray.indexOf(key) == -1) {
              return;
          }
          let timeString = this.getKeyTimeString(key);
          let expValueItem = this.expValueCache[key];
          if (!expValueItem) {
              expValueItem = {
                  exp_name: key,
                  exp_time: timeString,
                  exp_value: 1
              };
              this.expValueCache[key] = expValueItem;
          }
          else {
              if (timeString != expValueItem.exp_time) {
                  expValueItem.exp_time = timeString;
                  expValueItem.exp_value = 1;
              }
              else {
                  expValueItem.exp_value += 1;
              }
          }
          this.updateValue--;
          if (this.updateValue <= 0) {
              this.updateValue = 10;
              this.saveStoreValue();
          }
      }
      saveStoreValue() {
          let recordExpKey = this._getRecordKey();
          ULStorageManager.getInstance().setStorage(recordExpKey, JSON.stringify(this.expValueCache));
      }
      getKeyTimeString(key) {
          let timeString = ULTools.formatDate(new Date(), "yyyyMMdd");
          let keyFirstChar = key.substr(0, 1);
          switch (keyFirstChar) {
              case "d":
                  timeString = ULTools.formatDate(new Date(), "yyyyMMdd");
                  break;
              case "w":
                  let today = new Date();
                  let day = today.getDay() || 7;
                  let date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1 - day);
                  timeString = ULTools.formatDate(date, "yyyyMMdd");
                  break;
              case "m":
                  timeString = ULTools.formatDate(new Date(), "yyyyMM");
                  break;
              case "y":
                  timeString = ULTools.formatDate(new Date(), "yyyy");
                  break;
          }
          return timeString;
      }
  }
  ULAdvExpManager.instance = null;

  class ULAdvSlot {
      constructor(advId, schemes, subAids, rcd) {
          this.advId = advId;
          this.schemes = schemes;
          this._subAids = subAids;
          this._rcd = rcd;
      }
      refreshValidAdvKeys() {
          let validSchemes = this.getValidSchemes();
          if (!validSchemes || validSchemes.length == 0) {
              return;
          }
          this.validAdvKeys = [];
          for (let i = 0, len = validSchemes.length; i < len; i++) {
              let scheme = validSchemes[i];
              let validTemplates = this.getValidTemplates(scheme);
              if (!validTemplates || validTemplates.length == 0) {
                  continue;
              }
              for (const template of validTemplates) {
                  let tid = template.templateId;
                  let keys = ULSdkManager.getInstance().advManager.getAdvKeysByTemplateId(tid);
                  if (!keys || keys.length == 0) {
                      continue;
                  }
                  for (const key of keys) {
                      if (this.validAdvKeys.indexOf(key) == -1) {
                          this.validAdvKeys.push(key);
                      }
                  }
              }
          }
      }
      set openingInfo(v) {
          this._openingInfo = v;
      }
      get openingInfo() {
          return this._openingInfo;
      }
      get preLoadState() {
          return this._preLoadState;
      }
      set preLoadState(v) {
          this._preLoadState = v;
          ULSdkManager.getInstance().advManager.onAdvSlotPreloadStateChanged(this.advId);
      }
      get rcd() {
          return this._rcd;
      }
      get subAids() {
          return this._subAids;
      }
      set showTid(t) {
          this._showTid = t;
      }
      get showTid() {
          return this._showTid;
      }
      openAdv(advRequestSerialNum, data) {
          console.info("88888888888888888888888888888888888888888888888888");
          let ulAdvInfo = {
              data: data,
              requestSerialNum: advRequestSerialNum
          };
          this.openingInfo = ulAdvInfo;
          let scheme = this.getShowScheme();
          if (!scheme) {
              console.warn("ULAdvSlot-openAdv:广告位[" + this.advId + "]未获取到有效策略");
              this.openingInfo = null;
              ULSdkManager.getInstance().advManager.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, { code: "", msg: `广告位[${this.advId}]未获取到有效策略` });
              return;
          }
          let validTemplates = this.getValidTemplates(scheme);
          if (!validTemplates || validTemplates.length == 0) {
              console.warn("ULAdvSlot-openAdv:广告位[" + this.advId + "]未获取到可用模板");
              this.openingInfo = null;
              ULSdkManager.getInstance().advManager.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, { code: "", msg: `广告位[${this.advId}]未获取到可用模板` });
              return;
          }
          ULLog.console.log("ULAdvSlot-openAdv:广告位[" + this.advId + "]当前展示策略：" + JSON.stringify(scheme));
          this.openingInfo.scheme = scheme;
          let validTemplateIdArray = [];
          let validTemplateWeightArray = [];
          for (let i = 0; i < validTemplates.length; i++) {
              let tid = validTemplates[i].templateId;
              let tidWeight = 0;
              let tidsArray = scheme.tids;
              let tidsWeightsArray = scheme.tidWeights;
              for (let j = 0; j < tidsArray.length; j++) {
                  if (tid == tidsArray[j].toString()) {
                      tidWeight = Number(tidsWeightsArray[j] || 0);
                      validTemplateIdArray.push(tid);
                      validTemplateWeightArray.push(tidWeight);
                      break;
                  }
              }
          }
          this.openingInfo.validTemplateIdArray = validTemplateIdArray;
          this.openingInfo.validTemplateWeightArray = validTemplateWeightArray;
          this.showNextAdv(data);
      }
      showNextAdv(data, info) {
          let validTemplateIdArray = this.openingInfo.validTemplateIdArray;
          let validTemplateWeightArray = this.openingInfo.validTemplateWeightArray;
          let index = ULTools.calcWheelTargetByArray(validTemplateWeightArray, ULConst.ADV_MUST_DEFAULT_WEIGHT);
          if (index == null) {
              console.warn("ULAdvSlot-showNextAdv:广告位[" + this.advId + "]无有效模板展示");
              this.openingInfo = null;
              let mInfo = {
                  code: "",
                  msg: `广告位[${this.advId}]无有效模板展示`
              };
              ULSdkManager.getInstance().advManager.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, info ? info : mInfo);
              return;
          }
          let templateId = validTemplateIdArray[index];
          this.openingInfo.tid = templateId;
          this.showTid = templateId;
          validTemplateIdArray.splice(index, 1);
          this.openingInfo.validTemplateIdArray = validTemplateIdArray;
          validTemplateWeightArray.splice(index, 1);
          this.openingInfo.validTemplateWeightArray = validTemplateWeightArray;
          let advType = ULSdkManager.getInstance().advManager.getAdvTypeByTemplateId(templateId);
          let type_ad_ecd = ULSdkManager.getInstance().advManager.getLaunchCdByType(advType);
          if (ULTools.time() - ULSdkManager.getInstance().advManager.sdkInitTime < type_ad_ecd / 1000) {
              ULLog.console.log(`ULAdvSlot-showNextAdv:广告${advType}处于启动请求cd中`);
              this.showNextAdv(data);
              return;
          }
          let advTypeCd = ULSdkManager.getInstance().advManager.getAdvTypeCd(advType);
          if (advTypeCd > 0) {
              let lastTriggerTime = (ULSdkManager.getInstance().advManager.getAdvTypeLastTriggerTimeLog())[advType] || 0;
              let triggerGap = ULTools.time() - lastTriggerTime;
              ULLog.console.log(ULTools.format("ULAdvSlot-showNextAdv:检查广告类型cd。上次播放间隔%d秒，cd%d秒", triggerGap, advTypeCd / 1000));
              if (triggerGap <= advTypeCd / 1000) {
                  ULLog.console.log(ULTools.format("ULAdvSlot-showNextAdv:广告类型[%s]cd中，请%d后再试", advType, (advTypeCd / 1000) - triggerGap));
                  this.showNextAdv(data);
                  return;
              }
          }
          let advTypeDailyLimit = ULSdkManager.getInstance().advManager.getAdvTypeDailyLimit(advType);
          if (advTypeDailyLimit > 0) {
              let dailyCount = (ULSdkManager.getInstance().advManager.getAdvTypeDailyCountLog())[advType] || 0;
              ULLog.console.log(ULTools.format("检查广告日限。今日已播放%d次，日限制%d次", dailyCount, advTypeDailyLimit));
              if (dailyCount >= advTypeDailyLimit) {
                  ULLog.console.log(ULTools.format("广告类型[%s]今日已播放%d次，限制%d次。无法播放。", advType, dailyCount, advTypeDailyLimit));
                  this.showNextAdv(data);
                  return;
              }
          }
          if (ULSdkManager.getInstance().advManager.isAdvTypeOpened(advType)) {
              console.warn("ULAdvSlot-showNextAdv:一个广告类型，同一时间只允许启动一个广告");
              this.showNextAdv(data);
              return;
          }
          let ulAdvTemplate = ULSdkManager.getInstance().advManager.getTemplateObjByTid(templateId);
          let rcd = ulAdvTemplate.rcd || 0;
          let lastRequestTime = ULAdvSlot.tid_lastRequestTime[templateId] || 0;
          let nowTime = (new Date()).valueOf();
          if ((nowTime - lastRequestTime) < rcd) {
              console.warn("ULAdvSlot-showNextAdv:广告位[" + this.advId + "]当前展示模板【" + templateId + "】in rcd");
              this.showNextAdv(data);
              return;
          }
          else {
              ULAdvSlot.tid_lastRequestTime[templateId] = nowTime;
          }
          let advObject = this.calcValidObjectByTemplateId(templateId);
          if (advObject == null) {
              console.warn("ULAdvSlot-showNextAdv:广告位[" + this.advId + "]当前展示模板【" + templateId + "】未获取到可用广告对象");
              this.showNextAdv(data);
              return;
          }
          if (advType == typeExp.video) {
              let tag = data.tag || "";
              if (ULSdkManager.getInstance().advManager.isFirstPlayVideo) {
                  ULSdkManager.getInstance().advManager.isFirstPlayVideo = false;
                  let firstOpenVideoTimeSec = ULTools.time() - ULSdkManager.getInstance().advManager.sdkInitTime;
                  firstOpenVideoTimeSec = Math.floor(firstOpenVideoTimeSec);
                  if (isNaN(firstOpenVideoTimeSec))
                      firstOpenVideoTimeSec = 0;
                  if (firstOpenVideoTimeSec < ULConfig.getConfig().t_sdk_miniplay_game_adv_point_first_click_event_report_time_limit) {
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_game_adv_point_first_click_event_id, tag, firstOpenVideoTimeSec.toString()]);
                  }
              }
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_game_click_video_event_id, tag]);
          }
          ULSdkManager.getInstance().advManager.updateAdvIds(advType, this.advId);
          let advKey = advObject.advKey;
          this.openingInfo.advTemplateItemName = advKey;
          ULLog.console.log("ULAdvSlot-showNextAdv:广告位[" + this.advId + "]当前展示模板：" + JSON.stringify(this.openingInfo));
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShowRequest(advKey, data);
          data["type"] = advType;
          let rType = ULSdkManager.getInstance().advManager.getRewardTypeByTemplateId(templateId);
          data["rewardType"] = rType;
          advObject.showAdv(data);
      }
      closeAdv(data) {
          let advKey = this.openingInfo.advTemplateItemName;
          let objectBase = ULSdkManager.getInstance().advManager.getAdvObjectByAdvKey(advKey);
          if (!objectBase) {
              ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "advobject未找到");
              return;
          }
          if (objectBase.isOpened) {
              objectBase.closeAdv(data);
          }
          else {
              ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "广告未展示");
          }
      }
      getShowScheme() {
          let schemeList = this.getValidSchemes();
          if (!schemeList || schemeList.length == 0) {
              return null;
          }
          let validSchemes = [];
          for (const scheme of schemeList) {
              let validTemplates = this.getValidTemplates(scheme);
              if (validTemplates && validTemplates.length > 0) {
                  validSchemes.push(scheme);
              }
          }
          if (validSchemes.length == 0) {
              return null;
          }
          let weightArray = new Array(validSchemes.length);
          for (let i = 0; i < validSchemes.length; i++) {
              weightArray[i] = validSchemes[i].weight;
          }
          let index = ULTools.calcWheelTargetByArray(weightArray, ULConst.ADV_MUST_DEFAULT_WEIGHT);
          if (index != null) {
              return validSchemes[index];
          }
          return null;
      }
      getValidSchemes() {
          let validSchemes = [];
          for (let scheme of this.schemes) {
              if (!ULAdvExpManager.calcExp(scheme.exp)) {
                  continue;
              }
              let weight = scheme.weight;
              if (weight <= 0) {
                  continue;
              }
              if (weight == 100) {
                  validSchemes.unshift(scheme);
              }
              else {
                  validSchemes.push(scheme);
              }
          }
          if (validSchemes.length == 0) {
              return null;
          }
          return validSchemes;
      }
      getValidTemplates(scheme) {
          let validTemplates = [];
          let tids = scheme.tids;
          if (!tids || tids.length == 0) {
              return null;
          }
          for (let i = 0; i < tids.length; i++) {
              let tidS = tids[i];
              let ulAdvTemplate = ULSdkManager.getInstance().advManager.getTemplateObjByTid(tidS);
              if (!ulAdvTemplate) {
                  console.warn("ULAdvSlot-getValidTemplates:广告位【" + this.advId + "】对应的模板【" + tidS + "】不存在模板对象，需检查模板列表中是否配置该模板id");
                  continue;
              }
              if (!ULAdvExpManager.calcExp(ulAdvTemplate.exp)) {
                  continue;
              }
              let tidWeight = scheme.tidWeights[i];
              if (tidWeight <= 0) {
                  continue;
              }
              validTemplates.push(ulAdvTemplate);
          }
          return validTemplates;
      }
      calcValidObjectByTemplateId(tid) {
          let objectBases = ULSdkManager.getInstance().advManager.getAdvObjsByTid(tid);
          if (!objectBases || objectBases.length == 0)
              return null;
          let readyObjects = [];
          for (const base of objectBases) {
              if (base.preLoadState == ULConst.ADV_PRELOAD_STATE_READY) {
                  readyObjects.push(base);
              }
          }
          let targetObjects;
          if (readyObjects.length == 0) {
              targetObjects = objectBases;
          }
          else {
              targetObjects = readyObjects;
          }
          let argWeights = new Array(targetObjects.length);
          let ulAdvTemplate = ULSdkManager.getInstance().advManager.getTemplateObjByTid(tid);
          if (!ulAdvTemplate) {
              return null;
          }
          for (let j = 0, len = targetObjects.length; j < len; j++) {
              let objectBase = targetObjects[j];
              for (let i = 0, len = ulAdvTemplate.args.length; i < len; i++) {
                  let arg = ulAdvTemplate.args[i];
                  let key = ulAdvTemplate.moduleName + "_" + arg;
                  let argWeight = ulAdvTemplate.argWeights[i];
                  if (key == objectBase.advKey) {
                      argWeights[j] = argWeight;
                  }
              }
          }
          let index = ULTools.calcWheelTargetByArray(argWeights, ULConst.ADV_MUST_DEFAULT_WEIGHT);
          if (index != null) {
              return targetObjects[index];
          }
          return null;
      }
      onAdvObjectPreloadStateChanged(advKey) {
          if (!this.validAdvKeys || this.validAdvKeys.indexOf(advKey) == -1)
              return;
          this.refreshPreloadState();
      }
      refreshPreloadState() {
          let bHasLoading = false;
          let bHasReady = false;
          for (const advKey of this.validAdvKeys) {
              let state = ULSdkManager.getInstance().advManager.getAdvObjPreloadStateByAdvKey(advKey);
              if (state == ULConst.ADV_PRELOAD_STATE_LOADING) {
                  bHasLoading = true;
              }
              else if (state == ULConst.ADV_PRELOAD_STATE_READY) {
                  bHasReady = true;
              }
          }
          if (bHasReady) {
              this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          }
          else if (bHasLoading) {
              this.preLoadState = ULConst.ADV_PRELOAD_STATE_LOADING;
          }
          else {
              this.preLoadState = ULConst.ADV_PRELOAD_STATE_NOAD;
          }
      }
      onAdvObjectLifeCycleSkip(data, info) {
          if (this.openingInfo == null) {
              return;
          }
          if (this.openingInfo != null) {
              this.openingInfo.advTemplateItemName = null;
          }
          this.showNextAdv(data, info);
      }
      onAdvObjectLifeCycleShow(msg, data) {
          let rType = ULSdkManager.getInstance().advManager.getRewardTypeByTemplateId(this.showTid);
          let advType = ULSdkManager.getInstance().advManager.getAdvTypeByTemplateId(this.showTid);
          ULSdkManager.getInstance().advManager.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, { code: "", msg: msg });
          if (rewardType.show == rType) {
              ULSdkManager.getInstance().advManager.responseRewardAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, msg);
          }
      }
      onAdvObjectLifeCycleClick(msg, data) {
          ULSdkManager.getInstance().advManager.responseClickAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, msg);
          let rType = ULSdkManager.getInstance().advManager.getRewardTypeByTemplateId(this.showTid);
          if (rewardType.click == rType) {
              ULSdkManager.getInstance().advManager.responseRewardAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, msg);
          }
      }
      onAdvObjectLifeCycleClose() {
          let advType = ULSdkManager.getInstance().advManager.getAdvTypeByTemplateId(this.showTid);
          ULSdkManager.getInstance().advManager.deleteAdvIdOpening(advType, this.advId);
          this.openingInfo = null;
      }
      onAdvObjectLifeCycleFail(info, data) {
          ULSdkManager.getInstance().advManager.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, info);
          this.openingInfo = null;
      }
  }
  ULAdvSlot.tid_lastRequestTime = {};

  class ULAdvItem {
      constructor(advId, userData, tag) {
          this.advId = advId;
          this.advType = ULSdkManager.getInstance().advManager.searchAdvTypeByAdvId(advId);
          this.advGroupId = ULSdkManager.getInstance().advManager.searchAdvGroupIdByAdvId(advId);
          this.userData = userData;
          this.tag = tag;
          this.serialId = ULAdvItem.SERIAL_ID++;
          this.bOpenAdvResultResponsed = false;
          this.bClickAdvResultResponsed = false;
          this.lifeCycleLog = {};
          this.bRequesting = true;
          this.statisChannelName = "";
          this.statisSdkAdvId = "";
          this.statisNativeAdTitle = "";
      }
      startimeoutTimer(timeoutSec) {
          if (this.timeoutTimer)
              return;
          this.timeoutTimer = new ULTimer(timeoutSec, 1, () => {
              ULSdkManager.getInstance().advManager.onAdvTimeout(this);
          });
          this.timeoutTimer.start();
      }
      stopTimeoutTimer() {
          if (this.timeoutTimer) {
              this.timeoutTimer.stop();
              this.timeoutTimer = null;
          }
      }
      setLifeCycleLogAllCycle() {
          this.lifeCycleLog = {
              0: true, 1: true, 2: true, 3: true, 4: true, 5: true
          };
      }
      set advData(data) {
          this._advData = data;
      }
      get advData() {
          return this._advData;
      }
  }
  ULAdvItem.SERIAL_ID = 0;

  var ULErrorRuleLogic;
  (function (ULErrorRuleLogic) {
      ULErrorRuleLogic[ULErrorRuleLogic["ordinary"] = 0] = "ordinary";
      ULErrorRuleLogic[ULErrorRuleLogic["or"] = 1] = "or";
      ULErrorRuleLogic[ULErrorRuleLogic["with"] = 2] = "with";
      ULErrorRuleLogic[ULErrorRuleLogic["error"] = 3] = "error";
  })(ULErrorRuleLogic || (ULErrorRuleLogic = {}));
  class ULErrorRuleItem {
      constructor(ruleString = null) {
          this.ruleString = null;
          this.logic = ULErrorRuleLogic.ordinary;
          this.rule = null;
          this.rules = [];
          this.ruleString = ruleString;
          if (!ruleString || ruleString.length == 0) {
              this.logic = ULErrorRuleLogic.error;
              return;
          }
          this.initWithRule(this.ruleString);
      }
      get isWildcard() {
          return this.rule == "*";
      }
      initWithErrRule() {
          this.logic = ULErrorRuleLogic.error;
          this.rule = null;
          this.rules = [];
      }
      initWithRule(rule) {
          rule = rule.replace(/\s/g, "");
          let leftBracketNum = 0;
          let startLeftBracketNum = 0;
          let trimString = "";
          while (rule.length) {
              let char = rule.charAt(0);
              let nextChar = rule.length > 0 ? rule.charAt(1) : "";
              rule = rule.slice(1);
              switch (char) {
                  case "(":
                      {
                          leftBracketNum++;
                          let string = trimString;
                          if (string.replace(/\(/g, '') == "") {
                              startLeftBracketNum++;
                          }
                      }
                      break;
                  case ")":
                      {
                          let string = rule;
                          if (string.replace(/\)/g, '') == "" && startLeftBracketNum != 0) {
                              trimString = trimString.substring(startLeftBracketNum);
                              return this.initWithRule(trimString);
                          }
                          leftBracketNum--;
                          startLeftBracketNum = leftBracketNum > startLeftBracketNum ? startLeftBracketNum : leftBracketNum;
                      }
                      break;
                  case "|":
                      {
                          if (leftBracketNum == 0) {
                              if (char + nextChar == "||") {
                                  if (this.logic != ULErrorRuleLogic.or && this.logic != ULErrorRuleLogic.ordinary) {
                                      return this.initWithErrRule();
                                  }
                                  this.logic = ULErrorRuleLogic.or;
                                  this.rules.push(new ULErrorRuleItem(trimString));
                                  trimString = "";
                              }
                              continue;
                          }
                      }
                      break;
                  case "&":
                      {
                          if (leftBracketNum == 0) {
                              if (char + nextChar == "&&") {
                                  if (this.logic != ULErrorRuleLogic.with && this.logic != ULErrorRuleLogic.ordinary) {
                                      return this.initWithErrRule();
                                  }
                                  this.logic = ULErrorRuleLogic.with;
                                  this.rules.push(new ULErrorRuleItem(trimString));
                                  trimString = "";
                              }
                              continue;
                          }
                      }
                      break;
              }
              trimString += char;
          }
          if (trimString.length > 0) {
              if (this.logic == ULErrorRuleLogic.ordinary) {
                  this.rule = trimString;
              }
              else {
                  this.rules.push(new ULErrorRuleItem(trimString));
              }
          }
      }
      complianceTheRules(key, customData = null) {
          switch (this.logic) {
              case ULErrorRuleLogic.ordinary:
                  {
                      return this.judgmentStandard(key, customData);
                  }
                  break;
              case ULErrorRuleLogic.or:
                  {
                      for (let subRuleItem of this.rules) {
                          if (subRuleItem.complianceTheRules(key, customData)) {
                              return true;
                          }
                      }
                      return false;
                  }
                  break;
              case ULErrorRuleLogic.with:
                  {
                      for (let subRuleItem of this.rules) {
                          if (!subRuleItem.complianceTheRules(key, customData)) {
                              return false;
                          }
                      }
                      return true;
                  }
                  break;
          }
          return false;
      }
      judgmentStandard(key, customData = null) {
          if (this.rule == null) {
              return false;
          }
          if (this.rule == "*") {
              return true;
          }
          if (this.rule == key) {
              return true;
          }
          if (this.rule.length > 2) {
              let rule = this.rule;
              let firstChar = rule.charAt(0);
              let lastChar = rule.charAt(this.rule.length - 1);
              if (firstChar + lastChar == '//') {
                  rule = rule.substring(1, rule.length - 1);
                  var reg = RegExp(rule);
                  if (reg.exec(key)) {
                      return true;
                  }
              }
          }
          var patrn = /(?==|!=|>=|>|<|<=)/;
          if (customData && patrn.exec(this.rule)) {
              let trimRule = this.rule.replace("this.", "customData.");
              return ULEvalExp.evalExpResults(trimRule, (key) => {
                  if (key == "customData") {
                      return customData;
                  }
                  return null;
              });
          }
          return false;
      }
  }
  class ULAdvTrimErrorManager {
      static trimErrMessage(msg, error) {
          let config = ULConfig.getConfig();
          if (!config.i_sdk_trim_adv_err_switch) {
              return (error && ULTools.format("%s %d", ULConst.ADV_FAIL_TIP_NOAD, error.code || error.errCode)) || msg || ULTools.format(ULConst.ADV_FAIL_TIP_NOAD, ULConst.ADV_ERR_CODE_UNKNOWN);
          }
          let errJson = config.t_sdk_trim_adv_err_object || {};
          if (!error) {
              return msg || ULTools.format(ULConst.ADV_FAIL_TIP_NOAD, ULConst.ADV_ERR_CODE_UNKNOWN);
          }
          let channelName = ULSdkManager.getInstance().channelInfo.channelName || "";
          let channelNameErrJson = {};
          channelNameErrJson[channelName] = error;
          let customMsg = null;
          try {
              customMsg = this.getCustomMsgFromRules(errJson, channelNameErrJson);
          }
          catch (error) {
              ULLog.console.error("ULAdvTrimErrorManager:错误整理报错-------------请检查配置");
              ULLog.console.error("ULAdvTrimErrorManager:errJson：", errJson);
              ULLog.console.error("ULAdvTrimErrorManager:channelNameErrJson：", channelNameErrJson);
          }
          if (customMsg) {
              customMsg = ULTools.format("%s %d", customMsg, error.code || error.errCode);
          }
          let trimMsg = customMsg || msg || ULTools.format(ULConst.ADV_FAIL_TIP_NOAD, ULConst.ADV_ERR_CODE_UNKNOWN);
          return trimMsg;
      }
      static getCustomMsgFromRules(type, errorData) {
          let typeKeys = [];
          let errorDataKeys = [];
          if (typeof type === 'object') {
              typeKeys = Object.keys(type);
          }
          else if (typeof type === 'string') {
              return type;
          }
          else {
              return "";
          }
          if (!errorData) {
              return "";
          }
          else if (typeof errorData === 'object') {
              errorDataKeys = Object.keys(errorData);
          }
          else {
              errorDataKeys.push(errorData);
          }
          let count = typeKeys.length;
          while (typeKeys.length) {
              let typeKey = typeKeys.shift();
              count--;
              let ruleItem = this.trimRules[typeKey];
              if (!ruleItem) {
                  ruleItem = new ULErrorRuleItem(typeKey);
                  this.trimRules[typeKey] = ruleItem;
              }
              if (ruleItem.isWildcard && count > 0) {
                  typeKeys.join(typeKey);
                  continue;
              }
              let typeValue = type[typeKey];
              for (let errorDataKey of errorDataKeys) {
                  if (ruleItem.complianceTheRules(errorDataKey, errorData)) {
                      let errorDataValue = errorData[errorDataKey] || null;
                      let returnString = this.getCustomMsgFromRules(typeValue, errorDataValue);
                      if (returnString) {
                          return returnString;
                      }
                  }
              }
          }
          return "";
      }
  }
  ULAdvTrimErrorManager.trimRules = {};

  var typeExp;
  (function (typeExp) {
      typeExp["all"] = "all";
      typeExp["splash"] = "splash";
      typeExp["inter"] = "inter";
      typeExp["video"] = "video";
      typeExp["custom"] = "custom";
      typeExp["interVideo"] = "interVideo";
      typeExp["banner"] = "banner";
      typeExp["embed"] = "embed";
      typeExp["url"] = "url";
      typeExp["paster"] = "paster";
  })(typeExp || (typeExp = {}));
  var rewardType;
  (function (rewardType) {
      rewardType["show"] = "show";
      rewardType["click"] = "click";
  })(rewardType || (rewardType = {}));
  var countExp;
  (function (countExp) {
      countExp["rc"] = "rc";
      countExp["sc"] = "sc";
      countExp["cc"] = "cc";
      countExp["fc"] = "fc";
      countExp["mcc"] = "mcc";
  })(countExp || (countExp = {}));
  var cdExp;
  (function (cdExp) {
      cdExp["rcd"] = "rcd";
      cdExp["scd"] = "scd";
      cdExp["ecd"] = "ecd";
  })(cdExp || (cdExp = {}));
  var dataExp;
  (function (dataExp) {
      dataExp["nil"] = "nil";
      dataExp["d"] = "d";
      dataExp["w"] = "w";
      dataExp["m"] = "m";
      dataExp["y"] = "y";
  })(dataExp || (dataExp = {}));
  var openResult;
  (function (openResult) {
      openResult["totalAdvRequest"] = "totalAdvRequest";
      openResult["branchAdvRequest"] = "branchAdvRequest";
      openResult["success"] = "success";
      openResult["failed"] = "failed";
      openResult["clicked"] = "clicked";
      openResult["playStart"] = "playStart";
      openResult["playCompletion"] = "playCompletion";
      openResult["loadAdvRequest"] = "loadAdvRequest";
      openResult["close"] = "close";
      openResult["hide"] = "hide";
  })(openResult || (openResult = {}));
  var oldTypeExp;
  (function (oldTypeExp) {
      oldTypeExp["interstitial"] = "interstitial";
      oldTypeExp["embedded"] = "embedded";
      oldTypeExp["fullscreen"] = "fullscreen";
  })(oldTypeExp || (oldTypeExp = {}));
  class ULAdvManager {
      constructor() {
          this.systemAdvExpKeyArray = [];
          this.advExpKeyArray = [];
          this.advRequestSerialNum = 0;
          this.advId_2_advSlot = {};
          this.templateId_2_advTemplate = {};
          this.templateId_2_advTemplateItemArray = {};
          this.advKey_2_templateIdArray = {};
          this.moduleName_2_argsArray = {};
          this.moduleName_2_advIdsArray = {};
          this.templateId_2_moduleName = {};
          this.moduleName_2_advTemplate = {};
          this.mainName_2_advObjectArray = {};
          this.templateId_2_advObjectArray = {};
          this.advType_2_advObjectArray = {};
          this.moduleName_2_templateIdsArray = {};
          this.logKey_2_countNum = {};
          this.advKey_2_advIdArray = {};
          this.tid_2_advKeyArray = {};
          this.advId_2_tidArray = {};
          this.nativeType_2_advObjectArray = {};
          this.advKey_2_advObject = {};
          this.ADV_RELOAD_DEFAULT_TIME = 15000;
          this.ADV_RELOAD_TIME = 15000;
          this.bannerStartShowTime = 0;
          this.advKey_2_rcd = {};
          this.advId_2_lastRequestTime = {};
          this.adMainName_2_obj = {};
          this.type_2_advIds = {};
          this.exp_2_result = {};
          this.advTypeLastTriggerTimeLog = {};
      }
      static getInstance() {
          if (this.instance == null) {
              this.instance = new ULAdvManager();
          }
          return this.instance;
      }
      get isFirstPlayVideo() {
          return this._isFirstPlayVideo;
      }
      set isFirstPlayVideo(v) {
          this._isFirstPlayVideo = v;
      }
      init() {
          this.loadRecord();
          this.initAdvExpKey();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, ULConst.PRIORITY_NONE, this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_OPEN_ADV, ULConst.PRIORITY_NONE, this.onCmdOpenAdv.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_CLOSE_ADV, ULConst.PRIORITY_NONE, this.onCmdCloseAdv.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_CLOSE_NATIVE_ADV, ULConst.PRIORITY_NONE, this.onCmdCloseNativeAdv.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_CLICK_NATIVE_ADV, ULConst.PRIORITY_NONE, this.onCmdClickNativeAdv.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_RESUME, ULConst.PRIORITY_NONE, this.onCmdSdkOnGameResume.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_PAUSE, ULConst.PRIORITY_NONE, this.onCmdSdkOnGamePause.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_GET_ADV_STATE, ULConst.PRIORITY_NONE, this.onCmdGetAdvState.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_COP_CHANGED, 1, this.onCopChanged.bind(this));
          this._sdkInitTime = ULTools.time();
          this.isFirstPlayVideo = true;
      }
      loadRecord() {
          let recordStr = ULStorageManager.getInstance().getStorage(this._getRecordKey()) || "{}";
          let record;
          try {
              record = JSON.parse(recordStr);
          }
          catch (error) {
              record = {};
          }
          this.advTypeDailyCountLog = record.advTypeDailyCountLog || {};
          this.advTypeDailyRefreshTime = record.advTypeDailyRefreshTime || 0;
          this.tryDailyRefresh();
      }
      saveRecord() {
          let recordStr = ULStorageManager.getInstance().getStorage(this._getRecordKey()) || "{}";
          let record;
          try {
              record = JSON.parse(recordStr);
          }
          catch (error) {
              record = {};
          }
          record.advTypeDailyCountLog = this.advTypeDailyCountLog || {};
          record.advTypeDailyRefreshTime = this.advTypeDailyRefreshTime || 0,
              ULStorageManager.getInstance().setStorage(this._getRecordKey(), JSON.stringify(record));
      }
      _getRecordKey() {
          let config = ULConfig.getConfig();
          return ULTools.format("ULAdvManager_record_%d", config.s_sdk_megadata_game_id);
      }
      tryDailyRefresh() {
          if (!ULTools.isOneDay(this.advTypeDailyRefreshTime, ULTools.time())) {
              ULLog.console.log("ULAdvManager-tryDailyRefresh 进行日常刷新");
              this.advTypeDailyCountLog = {};
              this.advTypeDailyRefreshTime = ULTools.time();
              this.saveRecord();
          }
      }
      searchAdvGroupIdByAdvId(advId) {
          let config = ULConfig.getConfig();
          let advInfo = config.s_sdk_adv_info;
          let advGroupId = "";
          ULTools.forEachMap(advInfo, (k, v) => {
              if (v.group.indexOf(advId) >= 0) {
                  advGroupId = k;
                  return true;
              }
          });
          return advGroupId;
      }
      searchAdvTypeByAdvId(advId) {
          let config = ULConfig.getConfig();
          let advInfo = config.s_sdk_adv_info;
          let advType = "";
          ULTools.forEachMap(advInfo, (k, v) => {
              if (v.group.indexOf(advId) >= 0) {
                  advType = v.type;
                  return true;
              }
          });
          return advType;
      }
      onCopChanged(e) {
          try {
              this.initAdv();
          }
          catch (error) {
              ULLog.console.error("ULAdvManager.onCopChanged err:", error.stack);
          }
      }
      onCmdSdkOnGameResume(e) {
          ULLog.console.log("ULAdvManager-onCmdSdkOnGameResume");
          let objectBase = this.getAdvObjectOpeningByAdvType(typeExp.banner);
          if (!objectBase)
              return;
          this.bannerStartShowTime = ULTools.time();
      }
      onCmdSdkOnGamePause(e) {
          let objectBase = this.getAdvObjectOpeningByAdvType(typeExp.banner);
          if (!objectBase)
              return;
          let nativeData;
          if (objectBase instanceof ULAdvNativeObjectBase) {
              nativeData = objectBase.nativeData;
          }
          this.reportBannerShowTime(objectBase.advKey, objectBase.showData, nativeData);
      }
      onCmdSdkCollectionModuleCheckerConfig(e) {
          let config = e.getReturnValue() || [];
          let advTypes = ["interstitial", "banner", "embedded", "video", "url", "paster"];
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "广告cd限制:" });
          config.push({ type: "newLine" });
          for (let i = 0; i < advTypes.length; i++) {
              const advType = advTypes[i];
              let cdTag = "未配置CD";
              let lastTriggerTag = "未触发";
              let cd = this.getAdvTypeCd(advType);
              if (cd > 0) {
                  cdTag = ULTools.format("CD%d秒", cd / 1000);
              }
              let lastTriggerTime = this.advTypeLastTriggerTimeLog[advType] || 0;
              if (lastTriggerTime > 0) {
                  lastTriggerTag = ULTools.formatDate(new Date(lastTriggerTime * 1000), "触发时间：HH:mm:ss");
              }
              config.push({ type: "label", text: ULTools.format("%s: %s %s", advType, cdTag, lastTriggerTag) });
              config.push({ type: "newLine" });
          }
          config.push({ type: "label", text: "广告次数限制:" });
          config.push({ type: "newLine" });
          for (let i = 0; i < advTypes.length; i++) {
              const advType = advTypes[i];
              let limitTag = "未配置次数限制";
              let countTag = "未触发";
              let dailyLimit = this.getAdvTypeDailyLimit(advType);
              if (dailyLimit > 0) {
                  limitTag = ULTools.format("日限制%d次", dailyLimit);
              }
              let dailyCount = this.advTypeDailyCountLog[advType] || 0;
              if (dailyCount > 0) {
                  countTag = ULTools.format("今日已触发%d次", dailyCount);
              }
              config.push({ type: "label", text: ULTools.format("%s: %s %s", advType, limitTag, countTag) });
              config.push({ type: "newLine" });
          }
          e.setReturnValue(config, true);
      }
      initAdv() {
          let config = ULConfig.getConfig();
          this.ADV_RELOAD_TIME = config["i_sdk_adv_reload_time"] || this.ADV_RELOAD_DEFAULT_TIME;
          let showListS = config["o_sdk_adv_show_list"];
          if (!showListS || typeof (showListS) !== "string") {
              console.warn("ULAdvManager-initAdv:adv show list error");
              return;
          }
          let showListObject = JSON.parse(showListS);
          let templatesObj = showListObject["templates"];
          if (!templatesObj || typeof (templatesObj) !== "object") {
              console.warn("ULAdvManager-initAdv:templates error");
              return;
          }
          let advSlotsObj = showListObject["advSlots"];
          if (!advSlotsObj || typeof (advSlotsObj) !== "object") {
              console.warn("ULAdvManager-initAdv:advSlots error");
              return;
          }
          let old_advKey_2_advObject = this.advKey_2_advObject;
          this.advKey_2_advObject = {};
          this.advId_2_advSlot = {};
          this.templateId_2_advTemplate = {};
          this.templateId_2_advTemplateItemArray = {};
          this.advKey_2_templateIdArray = {};
          this.templateId_2_moduleName = {};
          this.mainName_2_advObjectArray = {};
          this.templateId_2_advObjectArray = {};
          this.advType_2_advObjectArray = {};
          this.moduleName_2_templateIdsArray = {};
          this.logKey_2_countNum = {};
          this.advKey_2_advIdArray = {};
          this.tid_2_advKeyArray = {};
          this.advId_2_tidArray = {};
          this.nativeType_2_advObjectArray = {};
          this.advKey_2_rcd = {};
          this.updateAdvExpKey(templatesObj);
          let templateArray = new Array();
          for (const key in templatesObj) {
              let templateId = key;
              let templateItem = templatesObj[templateId];
              if (typeof (templateItem) !== "object") {
                  console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】格式配置非法`);
                  continue;
              }
              let moduleName = templateItem['moduleName'];
              if (!moduleName || (typeof moduleName) !== "string") {
                  console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】缺少必配字段moduleName`);
                  continue;
              }
              let rewardType = templateItem['rewardType'];
              if (!rewardType || (typeof moduleName) !== "string") {
                  console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】缺少必配字段rewardType`);
                  continue;
              }
              let args = templateItem['args'];
              if (!args || !(args instanceof Array)) {
                  console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】缺少必配字段args，或格式非法`);
                  continue;
              }
              if (args.length == 0) {
                  console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】必配字段args长度不能为0`);
                  continue;
              }
              let exp = templateItem['exp'] || "";
              let argWeights = templateItem["argWeights"] || [];
              let loadTypes = templateItem["loadTypes"] || [];
              let rcd = templateItem["rcd"];
              if ((typeof rcd) !== "number") {
                  rcd = 0;
                  console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】字段rcd未配置或格式错误，写入默认值0`);
              }
              let templateIdsArray = this.moduleName_2_templateIdsArray[moduleName];
              if (!templateIdsArray) {
                  templateIdsArray = [];
                  templateIdsArray.push(templateId);
                  this.moduleName_2_templateIdsArray[moduleName] = templateIdsArray;
              }
              else {
                  if (templateIdsArray.indexOf(templateId) == -1) {
                      templateIdsArray.push(templateId);
                  }
              }
              if (!this.templateId_2_moduleName[templateId]) {
                  this.templateId_2_moduleName[templateId] = moduleName;
              }
              if (templateArray.indexOf(templateId) == -1) {
                  templateArray.push(templateId);
              }
              let newArgWeights = [];
              let newLoadTypes = [];
              for (let i = 0, len = args.length; i < len; i++) {
                  let arg = args[i];
                  if (typeof (arg) !== "string") {
                      console.warn(`ULAdvManager-initAdv:模板【 ${templateId} 】字段args中的参数${arg}，为非字符串类型`);
                      arg = arg.toString();
                  }
                  let argWeight = 0;
                  if (argWeights.length == 0) {
                      argWeight = ULConst.ADV_RANDOM_DEFAULT_WEIGHT;
                  }
                  else {
                      argWeight = argWeights[i];
                  }
                  newArgWeights.push(argWeight);
                  let loadType = undefined;
                  try {
                      loadType = loadTypes[i];
                      if (loadType && typeof (loadType) !== "number") {
                          loadType = Number(loadType);
                      }
                  }
                  catch (error) {
                  }
                  newLoadTypes.push(loadType);
                  let ulAdvTemplateItem = {
                      templateId: templateId,
                      moduleName: moduleName,
                      rewardType: rewardType,
                      arg: arg,
                      argWeight: argWeight,
                      exp: exp,
                      loadType: loadType
                  };
                  let templateItemArray = this.templateId_2_advTemplateItemArray[templateId];
                  if (!templateItemArray) {
                      templateItemArray = [];
                      templateItemArray.push(ulAdvTemplateItem);
                      this.templateId_2_advTemplateItemArray[templateId] = templateItemArray;
                  }
                  else {
                      let bContains = false;
                      for (const item of templateItemArray) {
                          let key = item.templateId + "_" + item.arg;
                          let targetKey = templateId + "_" + arg;
                          if (key == targetKey) {
                              bContains = true;
                          }
                      }
                      if (!bContains) {
                          templateItemArray.push(ulAdvTemplateItem);
                      }
                  }
                  let advKey = ULTools.format("%s%s%s", moduleName, "_", arg);
                  let tidArray = this.advKey_2_templateIdArray[advKey];
                  if (!tidArray) {
                      tidArray = [];
                      tidArray.push(templateId);
                      this.advKey_2_templateIdArray[advKey] = tidArray;
                  }
                  else {
                      if (tidArray.indexOf(templateId) == -1) {
                          tidArray.push(templateId);
                      }
                  }
                  let advkeyArray = this.tid_2_advKeyArray[templateId];
                  if (!advkeyArray) {
                      advkeyArray = [];
                      advkeyArray.push(advKey);
                      this.tid_2_advKeyArray[templateId] = advkeyArray;
                  }
                  else {
                      if (advkeyArray.indexOf(advKey) == -1) {
                          advkeyArray.push(advKey);
                      }
                  }
                  let num = this.advKey_2_rcd[advKey];
                  let cd;
                  if (num != undefined) {
                      cd = Math.min(rcd, num);
                  }
                  else {
                      cd = rcd;
                  }
                  this.advKey_2_rcd[advKey] = cd;
              }
              let advTemplate = {
                  templateId: templateId,
                  moduleName: moduleName,
                  rewardType: rewardType,
                  exp: exp,
                  args: args,
                  argWeights: newArgWeights,
                  rcd: rcd,
                  loadTypes: newLoadTypes
              };
              if (!this.templateId_2_advTemplate[templateId]) {
                  this.templateId_2_advTemplate[templateId] = advTemplate;
              }
          }
          let tidsInAdvSlotsArray = [];
          for (const key in advSlotsObj) {
              let advId = key;
              let advSlotItem = advSlotsObj[advId];
              if (typeof (advSlotItem) !== "object") {
                  console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】格式配置非法`);
                  continue;
              }
              let schemesArray = advSlotItem["schemes"];
              if (!schemesArray) {
                  console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】缺少必配字段schemes,或该字段格式非法`);
                  continue;
              }
              let subAidsArray = advSlotItem["subAids"] || [];
              let rcd = advSlotItem["rcd"];
              if ((typeof rcd) !== "number") {
                  rcd = 0;
                  console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】字段rcd未配置或格式错误，写入默认值0`);
              }
              let schemeArray = [];
              for (let i = 0, len = schemesArray.length; i < len; i++) {
                  const schemeItemObj = schemesArray[i];
                  let tids = schemeItemObj["tids"];
                  if (!tids) {
                      console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】第【 ${i + 1} 】条策略缺少必配字段tids,或该字段格式非法`);
                      continue;
                  }
                  if (tids.length == 0) {
                      console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】第【 ${i + 1} 】条策略必配字段tids长度不能为0`);
                      continue;
                  }
                  let tidWeights = schemeItemObj["tidWeights"] || [];
                  let newTidWeights = [];
                  for (let j = 0, len = tids.length; j < len; j++) {
                      let tid = tids[j];
                      let tidWeight = 0;
                      if (tidWeights.length == 0) {
                          console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】第【 ${i + 1} 】条策略第【 ${j + 1} 】个模板权重未配置，写入默认值${ULConst.ADV_MUST_DEFAULT_WEIGHT}`);
                          tidWeight = ULConst.ADV_MUST_DEFAULT_WEIGHT;
                      }
                      else {
                          let tidW = tidWeights[j];
                          if ((typeof tidW) !== "number") {
                              console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】第【 ${i + 1} 】条策略第【 ${j + 1} 】个模板权重格式异常，写入默认值${ULConst.ADV_MUST_DEFAULT_WEIGHT}`);
                              tidWeight = ULConst.ADV_MUST_DEFAULT_WEIGHT;
                          }
                          else {
                              tidWeight = tidW;
                          }
                      }
                      newTidWeights.push(tidWeight);
                      if (tidsInAdvSlotsArray.indexOf(tid) == -1) {
                          tidsInAdvSlotsArray.push(tid);
                      }
                      let tidArray = this.advId_2_tidArray[advId];
                      if (!tidArray) {
                          tidArray = [];
                          tidArray.push(tid);
                          this.advId_2_tidArray[advId] = tidArray;
                      }
                      else {
                          if (tidArray.indexOf(tid) == -1) {
                              tidArray.push(tid);
                          }
                      }
                      if (subAidsArray.length > 0) {
                          for (const advId of subAidsArray) {
                              let tidArray = this.advId_2_tidArray[advId];
                              if (!tidArray) {
                                  tidArray = [];
                                  tidArray.push(tid);
                                  this.advId_2_tidArray[advId] = tidArray;
                              }
                              else {
                                  if (tidArray.indexOf(tid) == -1) {
                                      tidArray.push(tid);
                                  }
                              }
                          }
                      }
                  }
                  let exp = schemeItemObj["exp"] || "";
                  let weight = schemeItemObj["weight"];
                  if ((typeof weight) !== "number") {
                      weight = ULConst.ADV_RANDOM_DEFAULT_WEIGHT;
                      console.warn(`ULAdvManager-initAdv:广告位【 ${advId} 】第【 ${i + 1} 】条策略字段weight格式异常，写入默认值${ULConst.ADV_RANDOM_DEFAULT_WEIGHT}`);
                  }
                  let ulAdvScheme = {
                      tids: tids,
                      tidWeights: newTidWeights,
                      exp: exp,
                      weight: weight
                  };
                  schemeArray.push(ulAdvScheme);
              }
              let advSlot = new ULAdvSlot(advId, schemeArray, subAidsArray, rcd);
              if (!this.advId_2_advSlot[advId]) {
                  this.advId_2_advSlot[advId] = advSlot;
              }
              if (subAidsArray.length > 0) {
                  for (const mAdvId of subAidsArray) {
                      let newSubAidsArray = ULTools.clone(subAidsArray);
                      let index = newSubAidsArray.indexOf(mAdvId);
                      if (index > -1) {
                          newSubAidsArray.splice(index, 1);
                      }
                      newSubAidsArray.push(advId);
                      let subIdAdvSlot = new ULAdvSlot(mAdvId, schemeArray, newSubAidsArray, rcd);
                      if (!this.advId_2_advSlot[mAdvId]) {
                          this.advId_2_advSlot[mAdvId] = subIdAdvSlot;
                      }
                  }
              }
          }
          ULTools.forEachMap(this.advId_2_tidArray, (advId, tidArray) => {
              for (const tid of tidArray) {
                  let advKeyArray = this.tid_2_advKeyArray[tid];
                  if (!advKeyArray)
                      continue;
                  for (const key of advKeyArray) {
                      let advIdArray = this.advKey_2_advIdArray[key];
                      if (!advIdArray) {
                          advIdArray = [];
                          advIdArray.push(advId);
                          this.advKey_2_advIdArray[key] = advIdArray;
                      }
                      else {
                          if (advIdArray.indexOf(advId) == -1) {
                              advIdArray.push(advId);
                          }
                      }
                  }
              }
          });
          let newAdvBaseObjectArray = [];
          for (const tid in this.templateId_2_advTemplateItemArray) {
              let tidItemArray = this.templateId_2_advTemplateItemArray[tid];
              if (tidsInAdvSlotsArray.indexOf(tid) == -1) {
                  console.warn("ULAdvManager-initAdv:tid [" + tid + "] no advId use");
                  continue;
              }
              let moduleName = this.templateId_2_moduleName[tid];
              let moduleMainClass;
              ULTools.forEachMap(ULSdkModuleLoader.getSubAdModuleClassName(), (k, v) => {
                  let moduleNameArray = v;
                  if (moduleNameArray.indexOf(moduleName) >= 0) {
                      moduleMainClass = k;
                      return true;
                  }
              });
              if (!moduleMainClass) {
                  console.warn("ULAdvManager-initAdv: class " + moduleName + " not found ,continue");
                  continue;
              }
              for (let i = 0, len = tidItemArray.length; i < len; i++) {
                  let templateItem = tidItemArray[i];
                  let advKey = templateItem.moduleName + "_" + templateItem.arg;
                  if (old_advKey_2_advObject[advKey]) {
                      let obj = old_advKey_2_advObject[advKey];
                      this.advKey_2_advObject[advKey] = obj;
                      delete old_advKey_2_advObject[advKey];
                  }
                  if (this.advKey_2_advObject[advKey]) {
                      console.warn("ULAdvManger-initAdv: class " + moduleName + " already init,continue");
                      let obj = this.advKey_2_advObject[advKey];
                      let templateItemObjectsArray = this.templateId_2_advObjectArray[tid];
                      if (!templateItemObjectsArray) {
                          templateItemObjectsArray = [];
                          templateItemObjectsArray.push(obj);
                          this.templateId_2_advObjectArray[tid] = templateItemObjectsArray;
                      }
                      else {
                          if (templateItemObjectsArray.indexOf(obj) == -1) {
                              templateItemObjectsArray.push(obj);
                          }
                      }
                      continue;
                  }
                  let mainObj = ULSdkModuleLoader.getObjectByModuleName(moduleMainClass);
                  let targetObj = mainObj.createSubAdObj(moduleName, templateItem.arg);
                  targetObj.setLoadType = templateItem.loadType;
                  let advMainClassNameString = targetObj.getMainClassNameString();
                  if (newAdvBaseObjectArray.indexOf(targetObj) == -1) {
                      newAdvBaseObjectArray.push(targetObj);
                  }
                  let templateItemObjectArray = this.mainName_2_advObjectArray[advMainClassNameString];
                  if (!templateItemObjectArray) {
                      templateItemObjectArray = [];
                      templateItemObjectArray.push(targetObj);
                      this.mainName_2_advObjectArray[advMainClassNameString] = templateItemObjectArray;
                  }
                  else {
                      if (templateItemObjectArray.indexOf(targetObj) == -1) {
                          templateItemObjectArray.push(targetObj);
                      }
                  }
                  let templateItemObjectsArray = this.templateId_2_advObjectArray[tid];
                  if (!templateItemObjectsArray) {
                      templateItemObjectsArray = [];
                      templateItemObjectsArray.push(targetObj);
                      this.templateId_2_advObjectArray[tid] = templateItemObjectsArray;
                  }
                  else {
                      if (templateItemObjectsArray.indexOf(targetObj) == -1) {
                          templateItemObjectsArray.push(targetObj);
                      }
                  }
                  if (targetObj instanceof ULAdvNativeObjectBase) {
                      let type = targetObj.advType;
                      let ulAdvNativeObjectBases = this.nativeType_2_advObjectArray[type];
                      if (ulAdvNativeObjectBases == null) {
                          ulAdvNativeObjectBases = [];
                          ulAdvNativeObjectBases.push(targetObj);
                          this.nativeType_2_advObjectArray[type] = ulAdvNativeObjectBases;
                      }
                      else {
                          if (ulAdvNativeObjectBases.indexOf(targetObj) == -1) {
                              ulAdvNativeObjectBases.push(targetObj);
                          }
                      }
                  }
              }
          }
          ;
          ULTools.forEachMap(this.advKey_2_advObject, (k, v) => {
              let objectBase = v;
              let bases = this.advType_2_advObjectArray[objectBase.advType];
              if (!bases) {
                  bases = [];
                  bases.push(objectBase);
                  this.advType_2_advObjectArray[objectBase.advType] = bases;
              }
              else {
                  if (bases.indexOf(objectBase) == -1) {
                      bases.push(objectBase);
                  }
              }
          });
          for (const key in old_advKey_2_advObject) {
              let object = old_advKey_2_advObject[key];
              object.onDisposeModule();
          }
          ULTools.forEachMap(this.advId_2_advSlot, (advId, advSlot) => {
              let slot = advSlot;
              slot.refreshValidAdvKeys();
          });
          let newAdvBaseCache = {};
          for (let i = 0, len = newAdvBaseObjectArray.length; i < len; i++) {
              let advObjectBaseCacheItem = newAdvBaseObjectArray[i];
              let advMainClassNameString = advObjectBaseCacheItem.getMainClassNameString();
              ULTools.forEachMap(ULSdkModuleLoader.getSubAdMainClassName(), (k, v) => {
                  let adMainClassName = v;
                  if (advMainClassNameString == adMainClassName) {
                      if (this.adMainName_2_obj[adMainClassName]) {
                          let targetObj = this.adMainName_2_obj[adMainClassName];
                          advObjectBaseCacheItem.receiveMainClassInitState(targetObj.initState);
                      }
                      else if (!newAdvBaseCache[adMainClassName]) {
                          let obj = ULSdkModuleLoader.getObjectByModuleName(k);
                          let targetObj = obj.createMainAdObj();
                          newAdvBaseCache[adMainClassName] = targetObj;
                      }
                  }
              });
          }
          for (const key in newAdvBaseCache) {
              this.adMainName_2_obj[key] = newAdvBaseCache[key];
          }
          ULLog.console.log("ULAdvManager-initAdv-advExpKeyArray:", this.advExpKeyArray);
          ULLog.console.log("ULAdvManager-initAdv-templateArray:", templateArray);
          ULLog.console.log("ULAdvManager-initAdv-advId_2_advSlot:", this.advId_2_advSlot);
          ULLog.console.log("ULAdvManager-initAdv-templateId_2_advTemplate:", this.templateId_2_advTemplate);
          ULLog.console.log("ULAdvManager-initAdv-templateId_2_advTemplateItemArray:", this.templateId_2_advTemplateItemArray);
          ULLog.console.log("ULAdvManager-initAdv-advKey_2_templateIdArray:", this.advKey_2_templateIdArray);
          ULLog.console.log("ULAdvManager-initAdv-templateId_2_moduleName:", this.templateId_2_moduleName);
          ULLog.console.log("ULAdvManager-initAdv-mainName_2_advObjectArray:", this.mainName_2_advObjectArray);
          ULLog.console.log("ULAdvManager-initAdv-templateId_2_advObjectArray:", this.templateId_2_advObjectArray);
          ULLog.console.log("ULAdvManager-initAdv-advType_2_advObjectArray:", this.advType_2_advObjectArray);
          ULLog.console.log("ULAdvManager-initAdv-moduleName_2_templateIdsArray:", this.moduleName_2_templateIdsArray);
          ULLog.console.log("ULAdvManager-initAdv-logKey_2_countNum:", this.logKey_2_countNum);
          ULLog.console.log("ULAdvManager-initAdv-advKey_2_advIdArray:", this.advKey_2_advIdArray);
          ULLog.console.log("ULAdvManager-initAdv-tid_2_advKeyArray:", this.tid_2_advKeyArray);
          ULLog.console.log("ULAdvManager-initAdv-advId_2_tidArray:", this.advId_2_tidArray);
          ULLog.console.log("ULAdvManager-initAdv-nativeType_2_advObjectArray:", this.nativeType_2_advObjectArray);
          ULLog.console.log("ULAdvManager-initAdv-advKey_2_advObject:", this.advKey_2_advObject);
          ULLog.console.log("ULAdvManager-initAdv-advKey_2_rcd:", this.advKey_2_rcd);
      }
      getAdvReloadTime() {
          return this.ADV_RELOAD_TIME;
      }
      getAdvExpKeyArray() {
          return this.advExpKeyArray;
      }
      getLogKeyCountNum() {
          return this.logKey_2_countNum;
      }
      initAdvExpKey() {
          let keyArray = new Array();
          for (const type in typeExp) {
              for (const count in countExp) {
                  let key = ULTools.format("%s%s%s%s", ULConst.EXP_ADV_TYPE_CONST, type, ULConst.EXP_ADV_POINT_CONST, count);
                  if (keyArray.indexOf(key) == -1) {
                      keyArray.push(key);
                  }
              }
              for (const cd in cdExp) {
                  let key = ULTools.format("%s%s%s%s", ULConst.EXP_ADV_TYPE_CONST, type, ULConst.EXP_ADV_POINT_CONST, cd);
                  if (keyArray.indexOf(key) == -1) {
                      keyArray.push(key);
                  }
              }
          }
          for (let i = 0; i < keyArray.length; i++) {
              let key = keyArray[i];
              for (const data in dataExp) {
                  let newKey;
                  if (data == dataExp.nil) {
                      newKey = key;
                  }
                  else {
                      newKey = data + key;
                  }
                  if (this.systemAdvExpKeyArray.indexOf(newKey) == -1) {
                      this.systemAdvExpKeyArray.push(newKey);
                  }
              }
          }
      }
      updateAdvExpKey(templatesObj) {
          this.advExpKeyArray = this.systemAdvExpKeyArray.slice(0);
          let keyArray = new Array();
          for (const template in templatesObj) {
              for (const count in countExp) {
                  let key = ULTools.format("%s%s%s%s", ULConst.EXP_ADV_TEMPLATE_CONST, template, ULConst.EXP_ADV_POINT_CONST, count);
                  if (keyArray.indexOf(key) == -1) {
                      keyArray.push(key);
                  }
              }
              for (const cd in cdExp) {
                  let key = ULTools.format("%s%s%s%s", ULConst.EXP_ADV_TEMPLATE_CONST, template, ULConst.EXP_ADV_POINT_CONST, cd);
                  if (keyArray.indexOf(key) == -1) {
                      keyArray.push(key);
                  }
              }
          }
          for (let i = 0; i < keyArray.length; i++) {
              let key = keyArray[i];
              for (const data in dataExp) {
                  let newKey;
                  if (data == dataExp.nil) {
                      newKey = key;
                  }
                  else {
                      newKey = data + key;
                  }
                  if (this.advExpKeyArray.indexOf(newKey) == -1) {
                      this.advExpKeyArray.push(newKey);
                  }
              }
          }
          ULAdvExpManager.updateExpKeys(this.advExpKeyArray);
      }
      updateAdvKeyObjMap(advKey, advObject) {
          this.advKey_2_advObject[advKey] = advObject;
      }
      updateAdvIds(type, advId) {
          let advIds = this.type_2_advIds[type];
          if (!advIds) {
              advIds = [];
              advIds.push(advId);
              this.type_2_advIds[type] = advIds;
          }
          else {
              if (advIds.indexOf(advId) == -1) {
                  advIds.push(advId);
              }
          }
      }
      deleteAdvIdOpening(type, advId) {
          let advIds = this.type_2_advIds[type];
          if (advIds) {
              advIds = advIds.filter(item => item !== advId);
              this.type_2_advIds[type] = advIds;
          }
      }
      getAdvObjectsByName(mainName) {
          return this.mainName_2_advObjectArray[mainName];
      }
      onAdvObjectPreloadStateChanged(advKey) {
          ULTools.forEachMap(this.advId_2_advSlot, (k, v) => {
              let advSlot = v;
              advSlot.onAdvObjectPreloadStateChanged(advKey);
          });
      }
      onAdvSlotPreloadStateChanged(advId) {
          let ulAdvSlot = this.advId_2_advSlot[advId];
          if (!ulAdvSlot) {
              return;
          }
          let states = {};
          states[advId] = ulAdvSlot.preLoadState;
      }
      getTemplateObjByTid(tid) {
          return this.templateId_2_advTemplate[tid];
      }
      getAdvObjsByTid(tid) {
          return this.templateId_2_advObjectArray[tid];
      }
      getAdvTypeByTemplateId(tid) {
          let advType = null;
          let advObjects = this.templateId_2_advObjectArray[tid];
          if (advObjects && advObjects.length > 0) {
              advType = advObjects[0].advType;
          }
          return advType;
      }
      isAdvTypeOpened(advType) {
          let config = ULConfig.getConfig();
          let exemptArray = config.t_sdk_exempt_advType_limit_arrays;
          if (exemptArray.indexOf(advType) != -1) {
              return false;
          }
          let mutuallyExclusive = config.t_sdk_mutuallyExclusive_advType_setting || {};
          let trimMutuallyExclusiv = {};
          for (let advType of Object.keys(mutuallyExclusive)) {
              let itemList = mutuallyExclusive[advType];
              for (let subAdvType of itemList) {
                  let list = trimMutuallyExclusiv[advType] || [advType];
                  let otherList = trimMutuallyExclusiv[subAdvType] || [subAdvType];
                  list.push(subAdvType);
                  otherList.push(advType);
                  trimMutuallyExclusiv[advType] = list;
                  trimMutuallyExclusiv[subAdvType] = otherList;
              }
          }
          let itemList = trimMutuallyExclusiv[advType] || [advType];
          for (let subAdvType of itemList) {
              let objectBases = this.advType_2_advObjectArray[subAdvType];
              if (objectBases && objectBases.length > 0) {
                  for (let i = 0; i < objectBases.length; i++) {
                      let objectBase = objectBases[i];
                      if (objectBase.isOpened)
                          return true;
                  }
              }
          }
          return false;
      }
      getAdvObjectByAdvKey(advKey) {
          return this.advKey_2_advObject[advKey];
      }
      getRcdByAdvKey(advkey) {
          return this.advKey_2_rcd[advkey];
      }
      getAdvKeysByTemplateId(tid) {
          return this.tid_2_advKeyArray[tid];
      }
      getAdvSlotByAdvId(advId) {
          return this.advId_2_advSlot[advId];
      }
      getAdvObjPreloadStateByAdvKey(advKey) {
          let objectBase = this.advKey_2_advObject[advKey];
          if (objectBase) {
              return objectBase.preLoadState;
          }
          return ULConst.ADV_PRELOAD_STATE_NOAD;
      }
      getRewardTypeByTemplateId(tid) {
          let ulAdvTemplate = this.templateId_2_advTemplate[tid];
          if (!ulAdvTemplate) {
              return rewardType.show;
          }
          return ulAdvTemplate.rewardType;
      }
      getAdvTypeDailyLimit(advType) {
          let config = ULConfig.getConfig();
          let dailyLimit = 0;
          switch (advType) {
              case "interstitial":
                  dailyLimit = config.i_sdk_adv_type_interstitial_daily_limit;
                  break;
              case "banner":
                  dailyLimit = config.i_sdk_adv_type_banner_daily_limit;
                  break;
              case "embedded":
                  dailyLimit = config.i_sdk_adv_type_embedded_daily_limit;
                  break;
              case "video":
                  dailyLimit = config.i_sdk_adv_type_video_daily_limit;
                  break;
              case "url":
                  dailyLimit = config.i_sdk_adv_type_url_daily_limit;
                  break;
              case "paster":
                  dailyLimit = config.i_sdk_adv_type_paster_daily_limit;
                  break;
          }
          if (dailyLimit == null)
              return 0;
          if (isNaN(dailyLimit))
              return 0;
          return dailyLimit;
      }
      getAdvTypeCd(advType) {
          let config = ULConfig.getConfig();
          let cd = 0;
          switch (advType) {
              case typeExp.inter:
                  cd = config.i_sdk_adv_type_interstitial_cd;
                  break;
              case typeExp.banner:
                  cd = config.i_sdk_adv_type_banner_cd;
                  break;
              case typeExp.embed:
                  cd = config.i_sdk_adv_type_embedded_cd;
                  break;
              case typeExp.video:
                  cd = config.i_sdk_adv_type_video_cd;
                  break;
              case typeExp.url:
                  cd = config.i_sdk_adv_type_url_cd;
                  break;
              case typeExp.paster:
                  cd = config.i_sdk_adv_type_paster_cd;
                  break;
          }
          if (cd == null)
              return 0;
          if (isNaN(cd))
              return 0;
          return cd;
      }
      getLaunchCdByType(advType) {
          let config = ULConfig.getConfig();
          let cd = 0;
          switch (advType) {
              case typeExp.inter:
                  cd = config.i_sdk_adv_inter_launch_cd;
                  break;
              case typeExp.banner:
                  cd = config.i_sdk_adv_banner_launch_cd;
                  break;
              case typeExp.embed:
                  cd = config.i_sdk_adv_embed_launch_cd;
                  break;
              case typeExp.video:
                  cd = config.i_sdk_adv_video_launch_cd;
                  break;
              case typeExp.url:
                  cd = config.i_sdk_adv_url_launch_cd;
                  break;
              case typeExp.paster:
                  cd = config.i_sdk_adv_paster_launch_cd;
                  break;
              case typeExp.custom:
                  cd = config.i_sdk_adv_custom_launch_cd;
                  break;
          }
          if (cd == null)
              return 0;
          if (isNaN(cd))
              return 0;
          return cd;
      }
      get sdkInitTime() {
          return this._sdkInitTime;
      }
      getAdvTypeLastTriggerTimeLog() {
          return this.advTypeLastTriggerTimeLog;
      }
      getAdvTypeDailyCountLog() {
          return this.advTypeDailyCountLog;
      }
      getAdvObjectOpeningByAdvType(type) {
          for (let key in this.advType_2_advObjectArray) {
              if (type !== key) {
                  continue;
              }
              let objectBases = this.advType_2_advObjectArray[key];
              for (let objectBase of objectBases) {
                  if (objectBase.isOpened) {
                      return objectBase;
                  }
              }
          }
          return null;
      }
      getNewAdvTypeByOld(oldType) {
          let type = "";
          if (!oldType) {
              return type;
          }
          type = oldType;
          if (oldTypeExp.embedded == oldType) {
              type = typeExp.embed;
          }
          else if (oldTypeExp.interstitial == oldType) {
              type = typeExp.inter;
          }
          else if (oldTypeExp.fullscreen == oldType) {
              type = typeExp.interVideo;
          }
          return type;
      }
      geOldAdvTypeByNew(newType) {
          let type = "";
          if (!newType) {
              return type;
          }
          type = newType;
          if (typeExp.embed == newType) {
              type = oldTypeExp.embedded;
          }
          else if (typeExp.inter == newType) {
              type = oldTypeExp.interstitial;
          }
          else if (typeExp.interVideo == newType) {
              type = oldTypeExp.fullscreen;
          }
          return type;
      }
      onCmdGetAdvState(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let userData = data['userData'] || "";
          let advIds = data['advIds'] || [];
          let advIdPreLoadState = {};
          for (const advId of advIds) {
              let ulAdvSlot = this.advId_2_advSlot[advId];
              if (!ulAdvSlot) {
                  advIdPreLoadState[advId] = ULConst.ADV_PRELOAD_STATE_NOAD;
                  continue;
              }
              advIdPreLoadState[advId] = ulAdvSlot.preLoadState;
          }
          this.getAdvStateResult(advIdPreLoadState, userData);
      }
      onCmdOpenAdv(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let config = ULConfig.getConfig();
          this.advRequestSerialNum++;
          let advId = data["advId"] || "";
          let userData = data.userData || "";
          let tag = data.tag || "";
          let advType = this.searchAdvTypeByAdvId(advId);
          let advGroupId = this.searchAdvGroupIdByAdvId(advId);
          let advItem = new ULAdvItem(advId, userData, tag);
          advItem.advType = advType;
          advItem.advGroupId = advGroupId;
          ULSdkManager.getInstance().statisManager.reportAdvTotalRequest(advItem);
          let all_ad_ecd = config.i_sdk_adv_all_launch_cd;
          if (ULTools.time() - this.sdkInitTime < all_ad_ecd / 1000) {
              ULLog.console.log("ULAdvManager-onCmdOpenAdv:广告处于启动请求cd中");
              this.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, { code: "", msg: "in all adv launch cd" });
              return;
          }
          let advSolt = this.advId_2_advSlot[advId];
          if (!advSolt) {
              console.warn("ULAdvManager-onCmdOpenAdv:广告位[" + advId + "]对应的advSlot不存在");
              this.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, { code: "", msg: `广告位${advId}对应的advSlot不存在` });
              return;
          }
          let openingInfo = advSolt.openingInfo;
          if (openingInfo) {
              console.warn("ULAdvManager-onCmdOpenAdv:广告位[" + advId + "]已有广告请求中或正在展示");
              this.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, { code: "", msg: `广告位${advId}已有广告请求中或正在展示` });
              return;
          }
          let rcd = advSolt.rcd;
          ULLog.console.log("ULAdvManager-onCmdOpenAdv-rcd:", rcd);
          let lastRequestTime = this.advId_2_lastRequestTime[advId];
          let nowTime = (new Date()).valueOf();
          if (lastRequestTime) {
              if ((nowTime - lastRequestTime) < rcd) {
                  console.warn("ULAdvManager-onCmdOpenAdv:广告位[" + advId + "]in cd");
                  this.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, { code: "", msg: `广告位[${advId}]in cd` });
                  return;
              }
              else {
                  this.advId_2_lastRequestTime[advId] = nowTime;
              }
          }
          else {
              this.advId_2_lastRequestTime[advId] = nowTime;
          }
          advSolt.openAdv(this.advRequestSerialNum, data);
      }
      onCmdCloseAdv(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let advId = data.advId;
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot) {
              this.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "advSlot未找到!");
              return;
          }
          if (!advSlot.openingInfo) {
              this.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "advSlot没有广告执行!");
              return;
          }
          let objectBase = this.getAdvObjectByAdvKey(advSlot.openingInfo.advTemplateItemName);
          if (objectBase) {
              if (objectBase instanceof ULAdvNativeObjectBase) {
                  advSlot.closeAdv(data);
                  this.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, "close adv success");
              }
              else {
                  advSlot.closeAdv(data);
              }
          }
          else {
              this.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "no ad open!");
          }
      }
      onCmdCloseAllAdvByType(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let type = data.type || "";
          let advIds = this.type_2_advIds[type];
          if (advIds == null || advIds.length == 0) {
              this.responseCloseAllAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "no ad show");
              return;
          }
          for (let advId of advIds) {
              let advSlot = this.advId_2_advSlot[advId];
              if (advSlot == null || advSlot.openingInfo == null) {
                  continue;
              }
              let objectBase = this.getAdvObjectByAdvKey(advSlot.openingInfo.advTemplateItemName);
              if (objectBase != null) {
                  data["advId"] = advId;
                  if (objectBase instanceof ULAdvNativeObjectBase) {
                      objectBase.closeNativeAdv(data);
                  }
                  else {
                      advSlot.closeAdv(data);
                  }
              }
          }
          this.responseCloseAllAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, "关闭成功");
      }
      onCmdCloseNativeAdv(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let advId = data.advId;
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot) {
              this.responseCloseNativeAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "no advSlot");
              return;
          }
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CLOSE_NATIVE_ADV, data);
          this.responseCloseNativeAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, "关闭成功");
      }
      onCmdClickNativeAdv(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let advId = data.advId;
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", "109", advId || '', ""]);
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot) {
              this.responseClickNativeAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "no advSlot");
              return;
          }
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CLICK_NATIVE_ADV, data);
          ULSdkManager.getInstance().advManager.responseClickNativeAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, "点击成功");
      }
      responseOpenAdvResult(data, code, info) {
          let returnData = {};
          returnData["code"] = code;
          returnData["msg"] = ULAdvTrimErrorManager.trimErrMessage(info.msg, info.code ? info : null);
          returnData["advId"] = data.advId || "";
          returnData["userData"] = data.userData || "";
          returnData["tag"] = data.tag || "";
          if (code == 1) {
              returnData["type"] = data.type || "";
              returnData["rewardType"] = data.rewardType || "";
              this.advTypeLastTriggerTimeLog[data.type] = ULTools.time();
              this.advTypeDailyCountLog[data.type] = (this.advTypeDailyCountLog[data.type] || 0) + 1;
              this.saveRecord();
              let actualShowCount = data["actualShowCount"];
              returnData["actualShowCount"] = isNaN(actualShowCount) ? 1 : actualShowCount;
          }
          ULSdkManager.getInstance().response(ULConst.CMD_OPEN_ADV_RESULT, returnData);
      }
      responseRewardAdvResult(data, code, msg) {
          let returnData = {
              code: code,
              msg: msg,
              advId: data.advId || "",
              userData: data.userData || "",
              tag: data.tag || ""
          };
          if (code == 1) {
              let actualShowCount = data["actualShowCount"];
              returnData["actualShowCount"] = isNaN(actualShowCount) ? 1 : actualShowCount;
          }
          ULSdkManager.getInstance().response(ULConst.CMD_REWARD_ADV_RESULT, returnData);
      }
      responseClickAdvResult(data, code, msg) {
          ULSdkManager.getInstance().response(ULConst.CMD_CLICK_ADV_RESULT, {
              code: code,
              msg: msg,
              advId: data.advId || "",
              userData: data.userData || "",
              tag: data.tag || ""
          });
      }
      responseOpenNativeAdvResult(showData, nativeType, code, msg, nativeData) {
          let returnData = {};
          returnData["code"] = code;
          returnData["msg"] = msg;
          returnData["advId"] = showData.advId || "";
          returnData["userData"] = showData.userData || "";
          returnData["tag"] = showData.tag || "";
          returnData["nativeType"] = nativeType || "";
          returnData["nativeData"] = nativeData || {};
          if (code == 1) {
              returnData["type"] = showData.type || "";
              returnData["rewardType"] = showData.rewardType || "";
          }
          ULSdkManager.getInstance().response(ULConst.CMD_OPEN_NATIVE_ADV_RESULT, returnData);
          Advertisement.insertAdverV2();
          console.log("9999999999999999999999999999999999999999999999999999999999999999");
      }
      responseClickNativeAdvResult(data, code, msg) {
          ULSdkManager.getInstance().response(ULConst.CMD_CLICK_NATIVE_ADV_RESULT, {
              code: code,
              msg: msg,
              nativeType: data.nativeType || "",
              advId: data.advId || "",
              userData: data.userData || "",
              tag: data.tag || ""
          });
      }
      responseCloseNativeAdvResult(data, code, msg) {
          ULSdkManager.getInstance().response(ULConst.CMD_CLOSE_NATIVE_ADV_RESULT, {
              code: code,
              msg: msg,
              nativeType: data.nativeType || "",
              advId: data.advId || "",
              userData: data.userData || "",
              tag: data.tag || ""
          });
      }
      responseCloseAdvResult(data, code, msg) {
          ULSdkManager.getInstance().response(ULConst.CMD_CLOSE_ADV_RESULT, {
              code: code,
              msg: msg,
              advId: data.advId || "",
              userData: data.userData || "",
              tag: data.tag || ""
          });
      }
      responseCloseAllAdvResult(data, code, msg) {
          ULSdkManager.getInstance().response(ULConst.CMD_CLOSE_ALL_ADV_BY_TYPE_RESULT, {
              code: code,
              msg: msg,
              type: data.type || "",
              userData: data.userData || ""
          });
      }
      pauseSound() {
          ULSdkManager.getInstance().response(ULConst.CMD_PAUSE_SOUND_RESULT, {});
      }
      resumeSound() {
          ULSdkManager.getInstance().response(ULConst.CMD_RESUME_SOUND_RESULT, {});
      }
      getAdvStateResult(data, userData) {
          ULSdkManager.getInstance().response(ULConst.CMD_GET_ADV_STATE_RESULT, {
              states: data,
              userData: userData,
          });
      }
      onAdvObjectLifeCycleShowRequest(advKey, data) {
          this.addAdvCountLog(advKey, countExp.rc);
          let advId = data.advId || "";
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType && statisticsType != "") {
                  advType = statisticsType;
              }
              let userData = data.userData || "";
              let tag = data.tag || "";
              let advGroupId = this.searchAdvGroupIdByAdvId(advId);
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = advGroupId;
              ULSdkManager.getInstance().statisManager.reportAdvBranchRequest(advItem, advertiser, arg);
          }
      }
      onAdvObjectLifeCycleSkip(advKey, info, data) {
          let advId = data["advId"] || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          advSlot.onAdvObjectLifeCycleSkip(data, info);
          this.addAdvCountLog(advKey, countExp.fc);
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType && statisticsType != "") {
                  advType = statisticsType;
              }
              let userData = data.userData || "";
              let tag = data.tag || "";
              let advGroupId = this.searchAdvGroupIdByAdvId(advId);
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = advGroupId;
              advItem.statisChannelName = advertiser;
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvFail(advItem, "errCode=" + info.code + ";errMsg=" + info.msg);
          }
      }
      onAdvObjectLifeCycleShow(advKey, msg, data, nativeData) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          advSlot.onAdvObjectLifeCycleShow(msg, data);
          this.addAdvCountLog(advKey, countExp.sc);
          this.reportVideoPlayCompletion(advKey, data, nativeData);
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType && statisticsType != "") {
                  advType = statisticsType;
              }
              if (typeExp.banner == advType) {
                  this.bannerStartShowTime = ULTools.time();
              }
              let title = nativeData ? nativeData.title : "";
              let userData = data.userData || "";
              let tag = data.tag || "";
              let advGroupId = this.searchAdvGroupIdByAdvId(advId);
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = advGroupId;
              advItem.statisChannelName = advertiser;
              advItem.statisNativeAdTitle = title;
              advItem.statisSdkAdvId = arg;
              let actualShowCount = data["actualShowCount"];
              ULSdkManager.getInstance().statisManager.reportAdvSuccess(advItem, title, isNaN(actualShowCount) ? 1 : actualShowCount);
          }
      }
      onAdvObjectLifeCycleClick(advKey, msg, data, nativeData) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          advSlot.onAdvObjectLifeCycleClick(msg, data);
          this.addAdvCountLog(advKey, countExp.cc);
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType && statisticsType != "") {
                  advType = statisticsType;
              }
              let title = nativeData ? nativeData.title : "";
              let userData = data.userData || "";
              let tag = data.tag || "";
              let advGroupId = this.searchAdvGroupIdByAdvId(advId);
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = advGroupId;
              advItem.statisChannelName = advertiser;
              advItem.statisNativeAdTitle = title;
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvClicked(advItem);
          }
      }
      onAdvObjectLifeCycleClose(advKey, data, nativeData) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          this.reportBannerShowTime(advKey, data, nativeData);
          this.reportVideoPlayStart(advKey, data, nativeData);
          advSlot.onAdvObjectLifeCycleClose();
          this.responseCloseAdvResult(data, 1, "success");
      }
      onAdvTimeout(advItem, msg) {
      }
      reportBannerShowTime(advKey, data, nativeData) {
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase != null) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType != null && statisticsType != "") {
                  advType = statisticsType;
              }
              if (typeExp.banner == advType) {
                  let bannerShowDuration = Math.floor(ULTools.time() - this.bannerStartShowTime);
                  if (bannerShowDuration <= 0) {
                      return;
                  }
                  let bannerShowTime = String(bannerShowDuration);
                  let advId = data.advId || "";
                  let userData = data.userData || "";
                  let tag = data.tag || "";
                  let advGroupId = this.searchAdvGroupIdByAdvId(advId);
                  let advItem = new ULAdvItem(advId, userData, tag);
                  advItem.showAdvType = advType;
                  advItem.advGroupId = advGroupId;
                  advItem.statisChannelName = advertiser;
                  advItem.statisNativeAdTitle = nativeData ? nativeData.title : "";
                  advItem.statisSdkAdvId = arg;
                  ULSdkManager.getInstance().statisManager.reportAdvClose(advItem, bannerShowTime);
              }
          }
      }
      reportVideoPlayStart(advKey, data, nativeData) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase != null) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType != null && statisticsType != "") {
                  advType = statisticsType;
              }
              if (typeExp.video == advType) {
                  let title = nativeData ? nativeData.title : "";
                  let userData = data.userData || "";
                  let tag = data.tag || "";
                  let advGroupId = this.searchAdvGroupIdByAdvId(advId);
                  let advItem = new ULAdvItem(advId, userData, tag);
                  advItem.showAdvType = advType;
                  advItem.advGroupId = advGroupId;
                  advItem.statisChannelName = advertiser;
                  advItem.statisNativeAdTitle = title;
                  advItem.statisSdkAdvId = arg;
                  ULSdkManager.getInstance().statisManager.reportAdvPlayStart(advItem);
              }
          }
      }
      reportVideoPlayCompletion(advKey, data, nativeData) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase != null) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType != null && statisticsType != "") {
                  advType = statisticsType;
              }
              if (typeExp.video == advType) {
                  let title = nativeData ? nativeData.title : "";
                  let userData = data.userData || "";
                  let tag = data.tag || "";
                  let advGroupId = this.searchAdvGroupIdByAdvId(advId);
                  let advItem = new ULAdvItem(advId, userData, tag);
                  advItem.showAdvType = advType;
                  advItem.advGroupId = advGroupId;
                  advItem.statisChannelName = advertiser;
                  advItem.statisNativeAdTitle = title;
                  advItem.statisSdkAdvId = arg;
                  ULSdkManager.getInstance().statisManager.reportAdvPlayCompletion(advItem);
              }
          }
      }
      onAdvObjectLifeCycleRequest(advKey) {
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase != null && !objectBase.isReportLoading) {
              objectBase.isReportLoading = true;
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType != null && statisticsType != "") {
                  advType = statisticsType;
              }
              let advId = "";
              let userData = "";
              let tag = "";
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = "";
              advItem.statisChannelName = advertiser;
              advItem.statisNativeAdTitle = "";
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvLoadAdvRequest(advItem);
          }
      }
      onAdvObjectLifeCycleRequestSuccess(advKey) {
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase != null && objectBase.isReportLoading) {
              objectBase.isReportLoading = false;
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType != null && statisticsType != "") {
                  advType = statisticsType;
              }
              let advId = "";
              let userData = "";
              let tag = "";
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = "";
              advItem.statisChannelName = advertiser;
              advItem.statisNativeAdTitle = "";
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvLoadAdvSuccess(advItem);
          }
      }
      onAdvObjectLifeCycleRequestFailed(advKey, info) {
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase != null && objectBase.isReportLoading) {
              objectBase.isReportLoading = false;
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType != null && statisticsType != "") {
                  advType = statisticsType;
              }
              let advId = "";
              let userData = "";
              let tag = "";
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = "";
              advItem.statisChannelName = advertiser;
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvLoadAdvFailed(advItem, "errCode=" + info.code + ";errMsg=" + info.msg);
          }
      }
      onAdvObjectLifeCycleFail(advKey, info, data) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          advSlot.onAdvObjectLifeCycleFail(info, data);
          this.addAdvCountLog(advKey, countExp.fc);
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType && statisticsType != "") {
                  advType = statisticsType;
              }
              let userData = data.userData || "";
              let tag = data.tag || "";
              let advGroupId = this.searchAdvGroupIdByAdvId(advId);
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = advGroupId;
              advItem.statisChannelName = advertiser;
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvFail(advItem, "errCode=" + info.code + ";errMsg=" + info.msg);
          }
      }
      onAdvObjectLifeCycleReuse(advKey, info, data) {
          let advId = data.advId || "";
          let advSlot = this.advId_2_advSlot[advId];
          if (!advSlot)
              return;
          ULSdkManager.getInstance().advManager.responseOpenAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, info);
          this.addAdvCountLog(advKey, countExp.fc);
          let objectBase = this.getAdvObjectByAdvKey(advKey);
          if (objectBase) {
              let advType = objectBase.advType;
              let arg = objectBase.arg;
              let advertiser = objectBase.statisticsAdvertiser;
              let statisticsType = objectBase.statisticsType;
              if (statisticsType && statisticsType != "") {
                  advType = statisticsType;
              }
              let userData = data.userData || "";
              let tag = data.tag || "";
              let advGroupId = this.searchAdvGroupIdByAdvId(advId);
              let advItem = new ULAdvItem(advId, userData, tag);
              advItem.showAdvType = advType;
              advItem.advGroupId = advGroupId;
              advItem.statisChannelName = advertiser;
              advItem.statisSdkAdvId = arg;
              ULSdkManager.getInstance().statisManager.reportAdvFail(advItem, "errCode=" + info.code + ";errMsg=" + info.msg);
          }
      }
      addAdvFailCount(advKey) {
          this.addAdvCountLog(advKey, countExp.fc);
      }
      addAdvCountLog(advKey, countExp) {
          let tidArray = this.advKey_2_templateIdArray[advKey];
          if (tidArray && tidArray.length > 0) {
              for (const tid of tidArray) {
                  let key = ULConst.EXP_ADV_TEMPLATE_CONST + tid + ULConst.EXP_ADV_POINT_CONST + countExp;
                  this.updateAdvCountStoreNum(key);
                  this.advSlotRefreshValidAdvKeys(advKey);
              }
          }
          let objectBase = this.advKey_2_advObject[advKey];
          if (objectBase) {
              let advType = objectBase.advType;
              let key = ULConst.EXP_ADV_TYPE_CONST + advType + ULConst.EXP_ADV_POINT_CONST + countExp;
              this.updateAdvCountStoreNum(key);
              this.advSlotRefreshValidAdvKeys(advKey);
          }
      }
      updateAdvCountStoreNum(key) {
          ULAdvExpManager.updateExpValue(dataExp.d + key);
          ULAdvExpManager.updateExpValue(dataExp.w + key);
          ULAdvExpManager.updateExpValue(dataExp.m + key);
          ULAdvExpManager.updateExpValue(dataExp.y + key);
      }
      advSlotRefreshValidAdvKeys(advKey) {
          let advIdArray = this.advKey_2_advIdArray[advKey];
          if (advIdArray) {
              for (const advId of advIdArray) {
                  let ulAdvSlot = this.advId_2_advSlot[advId];
                  if (ulAdvSlot) {
                      ulAdvSlot.refreshValidAdvKeys();
                  }
              }
          }
      }
  }
  ULAdvManager.instance = null;

  let qg$2 = window["qg"];
  class ULAdvOppoQgVideo extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.video, ULTools.format("%s%s%s", "ULAdvOppoQgVideo", "_", arg));
          this.className = "ULAdvOppoQgVideo";
          this.videoAd = null;
          this.statisticsAdvertiser = ULAdvOppoQg.NORMAL_ADVERTISER;
          this.setSupportLoadType = [ULConst.ADV_LOAD_TYPE_PRELOAD, ULConst.ADV_LOAD_TYPE_UNPRELOAD];
          this.setLoadType = ULConst.ADV_LOAD_TYPE_PRELOAD;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgVideo-onDisposeModule arg:", this.arg);
          if (this.videoAd) {
              this.videoAd.offClose();
              this.videoAd.offLoad();
              this.videoAd.offError();
              this.videoAd.destroy();
              this.videoAd = null;
          }
      }
      initAdv() {
          return;
          let platformVersionCode = qg$2.getSystemInfoSync().platformVersionCode;
          if (platformVersionCode < 1051) {
              ULLog.console.log("ULAdvOppoQgVideo-initAdv-最低平台版本支持1051，直接跳过");
              return;
          }
          let loadType = this.getLoadType;
          if (loadType == undefined || this.getSupportLoadType.indexOf(loadType) == -1) {
              ULLog.console.log(`ULAdvOppoQgVideo-initAdv-当前加载类型${loadType}模块不支持`);
              loadType = ULConst.ADV_LOAD_TYPE_PRELOAD;
          }
          this.mLoadType = loadType;
          if (!this.videoAd) {
              this.videoAd = qg$2.createRewardedVideoAd({
                  adUnitId: this.arg
              });
          }
          if (this.mLoadType == ULConst.ADV_LOAD_TYPE_PRELOAD) {
              this.videoAd.onLoad(() => {
                  ULLog.console.log("ULAdvOppoQgVideo videoAd.onLoad");
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
                  this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
              });
              this.videoAd.onClose((res) => {
                  ULLog.console.log("ULAdvOppoQgVideo videoAd.onClose.res:", res);
                  this.isOpened = false;
                  if (res.isEnded) {
                      ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_video_success_show_event_id]);
                  }
                  else {
                      ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleFail(this.advKey, { code: "", msg: ULConst.ADV_VIDEO_PLAY_FAIL_MSG }, this.showData);
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_user_close_video_event_id]);
                  }
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, this.showData);
                  this.preLoadAdv();
              });
              this.videoAd.onError((err) => {
                  ULLog.console.log("ULAdvOppoQgVideo videoAd.onError", err);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(err.errCode), msg: err.errMsg });
                  this.onLoadFailErr = { code: String(err.errCode), msg: err.errMsg };
                  if (this.preLoadState == ULConst.ADV_PRELOAD_STATE_READY) {
                      this.isOpened = false;
                      this.advSkip(this.showData, { code: String(err.errCode), msg: err.errMsg });
                  }
                  else {
                      ULSdkManager.getInstance().advManager.addAdvFailCount(this.advKey);
                  }
                  this.reLoadAdv();
                  ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_user_open_video_event_id, "2"]);
              });
              this.preLoadAdv();
          }
          else {
              this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          }
      }
      loadAdv() {
          if (this.mLoadType == ULConst.ADV_LOAD_TYPE_PRELOAD) {
              this.preLoadState = ULConst.ADV_PRELOAD_STATE_LOADING;
              this.videoAd.load();
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          }
          else {
          }
      }
      showAdv(data) {
          console.info("777777777777777777777777777777777777777777777777777777777777777");
          // if (!this.videoAd) {
          //     console.warn("ULAdvOppoQgVideo-showAdv:广告未初始化,直接跳过当前广告展示");
          //     this.advSkip(data, { code: "", msg: "adv not init" });
          //     return;
          // }
          // if (this.preLoadState == ULConst.ADV_PRELOAD_STATE_LOADING) {
          //     console.warn("ULAdvOppoQgVideo-showAdv:广告未加载就绪,直接跳过当前广告展示");
          //     this.advSkip(data, { code: "", msg: "adv is loading" });
          //     return;
          // }
          // if (this.preLoadState == ULConst.ADV_PRELOAD_STATE_NOAD) {
          //     console.warn("ULAdvOppoQgVideo-showAdv:广告未加载就绪,直接跳过当前广告展示");
          //     this.advSkip(data, this.onLoadFailErr);
          //     return;
          // }
          this.showData = data;
          // this.isOpened = true;
          // if (this.mLoadType == ULConst.ADV_LOAD_TYPE_PRELOAD) {
          //     this.videoAd.show();
          //     ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_user_open_video_event_id, "1"]);
          // }
          // else {
          //     this.videoAd.offLoad();
          //     this.videoAd.offClose();
          //     this.videoAd.offError();
          //     this.videoAd.onLoad(() => {
          //         ULLog.console.log("ULAdvOppoQgVideo videoAd.onLoad");
          //         ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
          //         this.videoAd.show();
          //         ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_user_open_video_event_id, "1"]);
          //     });
          //     this.videoAd.onClose((res) => {
          //         ULLog.console.log("ULAdvOppoQgVideo videoAd.onClose.res:", res);
          //         this.isOpened = false;
          //         if (res.isEnded) {
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_video_success_show_event_id]);
          //         }
          //         else {
          //             ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleFail(this.advKey, { code: "", msg: ULConst.ADV_VIDEO_PLAY_FAIL_MSG }, this.showData);
          //             ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_user_close_video_event_id]);
          //         }
          //         ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, this.showData);
          //     });
          //     this.videoAd.onError((err) => {
          //         ULLog.console.log("ULAdvOppoQgVideo videoAd.onError", err);
          //         ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(err.errCode), msg: err.errMsg });
          //         this.isOpened = false;
          //         this.advSkip(this.showData, { code: String(err.errCode), msg: err.errMsg });
          //         ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [ULConfig.getConfig().s_sdk_miniplay_user_open_video_event_id, "2"]);
          //     });
          //     this.videoAd.load();
          // }
      }
      closeAdv(data) {
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgVideo-receiveInitState:初始化失败");
          }
      }
  }

  let qg$3 = window["qg"];
  class ULAdvOppoQgBannerBox extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.banner, ULTools.format("%s%s%s", "ULAdvOppoQgBannerBox", "_", arg));
          this.className = "ULAdvOppoQgBannerBox";
          this.statisticsAdvertiser = "ULAdvOppoQgBannerBox";
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgBannerBox-onDisposeModule arg:", this.arg);
          if (this.gameBannerAd) {
              this.gameBannerAd.destroy();
              this.gameBannerAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgBannerBox-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
      }
      loadAdv() {
      }
      showAdv(data) {
          return;
          if (qg$3.getSystemInfoSync().platformVersionCode < 1090) {
              ULLog.console.log('ULAdvOppoQgBannerBox-showAdv:快应用平台版本号低于1090，暂不支持互推盒子相关 API');
              this.advSkip(data, { code: "", msg: "api unsupport" });
              return;
          }
          let tag = data["tag"] || data["advId"] || "";
          let advSetting = ULConfig.getConfig().t_sdk_oppoqg_show_banner_box_adv_tags;
          let styleObj = advSetting[tag];
          if (!styleObj) {
              ULLog.console.log("ULAdvOppoQgBannerBox-showAdv:当前广告位不允许展示横幅的盒子");
              this.advSkip(data, { code: "", msg: `advId [${tag}] unsupport banner box` });
              return;
          }
          this.showData = data;
          this.isOpened = true;
          if (this.gameBannerAd) {
              this.gameBannerAd.destroy();
              this.gameBannerAd = null;
          }
          let sys = qg$3.getSystemInfoSync();
          let screenWidth = sys.screenWidth;
          let screenHeight = sys.screenHeight;
          let style = {};
          if (!isNaN(Number(styleObj.left))) {
              style["left"] = Number(styleObj.left) * screenWidth;
          }
          if (!isNaN(Number(styleObj.top))) {
              style["top"] = Number(styleObj.top) * screenHeight;
          }
          if (!isNaN(Number(styleObj.orientation))) {
              if (Number(styleObj.orientation) == 0) {
                  style["orientation"] = "horizontal";
              }
              else {
                  style["orientation"] = "vertical";
              }
          }
          this.gameBannerAd = qg$3.createGameBannerAd({
              adUnitId: this.arg,
              style: style
          });
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.gameBannerAd.show().then(() => {
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
          }).catch((error) => {
              ULLog.console.log("ULAdvOppoQgBannerBox-showAdv-show-catch:", error);
              this.isOpened = false;
              this.advSkip(this.showData, { code: String(error.errCode), msg: error.errMsg });
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(error.errCode), msg: error.errMsg });
          });
      }
      closeAdv(data) {
          if (this.isOpened) {
              this.gameBannerAd.hide().then(() => {
                  this.isOpened = false;
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data);
                  ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
              }).catch((error) => {
                  ULLog.console.log("ULAdvOppoQgBannerBox-closeAdv-hide-catch:", error);
                  ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, error.errCode + ',' + error.errMsg);
              });
          }
          else {
              ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "no ad show");
          }
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgBannerBox-receiveInitState:初始化失败");
          }
      }
  }

  let qg$4 = window["qg"];
  class ULAdvOppoQgPortalBox extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.inter, ULTools.format("%s%s%s", "ULAdvOppoQgPortalBox", "_", arg));
          this.className = "ULAdvOppoQgPortalBox";
          this.showPortalGameBoxTags = {};
          this.isCall = false;
          this.statisticsAdvertiser = "ULAdvOppoQgPortalBox";
          this.statisticsType = oldTypeExp.interstitial;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgPortalBox-onDisposeModule arg:", this.arg);
          if (this.gamePortalAd) {
              this.gamePortalAd.offClose();
              this.gamePortalAd.offLoad();
              this.gamePortalAd.offError();
              this.gamePortalAd.destroy();
              this.gamePortalAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgPortalBox-initAdv");
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_JUMP_LEISURE_SUBJECT, 1, this.onCmdJumpLeisureSubject.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_COP_CHANGED, ULConst.PRIORITY_NONE, this.onCmdFromCopChange.bind(this));
          this.trimSetting();
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
      }
      onCmdFromCopChange(e) {
          this.trimSetting();
      }
      trimSetting() {
          let config = ULConfig.getConfig();
          let interTags = config.t_sdk_oppoqg_show_inter_box_adv_tags || [];
          for (let index = 0; index < interTags.length; index++) {
              let tag = interTags[index];
              this.showPortalGameBoxTags[tag] = true;
          }
          ULLog.console.log("ULAdvOppoQgPortalBox.init showPortalGameBoxTags:", this.showPortalGameBoxTags);
      }
      onCmdJumpLeisureSubject(e) {
          e.stopImmediatePropagation();
          ULLog.console.log("ULAdvOppoQgPortalBox.onCmdJumpLeisureSubject................");
          let data = e.data;
          let advId = "jumpLeisureSubjectAdvId";
          let userData = data.userData || "";
          let tag = "jumpLeisureSubjectTag";
          if (!this.showPortalGameBoxTags[tag]) {
              this.showPortalGameBoxTags[tag] = true;
          }
          this.isCall = true;
          this.showPortalAd((state) => {
              this.isCall = false;
              if (state) {
                  ULSdkManager.getInstance().response(ULConst.CMD_JUMP_LEISURE_SUBJECT_RESULT, {
                      code: 1,
                      msg: "打开盒子广告成功",
                      userData: userData,
                  });
              }
              else {
                  ULSdkManager.getInstance().response(ULConst.CMD_JUMP_LEISURE_SUBJECT_RESULT, {
                      code: 0,
                      msg: "打开盒子广告失败",
                      userData: userData,
                  });
              }
          });
      }
      loadAdv() {
      }
      showAdv(data) {
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              console.warn("ULAdvOppoQgPortalBox-showAdv:广告未加载就绪,直接跳过当前广告展示");
              this.advSkip(data, { code: "", msg: "adv not ready" });
              return;
          }
          let tag = data["tag"] || "";
          if (!this.showPortalGameBoxTags[tag]) {
              ULLog.console.log("ULAdvOppoQgPortalBox-showAdv:当前广告位不允许展示盒子");
              this.advSkip(data, { code: "", msg: `advId [${tag}] unsupport box` });
              return;
          }
          this.showData = data;
          this.isOpened = true;
          this.showPortalAd();
      }
      showPortalAd(callback) {
          return;
          if (qg$4.getSystemInfoSync().platformVersionCode < 1076) {
              ULLog.console.log('ULAdvOppoQgPortalBox-showAdv:快应用平台版本号低于1076，暂不支持互推盒子相关 API');
              if (callback) {
                  callback(false);
              }
              else {
                  this.advSkip(this.showData, { code: "", msg: "api unsupport" });
              }
              return;
          }
          if (!this.gamePortalAd) {
              this.gamePortalAd = qg$4.createGamePortalAd({
                  adUnitId: this.arg
              });
              if (!this.gamePortalAd) {
                  ULLog.console.log('ULAdvOppoQgPortalBox-showAdv:广告对象创建失败，请检查参数配置');
                  if (callback) {
                      callback(false);
                  }
                  else {
                      this.advSkip(this.showData, { code: "", msg: "obj create fail" });
                  }
                  return;
              }
              this.gamePortalAd.offLoad(() => {
                  ULLog.console.log("ULAdvOppoQgPortalBox-showAdv-offLoad");
              });
              this.gamePortalAd.offError(() => {
                  ULLog.console.log("ULAdvOppoQgPortalBox-showAdv-offError");
              });
              this.gamePortalAd.onLoad(() => {
                  ULLog.console.log("ULAdvOppoQgPortalBox-showAdv-onLoad");
              });
              this.gamePortalAd.onClose(() => {
                  ULLog.console.log("ULAdvOppoQgPortalBox-showAdv-onClose");
                  if (!this.isCall) {
                      this.isOpened = false;
                      ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, this.showData);
                  }
              });
              this.gamePortalAd.onError((err) => {
                  ULLog.console.log("ULAdvOppoQgPortalBox-showAdv-onError:", err);
                  if (!this.isCall) {
                      this.isOpened = false;
                      let errMsg = err.errCode + ',' + err.errMsg;
                      this.advSkip(this.showData, { code: String(err.errCode), msg: err.errMsg });
                  }
              });
          }
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.gamePortalAd.load().then(() => {
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              this.gamePortalAd.show().then(() => {
                  if (callback) {
                      callback(true);
                  }
                  else {
                      ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
                  }
              }).catch((error) => {
                  if (callback) {
                      callback(false);
                  }
                  else {
                      this.isOpened = false;
                      let errMsg = error.errCode + ',' + error.errMsg;
                      this.advSkip(this.showData, { code: String(error.errCode), msg: error.errMsg });
                  }
              });
          }).catch((error) => {
              ULLog.console.log("ULAdvOppoQgPortalBox-showAdv-load-catch:", error);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(error.errCode), msg: error.errMsg });
              if (callback) {
                  callback(false);
              }
              else {
                  this.isOpened = false;
                  let errMsg = error.errCode + ',' + error.errMsg;
                  this.advSkip(this.showData, { code: String(error.errCode), msg: error.errMsg });
              }
          });
      }
      closeAdv(data) {
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgBannerBox-receiveInitState:初始化失败");
          }
      }
  }

  let qg$5 = window["qg"];
  class ULAdvOppoQgInter extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.inter, ULTools.format("%s%s%s", "ULAdvOppoQgInter", "_", arg));
          this.className = "ULAdvOppoQgInter";
          this.statisticsAdvertiser = ULAdvOppoQg.NORMAL_ADVERTISER;
          this.statisticsType = oldTypeExp.interstitial;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgInter-onDisposeModule arg:", this.arg);
          if (this.interstitialAd) {
              this.interstitialAd.offLoad();
              this.interstitialAd.offClose();
              this.interstitialAd.offError();
              this.interstitialAd.destroy();
              this.interstitialAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgInter-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
      }
      loadAdv() {
      }
      showAdv(data) {
          return;
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              console.warn("ULAdvOppoQgInter-showAdv:广告未加载就绪,直接跳过当前广告展示");
              this.advSkip(data, { code: "", msg: "adv not ready" });
              return;
          }
          this.showData = data;
          this.isOpened = true;
          if (!this.interstitialAd) {
              this.interstitialAd = qg$5.createInsertAd({
                  posId: this.arg
              });
          }
          if (!this.interstitialAd) {
              ULLog.console.log("ULAdvOppoQgInter-showAdv:广告对象创建异常，请检查参数是否正确：", this.arg);
              this.advSkip(data, { code: "", msg: "param error" });
              return;
          }
          this.interstitialAd.offLoad();
          this.interstitialAd.offClose();
          this.interstitialAd.offError();
          this.interstitialAd.onLoad(() => {
              ULLog.console.log("ULAdvOppoQgInter-showAdv-onLoad");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              this.interstitialAd.show();
          });
          this.interstitialAd.onShow(() => {
              ULLog.console.log("ULAdvOppoQgInter-showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
          });
          this.interstitialAd.onClose(() => {
              ULLog.console.log("ULAdvOppoQgInter-showAdv-onClose");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, this.showData);
          });
          this.interstitialAd.onError((err) => {
              ULLog.console.log("ULAdvOppoQgInter-showAdv-onError:", err);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(err.errCode), msg: err.errMsg });
              this.isOpened = false;
              this.advSkip(this.showData, { code: String(err.errCode), msg: err.errMsg });
          });
          this.interstitialAd.load();
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
      }
      closeAdv(data) {
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgInter-receiveInitState:初始化失败");
          }
      }
  }

  let qg$6 = window["qg"];
  class ULAdvOppoQgBanner extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.banner, "ULAdvOppoQgBanner" + "_" + arg);
          this.className = "ULAdvOppoQgBanner";
          this.isCallHide = false;
          this.channelBannerStyle = {};
          this.statisticsAdvertiser = ULAdvOppoQg.NORMAL_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgBanner-onDisposeModule arg:", this.arg);
          if (this.bannerAd) {
              this.bannerAd.offHide();
              this.bannerAd.offLoad();
              this.bannerAd.offError();
              this.bannerAd.offResize();
              this.bannerAd.destroy();
              this.bannerAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgBanner-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          this.channelBannerStyle = ULConfig.getConfig().t_sdk_adv_banner_tags_style_setting || {};
      }
      loadAdv() {
      }
      showAdv(data) {
          return;
          let platformVersionCode = qg$6.getSystemInfoSync().platformVersionCode;
          if (platformVersionCode < 1051) {
              console.warn("ULAdvOppoQgBanner-showAdv:原生api最低支持1051");
              this.advSkip(data, { code: "", msg: "minPlatformVersion unsupport" });
              return;
          }
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv:广告未加载就绪，直接跳过");
              this.advSkip(data, { code: "", msg: "adv not ready" });
              return;
          }
          let ad_limitTime = ULConfig.getConfig().i_sdk_oppoqg_ad_ecd;
          let requestTime = ULTools.time();
          if (requestTime - ULSdkManager.getInstance().advManager.sdkInitTime < ad_limitTime / 1000) {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv:未达到启动cd限制，无法展示广告");
              this.advSkip(data, { code: "", msg: "in start cd" });
              return;
          }
          this.isOpened = true;
          this.showData = data;
          this.bAutoCloseBannerFlag = false;
          let tag = data["tag"] || "";
          let style = data.layout || this.channelBannerStyle[tag] || this.channelBannerStyle["*"] || {};
          let systemInfo = qg$6.getSystemInfoSync();
          let windowWidth = systemInfo.windowWidth;
          let windowHeight = systemInfo.windowHeight;
          if (!this.bannerAd) {
              this.bannerAd = qg$6.createBannerAd({
                  adUnitId: this.arg,
              });
              let bannerWidth = Math.min(systemInfo.screenWidth, systemInfo.screenHeight);
              if (style) {
                  ULLog.console.log('ULAdvOppoQgBanner-showAdv systemInfo:', JSON.stringify(systemInfo));
                  let widthScale = style.width;
                  if (widthScale != undefined && widthScale >= 0) {
                      bannerWidth = bannerWidth * widthScale;
                  }
              }
              this.bannerAd.style.width = bannerWidth;
          }
          if (!this.bannerAd) {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv:广告对象创建异常，请检查参数是否正确：", this.arg);
              this.advSkip(data, { code: "", msg: "param error" });
              return;
          }
          this.bannerAd.offLoad(() => {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv-offLoad");
          });
          this.bannerAd.offError(() => {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv-offError");
          });
          this.bannerAd.offHide();
          this.bannerAd.offResize(() => {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv-offResize");
          });
          let isPlay = false;
          this.bannerAd.onLoad(() => {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv-onLoad");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              if (!isPlay && this.isOpened) {
                  isPlay = true;
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
              }
          });
          this.bannerAd.onHide(() => {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv-onHide");
              if (!this.bAutoCloseBannerFlag) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              this.isOpened = false;
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, this.showData);
          });
          this.bannerAd.onError((err) => {
              ULLog.console.log("ULAdvOppoQgBanner-showAdv-onError:", err);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(err.errCode), msg: err.errMsg });
              if (!this.isOpened && !this.isCallHide) {
                  this.advSkip(this.showData, { code: String(err.errCode), msg: err.errMsg });
              }
          });
          this.bannerAd.onResize(function (e) {
              ULLog.console.log('ULAdvOppoQgBanner-showAdv-onResize： ' + JSON.stringify(e));
              let left = (systemInfo.screenWidth - e.width) * 0.5;
              let top = systemInfo.screenHeight - e.height + 0.1;
              if (style) {
                  let x = style.x;
                  let y = style.y;
                  if (x != undefined && x >= 0 && x <= 1) {
                      left = (systemInfo.screenWidth - e.width) * x;
                      console.log("ULAdvOppoQgBanner.setBannerStyle bannerAd.onResize.newLeft", left);
                  }
                  if (y != undefined && y >= 0 && y <= 1) {
                      top = (1 - y) * (systemInfo.screenHeight - e.height);
                      console.log("ULAdvOppoQgBanner.setBannerStyle bannerAd.onResize.newTop", top);
                  }
              }
              this.bannerAd.style.left = left;
              this.bannerAd.style.top = top;
          });
          this.isCallHide = false;
          this.bannerAd.show();
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
      }
      closeAdv(data) {
          this.isOpened = false;
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data);
          ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
          if (this.bannerAd) {
              if (ULConfig.getConfig().i_sdk_oppoqg_banner_mode == 1) {
                  ULLog.console.log("ULAdvOppoQgBanner.closeAdv banner.hide()");
                  this.bAutoCloseBannerFlag = true;
                  this.isCallHide = true;
                  this.bannerAd.hide();
              }
              else {
                  ULLog.console.log("ULAdvOppoQgBanner.closeAdv banner.destroy()");
                  this.bannerAd.destroy();
                  this.bannerAd = null;
              }
          }
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgBanner-receiveInitState:初始化失败");
          }
      }
  }

  class ULAdvNativeAdLoadCycle {
      constructor() {
          this.onLoad = () => {
              ULLog.console.log("ULAdvNativeAdLoadCycle default onLoad");
          };
          this.onLoadFail = (errInfo) => {
              ULLog.console.log("ULAdvNativeAdLoadCycle default onLoadFail");
          };
      }
  }
  class ULAdvNativeAdShowCycle {
      constructor() {
          this.onShow = () => {
              ULLog.console.log("ULAdvNativeAdShowCycle default onShow");
          };
          this.onShowFail = (errInfo) => {
              ULLog.console.log("ULAdvNativeAdShowCycle default onShowFail");
          };
          this.onRefresh = () => {
              ULLog.console.log("ULAdvNativeAdShowCycle default onRefresh");
          };
          this.onClose = (isUserClick = true) => {
              ULLog.console.log("ULAdvNativeAdShowCycle default onClose isUserClick:", isUserClick);
          };
          this.onClick = () => {
              ULLog.console.log("ULAdvNativeAdShowCycle default onClick");
          };
      }
  }
  class ULAdvNativeData {
  }

  class ULAdvSDKNativeAd {
      constructor(parma) {
          this.showData = {};
          this.loadCycle = new ULAdvNativeAdLoadCycle();
          this.showCycle = new ULAdvNativeAdShowCycle();
          this.selfShowCycle = {
              onShow: () => {
                  if (!this.isShowing)
                      return;
                  this.showCall && this.showCall(this);
                  this.showCycle.onShow && this.showCycle.onShow();
              },
              onShowFail: (errInfo) => {
                  if (!this.isShowing)
                      return;
                  this.isShowing = false;
                  this.showCycle.onShowFail && this.showCycle.onShowFail(errInfo);
              },
              onRefresh: () => {
                  if (!this.isShowing)
                      return;
                  this.showCall && this.showCall(this);
                  this.showCycle.onRefresh && this.showCycle.onRefresh();
              },
              onClose: (isUserClick) => {
                  if (!this.isShowing)
                      return;
                  this.isShowing = false;
                  this.closeCall && this.closeCall(this);
                  this.showCycle.onClose && this.showCycle.onClose(isUserClick);
                  this.nativeData = null;
              },
              onClick: () => {
                  if (!this.isShowing)
                      return;
                  this.clickCall && this.clickCall(this);
                  this.showCycle.onClick && this.showCycle.onClick();
              }
          };
          this.loadCall = null;
          this.clickCall = null;
          this.showCall = null;
          this.closeCall = null;
          this.destroyCall = null;
          this.arg = parma.arg;
          this.type = parma.type;
          this.loadCall = parma.load;
          this.clickCall = parma.click;
          this.showCall = parma.show;
          this.closeCall = parma.close;
          this.destroyCall = parma.destroy;
      }
      click() {
          if (!this.isShowing)
              return;
          this.selfShowCycle.onClick && this.selfShowCycle.onClick();
          if (this.type == ULAdvNativeAdType.inter) {
              this.close(false);
          }
      }
      show(data) {
          if (this.isShowing)
              return;
          if (!this.loadCall || !this.showCall)
              return;
          this.isShowing = true;
          this.loadCall(this, {
              onLoad: (nativeData) => {
                  this.nativeData = nativeData;
                  this.loadCycle.onLoad && this.loadCycle.onLoad(nativeData);
                  this.showSDKView(data);
              },
              onLoadFail: (errInfo) => {
                  this.loadCycle.onLoadFail && this.loadCycle.onLoadFail(errInfo);
                  this.selfShowCycle.onShowFail(errInfo);
              }
          });
      }
      close(isUserClick) {
          if (!this.isShowing)
              return;
          this.closeSDKAd();
          this.selfShowCycle.onClose(isUserClick);
      }
      destroy() {
          this.isShowing = false;
          this.nativeData = null;
          this.destroyCall && this.destroyCall(this);
          this.loadCall = null;
          this.showCall = null;
          this.clickCall = null;
          this.closeCall = null;
          this.destroyCall = null;
      }
      refreshData(nativeData) {
          ULLog.console.log("ULAdvSDKNativeAd refreshData nativeData:", nativeData);
          if (this.isShowing) {
              this.nativeData = nativeData;
              this.showSDKView(this.showData, true);
          }
      }
      showSDKView(data, isRefreshing = false) {
          ULLog.console.log("ULAdvSDKNativeAd showSDKView nativeData:", this.nativeData);
          this.closeSDKAd();
          if (this.nativeData == null)
              return;
          this.showData = data;
          let obj = {
              nationData: this.nativeData,
              onShow: isRefreshing ? this.selfShowCycle.onRefresh : this.selfShowCycle.onShow,
              onError: (errMsg) => {
                  if (!isRefreshing) {
                      this.selfShowCycle.onShowFail({ code: "0", msg: errMsg });
                  }
              },
              onClick: this.selfShowCycle.onClick,
              onClose: (isUserClick) => {
                  if (isUserClick) {
                      this.selfShowCycle.onClose(isUserClick);
                  }
              }
          };
          switch (this.type) {
              case ULAdvNativeAdType.banner: {
                  let style = ULAdvNativeManager.getBannerStyle(data);
                  if (style == null) {
                      obj.onError('sdk自动刷新不包含此tag');
                      return;
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showNationBanner(obj, style);
                  break;
              }
              case ULAdvNativeAdType.embedded: {
                  let style = ULAdvNativeManager.getEmbeddStyle(data);
                  ULSdkManager.getInstance().moduleCheckerManager.showNationEmbedded(obj, style);
                  break;
              }
              case ULAdvNativeAdType.inter: {
                  ULSdkManager.getInstance().moduleCheckerManager.showNationInter(obj);
                  break;
              }
          }
      }
      closeSDKAd() {
          switch (this.type) {
              case ULAdvNativeAdType.banner: {
                  ULSdkManager.getInstance().moduleCheckerManager.closeNationBanner();
                  break;
              }
              case ULAdvNativeAdType.embedded: {
                  ULSdkManager.getInstance().moduleCheckerManager.closeNationEmbedded();
                  break;
              }
              case ULAdvNativeAdType.inter: {
                  ULSdkManager.getInstance().moduleCheckerManager.closeNationInter();
                  break;
              }
          }
      }
  }

  class ULAdvGameNativeAd {
      constructor(parma) {
          this.loadCycle = new ULAdvNativeAdLoadCycle();
          this.showCycle = new ULAdvNativeAdShowCycle();
          this.selfShowCycle = {
              onShow: () => {
                  if (!this.isShowing)
                      return;
                  this.showCall && this.showCall(this);
                  this.showCycle.onShow && this.showCycle.onShow();
              },
              onShowFail: (errInfo) => {
                  if (!this.isShowing)
                      return;
                  this.isShowing = false;
                  this.showCycle.onShowFail && this.showCycle.onShowFail(errInfo);
              },
              onRefresh: () => {
                  if (!this.isShowing)
                      return;
                  this.showCall && this.showCall(this);
                  this.showCycle.onRefresh && this.showCycle.onRefresh();
              },
              onClose: (isUserClick) => {
                  if (!this.isShowing)
                      return;
                  this.isShowing = false;
                  this.closeCall && this.closeCall(this);
                  this.showCycle.onClose && this.showCycle.onClose(isUserClick);
                  this.nativeData = null;
              },
              onClick: () => {
                  if (!this.isShowing)
                      return;
                  this.clickCall && this.clickCall(this);
                  this.showCycle.onClick && this.showCycle.onClick();
              }
          };
          this.loadCall = null;
          this.clickCall = null;
          this.showCall = null;
          this.closeCall = null;
          this.destroyCall = null;
          this.arg = parma.arg;
          this.type = parma.type;
          this.loadCall = parma.load;
          this.clickCall = parma.click;
          this.showCall = parma.show;
          this.closeCall = parma.close;
          this.destroyCall = parma.destroy;
      }
      click() {
          if (!this.isShowing)
              return;
          this.selfShowCycle.onClick && this.selfShowCycle.onClick();
      }
      show(data) {
          if (this.isShowing)
              return;
          if (!this.loadCall || !this.showCall)
              return;
          this.isShowing = true;
          this.loadCall(this, {
              onLoad: (nativeData) => {
                  this.nativeData = nativeData;
                  this.loadCycle.onLoad && this.loadCycle.onLoad(nativeData);
                  this.showGameView(data);
              },
              onLoadFail: (errInfo) => {
                  this.loadCycle.onLoadFail && this.loadCycle.onLoadFail(errInfo);
                  this.selfShowCycle.onShowFail(errInfo);
              }
          });
      }
      close(isUserClick) {
          if (!this.isShowing)
              return;
          this.selfShowCycle.onClose(isUserClick);
      }
      destroy() {
          this.isShowing = false;
          this.destroyCall && this.destroyCall(this);
          this.nativeData = null;
          this.loadCall = null;
          this.showCall = null;
          this.clickCall = null;
          this.closeCall = null;
          this.destroyCall = null;
      }
      showGameView(data) {
          if (!this.isShowing)
              return;
          let advType = this.type.toString();
          ULSdkManager.getInstance().advManager.responseOpenNativeAdvResult(data, advType, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_NATIVE_RESULT_MSG_SUCCESS, this.nativeData);
          this.selfShowCycle.onShow();
      }
  }

  var ULAdvNativeAdType;
  (function (ULAdvNativeAdType) {
      ULAdvNativeAdType["banner"] = "banner";
      ULAdvNativeAdType["inter"] = "inter";
      ULAdvNativeAdType["embedded"] = "embed";
  })(ULAdvNativeAdType || (ULAdvNativeAdType = {}));
  var ULAdvNativeAdShowType;
  (function (ULAdvNativeAdShowType) {
      ULAdvNativeAdShowType[ULAdvNativeAdShowType["game"] = 0] = "game";
      ULAdvNativeAdShowType[ULAdvNativeAdShowType["sdk"] = 1] = "sdk";
  })(ULAdvNativeAdShowType || (ULAdvNativeAdShowType = {}));
  class ULNativeItem {
      constructor(param) {
          this.showGameAdArray = [];
          this.showSdkAdArray = [];
          this.loadCycleList = [];
          this.lastExposureTime = 0;
          this.channelLoadCycle = new ULAdvNativeAdLoadCycle();
          this.arg = param.arg;
          this.channelAd = param.channelAd;
          this.hadClick = false;
          this.hadshown = false;
          this.isLoading = false;
          this.inUseNativeData = null;
          this.errInfo = null;
          this.remainRequestTime = 0;
          this.remainShowTime = this.adIntervals;
          this.remainShowNumber = this.allowShowNum;
          this.channelAd.init(this.arg);
      }
      get isShowing() {
          return this.showGameAdArray.length + this.showSdkAdArray.length > 0;
      }
      get adIntervals() {
          let config = ULConfig.getConfig();
          let refresh_intervals = config.i_sdk_native_autoRefresh_intervals || 30;
          let nation_autoRefresh_intervals = Number(refresh_intervals) || 30;
          return nation_autoRefresh_intervals;
      }
      get allowShowNum() {
          let config = ULConfig.getConfig();
          let allowShowNum = config.i_sdk_native_valid_show_count || 0;
          let trimAllowShowNum = Number(allowShowNum) || 2;
          return trimAllowShowNum;
      }
      get requestCD() {
          let config = ULConfig.getConfig();
          let nativeCD = config.i_sdk_adv_native_life_time || 0;
          let trimNativeCD = Number(nativeCD) / 1000 || 0;
          return Math.max(trimNativeCD, 15);
      }
      get exposureCd() {
          let config = ULConfig.getConfig();
          let exposureCd = config.i_sdk_adv_native_exposure_cd || 0;
          let trimExposureCd = Number(exposureCd) / 1000 || 0;
          return trimExposureCd;
      }
      get allowLoad() {
          if (this.showGameAdArray.length > 0)
              return false;
          if (this.remainRequestTime == 0) {
              if (this.hadClick)
                  return true;
              if (this.inUseNativeData == null)
                  return true;
              if (this.hadshown && this.remainShowTime == 0)
                  return true;
              if (this.hadshown && this.remainShowNumber == 0) {
                  let isAutoRefresh = ULAdvNativeManager.isAutoRefresh;
                  if (!this.isShowing && isAutoRefresh)
                      return true;
                  if (this.isShowing && !isAutoRefresh)
                      return true;
              }
          }
          return false;
      }
      performSecond() {
          this.remainRequestTime = Math.max(--this.remainRequestTime, 0);
          if (this.isShowing)
              this.remainShowTime = Math.max(--this.remainShowTime, 0);
          ULLog.console.log(`ULNativeItem allowLoad:${this.allowLoad},isShowing:${this.isShowing},rmRequestTime:${this.remainRequestTime},rmShowTime:${this.remainShowTime},rmShowNumber:${this.remainShowNumber}`);
      }
      refreshLoad() {
          this.loadChannelData({
              onLoad: (nativeData) => {
                  ULLog.console.log(`ULNativeItem refreshLoad onLoad:${nativeData}`);
                  this.showSdkAdArray.forEach(nativeAd => {
                      if (nativeAd instanceof ULAdvSDKNativeAd) {
                          nativeAd.refreshData(nativeData);
                      }
                  });
              },
              onLoadFail: (errInfo) => {
                  ULLog.console.log(`ULNativeItem refreshLoad onLoadFail:${errInfo}`);
                  this.showSdkAdArray.forEach(nativeAd => {
                      if (nativeAd instanceof ULAdvSDKNativeAd) {
                          nativeAd.refreshData(null);
                      }
                  });
              },
          });
      }
      load(cycle) {
          if (this.allowLoad || this.isLoading) {
              this.loadChannelData(cycle);
          }
          else if (this.inUseNativeData != null) {
              cycle.onLoad && cycle.onLoad(this.inUseNativeData);
          }
          else {
              cycle.onLoadFail && cycle.onLoadFail(this.errInfo || { code: "0", msg: this.isLoading ? "正在加载中" : "未知错误" });
          }
      }
      loadChannelData(cycle) {
          this.loadCycleList.push(cycle);
          if (this.isLoading)
              return;
          this.isLoading = true;
          this.remainRequestTime = this.requestCD;
          let timerId = setTimeout(() => {
              this.channelLoadCycle.onLoadFail({ code: "0", msg: "加载超时" });
          }, 20000);
          let baseLoadCycle = new ULAdvNativeAdLoadCycle();
          this.channelLoadCycle.onLoad = (nativeData) => {
              ULLog.console.log(`ULNativeItem onLoad nativeData:${nativeData}`);
              this.channelLoadCycle.onLoad = baseLoadCycle.onLoad;
              this.channelLoadCycle.onLoadFail = baseLoadCycle.onLoadFail;
              clearTimeout(timerId);
              this.isLoading = false;
              this.errInfo = null;
              this.inUseNativeData = nativeData;
              this.hadshown = false;
              this.hadClick = false;
              this.remainRequestTime = this.requestCD;
              this.remainShowTime = this.adIntervals;
              this.remainShowNumber = this.allowShowNum;
              while (this.loadCycleList.length) {
                  let cycleItem = this.loadCycleList.shift();
                  cycleItem.onLoad && cycleItem.onLoad(nativeData);
              }
          };
          this.channelLoadCycle.onLoadFail = (errInfo) => {
              ULLog.console.log("ULNativeItem channelLoadCycle onLoadFail:" + errInfo);
              this.channelLoadCycle.onLoad = baseLoadCycle.onLoad;
              this.channelLoadCycle.onLoadFail = baseLoadCycle.onLoadFail;
              clearTimeout(timerId);
              this.isLoading = false;
              this.errInfo = errInfo;
              this.inUseNativeData = null;
              while (this.loadCycleList.length) {
                  let cycleItem = this.loadCycleList.shift();
                  cycleItem.onLoadFail && cycleItem.onLoadFail(errInfo);
              }
          };
          this.channelAd.load(this.channelLoadCycle);
      }
      show(nativeAd, showType) {
          ULLog.console.log("ULNativeItem show");
          if (showType == ULAdvNativeAdShowType.game) {
              let index = this.showGameAdArray.indexOf(nativeAd);
              if (index == -1) {
                  this.showGameAdArray.push(nativeAd);
              }
          }
          else if (showType == ULAdvNativeAdShowType.sdk) {
              let index = this.showSdkAdArray.indexOf(nativeAd);
              if (index == -1) {
                  this.showSdkAdArray.push(nativeAd);
              }
          }
          this.remainShowNumber = Math.max(--this.remainShowNumber, 0);
          if (!this.hadshown || ULTools.time() - this.lastExposureTime > this.exposureCd) {
              this.channelAd.show();
              this.lastExposureTime = ULTools.time();
          }
          this.hadshown = true;
      }
      click() {
          this.channelAd.click();
          this.hadClick = true;
          this.remainRequestTime = 0;
      }
      close(nativeAd, showType) {
          ULLog.console.log(`ULNativeItem close `);
          if (showType == ULAdvNativeAdShowType.game) {
              let index = this.showGameAdArray.indexOf(nativeAd);
              if (index > -1) {
                  this.showGameAdArray.splice(index, 1);
              }
          }
          else if (showType == ULAdvNativeAdShowType.sdk) {
              let index = this.showSdkAdArray.indexOf(nativeAd);
              if (index > -1) {
                  this.showSdkAdArray.splice(index, 1);
              }
          }
      }
      destroy() {
      }
  }
  class ULAdvNativeManager {
      constructor() {
          this.timerId = null;
          this.nativeItemCache = {};
          this.showBannerAutoRefreshTags = null;
          let self = this;
          this.timerId = setInterval(function () {
              for (let key in self.nativeItemCache) {
                  let nativeItem = self.nativeItemCache[key];
                  self.showOneSecond(nativeItem);
              }
          }, 1000);
      }
      static getInstance() {
          if (!this.instance) {
              this.instance = new ULAdvNativeManager();
          }
          return this.instance;
      }
      get isAutoRefresh() {
          let config = ULConfig.getConfig();
          return config.i_sdk_native_autoRefresh_mode == 1;
      }
      static get isAutoRefresh() {
          return ULAdvNativeManager.getInstance().isAutoRefresh;
      }
      get channelBannerStyle() {
          if (this.showBannerAutoRefreshTags == null) {
              let config = ULConfig.getConfig();
              this.showBannerAutoRefreshTags = {};
              let banner_autoRefresh_tags = config.t_sdk_show_native_banner_autoRefresh_tags || [];
              let banner_autoRefresh_tags_style_setting = config.t_sdk_show_native_banner_autoRefresh_tags_style_setting || {};
              for (let index = 0; index < banner_autoRefresh_tags.length; index++) {
                  let tag = banner_autoRefresh_tags[index];
                  let style = banner_autoRefresh_tags_style_setting[tag] || banner_autoRefresh_tags_style_setting["*"] || {};
                  this.showBannerAutoRefreshTags[tag] = style;
              }
          }
          return this.showBannerAutoRefreshTags;
      }
      showOneSecond(nativeItem) {
          nativeItem.performSecond();
          if (!this.isAutoRefresh)
              return;
          if (nativeItem.allowLoad)
              nativeItem.refreshLoad();
      }
      static createNativeAd(channelAd, parma) {
          return ULAdvNativeManager.getInstance().createNativeAd(channelAd, parma);
      }
      static isShowing(arg) {
          if (this.instance.nativeItemCache[arg]) {
              return this.instance.nativeItemCache[arg].isShowing;
          }
          return false;
      }
      createNativeAd(channelAd, parma) {
          let nativeAd = null;
          if (!this.nativeItemCache[parma.arg]) {
              this.nativeItemCache[parma.arg] = new ULNativeItem({
                  arg: parma.arg,
                  channelAd: new channelAd()
              });
          }
          let item = this.nativeItemCache[parma.arg];
          let trimParma = {
              arg: parma.arg,
              type: parma.type,
              load: (nativeAd, loadCycle) => {
                  item.load(loadCycle);
              },
              click: (nativeAd) => {
                  item.click();
              },
              show: (nativeAd) => {
                  item.show(nativeAd, parma.showType);
              },
              close: (nativeAd) => {
                  item.close(nativeAd, parma.showType);
              },
              destroy: (nativeAd) => {
                  item.destroy();
                  delete this.nativeItemCache[item.arg];
              }
          };
          if (parma.showType == ULAdvNativeAdShowType.game) {
              ULLog.console.log("ULAdvNativeManager-createNativeAd-ULAdvGameNativeAd");
              nativeAd = new ULAdvGameNativeAd(trimParma);
          }
          else {
              ULLog.console.log("ULAdvNativeManager-createNativeAd-ULAdvSDKNativeAd");
              nativeAd = new ULAdvSDKNativeAd(trimParma);
          }
          return nativeAd;
      }
      static getBannerStyle(data) {
          let advId = data["advId"];
          let tag = data["tag"] || advId || "";
          let channelBannerStyle = ULAdvNativeManager.instance.channelBannerStyle;
          ULLog.console.log("ULAdvNativeManager data.layout:", data.layout);
          ULLog.console.log(`ULAdvNativeManager this.channelBannerStyle[${tag}]:`, channelBannerStyle[tag]);
          let style = data.layout || channelBannerStyle[tag] || null;
          if (style == null || style == undefined) {
              return null;
          }
          let trimStyle = {
              x: !isNaN(Number(style.x)) ? Number(style.x) : 0.5,
              y: !isNaN(Number(style.y)) ? Number(style.y) : 0,
              width: !isNaN(Number(style.width)) ? Number(style.width) : 1,
              height: !isNaN(Number(style.height)) ? Number(style.height) : 1,
          };
          return trimStyle;
      }
      static getEmbeddStyle(data) {
          let style = data.layout || {};
          let trimStyle = {
              x: !isNaN(Number(style.x)) ? Number(style.x) : 0.5,
              y: !isNaN(Number(style.y)) ? Number(style.y) : 0.5,
              width: !isNaN(Number(style.width)) ? Number(style.width) : 0.4,
              height: !isNaN(Number(style.height)) ? Number(style.height) : 0.2,
          };
          ULLog.console.log("ULAdvNativeManager data.layout:", data.layout);
          ULLog.console.log("ULAdvNativeManager data.trimStyle:", trimStyle);
          return trimStyle;
      }
  }
  ULAdvNativeManager.isPreLoad = true;

  let qg$7 = window["qg"];
  class ULAdvOppoQgNativeItem {
      set inUseData(inUseData) {
          if (this._inUseData == inUseData) {
              return;
          }
          this._inUseData = inUseData;
      }
      get inUseData() {
          return this._inUseData;
      }
      init(arg) {
          this.arg = arg;
      }
      load(cycle) {
          return;
          let platformVersionCode = qg$7.getSystemInfoSync().platformVersionCode;
          if (platformVersionCode < 1051) {
              ULLog.console.warn("ULAdvOppoQgNativeItem.load:原生api最低支持1051");
              cycle.onLoadFail && cycle.onLoadFail({ code: "", msg: "minPlatformVersion unsupport" });
              return;
          }
          if (this.nativeAd) {
              this.nativeAd.destroy();
              this.nativeAd = null;
          }
          this.nativeAd = qg$7.createNativeAd({
              adUnitId: this.arg
          });
          this.nativeAd.onLoad((res) => {
              ULLog.console.log('ULAdvOppoQgNativeItem-onLoad:', res);
              if (res && res.adList) {
                  let adData = res.adList.pop();
                  this.inUseData = adData;
                  let respone = {
                      title: adData.title || "",
                      desc: adData.desc || "",
                      icon: adData.icon || "",
                      url: adData.imgUrlList[0] || adData.iconUrlList[0] || "",
                      targetTitle: adData.clickBtnTxt || "点击查看",
                      adSource: adData.adSource || "",
                  };
                  cycle.onLoad && cycle.onLoad(respone);
              }
              else {
                  cycle.onLoadFail && cycle.onLoadFail({ code: "", msg: "no ad" });
              }
          });
          this.nativeAd.onError((err) => {
              ULLog.console.log('ULAdvOppoQgNativeItem-onError err:', err);
              let errInfo = {
                  code: String(err.errCode),
                  msg: err.errMsg
              };
              cycle.onLoadFail && cycle.onLoadFail(errInfo);
          });
          this.nativeAd.load();
      }
      click() {
          ULLog.console.log('ULAdvOppoQgNativeItem-click');
          if (this.nativeAd) {
              this.nativeAd.reportAdClick({
                  adId: this.inUseData.adId
              });
          }
      }
      show() {
          ULLog.console.log('ULAdvOppoQgNativeItem-show');
          if (this.nativeAd) {
              this.nativeAd.reportAdShow({
                  adId: this.inUseData.adId
              });
          }
      }
  }

  let qg$8 = window["qg"];
  class ULAdvOppoQgNativeBase extends ULAdvNativeObjectBase {
      constructor(arg, advType, templateItemName) {
          super(arg, advType, templateItemName);
          this.className = "ULAdvOppoQgNativeBase";
          this.statisticsAdvertiser = ULAdvOppoQg.NATIVE_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgNativeBase-onDisposeModule arg:", this.arg);
      }
      closeNativeAdv(e) {
          let data = e.data;
          let advId = data.advId;
          if (!this.showData || !this.showData.advId || this.showData.advId != advId) {
              return;
          }
          ULLog.console.log("ULAdvOppoQgNativeBase-closeNativeAdv");
          this.nativeAd.close(data.closeType == 1);
          ULSdkManager.getInstance().advManager.responseCloseNativeAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
      }
      clickNativeAdv(e) {
          let data = e.data;
          let advId = data.advId;
          if (!this.showData || !this.showData.advId || this.showData.advId != advId) {
              return;
          }
          ULLog.console.log("ULAdvOppoQgNativeBase-clickNativeAdv");
          this.nativeAd.click();
          this.nativeAd.close(false);
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgNativeBase-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          let type = this.advType == "banner" ? ULAdvNativeAdType.banner : ULAdvNativeAdType.inter;
          ULLog.console.log("ULAdvOppoQgNativeBase-initAdv:", type);
          this.nativeAd = ULAdvNativeManager.createNativeAd(ULAdvOppoQgNativeItem, {
              arg: this.arg,
              type: type,
              showType: ULAdvNativeAdShowType.game
          });
      }
      loadAdv() {
      }
      showAdv(showData) {
          ULLog.console.log("ULAdvOppoQgNativeBase-showAdv:");
          let ad_limitTime = ULConfig.getConfig().i_sdk_oppoqg_ad_ecd;
          let requestTime = ULTools.time();
          if (requestTime - ULSdkManager.getInstance().advManager.sdkInitTime < ad_limitTime / 1000) {
              ULLog.console.log("ULAdvOppoQgNativeBase.onShowNativeAdv:未达到启动cd限制，无法展示广告");
              this.advSkip(showData, { code: "", msg: "in start cd" });
              return;
          }
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              console.warn("ULAdvOppoQgNativeBase-showAdv:广告未加载就绪,直接跳过当前广告展示");
              this.advSkip(showData, { code: "", msg: "adv not ready" });
              return;
          }
          this.showData = showData;
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.nativeAd.showCycle.onShowFail = ((errInfo) => {
              ULLog.console.log("ULAdvOppoQgNativeBase-showAdv-onError:", errInfo);
              if (this.isOpened) {
                  this.isOpened = false;
                  this.advSkip(this.showData, errInfo);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, errInfo);
              }
          });
          this.nativeAd.showCycle.onShow = (() => {
              ULLog.console.log("ULAdvOppoQgNativeBase-showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, showData, this.nativeAd.nativeData);
          });
          this.nativeAd.showCycle.onClick = (() => {
              ULLog.console.log("ULAdvOppoQgNativeBase-showAdv-onClick");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClick(this.advKey, "点击", showData, { title: this.nativeAd.nativeData ? this.nativeAd.nativeData.title : "" });
          });
          this.nativeAd.showCycle.onClose = ((isUserClick) => {
              ULLog.console.log("ULAdvOppoQgNativeBase-showAdv-onClose");
              this.isOpened = false;
              this.nativeShowState = false;
              if (isUserClick == true) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, showData, { title: this.nativeAd.nativeData ? this.nativeAd.nativeData.title : "" });
          });
          this.isOpened = true;
          this.nativeShowState = true;
          this.nativeAd.show(showData);
      }
      closeAdv(data) {
          ULLog.console.log("ULAdvOppoQgNativeBase-closeAdv");
          this.nativeAd.close(data.closeType == 1);
          ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgNativeBase-receiveInitState:初始化失败");
          }
      }
  }

  class ULAdvOppoQgNativeBanner extends ULAdvOppoQgNativeBase {
      constructor(arg) {
          super(arg, typeExp.banner, "ULAdvOppoQgNativeBanner_" + arg);
      }
  }

  class ULAdvOppoQgNativeInter extends ULAdvOppoQgNativeBase {
      constructor(arg) {
          super(arg, typeExp.inter, "ULAdvOppoQgNativeInter_" + arg);
          this.statisticsType = oldTypeExp.interstitial;
      }
  }

  class ULAdvOppoQgNativeEmbed extends ULAdvOppoQgNativeBase {
      constructor(arg) {
          super(arg, typeExp.embed, "ULAdvOppoQgNativeEmbed_" + arg);
          this.statisticsType = oldTypeExp.embedded;
      }
  }

  let qg$9 = window["qg"];
  class ULAdvOppoQgAutoNativeBanner extends ULAdvNativeObjectBase {
      constructor(arg) {
          super(arg, typeExp.banner, "ULAdvOppoQgAutoNativeBanner" + "_" + arg);
          this.className = "ULAdvOppoQgAutoNativeBanner";
          this.statisticsAdvertiser = ULAdvOppoQg.NATIVE_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgAutoNativeBanner-onDisposeModule arg:", this.arg);
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgAutoNativeBanner-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          this.nativeAd = ULAdvNativeManager.createNativeAd(ULAdvOppoQgNativeItem, {
              arg: this.arg,
              type: ULAdvNativeAdType.banner,
              showType: ULAdvNativeAdShowType.sdk
          });
      }
      loadAdv() {
      }
      showAdv(data) {
          ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv");
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv:广告未加载就绪，直接跳过");
              this.advSkip(data, { code: "", msg: "adv not ready" });
              return;
          }
          let ad_limitTime = ULConfig.getConfig().i_sdk_oppoqg_ad_ecd;
          let requestTime = ULTools.time();
          if (requestTime - ULSdkManager.getInstance().advManager.sdkInitTime < ad_limitTime / 1000) {
              ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv:未达到启动cd限制，无法展示广告");
              this.advSkip(data, { code: "", msg: "in start cd" });
              return;
          }
          this.showData = data;
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.nativeAd.showCycle.onShowFail = ((errInfo) => {
              ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv-onError:", errInfo);
              if (this.isOpened) {
                  this.isOpened = false;
                  this.advSkip(this.showData, errInfo);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, errInfo);
              }
          });
          this.nativeAd.showCycle.onShow = (() => {
              ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, data, this.nativeAd.nativeData);
          });
          this.nativeAd.showCycle.onClick = (() => {
              ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv-onClick");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClick(this.advKey, "点击", data, { title: this.nativeAd.nativeData ? this.nativeAd.nativeData.title : "" });
          });
          this.nativeAd.showCycle.onClose = ((isUserClick) => {
              ULLog.console.log("ULAdvOppoQgAutoNativeBanner-showAdv-onClose");
              this.isOpened = false;
              this.nativeShowState = false;
              if (isUserClick == true) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data, { title: this.nativeAd.nativeData ? this.nativeAd.nativeData.title : "" });
          });
          this.isOpened = true;
          this.nativeShowState = true;
          this.nativeAd.show(data);
      }
      closeAdv(data) {
          ULLog.console.log("ULAdvOppoQgAutoNativeBanner-closeAdv");
          this.nativeAd.close(false);
          ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
      }
      closeNativeAdv(e) {
          ULLog.console.log("ULAdvOppoQgAutoNativeBanner-closeNativeAdv");
      }
      clickNativeAdv(e) {
          ULLog.console.log("ULAdvOppoQgAutoNativeBanner-clickNativeAdv");
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgAutoNativeBanner-receiveInitState:初始化失败");
          }
      }
  }

  let qg$a = window["qg"];
  class ULAdvOppoQgAutoNativeInter extends ULAdvNativeObjectBase {
      constructor(arg) {
          super(arg, typeExp.inter, "ULAdvOppoQgAutoNativeInter" + "_" + arg);
          this.className = "ULAdvOppoQgAutoNativeInter";
          this.statisticsAdvertiser = ULAdvOppoQg.NATIVE_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgAutoNativeInter-onDisposeModule arg:", this.arg);
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgAutoNativeInter-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          this.nativeAd = ULAdvNativeManager.createNativeAd(ULAdvOppoQgNativeItem, {
              arg: this.arg,
              type: ULAdvNativeAdType.inter,
              showType: ULAdvNativeAdShowType.sdk
          });
      }
      loadAdv() {
      }
      showAdv(data) {
          console.warn("ULAdvOppoQgAutoNativeInter-showAdv");
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              ULLog.console.log("ULAdvOppoQgAutoNativeInter-showAdv:广告未加载就绪，直接跳过");
              this.advSkip(data, { code: "", msg: "adv not ready" });
              return;
          }
          let ad_limitTime = ULConfig.getConfig().i_sdk_oppoqg_ad_ecd;
          let requestTime = ULTools.time();
          if (requestTime - ULSdkManager.getInstance().advManager.sdkInitTime < ad_limitTime / 1000) {
              ULLog.console.log("ULAdvOppoQgAutoNativeInter-showAdv:未达到启动cd限制，无法展示广告");
              this.advSkip(data, { code: "", msg: "in start cd" });
              return;
          }
          this.showData = data;
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.nativeAd.showCycle.onShowFail = ((errInfo) => {
              ULLog.console.log("ULAdvOppoQgAutoNativeInter-showAdv-onError:", errInfo);
              if (this.isOpened) {
                  this.isOpened = false;
                  this.advSkip(this.showData, errInfo);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, errInfo);
              }
          });
          this.nativeAd.showCycle.onShow = (() => {
              ULLog.console.log("ULAdvOppoQgAutoNativeInter-showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, data, this.nativeAd.nativeData);
          });
          this.nativeAd.showCycle.onClick = (() => {
              ULLog.console.log("ULAdvOppoQgAutoNativeInter-showAdv-onClick");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClick(this.advKey, "点击", data, { title: this.nativeAd.nativeData ? this.nativeAd.nativeData.title : "" });
          });
          this.nativeAd.showCycle.onClose = ((isUserClick) => {
              ULLog.console.log("ULAdvOppoQgAutoNativeInter-showAdv-onClose isUserClick：", isUserClick);
              if (isUserClick == true) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              this.isOpened = false;
              this.nativeShowState = false;
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data);
          });
          this.isOpened = true;
          this.nativeShowState = true;
          this.nativeAd.show(data);
      }
      closeAdv(data) {
          ULLog.console.log("ULAdvOppoQgAutoNativeInter-closeAdv");
          this.nativeAd.close(false);
          ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
      }
      closeNativeAdv(e) {
          ULLog.console.log("ULAdvOppoQgAutoNativeInter-closeNativeAdv");
      }
      clickNativeAdv(e) {
          ULLog.console.log("ULAdvOppoQgAutoNativeInter-clickNativeAdv");
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgAutoNativeInter-receiveInitState:初始化失败");
          }
      }
  }

  let qg$b = window["qg"];
  class ULAdvOppoQgAutoNativeEmbed extends ULAdvNativeObjectBase {
      constructor(arg) {
          super(arg, typeExp.embed, "ULAdvOppoQgAutoNativeEmbed" + "_" + arg);
          this.className = "ULAdvOppoQgAutoNativeEmbed";
          this.statisticsAdvertiser = ULAdvOppoQg.NATIVE_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-onDisposeModule arg:", this.arg);
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          this.nativeAd = ULAdvNativeManager.createNativeAd(ULAdvOppoQgNativeItem, {
              arg: this.arg,
              type: ULAdvNativeAdType.embedded,
              showType: ULAdvNativeAdShowType.sdk
          });
      }
      loadAdv() {
      }
      showAdv(data) {
          console.warn("ULAdvOppoQgAutoNativeEmbed-showAdv");
          if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
              ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-showAdv:广告未加载就绪，直接跳过");
              this.advSkip(data, { code: "", msg: "adv not ready" });
              return;
          }
          let ad_limitTime = ULConfig.getConfig().i_sdk_oppoqg_ad_ecd;
          let requestTime = ULTools.time();
          if (requestTime - ULSdkManager.getInstance().advManager.sdkInitTime < ad_limitTime / 1000) {
              ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-showAdv:未达到启动cd限制，无法展示广告");
              this.advSkip(data, { code: "", msg: "in start cd" });
              return;
          }
          this.showData = data;
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.nativeAd.showCycle.onShowFail = ((errInfo) => {
              ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-showAdv-onError:", errInfo);
              if (this.isOpened) {
                  this.isOpened = false;
                  this.advSkip(this.showData, errInfo);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, errInfo);
              }
          });
          this.nativeAd.showCycle.onShow = (() => {
              ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, data, this.nativeAd.nativeData);
          });
          this.nativeAd.showCycle.onClick = (() => {
              ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-showAdv-onClick");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClick(this.advKey, "点击", data, { title: this.nativeAd.nativeData ? this.nativeAd.nativeData.title : "" });
          });
          this.nativeAd.showCycle.onClose = ((isUserClick) => {
              ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-showAdv-onClose isUserClick：", isUserClick);
              if (isUserClick == true) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              this.isOpened = false;
              this.nativeShowState = false;
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data);
          });
          this.isOpened = true;
          this.nativeShowState = true;
          this.nativeAd.show(data);
      }
      closeAdv(data) {
          ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-closeAdv");
          this.nativeAd.close(false);
          ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
      }
      closeNativeAdv(e) {
          ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-closeNativeAdv");
      }
      clickNativeAdv(e) {
          ULLog.console.log("ULAdvOppoQgAutoNativeEmbed-clickNativeAdv");
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgAutoNativeEmbed-receiveInitState:初始化失败");
          }
      }
  }

  class ULAdvCustomAdStyle {
      constructor() {
          this.x = 0.5;
          this.y = 0;
          this.width = 1;
          this.height = 1;
      }
  }
  class ULAdvCustomAdLoadCycle {
      constructor() {
          this.onLoad = () => {
              ULLog.console.log("ULAdvCustomAdLoadCycle default onLoad");
          };
          this.onLoadFail = (errInfo) => {
              ULLog.console.log("ULAdvCustomAdLoadCycle default onLoadFail");
          };
      }
  }
  class ULAdvCustomAdShowCycle {
      constructor() {
          this.onShow = () => {
              ULLog.console.log("ULAdvCustomAdShowCycle default onShow");
          };
          this.onShowFail = (errInfo) => {
              ULLog.console.log("ULAdvCustomAdShowCycle default onShowFail");
          };
          this.onRefresh = () => {
              ULLog.console.log("ULAdvCustomAdShowCycle default onRefresh");
          };
          this.onClose = (isUserClick = true) => {
              ULLog.console.log("ULAdvCustomAdShowCycle default onClose isUserClick:", isUserClick);
          };
          this.onClick = () => {
              ULLog.console.log("ULAdvCustomAdShowCycle default onClick");
          };
      }
  }

  class ULAdvCustomNormalAd {
      constructor(parma) {
          this.showCycle = new ULAdvCustomAdShowCycle();
          this.showCall = null;
          this.closeCall = null;
          this.destroyCall = null;
          this.arg = parma.arg;
          this.showCall = parma.show;
          this.closeCall = parma.close;
          this.destroyCall = parma.destroy;
      }
      show(data) {
          if (this.isShowing)
              return;
          if (!this.showCall)
              return;
          this.isShowing = true;
          this.showCall(data, {
              onShow: () => {
                  this.showCycle.onShow && this.showCycle.onShow();
              },
              onShowFail: (errInfo) => {
                  this.isShowing = false;
                  this.showCycle.onShowFail && this.showCycle.onShowFail(errInfo);
              },
              onRefresh: () => {
                  this.showCycle.onRefresh && this.showCycle.onRefresh();
              },
              onClose: (isUserClick) => {
                  this.isShowing = false;
                  this.showCycle.onClose && this.showCycle.onClose(isUserClick);
              },
              onClick: () => {
                  this.showCycle.onClick && this.showCycle.onClick();
              }
          });
      }
      close() {
          if (!this.isShowing)
              return;
          this.closeCall && this.closeCall();
      }
      destroy() {
          this.destroyCall && this.destroyCall();
          this.showCall = null;
          this.closeCall = null;
          this.destroyCall = null;
      }
  }

  class ULAdvCustomManager {
      constructor() {
          this.timerId = null;
          this.customItemCache = {};
          let self = this;
          this.timerId = setInterval(function () {
              for (let key in self.customItemCache) {
                  let customItem = self.customItemCache[key];
                  self.showOneSecond(customItem);
              }
          }, 1000);
      }
      get isAutoRefresh() {
          let config = ULConfig.getConfig();
          return !!config.i_sdk_custom_autoRefresh_mode;
      }
      get channelCustomStyle() {
          let config = ULConfig.getConfig();
          return config.t_sdk_adv_custom_args_style_setting || {};
      }
      static get isAutoRefresh() {
          return ULAdvCustomManager.getInstance().isAutoRefresh;
      }
      static getInstance() {
          if (!this.instance) {
              this.instance = new ULAdvCustomManager();
          }
          return this.instance;
      }
      showOneSecond(customItem) {
          customItem.performSecond();
          if (!this.isAutoRefresh)
              return;
          if (customItem.allowLoad) {
              customItem.refresh();
          }
      }
      static createCustomAd(channelAd, parma, allowRefreshShowing = true) {
          return ULAdvCustomManager.getInstance().createCustomAd(channelAd, parma, allowRefreshShowing);
      }
      createCustomAd(channelAd, parma, allowRefreshShowing = true) {
          let customAd = null;
          let item = this.customItemCache[parma.arg];
          if (!!!item) {
              item = new ULCustomItem({
                  arg: parma.arg,
                  channelAd: new channelAd()
              });
              this.customItemCache[parma.arg] = item;
          }
          customAd = new ULAdvCustomNormalAd({
              arg: item.arg,
              show: (data, cycle) => {
                  let advId = data["advId"];
                  let tag = data["tag"] || advId || "";
                  ULLog.console.log("ULAdvCustomManager this.channelCustomStyle[tag]:", this.channelCustomStyle[tag]);
                  ULLog.console.log("ULAdvCustomManager this.channelCustomStyle[arg]:", this.channelCustomStyle[item.arg]);
                  ULLog.console.log("ULAdvCustomManager this.channelCustomStyle[*]:", this.channelCustomStyle["*"]);
                  let style = this.channelCustomStyle[tag] || this.channelCustomStyle[item.arg] || this.channelCustomStyle["*"] || {};
                  let trimStyle = {
                      x: !isNaN(Number(style.x)) ? Number(style.x) : 0.5,
                      y: !isNaN(Number(style.y)) ? Number(style.y) : 0,
                      width: !isNaN(Number(style.width)) ? Number(style.width) : 1,
                      height: !isNaN(Number(style.height)) ? Number(style.height) : 0.5,
                  };
                  item.allowRefreshShowing = allowRefreshShowing;
                  item.show(trimStyle, cycle);
              },
              close: () => {
                  item.close();
              },
              destroy: () => {
                  item.destroy();
                  delete this.customItemCache[item.arg];
              }
          });
          return customAd;
      }
  }
  class ULCustomItem {
      constructor(param) {
          this.allowRefreshShowing = true;
          this.showStyle = { x: 0.5, y: 0, width: 1, height: 1 };
          this.showCycleList = [];
          this.loadCycleList = [];
          this.hadShowRulst = false;
          this.channelShowCycle = {
              onShow: () => {
                  ULLog.console.log("ULCustomItem.channelShow channelShowCycle onShow");
                  if (!this.isShowing) {
                      this.close();
                      return;
                  }
                  this.hadShowRulst = true;
                  this.hadshown = true;
                  this.remainShowNumber = Math.max(--this.remainShowNumber, 0);
                  for (let i = 0; i < this.showCycleList.length; i++) {
                      let cycleItem = this.showCycleList[i];
                      cycleItem.onShow && cycleItem.onShow();
                  }
              },
              onShowFail: (errInfo) => {
                  ULLog.console.log("ULCustomItem.channelShow channelShowCycle onShowFail");
                  if (!this.isShowing) {
                      return;
                  }
                  this.hadShowRulst = true;
                  this.isShowing = false;
                  this.loadSuccess = false;
                  this.errInfo = errInfo;
                  for (let i = 0; i < this.showCycleList.length; i++) {
                      let cycleItem = this.showCycleList.shift();
                      cycleItem.onShowFail && cycleItem.onShowFail(errInfo);
                  }
              },
              onRefresh: (errInfo = null) => {
                  if (!this.isShowing) {
                      return;
                  }
                  this.hadShowRulst = true;
                  ULLog.console.log("ULCustomItem.channelShow channelShowCycle refresh onRefresh err:", errInfo);
                  if (errInfo) {
                      return;
                  }
                  this.hadshown = true;
                  this.remainShowNumber = Math.max(--this.remainShowNumber, 0);
                  for (let i = 0; i < this.showCycleList.length; i++) {
                      let cycleItem = this.showCycleList[i];
                      cycleItem.onRefresh && cycleItem.onRefresh();
                  }
              },
              onClose: (isUserClick = false) => {
                  if (!this.isShowing) {
                      return;
                  }
                  if (this.isLoading && isUserClick) {
                      return;
                  }
                  if (!this.hadshown && isUserClick) {
                      return;
                  }
                  if (!this.hadShowRulst)
                      return;
                  ULLog.console.log("ULCustomItem.channelShow channelShowCycle onClose");
                  this.isShowing = false;
                  while (this.showCycleList.length) {
                      let cycleItem = this.showCycleList.shift();
                      cycleItem.onClose && cycleItem.onClose(isUserClick);
                  }
              },
              onClick: () => {
                  if (!this.isShowing) {
                      return;
                  }
                  ULLog.console.log("ULCustomItem.channelShow channelShowCycle onClick");
                  this.hadClick = true;
                  this.remainRequestTime = 0;
                  for (let i = 0; i < this.showCycleList.length; i++) {
                      let cycleItem = this.showCycleList[i];
                      cycleItem.onClick && cycleItem.onClick();
                  }
              }
          };
          this.channelLoadCycle = new ULAdvCustomAdLoadCycle();
          this.arg = param.arg;
          this.channelAd = param.channelAd;
          this.isShowing = false;
          this.hadClick = false;
          this.hadshown = false;
          this.isLoading = false;
          this.loadSuccess = false;
          this.remainRequestTime = 0;
          this.remainShowTime = this.adIntervals;
          this.remainShowNumber = this.allowShowNum;
          this.channelAd.init(this.arg);
      }
      get adIntervals() {
          let config = ULConfig.getConfig();
          let adIntervals = config.i_sdk_custom_refresh_intervals || 30;
          return Number(adIntervals) || 30;
      }
      get allowShowNum() {
          let config = ULConfig.getConfig();
          let allowShowNum = config.i_sdk_adv_custom_valid_show_count || 0;
          let trimAllowShowNum = Number(allowShowNum) || 2;
          return trimAllowShowNum;
      }
      get requestCD() {
          let config = ULConfig.getConfig();
          let customCD = config.i_sdk_adv_custom_cd || 0;
          let trimCustomCD = Number(customCD) / 1000 || 0;
          return Math.max(trimCustomCD, 15);
      }
      get allowLoad() {
          if (this.remainRequestTime == 0) {
              if (this.hadClick)
                  return true;
              if (!this.loadSuccess)
                  return true;
              if (this.hadshown && this.remainShowTime == 0)
                  return true;
              if (this.hadshown && this.remainShowNumber == 0) {
                  let isAutoRefresh = ULAdvCustomManager.isAutoRefresh;
                  if (!this.isShowing && isAutoRefresh && this.allowRefreshShowing)
                      return true;
                  if (this.isShowing && !isAutoRefresh)
                      return true;
              }
          }
          return false;
      }
      performSecond() {
          this.remainRequestTime = Math.max(--this.remainRequestTime, 0);
          if (this.isShowing) {
              this.remainShowTime = Math.max(--this.remainShowTime, 0);
          }
          ULLog.console.log("ULCustomItem:", {
              allowLoad: this.allowLoad,
              isShowing: this.isShowing,
              remainRequestTime: this.remainRequestTime,
              remainShowTime: this.remainShowTime,
              remainShowNumber: this.remainShowNumber,
          });
      }
      loadData(cycle) {
          this.loadCycleList.push(cycle);
          if (this.isLoading)
              return;
          this.isLoading = true;
          this.remainRequestTime = this.requestCD;
          let timerId = setTimeout(() => {
              this.channelLoadCycle.onLoadFail({ code: "0", msg: "加载超时" });
          }, 20000);
          let baseLoadCycle = new ULAdvCustomAdLoadCycle();
          this.channelLoadCycle.onLoad = () => {
              ULLog.console.log("ULCustomItem channelLoadCycle onLoad");
              this.channelLoadCycle.onLoad = baseLoadCycle.onLoad;
              this.channelLoadCycle.onLoadFail = baseLoadCycle.onLoadFail;
              clearTimeout(timerId);
              this.isLoading = false;
              this.errInfo = null;
              this.loadSuccess = true;
              this.hadshown = false;
              this.hadClick = false;
              this.remainRequestTime = this.requestCD;
              this.remainShowTime = this.adIntervals;
              this.remainShowNumber = this.allowShowNum;
              while (this.loadCycleList.length) {
                  let cycleItem = this.loadCycleList.shift();
                  cycleItem.onLoad && cycleItem.onLoad();
              }
          };
          this.channelLoadCycle.onLoadFail = (errInfo) => {
              ULLog.console.log("ULCustomItem channelLoadCycle onLoadFail:" + errInfo);
              this.channelLoadCycle.onLoad = baseLoadCycle.onLoad;
              this.channelLoadCycle.onLoadFail = baseLoadCycle.onLoadFail;
              clearTimeout(timerId);
              this.isLoading = false;
              this.errInfo = errInfo;
              this.loadSuccess = false;
              while (this.loadCycleList.length) {
                  let cycleItem = this.loadCycleList.shift();
                  cycleItem.onLoadFail && cycleItem.onLoadFail(errInfo);
              }
          };
          this.channelAd.load(this.channelLoadCycle);
      }
      channelShow(isRefresh = false) {
          if (!this.isShowing)
              return;
          this.hadShowRulst = false;
          this.channelAd.show(this.showStyle, {
              onShow: isRefresh ? this.channelShowCycle.onRefresh : this.channelShowCycle.onShow,
              onShowFail: isRefresh ? this.channelShowCycle.onRefresh : this.channelShowCycle.onShowFail,
              onRefresh: this.channelShowCycle.onRefresh,
              onClose: this.channelShowCycle.onClose,
              onClick: this.channelShowCycle.onClick
          });
      }
      show(style, cycle) {
          ULLog.console.log("ULAdvCustomManager.show isShowing:", this.isShowing);
          if (this.isShowing) {
              cycle.onShowFail({ code: "0", msg: "正在播放中" });
              return;
          }
          this.isShowing = true;
          this.showStyle = style;
          this.showCycleList.push(cycle);
          if (this.allowLoad || this.isLoading) {
              ULLog.console.log("ULAdvCustomManager.show loadData");
              this.loadData({
                  onLoad: () => {
                      ULLog.console.log("ULAdvCustomManager.show loadData onLoad");
                      this.channelShow();
                  },
                  onLoadFail: (errInfo) => {
                      ULLog.console.log("ULAdvCustomManager.show loadData onLoadFail");
                      this.channelShowCycle.onShowFail(errInfo);
                  }
              });
          }
          else if (this.loadSuccess) {
              ULLog.console.log("ULAdvCustomManager.show loadSuccess");
              this.remainRequestTime = Math.max(this.remainRequestTime, 3);
              this.channelShow();
          }
          else {
              ULLog.console.log("ULAdvCustomManager.show errInfo");
              this.channelShowCycle.onShowFail(this.errInfo || (this.isLoading ? { code: "0", msg: "正在加载中" } : { code: "0", msg: "未知错误" }));
          }
      }
      refresh() {
          ULLog.console.log("ULAdvCustomManager.refresh");
          var isShowing = this.isShowing;
          this.loadData({
              onLoad: () => {
                  ULLog.console.log("ULAdvCustomManager.refresh onLoad isShowing:", this.isShowing);
                  if (isShowing && this.isShowing)
                      this.channelShow(true);
              },
              onLoadFail: (errInfo) => {
                  ULLog.console.log("ULAdvCustomManager.refresh onLoadFail");
              },
          });
      }
      close() {
          ULLog.console.log("ULAdvCustomManager.close");
          this.hadShowRulst = true;
          this.loadCycleList = [];
          this.channelAd.close();
          this.channelShowCycle.onClose && this.channelShowCycle.onClose(false);
      }
      destroy() {
          ULLog.console.log("ULAdvCustomManager.destroy");
          this.close();
          this.channelAd.destroy();
          this.channelAd = null;
      }
  }

  let qg$c = window["qg"];
  class ULAdvOppoQgCustomItem {
      constructor() {
          this.arg = null;
          this.customAd = null;
          this.channelStyle = null;
          this.showStyleString = "";
      }
      init(arg) {
          this.arg = arg;
          let config = ULConfig.getConfig();
          let t_sdk_oppoqg_custom_adv_setting = config.t_sdk_oppoqg_custom_adv_setting;
          this.channelStyle = t_sdk_oppoqg_custom_adv_setting[this.arg] || t_sdk_oppoqg_custom_adv_setting["*"] || {};
          ULLog.console.log("ULAdvOppoQgCustomItem.initAdv channelStyle:", this.channelStyle);
      }
      load(cycle) {
          ULLog.console.log("ULAdvOppoQgCustomItem.load ");
          if (this.customAd) {
              this.customAd.offHide();
              this.customAd.hide();
              this.customAd.destroy();
              this.customAd = null;
          }
          cycle.onLoad();
      }
      createNewCustomAd(style) {
          if (this.customAd) {
              this.customAd.offHide();
              this.customAd.hide();
              this.customAd.destroy();
              this.customAd = null;
          }
          let sys = qg$c.getSystemInfoSync();
          let screenWidth = sys.screenWidth;
          let screenHeight = sys.screenHeight;
          let width = Math.min(screenWidth, screenHeight);
          let height = 0;
          try {
              let size = this.channelStyle.size;
              size = size.replace(/\s*/g, "");
              let sizeArray = size.split("*");
              if (sizeArray.length == 2) {
                  let sizeWidth = parseInt(sizeArray[0]);
                  let sizeHeight = parseInt(sizeArray[1]);
                  width = width * Math.min(Math.max(0.6, style.width), 1);
                  height = width * sizeHeight / sizeWidth;
              }
          }
          catch (error) {
              ULLog.console.log("ULAdvOppoQgCustomItem.createNewCustomAd catch:", error.stack);
              width = width * Math.min(Math.max(0.6, style.width), 1);
              height = width;
          }
          let left = (screenWidth - width) * style.x;
          let top = (1 - style.y) * (screenHeight - height);
          ULLog.console.log("ULAdvOppoQgCustomItem.createNewCustomAd style:", {
              top: top,
              left: left,
              width: width,
          });
          this.customAd = qg$c.createCustomAd({
              adUnitId: this.arg,
              style: {
                  top: top,
                  left: left,
                  width: width,
              },
          });
      }
      show(style, cycle) {
          let showStyleString = JSON.stringify(style);
          let isEqual = showStyleString == this.showStyleString;
          this.showStyleString = showStyleString;
          console.log(`ULAdvOppoQgCustomItem.show style :${showStyleString} :`, isEqual);
          if (!this.customAd || !isEqual) {
              this.createNewCustomAd(style);
          }
          this.customAd.offHide();
          this.customAd.onHide(() => {
              ULLog.console.log("ULAdvOppoQgCustomItem.show onHide");
              cycle.onClose(true);
          });
          this.customAd
              .show()
              .then(() => {
                  ULLog.console.log("ULAdvOppoQgCustomItem.show then");
                  cycle.onShow();
              })
              .catch((e) => {
                  ULLog.console.log("ULAdvOppoQgCustomItem.show catch e:", e);
                  cycle.onShowFail({ code: "" + e.errCode, msg: e.errMsg });
              });
      }
      close() {
          ULLog.console.log("ULAdvOppoQgCustomItem.close ");
          this.customAd && this.customAd.hide();
      }
      destroy() {
          ULLog.console.log("ULAdvOppoQgCustomItem.destroy ");
          this.customAd && this.customAd.destroy();
          this.customAd = null;
      }
  }

  class ULAdvOppoQgCustom extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.custom, ULTools.format("%s%s%s", "ULAdvOppoQgCustom", "_", arg));
          this.className = "ULAdvOppoQgCustom";
          this.customAd = null;
          this.statisticsAdvertiser = ULAdvOppoQg.NORMAL_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgCustom-onDisposeModule arg:", this.arg);
          if (this.customAd) {
              this.customAd.destroy();
              this.customAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgCustom-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          this.customAd = ULAdvCustomManager.createCustomAd(ULAdvOppoQgCustomItem, { arg: this.arg }, false);
      }
      loadAdv() {
      }
      showAdv(data) {
          ULLog.console.log("ULAdvOppoQgCustom.showAdv");
          this.customAd.showCycle.onShowFail = ((errInfo) => {
              ULLog.console.log("ULAdvOppoQgCustom.showAdv-onError:", errInfo);
              if (this.isOpened) {
                  this.isOpened = false;
                  this.advSkip(data, errInfo);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, errInfo);
              }
          });
          this.customAd.showCycle.onShow = (() => {
              ULLog.console.log("ULAdvOppoQgCustom.showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, data, null);
              let config = ULConfig.getConfig();
              let sw = config.s_sdk_oppo_custom_mode || "1";
              if (sw === "1") {
                  if (ULSdkManager.getInstance().channelInfo.getChannelOpenIdFunc) {
                      ULSdkManager.getInstance().channelInfo.getChannelOpenIdFunc((openId, err) => {
                          if (openId) {
                              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", "206", "0", `${new Date().getTime()}_${openId}_${this.arg}_0`]);
                          }
                          else {
                              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", "206", "0", `${new Date().getTime()}_${0}_${this.arg}_0`]);
                          }
                      });
                  }
                  else {
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", "206", "0", `${new Date().getTime()}_${0}_${this.arg}_0`]);
                  }
              }
          });
          this.customAd.showCycle.onClick = (() => {
              ULLog.console.log("ULAdvOppoQgCustom.showAdv-onClick");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClick(this.advKey, "点击", data, null);
          });
          this.customAd.showCycle.onClose = ((isUserClick) => {
              ULLog.console.log("ULAdvOppoQgCustom.showAdv-onClose");
              if (isUserClick == true) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              this.isOpened = false;
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data, null);
          });
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.isOpened = true;
          this.customAd.show(data);
      }
      closeAdv(data) {
          ULLog.console.log("ULAdvOppoQgCustom.closeAdv");
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgCustom-receiveInitState:初始化失败");
          }
      }
  }

  class ULAdvOppoQgCustomBanner extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.custom, ULTools.format("%s%s%s", "ULAdvOppoQgCustomBanner", "_", arg));
          this.className = "ULAdvOppoQgCustomBanner";
          this.customAd = null;
          this.statisticsAdvertiser = ULAdvOppoQg.NORMAL_ADVERTISER;
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgCustomBanner-onDisposeModule arg:", this.arg);
          if (this.customAd) {
              this.customAd.destroy();
              this.customAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgCustomBanner-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
          this.customAd = ULAdvCustomManager.createCustomAd(ULAdvOppoQgCustomItem, { arg: this.arg });
      }
      loadAdv() {
      }
      showAdv(data) {
          ULLog.console.log("ULAdvOppoQgCustomBanner.showAdv");
          this.customAd.showCycle.onShowFail = ((errInfo) => {
              ULLog.console.log("ULAdvOppoQgCustomBanner.showAdv-onError:", errInfo);
              if (this.isOpened) {
                  this.isOpened = false;
                  this.advSkip(data, errInfo);
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, errInfo);
              }
          });
          this.customAd.showCycle.onShow = (() => {
              ULLog.console.log("ULAdvOppoQgCustomBanner.showAdv-onShow");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, data, null);
          });
          this.customAd.showCycle.onClick = (() => {
              ULLog.console.log("ULAdvOppoQgCustomBanner.showAdv-onClick");
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClick(this.advKey, "点击", data, null);
          });
          this.customAd.showCycle.onClose = ((isUserClick) => {
              ULLog.console.log("ULAdvOppoQgCustomBanner.showAdv-onClose");
              if (isUserClick == true) {
                  ULSdkManager.getInstance().advManager.addAdvCountLog(this.advKey, countExp.mcc);
              }
              this.isOpened = false;
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data, null);
          });
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.isOpened = true;
          this.customAd.show(data);
      }
      closeAdv(data) {
          ULLog.console.log("ULAdvOppoQgCustomBanner.closeAdv");
          this.customAd.close();
          ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgCustomBanner-receiveInitState:初始化失败");
          }
      }
  }

  let qg$d = window["qg"];
  class ULAdvOppoQgDrawerBox extends ULAdvObjectBase {
      constructor(arg) {
          super(arg, typeExp.embed, ULTools.format("%s%s%s", "ULAdvOppoQgDrawerBox", "_", arg));
          this.className = "ULAdvOppoQgDrawerBox";
          this.statisticsAdvertiser = "ULAdvOppoQgDrawerBox";
      }
      onDisposeModule() {
          super.onDisposeModule();
          ULLog.console.log("ULAdvOppoQgDrawerBox-onDisposeModule arg:", this.arg);
          if (this.gameDrawerAd) {
              this.gameDrawerAd.destroy();
              this.gameDrawerAd = null;
          }
      }
      initAdv() {
          ULLog.console.log("ULAdvOppoQgDrawerBox-initAdv");
          this.preLoadState = ULConst.ADV_PRELOAD_STATE_READY;
      }
      loadAdv() {
      }
      showAdv(data) {
          if (qg$d.getSystemInfoSync().platformVersionCode < 1090) {
              ULLog.console.log('ULAdvOppoQgDrawerBox-showAdv:快应用平台版本号低于1090，暂不支持互推盒子相关 API');
              this.advSkip(data, { code: "", msg: "api unsupport" });
              return;
          }
          let tag = data["tag"] || data["advId"] || "";
          let advSetting = ULConfig.getConfig().t_sdk_oppoqg_show_drawer_box_adv_tags;
          let styleObj = advSetting[tag];
          if (!styleObj) {
              ULLog.console.log("ULAdvOppoQgDrawerBox-showAdv:当前广告位不允许展示互推盒子抽屉广告");
              this.advSkip(data, { code: "", msg: `advId [${tag}] unsupport drawer box` });
              return;
          }
          this.showData = data;
          this.isOpened = true;
          if (this.gameDrawerAd) {
              this.gameDrawerAd.destroy();
              this.gameDrawerAd = null;
          }
          let sys = qg$d.getSystemInfoSync();
          let screenHeight = sys.screenHeight;
          let style = {};
          if (!isNaN(Number(styleObj.top))) {
              style["top"] = Number(styleObj.top) * screenHeight;
          }
          this.gameDrawerAd = qg$d.createGameDrawerAd({
              adUnitId: this.arg,
              style: style
          });
          ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
          this.gameDrawerAd.show().then(() => {
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
          }).catch((error) => {
              ULLog.console.log("ULAdvOppoQgDrawerBox-showAdv-show-catch:", error);
              this.isOpened = false;
              this.advSkip(this.showData, { code: String(error.errCode), msg: error.errMsg });
              ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(error.errCode), msg: error.errMsg });
          });
      }
      closeAdv(data) {
          if (this.isOpened) {
              this.gameDrawerAd.hide().then(() => {
                  this.isOpened = false;
                  ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data);
                  ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_SUCCESS, ULConst.ADV_RESULT_MSG_CLOSE);
              }).catch((error) => {
                  ULLog.console.log("ULAdvOppoQgDrawerBox-closeAdv-hide-catch:", error);
                  ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, error.errCode + ',' + error.errMsg);
              });
          }
          else {
              ULSdkManager.getInstance().advManager.responseCloseAdvResult(data, ULConst.ADV_RESULT_CODE_FAILED, "no ad show");
          }
      }
      getMainClassName() {
          return "ULAdvOppoQg";
      }
      receiveInitState(initState) {
          if (initState) {
              this.initState = initState;
              this.initAdv();
          }
          else {
              console.warn("ULAdvOppoQgDrawerBox-receiveInitState:初始化失败");
          }
      }
  }

  let qg$e = window["qg"];
  class ULModuleOppoQg extends ULChannelModuleBase {
      constructor() {
          super(...arguments);
          this.className = "ULModuleOppoQg";
          this.manualCloseBannerCount = 0;
          this.lastDailyResetTime = 0;
          this.userInfoData = null;
      }
      getSubAdModuleClassName() {
          return ["ULAdvOppoQgInter", "ULAdvOppoQgBanner", "ULAdvOppoQgVideo", "ULAdvOppoQgBannerBox", "ULAdvOppoQgPortalBox", "ULAdvOppoQgNativeBanner", "ULAdvOppoQgNativeInter", "ULAdvOppoQgNativeEmbed", "ULAdvOppoQgAutoNativeBanner", "ULAdvOppoQgAutoNativeInter", "ULAdvOppoQgAutoNativeEmbed", "ULAdvOppoQgCustom", "ULAdvOppoQgCustomBanner", "ULAdvOppoQgDrawerBox"];
      }
      getAdMainClassName() {
          return "ULAdvOppoQg";
      }
      createSubAdObj(className, param) {
          let targetObj;
          let advKey;
          switch (className) {
              case "ULAdvOppoQgInter":
                  targetObj = new ULAdvOppoQgInter(param);
                  break;
              case "ULAdvOppoQgBanner":
                  targetObj = new ULAdvOppoQgBanner(param);
                  break;
              case "ULAdvOppoQgVideo":
                  targetObj = new ULAdvOppoQgVideo(param);
                  break;
              case "ULAdvOppoQgBannerBox":
                  targetObj = new ULAdvOppoQgBannerBox(param);
                  break;
              case "ULAdvOppoQgPortalBox":
                  targetObj = new ULAdvOppoQgPortalBox(param);
                  break;
              case "ULAdvOppoQgNativeBanner":
                  targetObj = new ULAdvOppoQgNativeBanner(param);
                  break;
              case "ULAdvOppoQgNativeInter":
                  targetObj = new ULAdvOppoQgNativeInter(param);
                  break;
              case "ULAdvOppoQgNativeEmbed":
                  targetObj = new ULAdvOppoQgNativeEmbed(param);
                  break;
              case "ULAdvOppoQgAutoNativeBanner":
                  targetObj = new ULAdvOppoQgAutoNativeBanner(param);
                  break;
              case "ULAdvOppoQgAutoNativeInter":
                  targetObj = new ULAdvOppoQgAutoNativeInter(param);
                  break;
              case "ULAdvOppoQgAutoNativeEmbed":
                  targetObj = new ULAdvOppoQgAutoNativeEmbed(param);
                  break;
              case "ULAdvOppoQgCustom":
                  targetObj = new ULAdvOppoQgCustom(param);
                  break;
              case "ULAdvOppoQgCustomBanner":
                  targetObj = new ULAdvOppoQgCustomBanner(param);
                  break;
              case "ULAdvOppoQgDrawerBox":
                  targetObj = new ULAdvOppoQgDrawerBox(param);
                  break;
              default:
                  break;
          }
          if (targetObj) {
              advKey = ULTools.format("%s%s%s", className, "_", param);
              ULSdkManager.getInstance().advManager.updateAdvKeyObjMap(advKey, targetObj);
          }
          return targetObj;
      }
      createMainAdObj() {
          return new ULAdvOppoQg();
      }
      init() {
          super.init();
          ULSdkManager.getInstance().statisManager.addPreparationFlag("oppoMoreGameExtra");
          this.loadRecord();
          this.initUserJumpGameInfo();
          this.initSdk();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SET_VERSION, 1, this.onCmdSetVersion.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_USER_LOGIN, 1, this.onCmdUserLogin.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_USER_IS_LOGIN, 1, this.onCmdUserIsLogin.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_GET_USER_INFO_MSG, 1, this.onCmdGetUserInfo.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_OPEN_PAY, ULConst.PRIORITY_NONE, this.onCmdOpenPay.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_OPEN_JUMP, ULConst.PRIORITY_NONE, this.onCmdOpenJump.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_JUMP_OTHER_GAME, ULConst.PRIORITY_NONE, this.onCmdJumpOtherGame.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_RESUME, ULConst.PRIORITY_NONE, this.onCmdSdkOnGameResume.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_INSTALL_SHORTCUT, ULConst.PRIORITY_NONE, this.onCmdInstallShortcut.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_MORE_GAME_AB_TEST_CONFIG, ULConst.PRIORITY_NONE, this.onCmdSdkCollectionModuleCheckerMoreGameTestConfig.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_GET_SHORTCUT_STATE, ULConst.PRIORITY_NONE, this.onCmdGetShortcutState.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_OPPOQG_MARK_MANUAL_CLOSE_BANNER_COUNT, ULConst.PRIORITY_NONE, this.onCmdSdkMarkManualCloseBannerCount.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_OPPOQG_GET_MANUAL_CLOSE_BANNER_COUNT, ULConst.PRIORITY_NONE, this.onCmdSdkGetManualCloseBannerCount.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_PHONE_VIBRATE, 1, this.onCmdPhoneVibrate.bind(this));
          this.onCmdSdkOnGameResume(new ULEvent(ULConst.CMD_SDK_ON_GAME_RESUME, {}));
      }
      loadSubModules() {
          return [];
      }
      loadRecord() {
          let recordStr = ULStorageManager.getInstance().getStorage(this._getRecordKey()) || "{}";
          ULLog.console.log("ULModuleOppoQg.loadRecord recordStr:", recordStr);
          let record;
          try {
              record = JSON.parse(recordStr);
          }
          catch (error) {
              record = {};
          }
          this["jumpResourceIndex"] = record.jumpResourceIndex;
          this.lastJumpRecord = record.lastJumpRecord || null;
          this.jumpGameReceivedFlags = record.jumpGameReceivedFlags || {};
          this.lastDailyResetTime = record.lastDailyResetTime || ULTools.time();
          this.manualCloseBannerCount = record.manualCloseBannerCount || 0;
          this.tryDailyReset();
      }
      saveRecord() {
          let record = {
              jumpResourceIndex: this["jumpResourceIndex"],
              lastJumpRecord: this.lastJumpRecord,
              jumpGameReceivedFlags: this.jumpGameReceivedFlags,
              lastDailyResetTime: this.lastDailyResetTime,
              manualCloseBannerCount: this.manualCloseBannerCount,
          };
          let recordStr = JSON.stringify(record);
          ULStorageManager.getInstance().setStorage(this._getRecordKey(), recordStr);
      }
      tryDailyReset() {
          if (!ULTools.isOneDay(ULTools.time(), this.lastDailyResetTime)) {
              this.lastDailyResetTime = ULTools.time();
              this.manualCloseBannerCount = 0;
              this.saveRecord();
          }
      }
      _getRecordKey() {
          let config = ULConfig.getConfig();
          return ULTools.format("ULModuleOppoQg_record_%d", config.s_sdk_megadata_game_id);
      }
      initSdk() {
          let config = ULConfig.getConfig();
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          channelInfo.channelName = "oppoqg";
          channelInfo.uuid = this.sdkUserId;
          channelInfo.isSupportRecordShare = false;
          channelInfo.isShareEnabled = !!config.i_sdk_share_mode;
          channelInfo.copChannelId = config.s_sdk_cop_channel_id;
          channelInfo.isPayEnabled = !!config.i_sdk_pay_mode;
          channelInfo.isUseSdkRank = !!config.i_sdk_sdk_rank_mode;
          channelInfo.isSupportInstallShortcut = true;
          channelInfo.appName = "oppoqg";
          channelInfo.isSupportJumpList = true;
          channelInfo.jumpInfo = this.getJumpInfo();
          channelInfo.referenceBannerHeight = 110;
          channelInfo.payInfo = config.t_sdk_oppoqg_pay_code || {};
          channelInfo.getChannelOpenIdFunc = this.getChannelOpenIdFunc.bind(this);
          // let options = qg$e.getLaunchOptionsSync();
          // let referrerInfo = options && (options.referrerInfo || {});
          // if (JSON.stringify(referrerInfo) != "{}") {
          //     ULSdkManager.getInstance().statisManager.setGameStartSourceMsg(JSON.stringify(referrerInfo));
          // }
          // if (qg$e.getSystemInfoSync().platformVersionCode >= 1076) {
          //     channelInfo.isJumpLeisureEnabled = true;
          // }
          // else {
          channelInfo.isJumpLeisureEnabled = false;
          // }
          // ULLog.console.log("ULModuleOppoQg.initSdk getLaunchOptionsSync options:", options);
          ULSdkManager.getInstance().statisManager.removePreparationFlag("oppoMoreGameExtra");
          this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
      }
      initUserJumpGameInfo() {
          if (this["jumpResourceIndex"] == null || this["jumpResourceIndex"] == undefined) {
              this.setRandomJumpResourceIndex();
          }
          ULLog.console.log("ULModuleOppoQg.initUserJumpGameInfo this.jumpResourceIndex:", this["jumpResourceIndex"]);
      }
      getJumpResourceIndex() {
          let config = ULConfig.getConfig();
          if (config.i_sdk_jump_game_resource_mode == 1) {
              return this["jumpResourceIndex"];
          }
          else {
              return 0;
          }
      }
      setRandomJumpResourceIndex() {
          let config = ULConfig.getConfig();
          let jumpConfigs = config.t_sdk_oppoqg_jump_games || [];
          let jumpConfig = jumpConfigs[0];
          if (jumpConfig && jumpConfig.urls) {
              let urlsLength = jumpConfig.urls.length;
              let indexRange = urlsLength > 0 ? urlsLength - 1 : 0;
              this["jumpResourceIndex"] = ULTools.random(0, indexRange);
          }
          else {
              this["jumpResourceIndex"] = 0;
          }
          this.saveRecord();
      }
      getJumpInfo() {
          let config = ULConfig.getConfig();
          let jumpConfigs = config.t_sdk_oppoqg_jump_games;
          let jumpInfo = [];
          for (let i = 0; i < jumpConfigs.length; i++) {
              let jumpConfig = jumpConfigs[i];
              if (!jumpConfig.urls)
                  continue;
              let index = jumpConfig.index || "";
              let bReceived = this.jumpGameReceivedFlags[index] || false;
              jumpInfo.push({
                  index: jumpConfig.index,
                  url: jumpConfig.urls[this.getJumpResourceIndex()] || "",
                  rewards: jumpConfig.rewards || [],
                  bReceived: bReceived,
              });
          }
          return jumpInfo;
      }
      _hook_getStorage(key) {
          if (localStorage)
              return localStorage.getItem(key);
          return null;
      }
      _hook_setStorage(key, data) {
          if (localStorage)
              localStorage.setItem(key, data);
          return;
      }
      _hook_isSupportClipboard() {
          return true;
      }
      _hook_getClipboardData(finishCallback) {
          // qg$e.getClipboardData({
          //     success: function (res) {
          //         finishCallback(res.data);
          //     },
          //     fail: function (res) {
          //         finishCallback(null);
          //     }
          // });
      }
      _hook_setClipboardData(clipboardData, finishCallback) {
          // qg$e.setClipboardData({
          //     data: clipboardData,
          //     success(res) {
          //         finishCallback(true);
          //     },
          //     fail(res) {
          //         finishCallback(false);
          //     }
          // });
      }
      preOrderForSingleGame(payId, productDesc, productName, orderId, success, fail) {
          ULLog.console.log(`ULModuleOppoQg.preOrderForSingleGame token:`, payId);
          ULLog.console.log(`ULModuleOppoQg.preOrderForSingleGame orderId:`, orderId);
          let config = ULConfig.getConfig();
          let payData = config.t_sdk_oppoqg_pay_code[payId];
          if (!payData) {
              fail && fail("payId 不存在");
              return;
          }
          this.login({
              success: (token) => {
                  let timestamp = new Date().getTime();
                  let netTimeout = config.i_net_timeout;
                  let appkey = config.s_sdk_oppoqg_app_key;
                  let preOrderUrl = config.s_sdk_oppoqg_pre_order_url;
                  let privateKey = config.s_sdk_oppoqg_private_key;
                  let rsa = new RSAKey();
                  rsa.readPrivateKeyFromPEMString(privateKey);
                  let hashAlg = "sha256";
                  let params = {
                      appId: config.s_sdk_oppoqg_appid,
                      openId: token,
                      timestamp: timestamp,
                      productName: productName || payData.proName,
                      productDesc: productDesc || payData.proName,
                      count: 1,
                      price: parseInt(payData.price),
                      currency: "CNY",
                      cpOrderId: orderId,
                      appVersion: config.s_sdk_oppoqg_version_name,
                      // engineVersion: qg$e.getSystemInfoSync().platformVersion
                      engineVersion: 1
                  };
                  let signStr = `appId=${params.appId}&appVersion=${params.appVersion}&count=${params.count}&cpOrderId=${params.cpOrderId}&currency=${params.currency}&engineVersion=${params.engineVersion}&openId=${params.openId}&price=${params.price}&productDesc=${params.productDesc}&productName=${params.productName}&timestamp=${params.timestamp}`;
                  let hSig = rsa.sign(signStr, hashAlg);
                  params["sign"] = hex2b64(hSig);
                  ULTools.httpPost({
                      url: preOrderUrl,
                      postData: JSON.stringify(params),
                      timeoutMillisecond: netTimeout,
                      contentType: "application/json",
                      success: (res) => {
                          ULLog.console.log(`ULModuleOppoQg.preOrderForSingleGame timeoutMillisecond:`, res);
                          let resMsg = JSON.parse(res);
                          let code = resMsg.code;
                          if (code == "200") {
                              let orderNo = resMsg.data.orderNo;
                              let signStr = "appKey=" + appkey + "&orderNo=" + orderNo + "&timestamp=" + timestamp;
                              let hSig = rsa.sign(signStr, hashAlg);
                              let sign = hex2b64(hSig);
                              success && success(token, sign, orderNo, timestamp);
                          }
                          else {
                              fail && fail(resMsg);
                          }
                      },
                      fail: (res) => {
                          fail && fail(JSON.stringify(res));
                      }
                  });
              },
              fail: (res) => {
                  ULLog.console.log(`ULModuleOppoQg.preOrderForSingleGame login fail:`, res);
                  fail && fail(JSON.stringify(res));
              }
          });
      }
      preOrderForOnlineGame(payId, orderId, productDesc, productName, success, fail) {
          ULLog.console.log(`ULModuleOppoQg.preOrderForOnlineGame payId:`, payId);
          ULLog.console.log(`ULModuleOppoQg.preOrderForOnlineGame orderId:`, orderId);
          let config = ULConfig.getConfig();
          let payData = config.t_sdk_oppoqg_pay_code[payId];
          if (!payData) {
              fail && fail("payId 不存在");
              return;
          }
          this.login({
              success: (token) => {
                  let preOrderUrl = config.s_sdk_oppoqg_preOrder_online_url;
                  let params = {
                      mGameId: Number(config.s_sdk_megadata_game_id),
                      channel: "h5oppo",
                      orderInfo: JSON.stringify({
                          openId: token,
                          appVersion: config.s_sdk_oppoqg_version_name,
                          // engineVersion: qg$e.getSystemInfoSync().platformVersion.toString(),
                          engineVersion: 1,
                          productDesc: productDesc || payData.proName,
                          productName: productName || payData.proName,
                          price: parseInt(payData.price),
                      })
                  };
                  ULTools.httpPostEncryption({
                      url: preOrderUrl,
                      postString: JSON.stringify(params),
                      timeoutMillisecond: config.i_net_timeout,
                      success: (res) => {
                          ULLog.console.log(`ULModuleOppoQg.preOrderForOnlineGame httpPost success:`, res);
                          let resMsg = JSON.parse(res);
                          let code = resMsg.code || 0;
                          if (code == 1) {
                              let preOrderData = resMsg.preOrderData || {};
                              let orderNo = preOrderData.orderNo;
                              let timestamp = preOrderData.timestamp;
                              let sign = preOrderData.sign;
                              success && success(token, sign, orderNo, timestamp);
                          }
                          else {
                              fail && fail(resMsg);
                          }
                      },
                      fail: (res) => {
                          ULLog.console.log(`ULModuleOppoQg.preOrderForOnlineGame httpPost fail:`, res);
                          fail && fail(JSON.stringify(res));
                      }
                  });
              }, fail: (res) => {
                  ULLog.console.log(`ULModuleOppoQg.preOrderForOnlineGame login fail:`, res);
                  fail && fail(JSON.stringify(res));
              }
          });
      }
      doOpenPay(isOnline, payId, productDesc, productName, orderId, success, fail) {
          ULLog.console.log(`ULModuleOppoQg.doOpenPay payId:`, payId);
          ULLog.console.log(`ULModuleOppoQg.doOpenPay orderId:`, orderId);
          let config = ULConfig.getConfig();
          let payData = config.t_sdk_oppoqg_pay_code[payId];
          if (!payData) {
              fail && fail("payId 不存在");
              return;
          }
          let preOrder = isOnline ? this.preOrderForOnlineGame.bind(this) : this.preOrderForSingleGame.bind(this);
          preOrder(payId, orderId, productDesc, productName, (token, sign, orderNo, timestamp) => {
              ULLog.console.log("ULModuleHuawei.doOpenPay preOrder success token:", token);
              ULLog.console.log("ULModuleHuawei.doOpenPay preOrder success sign:", sign);
              ULLog.console.log("ULModuleHuawei.doOpenPay preOrder success orderNo:", orderNo);
              ULLog.console.log("ULModuleHuawei.doOpenPay preOrder success timestamp:", timestamp);
              ULSdkManager.getInstance().statisManager.reportPayRequest();
              // qg$e.pay({
              //     appId: config.s_sdk_oppoqg_appid,
              //     token: token,
              //     timestamp: timestamp,
              //     paySign: sign,
              //     orderNo: orderNo,
              //     success: function (res) {
              //         ULLog.console.log(`ULModuleOppoQg.doOpenPay pay success:`, JSON.stringify(res));
              success && success();
              //     },
              //     fail: function (res) {
              //         let errMsg = JSON.stringify(res);
              //         ULLog.console.log(`ULModuleOppoQg.doOpenPay pay fail:`, errMsg);
              //         fail && fail(errMsg);
              //     }
              // });
          }, (errmsg) => {
              ULLog.console.log("ULModuleHuawei.doOpenPay preOrder fail errmsg:", errmsg);
              fail && fail(errmsg);
          });
      }
      onCmdUserIsLogin(e) {
          e.stopImmediatePropagation();
          ULLog.console.log(`ULModuleWeixin.onCmdUserIsLogin `);
          let data = e.data;
          let userData = data.userData || "";
          ULSdkManager.getInstance().response(ULConst.CMD_USER_IS_LOGIN_RESULT, {
              code: 1,
              userData: userData
          });
      }
      onCmdUserLogin(e) {
          e.stopImmediatePropagation();
          ULLog.console.log(`ULModuleOppoQg.onCmdUserLogin 登陆`);
          let userData = e.data.userData || "";
          let config = ULConfig.getConfig();
          this.login({
              success: (token) => {
                  ULSdkManager.getInstance().response(ULConst.CMD_USER_LOGIN_RESULT, {
                      code: 1,
                      userData: userData,
                      loginData: {
                          mgid: Number(config.s_sdk_megadata_game_id),
                          channel: "h5oppo",
                          openId: "",
                          token: token
                      }
                  });
              }, fail: (res) => {
                  ULSdkManager.getInstance().response(ULConst.CMD_USER_LOGIN_RESULT, {
                      code: 0,
                      userData: userData
                  });
              }
          });
      }
      login(obj) {
          ULLog.console.log("ULModuleOppoQg.login start");
          // qg$e.login({
          //     success: (res) => {
          //         ULLog.console.log("ULModuleOppoQg.login success:", res);
          obj.success(res.data.token || "");
          //     },
          //     fail: (res) => {
          //         ULLog.console.log("ULModuleOppoQg.login fail：", res);
          //         obj.fail(res);
          //     }
          // });
      }
      getUserInfoData(obj) {
          if (this.userInfoData) {
              obj.success && obj.success(this.userInfoData);
              return;
          }
          let config = ULConfig.getConfig();
          this.login({
              success: (token) => {
                  ULLog.console.log("ULModuleOppoQg.getUserInfoData login success");
                  var userLoginUrl = config.s_sdk_common_login_url;
                  var postData = {
                      token: token,
                      channel: "h5oppo",
                      mgid: Number(config.s_sdk_megadata_game_id)
                  };
                  ULTools.httpPost({
                      url: userLoginUrl,
                      contentType: "application/json",
                      postData: JSON.stringify(postData),
                      timeoutMillisecond: config.i_net_timeout,
                      success: (responseText) => {
                          ULLog.console.log("ULModuleOppoQg.getUserInfoData success", responseText);
                          let resultObj = JSON.parse(responseText);
                          if (resultObj.code == 1) {
                              let openId = resultObj.openId;
                              this.userInfoData = {
                                  openId: openId,
                                  userInfo: {
                                      avatarUrl: resultObj.headImgUrl || "",
                                      nickName: resultObj.nickName || "",
                                  }
                              };
                              ULSdkManager.getInstance().channelInfo.channelUserId = openId;
                              obj.success && obj.success(this.userInfoData);
                          }
                          else {
                              ULLog.console.log("ULModuleOppoQg.getUserInfoData resultObj:", resultObj);
                              obj.fail && obj.fail(JSON.stringify(resultObj));
                          }
                      },
                      fail: (res) => {
                          ULLog.console.log("ULModuleOppoQg.getUserInfoData fail:", res);
                          obj.fail && obj.fail(JSON.stringify(res));
                      }
                  });
              },
              fail: (res) => {
                  ULLog.console.log("ULModuleOppoQg.getUserInfoData login fail:", res);
                  obj.fail && obj.fail(JSON.stringify(res));
              }
          });
      }
      onCmdOpenPay(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let payId = data.payId;
          let orderId = data.orderId;
          let userData = data.userData || "";
          let productDesc = data.productDesc;
          let productName = data.productName;
          let trimOrder = orderId || ULTools.createRandomOrderId();
          let callBack = (code, err) => {
              ULSdkManager.getInstance().response(ULConst.CMD_PAY_RESULT, {
                  code: code,
                  msg: err,
                  payId: payId,
                  userData: userData,
              });
          };
          this.doOpenPay(!!orderId, payId, productDesc, productName, trimOrder, () => {
              ULLog.console.log("ULModuleOppoQg.onCmdOpenPay doOpenPay success");
              callBack(1, "购买成功");
          }, (errmsg) => {
              ULLog.console.log("ULModuleOppoQg.onCmdOpenPay doOpenPay fail errmsg:", errmsg);
              callBack(0, errmsg);
          });
      }
      onCmdOpenJump(e) {
          this.bOpenJumpCalled = true;
          let config = ULConfig.getConfig();
          let data = e.data;
          let count = data.count || -1;
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          if (!channelInfo.isSupportJumpList) {
              ULLog.console.log("onCmdOpenJump----isSupportJumpList---不支持-");
              ULSdkManager.getInstance().response(ULConst.CMD_OPEN_JUMP_RESULT, {
                  code: 0,
                  msg: "isSupportJumpList false",
              });
              return;
          }
          ULSdkManager.getInstance().channelInfo.jumpInfo = this.getJumpInfo();
          let rawJumpInfo = ULTools.clone(ULSdkManager.getInstance().channelInfo.jumpInfo);
          let jumpInfo = [];
          let type = data.type;
          if (type == "single") {
              count = 1;
          }
          if (count == null || count <= 0) {
              count = rawJumpInfo.length;
          }
          for (let i = 0; i < rawJumpInfo.length; i++) {
              const v = rawJumpInfo[i];
              v["raw_order"] = i;
          }
          count = Math.min(count, rawJumpInfo.length);
          let single_random_length = config.i_sdk_jump_single_random_length || rawJumpInfo.length;
          for (let i = 0; i < count; i++) {
              let randLength = rawJumpInfo.length;
              if (type == "single") {
                  randLength = Math.min(Math.max(1, single_random_length), randLength);
                  single_random_length--;
              }
              let r = ULTools.random(randLength) - 1;
              let v = rawJumpInfo[r];
              rawJumpInfo.splice(r, 1);
              jumpInfo.push(v);
          }
          jumpInfo = ULTools.sortArrayByField(jumpInfo, "raw_order");
          for (let i = 0; i < jumpInfo.length; i++) {
              const v = jumpInfo[i];
              delete v["raw_order"];
          }
          ULSdkManager.getInstance().response(ULConst.CMD_OPEN_JUMP_RESULT, {
              code: 1,
              msg: "获取成功成功",
              jumpInfo: jumpInfo,
              type: type,
              userData: data.userData || "",
          });
          let sourceGameId = config.s_sdk_cop_game_id + "";
          for (let index = 0; index < jumpInfo.length; index++) {
              let jumpGameConfig = jumpInfo[index];
              let gameIndex = jumpGameConfig.index;
              let targetIconId = ULTools.format("%s_%d", gameIndex, this.getJumpResourceIndex());
              ULSdkManager.getInstance().statisManager.reportJumpGame("openJump", "oppoqg", sourceGameId, type, targetIconId);
          }
      }
      onCmdJumpOtherGame(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          let gameIndex = data.gameIndex;
          let type = data.type;
          let userData = data.userData;
          let jumpGames = config.t_sdk_oppoqg_jump_games;
          let sourceGameId = config.s_sdk_cop_game_id + "";
          let targetIconId = ULTools.format("%s_%d", gameIndex, this.getJumpResourceIndex());
          if (this.bOpenJumpCalled) {
              ULSdkManager.getInstance().statisManager.reportJumpGame("jump", "oppoqg", sourceGameId, type, targetIconId);
          }
          let gameId = null;
          let rewards = null;
          for (let i = 0; i < jumpGames.length; i++) {
              const v = jumpGames[i];
              if (v.index == gameIndex) {
                  gameId = v.id;
                  rewards = v.rewards;
                  break;
              }
          }
          if (!gameId) {
              ULSdkManager.getInstance().response(ULConst.CMD_JUMP_OTHER_GAME_RESULT, {
                  code: 0,
                  msg: "目标游戏未找到",
                  userData: userData,
              });
              if (this.bOpenJumpCalled) {
                  ULSdkManager.getInstance().statisManager.reportJumpGame("jumpFail", "oppoqg", sourceGameId, type, targetIconId);
              }
              return;
          }
          // qg$e.navigateToMiniGame({
          //     pkgName: gameId,
          //     success: () => {
          //         ULSdkManager.getInstance().response(ULConst.CMD_JUMP_OTHER_GAME_RESULT, {
          //             code: 1,
          //             msg: "跳转其他游戏成功",
          //             userData: userData,
          //         });
          //         this.lastJumpRecord = {
          //             gameIndex: gameIndex,
          //             jumpTime: ULTools.time(),
          //             type: type,
          //             rewards: rewards,
          //         };
          //         this.saveRecord();
          //     },
          //     fail: (res) => {
          ULLog.console.log("跳转其他游戏失败---err ", JSON.stringify(res));
          ULSdkManager.getInstance().response(ULConst.CMD_JUMP_OTHER_GAME_RESULT, {
              code: 0,
              msg: "跳转其他游戏失败",
              userData: userData,
          });
          if (this.bOpenJumpCalled) {
              ULSdkManager.getInstance().statisManager.reportJumpGame("jumpFail", "oppoqg", sourceGameId, type, targetIconId);
          }
          //     }
          // });
      }
      onCmdSdkOnGameResume(e) {
          let config = ULConfig.getConfig();
          let lastJumpRecord = this.lastJumpRecord;
          if (!lastJumpRecord) {
              ULLog.console.log("ULModuleOppoQg.onCmdSdkOnGameResume 不存在上次跳转游戏");
              return;
          }
          let gameIndex = lastJumpRecord.gameIndex;
          let sourceGameId = config.s_sdk_cop_game_id + "";
          let targetIconId = ULTools.format("%s_%d", gameIndex, this.getJumpResourceIndex());
          let lastJumpTime = lastJumpRecord.jumpTime || 0;
          let now = ULTools.time();
          let bNeedUploadStatis = true;
          if (!this.bOpenJumpCalled) {
              bNeedUploadStatis = false;
          }
          let bJumpSuccess = (now - lastJumpTime) > config.i_sdk_oppoqg_jump_game_reward_time / 1000;
          if (bNeedUploadStatis) {
              if (bJumpSuccess) {
                  ULSdkManager.getInstance().statisManager.reportJumpGame("jumpSuccess", "oppoqg", sourceGameId, lastJumpRecord.type, targetIconId);
              }
              else {
                  ULSdkManager.getInstance().statisManager.reportJumpGame("jumpFail", "oppoqg", sourceGameId, lastJumpRecord.type, targetIconId);
              }
          }
          if (lastJumpRecord.type == "reward") {
              if (bJumpSuccess) {
                  if (this.jumpGameReceivedFlags[lastJumpRecord.gameIndex]) {
                      ULSdkManager.getInstance().response(ULConst.CMD_JUMP_OTHER_GAME_REWARD_RESULT, {
                          code: 0,
                          msg: "该游戏已经发过奖",
                          rewards: lastJumpRecord.rewards || [],
                      });
                  }
                  else {
                      ULSdkManager.getInstance().response(ULConst.CMD_JUMP_OTHER_GAME_REWARD_RESULT, {
                          code: 1,
                          msg: "跳转其他游戏成功，并达到发奖条件",
                          rewards: lastJumpRecord.rewards || [],
                      });
                      this.jumpGameReceivedFlags[gameIndex] = true;
                      this.saveRecord();
                      ULSdkManager.getInstance().channelInfo.jumpInfo = this.getJumpInfo();
                  }
              }
              else {
                  ULSdkManager.getInstance().response(ULConst.CMD_JUMP_OTHER_GAME_REWARD_RESULT, {
                      code: 0,
                      msg: "跳转其他游戏失败",
                      rewards: this.lastJumpRecord.rewards || [],
                  });
              }
          }
          this.lastJumpRecord = null;
          this.saveRecord();
      }
      onCmdSdkCollectionModuleCheckerMoreGameTestConfig(e) {
          let config = e.getReturnValue() || [];
          let text = ["A", "B", "C", "D", "E", "F"];
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "更多游戏ab测试信息:" });
          config.push({
              type: "label",
              text: text[this.getJumpResourceIndex()] || this.getJumpResourceIndex().toString(),
              name: "labelMoreGameUserIndex"
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: ULTools.format("更多游戏资源状态：%s", ULConfig.getConfig().i_sdk_jump_game_resource_mode == 1 ? "随机" : "固定0") });
          config.push({ type: "newLine" });
          config.push({
              type: "button",
              text: "更改更多游戏用户AB属性",
              onClick: () => {
                  let config = ULConfig.getConfig();
                  let jumpConfigs = config.t_sdk_baidu_jump_games || [];
                  let jumpConfig = jumpConfigs[0];
                  let urlsLength = 2;
                  if (jumpConfig && jumpConfig.urls) {
                      urlsLength = jumpConfig.urls.length;
                  }
                  let conf = [];
                  for (let index = 0; index < urlsLength; index++) {
                      conf.push({
                          text: text[index] || index.toString(),
                          value: index.toString()
                      });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("选择AB测试用户属性：", conf, (index) => {
                      this["jumpResourceIndex"] = parseInt(index.toString());
                      let labelText = text[this.getJumpResourceIndex()] || this.getJumpResourceIndex().toString();
                      ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelMoreGameUserIndex", labelText);
                      this.saveRecord();
                      ULSdkManager.getInstance().channelInfo.jumpInfo = this.getJumpInfo();
                  });
              }
          });
          e.setReturnValue(config, true);
      }
      onCmdGetShortcutState(e) {
          e.stopImmediatePropagation();
          // if (qg$e.hasShortcutInstalled) {
          //     qg$e.hasShortcutInstalled({
          //         success: (res) => {
          //             if (res == false) {
          //                 ULSdkManager.getInstance().response(ULConst.CMD_GET_SHORTCUT_STATE_RESULT, {
          //                     state: 1,
          //                     bHasPrompt: true
          //                 });
          //             }
          //             else {
          //                 ULLog.console.log("ULModuleOppoQg.onCmdGetShortcutState.hasShortcutInstalled success true :", res);
          //                 ULSdkManager.getInstance().response(ULConst.CMD_GET_SHORTCUT_STATE_RESULT, {
          //                     state: 3,
          //                     bHasPrompt: true
          //                 });
          //             }
          //         },
          //         fail: (err) => {
          //             ULLog.console.log("ULModuleOppoQg.onCmdGetShortcutState.hasShortcutInstalled fail:", err);
          //             ULSdkManager.getInstance().response(ULConst.CMD_GET_SHORTCUT_STATE_RESULT, {
          //                 state: 1,
          //                 bHasPrompt: true
          //             });
          //         }
          //     });
          // }
          // else {
          ULSdkManager.getInstance().response(ULConst.CMD_GET_SHORTCUT_STATE_RESULT, {
              state: 1,
              bHasPrompt: true
          });
          // }
      }
      onCmdInstallShortcut(e) {
          e.stopImmediatePropagation();
          let config = ULConfig.getConfig();
          let data = e.data;
          let userData = data.userData;
          qg$e.hasShortcutInstalled({
              success: (res) => {
                  if (res == false) {
                      ULSdkManager.getInstance().statisManager.reportAddShortcut("0");
                      qg$e.installShortcut({
                          success: () => {
                              setTimeout(() => {
                                  qg$e.hasShortcutInstalled({
                                      success: (res) => {
                                          if (res == false) {
                                              ULLog.console.log("ULModuleOppoQg.onCmdInstallShortcut.hasShortcutInstalled 2 success false :", res);
                                              ULSdkManager.getInstance().statisManager.reportAddShortcut("2");
                                              ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
                                                  code: 0,
                                                  msg: "添加桌面快捷方式失败",
                                                  userData: userData,
                                              });
                                              this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
                                          }
                                          else {
                                              ULSdkManager.getInstance().statisManager.reportAddShortcut("1");
                                              ULLog.console.log("ULModuleOppoQg.onCmdInstallShortcut.hasShortcutInstalled 2 success true :", res);
                                              ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
                                                  code: 1,
                                                  msg: "添加桌面快捷方式成功",
                                                  userData: userData,
                                              });
                                              this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
                                          }
                                      },
                                      fail: (err) => {
                                          ULSdkManager.getInstance().statisManager.reportAddShortcut("2");
                                          ULLog.console.log("ULModuleOppoQg.onCmdInstallShortcut.hasShortcutInstalled 2 fail:", err);
                                          ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
                                              code: 0,
                                              msg: "添加桌面快捷方式失败",
                                              userData: userData,
                                          });
                                          this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
                                      }
                                  });
                              }, 500);
                          },
                          fail: (err) => {
                              ULLog.console.log("ULModuleOppoQg.onCmdInstallShortcut.installShortcut fail:", err);
                              ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
                                  code: 0,
                                  msg: "添加桌面快捷方式失败",
                                  userData: userData,
                              });
                              this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
                          }
                      });
                  }
                  else {
                      ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
                          code: 2,
                          msg: "添加桌面快捷方式成功",
                          userData: userData,
                      });
                      this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
                  }
              },
              fail: (err) => {
                  ULLog.console.log("ULModuleOppoQg.onCmdInstallShortcut.hasShortcutInstalled 1 fail err:", err);
                  ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
                      code: 0,
                      msg: "添加桌面快捷方式失败",
                      userData: userData,
                  });
                  this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
              }
          });
      }
      onCmdSetVersion(e) {
          ULLog.console.log("ULModuleOppoQg.onCmdSetVersion................");
          // let version = qg$e.getSystemInfoSync().platformVersion;
          let version = 1;
          ULLog.console.log("ULModuleOppoQg.onCmdSetVersion.....version: ", version);
          if (version >= 1060) {
              ULLog.console.log("ULModuleOppoQg.onCmdSetVersion........数据正在上报");
              // qg$e.reportMonitor("game_scene", 0);
          }
          else {
              ULLog.console.log("ULModuleOppoQg.onCmdSetVersion........平台版本号低于1060，请升级平台");
          }
      }
      onCmdSdkMarkManualCloseBannerCount(e) {
          this.tryDailyReset();
          this.manualCloseBannerCount++;
          ULLog.console.log("ULModuleOppoQg.onCmdSdkMarkManualCloseBannerCount", this.manualCloseBannerCount);
          this.saveRecord();
      }
      onCmdSdkGetManualCloseBannerCount(e) {
          this.tryDailyReset();
          ULLog.console.log("ULModuleOppoQg.onCmdSdkGetManualCloseBannerCount", this.manualCloseBannerCount);
          e.setReturnValue(this.manualCloseBannerCount);
      }
      onCmdPhoneVibrate(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          // if (!qg$e.vibrateShort || !qg$e.vibrateShort) {
          // }
          let type = data.type || "short";
          switch (type) {
              case "long":
                  this.vibrateLong(data);
                  break;
              default:
                  this.vibrateShort(data);
                  break;
          }
      }
      vibrateShort(data) {
          // qg$e.vibrateShort({
          //     success: () => {
          //         this.responsePhoneVibrate(1, "success", data);
          //     },
          //     fail: () => {
          //         this.responsePhoneVibrate(0, "fail", data);
          //     },
          //     complete: () => {
          //     }
          // });
      }
      vibrateLong(data) {
          // qg$e.vibrateLong({
          //     success: () => {
          //         this.responsePhoneVibrate(1, "success", data);
          //     },
          //     fail: () => {
          //         this.responsePhoneVibrate(0, "fail", data);
          //     },
          //     complete: () => {
          //     }
          // });
      }
      responsePhoneVibrate(code, msg, data) {
          ULSdkManager.getInstance().response(ULConst.CMD_PHONE_VIBRATE_RESULT, {
              code: code,
              msg: msg,
              userData: data.userData,
              type: data.type,
              intensity: data.intensity
          });
      }
      getChannelOpenIdFunc(callback) {
          ULLog.console.log("ULModuleOppoQg.getChannelOpenIdFunc");
          this.getUserInfoData({
              success: (userInfoData) => {
                  callback && callback(userInfoData.openId, null);
              },
              fail: (err) => {
                  callback && callback(null, JSON.stringify(err));
              }
          });
      }
      onCmdGetUserInfo(e) {
          e.stopImmediatePropagation();
          let data = e.data;
          let userData = data.userData || "";
          this.getUserInfoData({
              success: (userInfoData) => {
                  ULLog.console.log("ULModuleOppoQg.onCmdGetUserInfo success:", userInfoData);
                  ULSdkManager.getInstance().response(ULConst.CMD_GET_USER_INFO_MSG_RESULT, {
                      code: 1,
                      msg: "获取用户信息成功",
                      userData: userData,
                      userInfo: userInfoData.userInfo
                  });
              },
              fail: (err) => {
                  ULLog.console.log("ULModuleOppoQg.onCmdGetUserInfo fail:", err);
                  ULSdkManager.getInstance().response(ULConst.CMD_GET_USER_INFO_MSG_RESULT, {
                      code: 0,
                      msg: JSON.stringify(err),
                      userData: userData
                  });
              }
          });
      }
  }

  class ULSdkModuleLoader {
      static getObjectByModuleName(moduleName) {
          return ULSdkModuleLoader.moduleName_2_object[moduleName];
      }
      static getSubAdModuleClassName() {
          return ULSdkModuleLoader.moduleName_2_subAdvModuleClassName;
      }
      static getSubAdMainClassName() {
          return ULSdkModuleLoader.moduleName_2_subAdvMainClassName;
      }
      static initAllModules() {
          let modules = [];
          modules.push(new ULModuleCdk());
          modules.push(new ULModuleMegadata());
          modules.push(new ULModuleUserData());
          modules.push(new ULModuleClipboard());
          modules.push(new ULModuleDefault());
          modules.push(new ULModuleOppoQg());
          modules.push(new ULModulePrivacyPolicy());
          for (let i = 0, len = modules.length; i < len; i++) {
              const module = modules[i];
              let moduleClassName = module.className;
              ULSdkModuleLoader.moduleName_2_subAdvModuleClassName[moduleClassName] = module.getSubAdModuleClassName();
              ULSdkModuleLoader.moduleName_2_subAdvMainClassName[moduleClassName] = module.getAdMainClassName();
          }
          ULLog.console.log("ULSdkModuleLoader-moduleName_2_subAdvModuleClassName:", ULSdkModuleLoader.moduleName_2_subAdvModuleClassName);
          ULLog.console.log("ULSdkModuleLoader-moduleName_2_subAdvMainClassName:", ULSdkModuleLoader.moduleName_2_subAdvMainClassName);
          for (let i = 0; i < modules.length; i++) {
              const module = modules[i];
              let subModules = module.loadSubModules();
              for (let j = 0; j < subModules.length; j++) {
                  const subModule = subModules[j];
                  modules.splice(i + 1, 0, subModule);
                  i++;
              }
          }
          ULLog.console.log("ULSdkModuleLoader--modules:", modules);
          for (let i = 0; i < modules.length; i++) {
              const module = modules[i];
              ULSdkModuleLoader.moduleName_2_object[module.className] = module;
              try {
                  ULLog.console.log("ULSdkModuleLoader--module.init:", module);
                  module.init();
              }
              catch (error) {
                  ULLog.console.error(error);
              }
          }
          return modules;
      }
  }
  ULSdkModuleLoader.moduleName_2_object = {};
  ULSdkModuleLoader.moduleName_2_subAdvModuleClassName = {};
  ULSdkModuleLoader.moduleName_2_subAdvMainClassName = {};

  class ULWaitTool {
      constructor() {
          this.conditionMap = {};
      }
      ok() {
          if (ULTools.getObjSize(this.conditionMap) <= 0)
              return true;
          return false;
      }
      getConditionMap() {
          let flags = [];
          ULTools.forEachMap(this.conditionMap, (k, v) => {
              flags.push(k);
          });
          return flags;
      }
      addCondition(key) {
          this.conditionMap[key] = true;
      }
      removeCondition(key) {
          delete this.conditionMap[key];
      }
  }

  class ULChannelInfo {
      constructor() {
          this.waits = null;
          this._agreePrivacyPolicyCallBackList = [];
          this._isAgreePrivacyPolicy = false;
          this.copInfo = "{}";
          this.payInfo = {};
          this.jumpInfo = [];
          this.isSupportRecordShare = false;
          this.channelName = "default";
          this.isPayEnabled = false;
          this.isShareEnabled = false;
          this.isUseSdkRank = false;
          this.isShowUrlAdIcon = false;
          this.appName = "";
          this.equipmentModel = "";
          this.platformVersionMessage = "";
          this.osVersionMessage = "";
          this.cardType = 0;
          this.isThirdExit = false;
          this.isAbout = false;
          this.isMoreGame = false;
          this.isULMoreGame = false;
          this.isSupportClipboardData = false;
          this.isSupportInstallShortcut = false;
          this.isSupportFindMinigames = false;
          this.findMinigamesImageUrl = "";
          this.isSupportRecommendationBtn = false;
          this.isSupportJumpList = false;
          this.is4399Watermark = false;
          this.uuid = "";
          this.sdcardPath = "";
          this.packageVersion = "";
          this.copChannelId = "";
          this.ulsdkVersion = "";
          this.cdkChannelId = "";
          this._channelUserId = "";
          this.referenceBannerHeight = ULConst.DEFAULT_REFERANCE_BANNER_HEIGHT;
          this.isNewUser = true;
          this.loginDays = 0;
          this._sdkUserId = "";
          this.isSupportPasterAdv = false;
          this.gameLanguage = "";
          this.isSupportChannelMoreGameBox = false;
          this.isSupportChannelBlockAd = false;
          this.isSupportSubscribe = false;
          this.isSupportColorSign = false;
          this.isSupportGridAd = false;
          this.isSupportVideoRank = false;
          this.isSupportFavoriteGuide = false;
          this.isSupportFollowOfficialAccount = false;
          this.appIdOrPkgName = "";
          this.isSupportContentSecurityCheck = false;
          this.isJumpLeisureEnabled = false;
          this.isSupportVibrate = true;
          this.isSupportOpenUrl = false;
          this.isSupportJumpInfoVideoType = false;
          this.isSupportUserCloudStorage = false;
          this.isSupportJoinGroup = false;
          this.isSupportOpenData = false;
          this.weixinIOSPayEnabled = false;
          this.isSupportHeadlineImRank = false;
          this.isSupportLaunchReward = false;
          this.getChannelOpenIdFunc = null;
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, ULConst.PRIORITY_NONE, this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
          this.waits = new ULWaitTool();
      }
      onAgreePrivacyPolicy(callback) {
          if (this._isAgreePrivacyPolicy) {
              callback();
              return;
          }
          this._agreePrivacyPolicyCallBackList.push(callback);
      }
      get isAgreePrivacyPolicy() {
          return this._isAgreePrivacyPolicy;
      }
      set isAgreePrivacyPolicy(v) {
          if (this._isAgreePrivacyPolicy)
              return;
          this._isAgreePrivacyPolicy = v;
          if (this._isAgreePrivacyPolicy) {
              while (this._agreePrivacyPolicyCallBackList.length > 0) {
                  let callback = this._agreePrivacyPolicyCallBackList.shift();
                  callback();
              }
          }
      }
      set channelUserId(v) {
          if (this._channelUserId == v)
              return;
          this._channelUserId = v;
          if (!!this._channelUserId) {
              setTimeout(() => {
                  ULSdkManager.getInstance().statisManager.reportUserChannelId(this._channelUserId);
              }, 1000);
          }
      }
      get channelUserId() {
          return this._channelUserId;
      }
      toBaseChannelInfoData() {
          let config = ULConfig.getConfig();
          ULLog.console.log("config", config);
          let licenceInfo = config.s_sdk_licence_info == undefined ? "" : config.s_sdk_licence_info;
          licenceInfo = licenceInfo.replace(/\/n/g, "\n");
          let isShowAgeLevelInfo = !!config.i_sdk_age_level_info_mode;
          let ageLevelInfo = config.s_sdk_age_level_info || "";
          let result = {
              gameName: config.s_game_name,
              gameId: config.s_sdk_cop_game_id,
              gameLanguage: this.gameLanguage,
              channelName: this.channelName,
              appName: this.appName,
              isShowLicenceInfo: config.i_sdk_licence_info_mode == 1,
              licenceInfo: licenceInfo,
              isShowAgeLevelInfo: isShowAgeLevelInfo,
              isStartGameByTouch: config.i_sdk_start_game_by_touch == 1,
              isSupportUserCloudStorage: this.isSupportUserCloudStorage,
          };
          if (ageLevelInfo) {
              result['ageLevelInfo'] = ageLevelInfo;
          }
          return result;
      }
      toResponseData() {
          let jumpInfo = [];
          for (let i = 0; i < this.jumpInfo.length; i++) {
              const v = this.jumpInfo[i];
              if (!v.index || !v.url) {
                  ULLog.console.warn("ULChannelInfo.toResponseData jump data error!", v);
                  continue;
              }
              jumpInfo.push({
                  index: v.index,
                  url: v.url,
                  rewards: v.rewards || [],
                  bReceived: v.bReceived || false,
                  appName: v.appName || ""
              });
          }
          let config = ULConfig.getConfig();
          if (config.i_sdk_adv_reference_banner_height != null) {
              this.referenceBannerHeight = config.i_sdk_adv_reference_banner_height;
          }
          this.isJumpLeisureEnabled = this.isJumpLeisureEnabled && !!config.i_sdk_moreWonderful_mode;
          this.isSupportInstallShortcut = this.isSupportInstallShortcut && !!config.i_sdk_installShortcut_mode;
          this.isSupportRecommendationBtn = this.isSupportRecommendationBtn && !!config.i_sdk_moregame_mode;
          this.isSupportJumpList = this.isSupportJumpList && !!config.i_sdk_jumplist_mode;
          this.isSupportVibrate = this.isSupportVibrate && !!config.i_sdk_phone_vibrate;
          this.isSupportOpenUrl = this.isSupportOpenUrl && !!config.i_sdk_support_open_url;
          this.isSupportRecordShare = this.isSupportRecordShare && !!config.i_sdk_support_record_share;
          this.isSupportSubscribe = this.isSupportSubscribe && !!config.i_sdk_subscribe_mode;
          this.isSupportJoinGroup = this.isSupportJoinGroup && !!config.i_sdk_joinGroup_mode;
          this.isPayEnabled = this.isPayEnabled && !!config.i_sdk_pay_mode;
          this.isShareEnabled = this.isShareEnabled && !!config.i_sdk_share_mode;
          this.isSupportLaunchReward = this.isSupportLaunchReward && !!config.i_sdk_launchReward_mode;
          if (this.weixinIOSPayEnabled) {
              this.isPayEnabled = this.weixinIOSPayEnabled && !!config.i_sdk_pay_mode && !!config.i_sdk_weixin_iosPay_mode;
          }
          return {
              copInfo: this.copInfo,
              cardType: this.cardType,
              isThirdExit: this.isThirdExit,
              isAbout: this.isAbout,
              payInfo: this.payInfo,
              isMoreGame: this.isMoreGame,
              isULMoreGame: this.isULMoreGame,
              uuid: this.uuid,
              sdcardPath: this.sdcardPath,
              packageVersion: this.packageVersion,
              copChannelId: this.copChannelId,
              ulsdkVersion: this.ulsdkVersion,
              isShowUrlAdIcon: this.isShowUrlAdIcon,
              cdkChannelId: this.cdkChannelId,
              isPayEnabled: this.isPayEnabled,
              isShareEnabled: this.isShareEnabled,
              isUseSdkRank: this.isUseSdkRank,
              isSupportRecordShare: this.isSupportRecordShare,
              isSupportInstallShortcut: this.isSupportInstallShortcut,
              isSupportClipboardData: this.isSupportClipboardData,
              isSupportFindMinigames: this.isSupportFindMinigames,
              findMinigamesImageUrl: this.findMinigamesImageUrl,
              isSupportRecommendationBtn: this.isSupportRecommendationBtn,
              isSupportJumpList: this.isSupportJumpList,
              is4399Watermark: this.is4399Watermark,
              appName: this.appName.toLocaleLowerCase(),
              jumpInfo: jumpInfo,
              channelUserId: this.channelUserId,
              referenceBannerHeight: this.referenceBannerHeight,
              isNewUser: this.isNewUser,
              loginDays: this.loginDays,
              isSupportPasterAdv: this.isSupportPasterAdv,
              gameLanguage: this.gameLanguage,
              isSupportChannelMoreGameBox: this.isSupportChannelMoreGameBox,
              isSupportChannelBlockAd: this.isSupportChannelBlockAd,
              isSupportSubscribe: this.isSupportSubscribe,
              isSupportGridAd: this.isSupportGridAd,
              isSupportVideoRank: this.isSupportVideoRank,
              isSupportFavoriteGuide: this.isSupportFavoriteGuide,
              isSupportFollowOfficialAccount: this.isSupportFollowOfficialAccount,
              customerServiceInfo: config.t_customer_service_info,
              appIdOrPkgName: this.appIdOrPkgName,
              isSupportContentSecurityCheck: this.isSupportContentSecurityCheck,
              isJumpLeisureEnabled: this.isJumpLeisureEnabled,
              isSupportVibrate: this.isSupportVibrate,
              isSupportOpenUrl: this.isSupportOpenUrl,
              isSupportJumpInfoVideoType: this.isSupportJumpInfoVideoType,
              isSupportUserCloudStorage: this.isSupportUserCloudStorage,
              isSupportJoinGroup: this.isSupportJoinGroup,
              isSupportHeadlineImRank: this.isSupportHeadlineImRank,
              isSupportOpenData: this.isSupportOpenData,
              isSupportLaunchReward: this.isSupportLaunchReward
          };
      }
      isReady() {
          return this.waits.ok();
      }
      getPreparationFlags() {
          return this.waits.getConditionMap();
      }
      addPreparationFlag(key) {
          this.waits.addCondition(key);
      }
      removePreparationFlag(key) {
          this.waits.removeCondition(key);
      }
      onCmdSdkCollectionModuleCheckerConfig(e) {
          let config = e.getReturnValue() || [];
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "渠道信息:" });
          config.push({ type: "newLine" });
          let text = "";
          let data = this.toResponseData();
          let keys = Object.keys(data);
          keys.sort();
          for (let i = 0; i < keys.length; i++) {
              const key = keys[i];
              let value = data[key];
              text += ULTools.format("[%s] = [%s]\n", key, JSON.stringify(value));
          }
          config.push({ type: "labelArea", text: text });
          config.push({ type: "newLine" });
          e.setReturnValue(config, true);
      }
  }

  class MCConsts {
  }
  MCConsts.COP_CITY_ID_2_NAME = {
      "": "关闭城市模拟",
  };

  class ULCopManager {
      constructor() {
          this.localCop = {};
          this.serverCop = {};
          this.cop = {};
          this.copStrategySetting = {};
          this.simulateCityId = "";
          this.simulateTemplateId = "";
          this.useCopStrategyName = "";
      }
      init() {
          this.loadRecord();
          let config = ULConfig.getConfig();
          this.localCop = config.t_sdk_cop_default_cop;
          this.localCop = ULTools.jsonValToStr(this.localCop);
          ULLog.console.log(`ULCopManager-init-localCop:${JSON.stringify(this.localCop)}`);
          this.processCop();
          this.requestServerCop(false);
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, 10, this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
      }
      loadRecord() {
          let recordStr = ULStorageManager.getInstance().getStorage(this._getRecordKey()) || "{}";
          let record;
          try {
              record = JSON.parse(recordStr);
          }
          catch (error) {
              record = {};
          }
          this.useCopStrategyName = record.useCopStrategyName || "";
          this.setSimulateCityId(record.simulateCityId || "");
          this.setSimulateTemplateId(record.simulateTemplateId || "");
      }
      saveRecord() {
          let record = {
              simulateCityId: this.simulateCityId || "",
              simulateTemplateId: this.simulateTemplateId || "",
              useCopStrategyName: this.useCopStrategyName || ""
          };
          let recordStr = JSON.stringify(record);
          ULStorageManager.getInstance().setStorage(this._getRecordKey(), recordStr);
      }
      _getRecordKey() {
          let config = ULConfig.getConfig();
          return ULTools.format("ULCopManager_record_%d", config.s_sdk_megadata_game_id);
      }
      requestServerCop(bRetry) {
          let config = ULConfig.getConfig();
          if (!config.s_sdk_cop_game_id || config.s_sdk_cop_game_id == '0') {
              ULLog.console.log("禁用cop");
              return;
          }
          if (!bRetry) {
              ULSdkManager.getInstance().channelInfo.addPreparationFlag("cop");
          }
          let cop_addr = config.s_sdk_cop_addr;
          if (!cop_addr) {
              ULLog.console.log("cop地址为空");
              return;
          }
          let cop_game_id = config.s_sdk_cop_game_id;
          let cop_channel_id = config.s_sdk_cop_channel_id;
          let cop_version = config.s_sdk_cop_version;
          let uid = ULSdkManager.getInstance().channelInfo._sdkUserId;
          var reg = RegExp(/^[0-9a-zA-Z_]{1,}$/);
          if (!reg.test(uid)) {
              uid = "";
          }
          let netTimeout = config.i_net_timeout;
          let copUrl = ULTools.format("%s?gameid=%d&qudao=%d&version=%d&uid=%s", cop_addr, cop_game_id, cop_channel_id, cop_version, uid);
          if (this.simulateCityId || this.simulateTemplateId) {
              ULLog.console.warn("使用debug模式cop地址");
              copUrl = copUrl.replace("getdata/", "getdatadebug");
              if (this.simulateCityId) {
                  copUrl += "&carrierid=0&zoneid=" + this.simulateCityId;
              }
              if (this.simulateTemplateId) {
                  copUrl += "&templateId=" + this.simulateTemplateId;
              }
          }
          ULLog.console.log("ULCopManager.requestServerCop:", copUrl);
          // ULTools.httpGet({
          //     url: copUrl,
          //     timeoutMillisecond: netTimeout,
          // success: (responseText) => {
          let responseText = {
              "ad_banner_ratios": "100;100;100;100;100;100;0;0;100;100;100;100;0;0;0;0;0;100;100;0;0;0;0;0;0;0;0;100;0;100;100;100;100;0;100;0;0;0;0;0;100;0;0;100;100;0;100;100;0;100;0;100;100;0;0",
              "ad_video_ratios": "100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100",
              "alert_dialog_ratios": "0;0;0;100;0;100;0;0",
              "b_advanced_game": "1",
              "b_advanced_setting": "1",
              "b_open_statics_item": "0",
              "b_show_banner_btn_switch": "1",
              "i_sdk_adv_banner_launch_cd": "60000",
              "i_sdk_adv_oppoqg_native_exposure_cd": "10000",
              "i_sdk_native_autoRefresh_intervals": "30",
              "i_sdk_native_autoRefresh_mode": "1",
              "i_sdk_native_valid_show_count": "3",
              "ip": "111.201.54.86",
              "newyear_time_task_and_fb": "20230109;20230205",
              "newyear_time_total": "20230109;20230205",
              "notice_content": "[color=#000000][b]《魔力火线联盟‎》[/b][/color]上线啦！\u003cbr\u003e\u0026nbsp;\u003cbr\u003e\u0026nbsp;\u003cbr\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;欢迎大家来到魔力火线联盟‎的世界！",
              "o_sdk_adv_show_list": "{\"templates\":{\"SP\":{\"moduleName\":\"ULAdvOppoQgVideo\",\"rewardType\":\"show\",\"loadTypes\":\"0\",\"exp\":\"\",\"rcd\":\"\",\"args\":[\"572936\"],\"argWeights\":[\"100\"]},\"BN1\":{\"moduleName\":\"ULAdvOppoQgAutoNativeBanner\",\"rewardType\":\"show\",\"loadTypes\":\"0\",\"exp\":\"\",\"rcd\":\"\",\"args\":[\"572937\"],\"argWeights\":[\"100\"]},\"BN2\":{\"moduleName\":\"ULAdvOppoQgNativeBanner\",\"rewardType\":\"show\",\"loadTypes\":\"0\",\"exp\":\"\",\"rcd\":\"\",\"args\":[\"572937\"],\"argWeights\":[\"100\"]}},\"advSlots\":{\"2\":{\"rcd\":\"\",\"subAids\":[\"banner_PanelBagEx\",\"banner_PanelChallenge\",\"banner_PanelCollect\",\"banner_PanelCollectDetailEnemy\",\"banner_PanelCollectDetailItem\",\"banner_PanelCollectDetailTower\",\"banner_PanelDeploy\",\"banner_PanelFBCoin\",\"banner_PanelFBDoor\",\"banner_PanelFBItem\",\"banner_PanelFBItemShow\",\"banner_PanelGame\",\"banner_PanelGameLose\",\"banner_PanelGameStatis\",\"banner_PanelGameWin\",\"banner_PanelGameWinReward\",\"banner_PanelHolyItemAutoSell\",\"banner_PanelHolyItemBag\",\"banner_PanelHolyItemChoose\",\"banner_PanelHolyitemInfo\",\"banner_PanelHolyItemLvup\",\"banner_PanelHolyItemLvupSuc\",\"banner_PanelHolyitemSlotUnlock\",\"banner_PanelIntroBag\",\"banner_PanelIntroBoss\",\"banner_PanelIntroChallenge\",\"banner_PanelIntroGoal\",\"banner_PanelIntroPeace\",\"banner_PanelIntroPray\",\"banner_PanelIntroStory\",\"banner_PanelIntroSummon\",\"banner_PanelItemGet\",\"banner_PanelItemInfo\",\"banner_PanelLoading\",\"banner_PanelMainHeroUnlock\",\"banner_PanelMenuBuff\",\"banner_PanelNotice\",\"banner_PanelOffline\",\"banner_PanelPray\",\"banner_PanelRewardFactor\",\"banner_PanelSetting\",\"banner_PanelShop\",\"banner_PanelSign\",\"banner_PanelSkillInfo\",\"banner_PanelSplash\",\"banner_PanelSummon\",\"banner_PanelTalent\",\"banner_PanelTask\",\"banner_PanelTowerInfo\",\"banner_PanelTowerMainHero\",\"banner_PanelTowerNew\",\"banner_PanelTowerRushReward\",\"banner_PanelTowerShow\",\"banner_PanelTowerSlotUnlock\",\"banner_PanelTowerStar\"],\"schemes\":[{\"exp\":\"\",\"rcd\":\"\",\"tids\":[\"BN1\",\"BN2\"],\"tidWeights\":[\"100\",\"100\"],\"weight\":\"100\"}]},\"4\":{\"rcd\":\"\",\"subAids\":[\"unlock_tower_slot\",\"unlock_item_slot\",\"unlock_main_hero\",\"mine_deep\",\"box_open_now\",\"boss_ex\",\"task_reward_now\",\"bag_expand\",\"gain_buff\",\"offline_ad\",\"sign_ad\",\"goal_ad\",\"talent_ad\",\"sign_fix_ad\",\"shop_ad\",\"boss_sweep\",\"icebreak\",\"secret_add\",\"daily_damage_ad\",\"sweep_fb_coin\",\"sweep_fb_item\",\"more_reward\",\"endness_reward\",\"pick_reward\",\"finalwar_sweep\",\"seven_again\",\"explore_sub_time\",\"explore_add\",\"explore_refresh_shop\",\"smelt_auto_put\",\"newyear_sign_fix_ad\",\"newyear_game_more\",\"map_unlock_tower_slot\",\"unlock_newbie_reward_box\"],\"schemes\":[{\"exp\":\"\",\"rcd\":\"\",\"tids\":[\"SP\"],\"tidWeights\":[\"100\"],\"weight\":\"100\"}]}}}",
              "shortcut_interval_idle": "120"
          };
          responseText = JSON.stringify(responseText);
          let copJsonData = null;
          try {
              copJsonData = JSON.parse(responseText);
              ULSdkManager.getInstance().statisManager.reportCopSuccess(responseText);
          }
          catch (error) {
              ULLog.console.error(error);
              ULSdkManager.getInstance().statisManager.reportCopFail(error.message);
          }
          ULLog.console.log("copJsonData", copJsonData);
          if (copJsonData) {
              this.serverCop = copJsonData;
          }
          else {
              this.serverCop = {};
          }
          this.processCop();
          this.triggerCopInfoResult();
          if (!bRetry) {
              ULSdkManager.getInstance().channelInfo.removePreparationFlag("cop");
          }
          //     },
          //     fail: (err) => {
          //         ULLog.console.warn("ULCopManager.requestServerCop http fail!", err);
          //         if (!bRetry) {
          //             ULSdkManager.getInstance().channelInfo.removePreparationFlag("cop");
          //         }
          //         ULSdkManager.getInstance().statisManager.reportCopFail("timeout");
          //         ULTimer.callLater(ULConst.COP_RETRY_TIME_SEC, () => {
          //             ULLog.console.log(ULTools.format("ULCopManager.requestServerCop 失败后，等待%d秒重新请求cop", ULConst.COP_RETRY_TIME_SEC));
          //             this.requestServerCop(true);
          //         });
          //     },
          // });
      }
      processCop() {
          let cop = {};
          ULTools.forEachMap(this.localCop, (k, v) => {
              cop[k] = v;
          });
          ULTools.forEachMap(this.serverCop, (k, v) => {
              if (k.substr(0, 2) == "i_" && !isNaN(parseFloat(v))) {
                  v = parseFloat(v);
              }
              if (k.substr(0, 2) == "t_") {
                  try {
                      v = JSON.parse(v);
                  }
                  catch (error) {
                      ULLog.console.log("processCop error --key:", k, " val:", v);
                      v = "";
                  }
              }
              cop[k] = v;
          });
          let config = ULConfig.getConfig();
          this.copStrategySetting = cop["t_sdk_cop_strategy_setting"] || config.t_sdk_cop_strategy_setting || {};
          if (this.useCopStrategyName && this.copStrategySetting[this.useCopStrategyName]) {
              let copStrategy = this.copStrategySetting[this.useCopStrategyName] || {};
              ULTools.forEachMap(copStrategy, (k, v) => {
                  if (k.substr(0, 2) == "i_" && !isNaN(parseFloat(v))) {
                      v = parseFloat(v);
                  }
                  if (k.substr(0, 2) == "t_" && typeof (v) !== "object") {
                      try {
                          v = JSON.parse(v);
                      }
                      catch (error) {
                          ULLog.console.log("processCop error --key:", k, " val:", v);
                          v = "";
                      }
                  }
                  cop[k] = v;
              });
              this.setUseStrategyName(this.useCopStrategyName);
          }
          ULLog.console.log("processCop.copresult cop:", cop);
          this.cop = cop;
          let channelInfoCop = ULTools.clone(this.cop);
          channelInfoCop["cop_game_id"] = config.s_sdk_cop_game_id || "unknown";
          channelInfoCop["cop_channel_id"] = config.s_sdk_cop_channel_id || "unknown";
          channelInfoCop["cop_version"] = config.s_sdk_cop_version || "unknown";
          ULSdkManager.getInstance().channelInfo.copInfo = JSON.stringify(channelInfoCop);
          ULConfig.updateValueByCop(this.cop);
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_COP_CHANGED, {});
      }
      get(key, defaultValue) {
          let value = this.cop[key];
          if (value == null) {
              value = defaultValue;
          }
          return value;
      }
      getNumberValue(key, defaultValue) {
          let value = this.get(key, defaultValue);
          let numberValue = parseFloat(value);
          if (isNaN(numberValue))
              return 0;
          return numberValue;
      }
      getNumberValueInRange(key, defaultValue, minValue, maxValue) {
          let value = this.getNumberValue(key, defaultValue);
          value = ULTools.clampf(value, minValue, maxValue);
          return value;
      }
      getBooleanValue(key, defaultValue) {
          let value = this.get(key, defaultValue);
          return value == true;
      }
      setSimulateCityId(cityId) {
          this.simulateCityId = cityId;
          this.saveRecord();
          if (cityId != "") {
              let debugInfo = ULTools.format("已开启COP调试模式，模拟城市：%s_%s", cityId, ULConfig.getConfig().t_sdk_cop_simulate_city_data[cityId]);
              ULSdkManager.getInstance().moduleCheckerManager.addDebugInfo("cop", debugInfo);
          }
          else {
              ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("cop");
          }
      }
      setSimulateTemplateId(templateId) {
          this.simulateTemplateId = templateId;
          this.saveRecord();
          if (templateId != "") {
              let debugInfo = ULTools.format("已开启COP调试模式，模板id：%s", templateId);
              ULSdkManager.getInstance().moduleCheckerManager.addDebugInfo("cop_templateId", debugInfo);
          }
          else {
              ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("cop_templateId");
          }
      }
      setUseStrategyName(useCopStrategyName) {
          this.useCopStrategyName = useCopStrategyName;
          this.saveRecord();
          if (useCopStrategyName != "") {
              let debugInfo = ULTools.format("已选择COP策略，策略名：%s", useCopStrategyName);
              ULSdkManager.getInstance().moduleCheckerManager.addDebugInfo("cop_useCopStrategyName", debugInfo);
          }
          else {
              ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("cop_useCopStrategyName");
          }
      }
      triggerCopInfoResult() {
          let referenceBannerHeight = ULConst.DEFAULT_REFERANCE_BANNER_HEIGHT;
          let config = ULConfig.getConfig();
          if (config.i_sdk_adv_reference_banner_height != null) {
              referenceBannerHeight = config.i_sdk_adv_reference_banner_height;
          }
          ULSdkManager.getInstance().response(ULConst.CMD_COP_INFO_RESULT, {
              copInfo: ULSdkManager.getInstance().channelInfo.copInfo,
              referenceBannerHeight: referenceBannerHeight,
          });
      }
      onCmdSdkCollectionModuleCheckerConfig(e) {
          let config = e.getReturnValue() || [];
          let cityId_2_name = ULTools.clone(MCConsts.COP_CITY_ID_2_NAME);
          let cConfig = ULConfig.getConfig();
          if (cConfig.t_sdk_cop_simulate_city_data) {
              ULLog.console.log("t_sdk_cop_simulate_city_data", cConfig.t_sdk_cop_simulate_city_data);
              ULTools.forEachMap(cConfig.t_sdk_cop_simulate_city_data, (k, v) => {
                  cityId_2_name[k] = v;
              });
          }
          ULLog.console.log("cityId_2_name", cityId_2_name);
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "Cop模块信息:" });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "Cop策略选择:" });
          config.push({ type: "label", name: "labelUseCopStrategyName", text: "(" + (this.useCopStrategyName || "已关闭") + ")" });
          config.push({
              type: "button",
              text: "策略选择",
              onClick: () => {
                  let conf = [{ text: "关闭", value: "" }];
                  for (let key in this.copStrategySetting) {
                      conf.push({ text: key, value: key });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("选择策略", conf, (value) => {
                      this.useCopStrategyName = value;
                      this.saveRecord();
                      ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelUseCopStrategyName", this.useCopStrategyName || "已关闭");
                      if (value) {
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("已打开cop 策略，将在下次启动游戏时生效");
                      }
                      else {
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("已关闭cop 策略，将在下次启动游戏时生效");
                      }
                  });
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "cop调试模式 模板id：" });
          config.push({
              type: "label",
              text: this.simulateTemplateId ? ULTools.format("%s(已开启) ", this.simulateTemplateId) : "已关闭 ",
              name: "labelCopTemplate",
          });
          config.push({
              type: "inputBox",
              name: "inputCopTemplate"
          });
          config.push({
              type: "button",
              text: "切换开关",
              onClick: () => {
                  let templateId = "";
                  if (this.simulateTemplateId) {
                      templateId = "";
                  }
                  else {
                      templateId = ULSdkManager.getInstance().moduleCheckerManager.getItemText("inputCopTemplate");
                      if (!templateId) {
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("请先设置 模板id");
                          return;
                      }
                  }
                  this.setSimulateTemplateId(templateId);
                  ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelCopTemplate", templateId ? ULTools.format("%s(已开启) ", templateId) : "已关闭 ");
                  ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("已开启cop调试模式，策略将在下次启动游戏时生效");
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "cop调试模式 城市id：" });
          config.push({
              type: "label",
              text: ULTools.format("%s_%s", this.simulateCityId, cityId_2_name[this.simulateCityId]),
              name: "labelCopCity",
          });
          config.push({
              type: "button",
              text: "选择城市..",
              onClick: () => {
                  let keys = Object.keys(cityId_2_name);
                  let ids = [];
                  for (let i = 0; i < keys.length; i++) {
                      const key = keys[i];
                      let id = parseInt(key);
                      if (!isNaN(id)) {
                          ids.push(id);
                      }
                  }
                  ids.sort((a, b) => {
                      return a - b;
                  });
                  ids.unshift("");
                  let conf1 = [];
                  for (let i = 0; i < Math.min(15, ids.length); i++) {
                      const cityId = ids[i];
                      conf1.push({ text: ULTools.format("%s_%s", cityId, cityId_2_name[cityId]), value: cityId });
                  }
                  conf1.push({ text: "加载其他城市...", "value": "more" });
                  let conf2 = [];
                  for (let i = 0; i < ids.length; i++) {
                      const cityId = ids[i];
                      conf2.push({ text: ULTools.format("%s_%s", cityId, cityId_2_name[cityId]), value: cityId });
                  }
                  let fOnSelectCity = (cityId) => {
                      if (cityId == "more") {
                          ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("选择需要模拟的城市：", conf2, fOnSelectCity);
                          return;
                      }
                      ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelCopCity", ULTools.format("%s_%s", cityId, cityId_2_name[cityId]));
                      this.setSimulateCityId(cityId);
                      if (cityId != "") {
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("已开启cop调试模式，策略将在下次启动游戏时生效");
                      }
                      else {
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("cop调试模式已关闭");
                      }
                  };
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("选择需要模拟的城市：", conf1, fOnSelectCity);
              },
          });
          config.push({
              type: "button",
              text: "重新请求cop",
              onClick: () => {
                  ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "重新请求cop不能保证所有功能生效，仅供查看cop使用。切换cop城市模拟后，请重新启动游戏测试功能", "知道了", () => {
                      ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("已重新请求cop，不能保证所有功能生效");
                      this.requestServerCop(false);
                  });
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "查看cop：" });
          config.push({
              type: "button",
              text: "默认cop",
              onClick: () => {
                  let cop = this.localCop;
                  let keys = Object.keys(cop);
                  keys.sort();
                  let copInfo = "默认cop：\n";
                  for (let i = 0; i < keys.length; i++) {
                      const key = keys[i];
                      let value = cop[key];
                      copInfo += ULTools.format("[%s] = [%s]\n", key, value);
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelCop", copInfo);
              },
          });
          config.push({
              type: "button",
              text: "远程cop",
              onClick: () => {
                  let cop = this.serverCop;
                  let keys = Object.keys(cop);
                  keys.sort();
                  let copInfo = "远程cop：\n";
                  for (let i = 0; i < keys.length; i++) {
                      const key = keys[i];
                      let value = cop[key];
                      copInfo += ULTools.format("[%s] = [%s]\n", key, value);
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelCop", copInfo);
              },
          });
          config.push({
              type: "button",
              text: "生效cop",
              onClick: () => {
                  let cop = this.cop;
                  let keys = Object.keys(cop);
                  keys.sort();
                  let copInfo = "生效cop：\n";
                  for (let i = 0; i < keys.length; i++) {
                      const key = keys[i];
                      let value = cop[key];
                      copInfo += ULTools.format("[%s] = [%s]\n", key, value);
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelCop", copInfo);
              },
          });
          config.push({ type: "newLine" });
          config.push({
              type: "labelArea",
              text: "<<这里显示cop信息>>",
              name: "labelCop",
          });
          config.push({ type: "newLine" });
          e.setReturnValue(config, true);
      }
  }

  class ULStatisEventId {
  }
  ULStatisEventId.OPEN_SHARE = "100";
  ULStatisEventId.CLICK_SHARE = "101";
  ULStatisEventId.ADD_SUBSCRIPTION = "102";
  ULStatisEventId.CLICK_SUBSCRIPTION = "103";
  ULStatisEventId.CLICK_MORE_GAME_ICON_SINGLE = "104";
  ULStatisEventId.CLICK_MORE_GAME_ICON_REWARD = "105";
  ULStatisEventId.CLICK_MORE_GAME_ICON_LIST = "106";
  ULStatisEventId.CDK = "107";
  ULStatisEventId.CLICK_MORE_GAME_CHANNEL_SYSTEM_BUTTON = "108";
  ULStatisEventId.NATIVE_ADV_CLICK_EVENT = "109";
  ULStatisEventId.WEIXIN_TOUFANG = "200";
  ULStatisEventId.IOS_USERID_EVENT = "201";
  ULStatisEventId.REAL_NAME_AUTHENTICATION = "202";
  ULStatisEventId.LOGIN_EVENT = "203";
  ULStatisEventId.GAME_PACK_EVENT = "204";
  ULStatisEventId.INSTALLATION_SOURCE = "205";
  ULStatisEventId.OPPO_CUSTOM_EVENT = "206";
  ULStatisEventId.LAUNCH_SCENE = "300";
  ULStatisEventId.ADD_SHORTCUT = "301";
  ULStatisEventId.ADD_FAVORITES = "302";
  ULStatisEventId.NATIVE_ADV_DATA_UPLOAD_EVENT = "888";

  class ULStatisManager {
      constructor() {
          this.bUploading = false;
          this.lastTimerLoopTime = null;
          this.isGamePause = false;
          this.pointEventLog = {};
          this.pointEventCategoryId_2_enabled = null;
          this.gameStartDataPreparationFlags = {};
          this.commonEventLog = {};
          this.levelStartLog = {};
          this.levelCompletetLog = {};
          this.videoPointLog = {};
          this.buyActionLog = {};
          this.coinChangeLog = {};
      }
      init() {
          this.channelInfoUuid = ULSdkManager.getInstance().channelInfo.uuid;
          this.megadataId = ULConfig.getConfig().s_sdk_megadata_server_type_id;
          this.loadRecord();
          ULTimer.callLoop(ULConfig.getConfig().i_sdk_megadata_upload_span / 1000, this.onTimerLoop.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_START, ULConst.PRIORITY_NONE, this.onCmdSdkOnGameStart.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_PAUSE, ULConst.PRIORITY_NONE, this.onCmdSdkOnGamePause.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_GAME_RESUME, ULConst.PRIORITY_NONE, this.onCmdSdkOnGameResume.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_ON_COP_CHANGED, ULConst.PRIORITY_NONE, this.onCmdSdkOnCopChanged.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, 9, this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
      }
      loadRecord() {
          let recordStr = ULStorageManager.getInstance().getStorage(this._getRecordKey()) || "{}";
          let record;
          try {
              record = JSON.parse(recordStr);
          }
          catch (error) {
              record = {};
          }
          this.cacheItems = record.cacheItems || [];
          let mode = record.postMegadataTestMode || 0;
          this.postMegadataTestUserId = record.postMegadataTestUserId;
          this.setPostMegadataMode(mode);
      }
      saveRecord() {
          let record = {
              cacheItems: this.cacheItems || [],
              postMegadataTestUserId: this.postMegadataTestUserId,
              postMegadataTestMode: this.postMegadataTestMode
          };
          let recordStr = JSON.stringify(record);
          ULStorageManager.getInstance().setStorage(this._getRecordKey(), recordStr);
      }
      _getRecordKey() {
          let config = ULConfig.getConfig();
          return ULTools.format("ULStatisManager_record_%d", config.s_sdk_megadata_game_id);
      }
      onTimerLoop(timer) {
          if (this.cacheItems.length <= 0) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULStatisManager.onTimerLoop no cacheItems");
              return;
          }
          this.tryUploadToServer();
      }
      setPostMegadataMode(mode) {
          this.postMegadataTestMode = mode;
          this.saveRecord();
          if (!!this.postMegadataTestMode) {
              this.channelInfoUuid = this.postMegadataTestUserId;
              let debugInfo = "数据上传已开启测试模式\n测试用户id:" + this.postMegadataTestUserId;
              ULSdkManager.getInstance().moduleCheckerManager.addDebugInfo("postMegadataTestModeInfo", debugInfo);
          }
          else {
              this.channelInfoUuid = ULSdkManager.getInstance().channelInfo.uuid;
              ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("postMegadataTestModeInfo");
          }
      }
      getPostMegadataMode() {
          return this.postMegadataTestMode;
      }
      _report(typeid, updata) {
          let config = ULConfig.getConfig();
          let closeIds = config.s_sdk_megadata_close_table_type_ids || "";
          let closeIdsList = closeIds.split(";");
          for (let index = 0; index < closeIdsList.length; index++) {
              let closeId = ULTools.format("%s-%s", this.megadataId, closeIdsList[index]);
              if (closeId == typeid) {
                  ULLog.console.log("ULStatisManager._report 大数据分表控制表数据上传closeId:", closeId);
                  return;
              }
          }
          ULLog.console.log("ULStatisManager._report i_sdk_megadata_mode 1 ", config.i_sdk_megadata_mode);
          try {
              let otherItem = { typeid: typeid, updata: updata };
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_REPORT_ULSDK_EVENT, {
                  parameter: otherItem
              });
          }
          catch (error) {
              ULLog.console.log("ULStatisManager.CMD_SDK_ON_REPORT_ULSDK_EVENT error:", error);
          }
          if (!config.i_sdk_megadata_mode) {
              ULLog.console.log("ULStatisManager._report !i_sdk_megadata_mode 关闭统计功能");
              return;
          }
          if (!!this.postMegadataTestMode) {
              let replaceVal = this.megadataId + "-";
              typeid = typeid.replace(replaceVal, "1-");
              ULLog.console.log("ULStatisManager._report postMegadataTestMode 已打开 typeid:", typeid);
          }
          if (updata.length == 0) {
              ULLog.console.log("ULStatisManager._report !updata 无有效数据，无法上报:", updata);
              return;
          }
          for (let i = 0; i < updata.length; i++) {
              let v = updata[i];
              if (typeof (v) != "string") {
                  if (v == null) {
                      v = "";
                  }
                  else {
                      v = "" + v;
                  }
              }
              updata[i] = v;
          }
          let item = { typeid: typeid, updata: updata };
          this.cacheItems.push(item);
          if (this.cacheItems.length >= ULConst.STATIS_UPLOAD_SINGLE_REQUEST_MAX_COUNT) {
              this.tryUploadToServer();
          }
      }
      tryUploadToServer() {
          if (this.bUploading) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULStatisManager.tryUploadToServer 数据上传中");
              return;
          }
          let uploadCount = Math.min(this.cacheItems.length, ULConst.STATIS_UPLOAD_SINGLE_REQUEST_MAX_COUNT);
          if (uploadCount <= 0) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULStatisManager.tryUploadToServer 没有数据需要上传");
              return;
          }
          this.bUploading = true;
          let uploadItems = this.cacheItems.slice(0, uploadCount);
          this.cacheItems.splice(0, uploadCount);
          this.saveRecord();
          let config = ULConfig.getConfig();
          let url = config.s_sdk_megadata_url;
          if (!!this.postMegadataTestMode) {
              url = config.s_sdk_megadata_test_url;
          }
          if (!url) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULStatisManager.tryUploadToServer url为空");
              return;
          }
          if (!!config.i_sdk_megadata_encrypt) {
              ULTools.httpPostEncryption({
                  url: url,
                  postString: JSON.stringify(uploadItems),
                  timeoutMillisecond: config.i_net_timeout,
                  success: (responseText) => {
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("  加密统计上报成功!");
                      this.bUploading = false;
                  },
                  fail: (err) => {
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("  加密统计上报错误!", err);
                      this.cacheItems = uploadItems.concat(this.cacheItems);
                      this.saveRecord();
                      this.bUploading = false;
                  },
              });
              return;
          }
          let postData = "updata=" + JSON.stringify(uploadItems);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULStatisManager.tryUploadToServer");
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  url:", url);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  postData:", postData);
          postData = postData.replace(";", ",");
          ULTools.httpPost({
              url: url,
              postData: postData,
              timeoutMillisecond: config.i_net_timeout,
              success: (responseText) => {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("  统计上报成功!");
                  this.bUploading = false;
              },
              fail: (err) => {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("  统计上报错误!", err);
                  this.cacheItems = uploadItems.concat(this.cacheItems);
                  this.saveRecord();
                  this.bUploading = false;
              },
          });
      }
      uploadToServerRightNow(typeid, updata) {
          let config = ULConfig.getConfig();
          let url = config.s_sdk_megadata_url;
          if (!config.i_sdk_megadata_mode) {
              ULLog.console.log("ULStatisManager.uploadToServerRightNow !i_sdk_megadata_mode 关闭统计功能");
              return;
          }
          if (!!this.postMegadataTestMode) {
              url = config.s_sdk_megadata_test_url;
              let replaceVal = this.megadataId + "-";
              typeid = typeid.replace(replaceVal, "1-");
              ULLog.console.log("ULStatisManager.uploadToServerRightNow postMegadataTestMode 已打开 typeid:", typeid);
          }
          let item = { typeid: typeid, updata: updata };
          let uploadItems = [];
          uploadItems.push(item);
          if (!!config.i_sdk_megadata_encrypt) {
              ULTools.httpPostEncryption({
                  url: url,
                  postString: JSON.stringify(uploadItems),
                  timeoutMillisecond: config.i_net_timeout,
                  success: (responseText) => {
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("  统计上报成功!");
                  },
                  fail: (err) => {
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("  统计上报错误!", err);
                  },
              });
              return;
          }
          let postData = "updata=" + JSON.stringify(uploadItems);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULStatisManager.uploadToServerRightNow");
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  url:", url);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  postData:", postData);
          ULTools.httpPost({
              url: url,
              postData: postData,
              timeoutMillisecond: config.i_net_timeout,
              success: (responseText) => {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("  统计上报成功!");
              },
              fail: (err) => {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("  统计上报错误!", err);
              },
          });
      }
      genPointEventLog() {
          let rawLog = this.pointEventLog;
          let arr = [];
          let arr1 = [];
          ULTools.forEachMap(rawLog, (k, v) => {
              let eventId = parseInt(k);
              arr1.push({ eventId: eventId, v: v });
          });
          arr1 = ULTools.sortArrayByField(arr1, "eventId");
          for (let i = 0; i < arr1.length; i++) {
              const v = arr1[i];
              let arr2 = [];
              ULTools.forEachMap(v.v, (k, count) => {
                  let paramId = parseInt(k);
                  arr2.push({ paramId: paramId, count: count });
              });
              arr2 = ULTools.sortArrayByField(arr2, "paramId");
              for (let j = 0; j < arr2.length; j++) {
                  const vv = arr2[j];
                  arr.push(ULTools.format("%d-%d: %d", v.eventId, vv.paramId, vv.count));
              }
          }
          return arr;
      }
      getCommonEventLog() {
          let arr = [];
          let keyArr = [];
          let rawLog = this.commonEventLog;
          ULLog.console.log("ULStatisManager.getCommonEventLog rawLog:", rawLog);
          ULTools.forEachMap(rawLog, (k, v) => {
              keyArr.push(k);
          });
          keyArr.sort();
          for (let index = 0; index < keyArr.length; index++) {
              let key = keyArr[index];
              arr.push(ULTools.format("%s: %d", key, rawLog[key]));
          }
          return arr;
      }
      getLevelStartLog() {
          let arr = [];
          let keyArr = [];
          let rawLog = this.levelStartLog;
          ULLog.console.log("ULStatisManager.getLevelStartLog rawLog:", rawLog);
          ULTools.forEachMap(rawLog, (k, v) => {
              keyArr.push(k);
          });
          keyArr.sort();
          for (let index = 0; index < keyArr.length; index++) {
              let key = keyArr[index];
              arr.push(ULTools.format("%s: %d", key, rawLog[key]));
          }
          return arr;
      }
      getLevelCompletetLog() {
          let arr = [];
          let keyArr = [];
          let rawLog = this.levelCompletetLog;
          ULLog.console.log("ULStatisManager.getLevelCompletetLog rawLog:", rawLog);
          ULTools.forEachMap(rawLog, (k, v) => {
              keyArr.push(k);
          });
          keyArr.sort();
          for (let index = 0; index < keyArr.length; index++) {
              let key = keyArr[index];
              arr.push(ULTools.format("%s: %d   时长：%d", key, rawLog[key].count, rawLog[key].playTime));
          }
          return arr;
      }
      getVideoPointLog() {
          let arr = [];
          let keyArr = [];
          let rawLog = this.videoPointLog;
          ULLog.console.log("ULStatisManager.getVideoPointLog rawLog:", rawLog);
          ULTools.forEachMap(rawLog, (k, v) => {
              keyArr.push(k);
          });
          keyArr.sort();
          for (let index = 0; index < keyArr.length; index++) {
              let key = keyArr[index];
              arr.push(ULTools.format("%s: %d", key, rawLog[key]));
          }
          return arr;
      }
      getBuyActionLog() {
          let arr = [];
          let keyArr = [];
          let rawLog = this.buyActionLog;
          ULLog.console.log("ULStatisManager.getBuyActionLog rawLog:", rawLog);
          ULTools.forEachMap(rawLog, (k, v) => {
              keyArr.push(k);
          });
          keyArr.sort();
          for (let index = 0; index < keyArr.length; index++) {
              let key = keyArr[index];
              arr.push(ULTools.format("%s: %d", key, rawLog[key]));
          }
          return arr;
      }
      getCoinChangeLog() {
          let arr = [];
          let keyArr = [];
          let rawLog = this.coinChangeLog;
          ULLog.console.log("ULStatisManager.coinChangeLog rawLog:", rawLog);
          ULTools.forEachMap(rawLog, (k, v) => {
              keyArr.push(k);
          });
          keyArr.sort();
          for (let index = 0; index < keyArr.length; index++) {
              let key = keyArr[index];
              arr.push(ULTools.format("%s  次数：%d   货币数量：%d", key, rawLog[key].count, rawLog[key].changeCount));
          }
          return arr;
      }
      isReady() {
          if (ULTools.getObjSize(this.gameStartDataPreparationFlags) <= 0)
              return true;
          return false;
      }
      getPreparationFlags() {
          let flags = [];
          ULTools.forEachMap(this.gameStartDataPreparationFlags, (k, v) => {
              flags.push(k);
          });
          return flags;
      }
      addPreparationFlag(key) {
          this.gameStartDataPreparationFlags[key] = true;
      }
      removePreparationFlag(key) {
          delete this.gameStartDataPreparationFlags[key];
      }
      setGameStartSourceMsg(param) {
          this.gameStartSourceMsg = param;
      }
      reportGameStart() {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_BASE_INFO);
          let updata = [];
          updata.push(this.gameStartTimeFormattedStr);
          updata.push(this.channelInfoUuid);
          updata.push("");
          updata.push("");
          updata.push("");
          updata.push(config.s_game_name);
          updata.push(config.s_sdk_cop_game_id);
          updata.push(channelInfo.appName);
          updata.push(config.s_sdk_cop_channel_id);
          updata.push(config.s_sdk_cop_version);
          updata.push(channelInfo.osVersionMessage || "");
          updata.push("gameStart");
          updata.push("");
          updata.push(config.s_sdk_version);
          updata.push(channelInfo.equipmentModel || "");
          updata.push(this.gameStartSourceMsg);
          updata.push(channelInfo.platformVersionMessage || "");
          updata.push("");
          updata.push("");
          updata.push("");
          this._report(typeid, updata);
      }
      reportPayRequest() {
          this.reportPayResult("", "", "requestPay");
      }
      reportPaySuccess(payType, priceCent) {
          let trimPriceCent = priceCent || 0;
          let strPrice = ULTools.format("%.2f", trimPriceCent / 100);
          this.reportPayResult(payType, strPrice, "success");
      }
      reportPayCancel(payType, priceCent) {
          let trimPriceCent = priceCent || 0;
          let strPrice = ULTools.format("%.2f", trimPriceCent / 100);
          this.reportPayResult(payType, strPrice, "cancel");
      }
      reportPayFail(payType, priceCent) {
          let trimPriceCent = priceCent || 0;
          let strPrice = ULTools.format("%.2f", trimPriceCent / 100);
          this.reportPayResult(payType, strPrice, "failed");
      }
      reportPayResult(payType, price, result) {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_PAY_INFO);
          let updata = [];
          updata.push(ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
          updata.push(this.channelInfoUuid);
          updata.push("");
          updata.push(channelInfo.channelName);
          updata.push(payType || "");
          updata.push(price || "");
          updata.push(result || "");
          updata.push(config.s_sdk_cop_version);
          updata.push(config.s_sdk_version);
          this._report(typeid, updata);
      }
      reportAdvBranchRequest(advItem, channel, sdkAdvId) {
          advItem.statisChannelName = channel;
          advItem.statisSdkAdvId = sdkAdvId;
          this.reportAdvInfo(channel, advItem.showAdvType, "branchAdvRequest", "", advItem.advGroupId, advItem.advId, advItem.tag, "", sdkAdvId, "");
      }
      reportAdvTotalRequest(advItem) {
          this.reportAdvInfo("", advItem.advType, "totalAdvRequest", "", advItem.advGroupId, advItem.advId, advItem.tag, "", "", "");
      }
      reportAdvSuccess(advItem, nativeAdvTitle, actualShowCount = 1) {
          advItem.statisNativeAdTitle = nativeAdvTitle;
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "success", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "", actualShowCount.toString());
      }
      reportAdvClicked(advItem) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "clicked", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvPlayStart(advItem) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "playStart", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvPlayCompletion(advItem) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "playCompletion", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvLoadAdvRequest(advItem) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "loadAdvRequest", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvLoadAdvSuccess(advItem) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "loadAdvSuccess", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvLoadAdvFailed(advItem, failMsg) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "loadAdvFailed", failMsg, advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvFail(advItem, failMsg) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "failed", failMsg, advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
      }
      reportAdvClose(advItem, advShowTimeSec) {
          this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "hide", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, advShowTimeSec);
      }
      reportAdvInfo(channel, advType, result, failMsg, advGroupId, advId, advEventInfo, nativeAdvInfo, sdkAdvId, advShowTimeSec, actualShowCount = "") {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_ADV_INFO);
          let updata = [];
          if (nativeAdvInfo && nativeAdvInfo.length > 6) {
              nativeAdvInfo = nativeAdvInfo.substr(0, 6);
          }
          updata.push(ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
          updata.push(this.channelInfoUuid);
          updata.push("");
          updata.push(channel || "");
          updata.push(advType || "");
          updata.push(result || "");
          updata.push(failMsg || "");
          updata.push(config.s_sdk_cop_version);
          updata.push(config.s_sdk_version);
          updata.push(advGroupId || "");
          updata.push(advId || "");
          updata.push(advEventInfo || "");
          updata.push(nativeAdvInfo || "");
          updata.push(sdkAdvId || "");
          updata.push(advShowTimeSec || "");
          updata.push("");
          updata.push(actualShowCount);
          ULLog.console.log("reportAdvInfo result:", result);
          if (result == 'hide') {
              this.uploadToServerRightNow(typeid, updata);
          }
          else {
              this._report(typeid, updata);
          }
      }
      reportCopSuccess(responseJson) {
          this.reportCopResult("success", "", responseJson);
      }
      reportCopFail(failMsg) {
          this.reportCopResult("filed", failMsg, "");
      }
      reportCopResult(result, failMsg, responseJson) {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_COP_REQUEST);
          let updata = [];
          responseJson = "";
          updata.push(ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
          updata.push(this.channelInfoUuid);
          updata.push("");
          updata.push("coprequest");
          updata.push(result || "");
          updata.push(config.s_sdk_cop_version);
          updata.push(config.s_sdk_version);
          updata.push(failMsg || "");
          updata.push(responseJson || "");
          this._report(typeid, updata);
      }
      reportUserEvent(rawData) {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_USER_EVENT);
          let updata = [];
          updata.push(ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
          updata.push(this.channelInfoUuid);
          updata.push("");
          for (let i = 0; i < rawData.length; i++) {
              const v = rawData[i];
              updata.push(v);
          }
          updata.push(config.s_sdk_cop_version);
          updata.push(config.s_sdk_version);
          updata.push(channelInfo.channelName);
          this._report(typeid, updata);
      }
      reportUserChannelId(channelId) {
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_COMMON_EVENT);
          let updata = [];
          updata.push(ULStatisEventId.LOGIN_EVENT);
          updata.push("1");
          updata.push(channelId);
          updata.push("0");
          this.reportUserActionEvent(updata, typeid);
      }
      reportUserActionEvent(rawData, typeid) {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let sdkIndexObj = {
              levelStart: [0, 1, 2, 5, 6, 7],
              levelComplete: [0, 1, 2, 11, 12, 13, 14],
              coinChange: [0, 1, 2, 7, 8, 9],
              itemBuy: [0, 1, 2, 6, 7, 8],
              buyAction: [0, 1, 2, 6, 7, 8],
              commonEvent: [0, 1, 2, 6, 7, 8],
              videoPointEvent: [0, 1, 2, 5, 6, 7,],
          };
          let sdkValue = [
              ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"),
              this.channelInfoUuid,
              "",
              config.s_sdk_cop_version,
              config.s_sdk_version,
              channelInfo.copChannelId
          ];
          let updata = [];
          if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_COMMON_EVENT)) {
              try {
                  rawData.length > 0 && ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_COMMONEVENT_ID_POST, { commonEventId: rawData[0] });
              }
              catch (error) { }
              updata = this.rebuildData(sdkIndexObj.commonEvent, sdkValue, rawData);
              let key = rawData[0] + "-" + rawData[1];
              this.commonEventLog[key] = !!this.commonEventLog[key] ? (this.commonEventLog[key] + 1) : 1;
          }
          else if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_LEVEL_START_EVENT)) {
              updata = this.rebuildData(sdkIndexObj.levelStart, sdkValue, rawData);
              let key = rawData[0];
              this.levelStartLog[key] = !!this.levelStartLog[key] ? (this.levelStartLog[key] + 1) : 1;
          }
          else if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_LEVEL_COMPLETE_EVENT)) {
              try {
                  if (rawData.length >= 2) {
                      let state = rawData[1] || "0";
                      if (state == "1") {
                          let levelName = rawData[0] || "";
                          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_LEVELCOMPLETEEVENT_ID_POST, { levelCompleteEventId: levelName });
                      }
                  }
              }
              catch (error) { }
              let key = rawData[0] + "-" + rawData[1];
              if (!this.levelCompletetLog[key]) {
                  this.levelCompletetLog[key] = { count: 0, playTime: 0 };
              }
              this.levelCompletetLog[key].count = !!this.levelCompletetLog[key].count ? (this.levelCompletetLog[key].count + 1) : 1;
              this.levelCompletetLog[key].playTime = !!this.levelCompletetLog[key].playTime ? (this.levelCompletetLog[key].playTime + parseInt(rawData[rawData.length - 1])) : parseInt(rawData[rawData.length - 1]);
              let time = rawData.pop();
              sdkValue.splice(3, 0, time);
              updata = this.rebuildData(sdkIndexObj.levelComplete, sdkValue, rawData);
          }
          else if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_VIDEO_POINT_EVENT)) {
              updata = this.rebuildData(sdkIndexObj.videoPointEvent, sdkValue, rawData);
              let key = rawData[0] + "-" + rawData[1];
              this.videoPointLog[key] = !!this.videoPointLog[key] ? (this.videoPointLog[key] + 1) : 1;
          }
          else if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_BUY_ACTION)) {
              updata = this.rebuildData(sdkIndexObj.buyAction, sdkValue, rawData);
              let key = rawData[0] + "-" + rawData[1] + "-" + rawData[2];
              this.buyActionLog[key] = !!this.buyActionLog[key] ? (this.buyActionLog[key] + 1) : 1;
          }
          else if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_COIN_CHANGE_EVENT)) {
              updata = this.rebuildData(sdkIndexObj.coinChange, sdkValue, rawData);
              let key = rawData[0] + "-" + rawData[1] + "-" + rawData[3];
              if (!this.coinChangeLog[key]) {
                  this.coinChangeLog[key] = { count: 0, changeCount: 0 };
              }
              this.coinChangeLog[key].count = !!this.coinChangeLog[key].count ? (this.coinChangeLog[key].count + 1) : 1;
              this.coinChangeLog[key].changeCount = !!this.coinChangeLog[key].changeCount ? (this.coinChangeLog[key].changeCount + parseInt(rawData[2])) : parseInt(rawData[2]);
          }
          else if (typeid == ULTools.format("%s-%s", config.s_sdk_megadata_server_type_id, ULConst.STATIS_TYPE_ITEM_BUY)) {
              updata = this.rebuildData(sdkIndexObj.itemBuy, sdkValue, rawData);
          }
          this._report(typeid, updata);
      }
      rebuildData(sdkIndex, sdkValue, rawData) {
          let mSdkIndex = ULTools.clone(sdkIndex);
          let mSdkValue = ULTools.clone(sdkValue);
          let mRawData = ULTools.clone(rawData);
          let updata = [];
          while (mSdkValue.length || mRawData.length) {
              let index = mSdkIndex[0];
              if (index == updata.length) {
                  updata.push(mSdkValue.shift());
                  mSdkIndex.shift();
              }
              else if (mRawData.length) {
                  updata.push(mRawData.shift());
              }
              else {
                  updata.push("");
              }
          }
          return updata;
      }
      reportOnlineTime(onlineTimeSec) {
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_ONLINE_TIME);
          let updata = [];
          updata.push(ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
          updata.push(this.channelInfoUuid);
          updata.push("");
          updata.push(this.gameStartTimeFormattedStr || "");
          updata.push(onlineTimeSec.toString() || "0");
          updata.push(config.s_sdk_cop_version);
          updata.push(config.s_sdk_version);
          this.uploadToServerRightNow(typeid, updata);
      }
      reportShareSuccess(index) {
          let singleField = ["openShare", "success", index || 0].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["open_share"] || "100", 1, index || 0]);
          }
      }
      reportShareFail(index) {
          let singleField = ["openShare", "fail", index || 0].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["open_share"] || "100", 0, index || 0]);
          }
      }
      reportAppShare(index) {
          let singleField = ["openShare", "appShare", index || 0].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["open_share"] || "100", 2, index || 0]);
          }
      }
      reportShareClick(queryMsg) {
          let singleField = ["clickShare", queryMsg || ""].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["click_share"] || "101", queryMsg || "", ""]);
          }
      }
      reportAddSubcrible(code) {
          let singleField = ["addSubscrible", code || ""].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["add_subscrible"] || "102", code || "", ""]);
          }
      }
      reportSubcribleClick(queryMsg) {
          let singleField = ["clickSubscrible", queryMsg || ""].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["click_subscrible"] || "103", queryMsg || "", ""]);
          }
      }
      reportClickMoreGameIcon(iconType, gameIndex) {
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let eventId = sdkEventIds["click_more_game_icon_list"] || "106";
          if (iconType == "single") {
              eventId = sdkEventIds["click_more_game_icon_single"] || "104";
          }
          else if (iconType == "reward") {
              eventId = sdkEventIds["click_more_game_icon_reward"] || "105";
          }
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              this.reportPointEvent(eventId, parseInt(gameIndex));
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", eventId, gameIndex || "", ""]);
          }
      }
      reportClickMoreGameButtonToChannelSystem() {
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let eventId = sdkEventIds["click_more_game_channel_system_button"] || "108";
          let megdataUrl = config.s_sdk_megadata_url || "";
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              this.reportPointEvent(eventId, 0);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", eventId, "", ""]);
          }
      }
      reportOpenCdk(code) {
          let singleField = ["openCdk", code].join("_");
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          let megdataUrl = config.s_sdk_megadata_url || "";
          ULLog.console.log("ULStatisManager.reportOpenCdk code:", code);
          if (megdataUrl.indexOf(`megadata.${ULTools.getCommonHost()}.cn`) >= 0) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_MEGADATA_SERVER, ["commonEvent", singleField]);
          }
          else {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["open_cdk"] || "107", code || 0, ""]);
          }
      }
      reportJumpGame(eventId, channel, sourceGameId, type, targetIconId) {
          let config = ULConfig.getConfig();
          let openIds = config.s_sdk_jump_game_statis_game_indexes || "";
          let openIdsList = openIds.split(";");
          let openStatus = {};
          for (let index = 0; index < openIdsList.length; index++) {
              openStatus[openIdsList[index]] = true;
          }
          let gameIndex = targetIconId.split("_")[0];
          if (!openStatus[gameIndex]) {
              ULLog.console.log("ULStatisManager.reportJumpGame 当前跳转的游戏数据上报没开,targetIconId:", targetIconId);
              return;
          }
          let typeid = config.s_sdk_megadata_server_jump_game_type_id;
          let updata = [];
          updata.push(eventId);
          updata.push(channel);
          updata.push(sourceGameId);
          updata.push(type);
          updata.push(targetIconId);
          this._report(typeid, updata);
      }
      reportToufang(aid, traceId) {
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["weixin_toufang"] || "200", aid, traceId]);
      }
      reportLaunchScene(scene) {
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["launch_scene"] || "300", scene, ""]);
      }
      reportAddShortcut(code) {
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["add_shortcut"] || "301", code, ""]);
      }
      reportAddFavorites(code) {
          let config = ULConfig.getConfig();
          let sdkEventIds = config.t_sdk_common_event_ids || {};
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_POST_MEGADATA, ["commonEvent", sdkEventIds["add_favorites"] || "302", code, ""]);
      }
      _checkPointEventSwitch(eventId) {
          if (!this.pointEventCategoryId_2_enabled) {
              let config = ULConfig.getConfig();
              let arr = config.s_sdk_megadata_point_event_open_category_ids.split(";");
              let pointEventCategoryId_2_enabled = {};
              for (let i = 0; i < arr.length; i++) {
                  const categoryId = arr[i];
                  pointEventCategoryId_2_enabled[categoryId] = true;
              }
              this.pointEventCategoryId_2_enabled = pointEventCategoryId_2_enabled;
          }
          let categoryId = Math.floor(eventId / 1000);
          return !!this.pointEventCategoryId_2_enabled[categoryId];
      }
      reportPointEvent(eventId, param1) {
          eventId = parseInt(eventId) || 0;
          if (isNaN(eventId))
              eventId = 0;
          eventId = ULTools.clampf(eventId, 0, 0xffff);
          param1 = parseInt(param1) || 0;
          if (isNaN(param1))
              param1 = 0;
          param1 = ULTools.clampf(param1, 0, 0xffff);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULStatisManager.reportPointEvent", eventId, param1);
          if (!this._checkPointEventSwitch(eventId)) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("  打点统计上报未开启：", ULConfig.getConfig().s_sdk_megadata_point_event_open_category_ids);
              return;
          }
          let shortUserId = "";
          let sdkUserId = ULSdkManager.getInstance().channelInfo._sdkUserId;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log(ULTools.format("  sdkUserId = [%s]", sdkUserId));
          let reg = /(\d+)_(.*)_(\d+)/;
          if (reg.test(sdkUserId)) {
              shortUserId = RegExp.$2;
              if (!shortUserId || shortUserId.length != 22) {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("  核心长度不匹配，直接使用sdkUserId");
                  shortUserId = sdkUserId;
              }
              else {
                  shortUserId = shortUserId.substr(2, shortUserId.length - 2);
              }
          }
          else {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("  userId规则不匹配，直接使用sdkUserId");
              shortUserId = sdkUserId;
          }
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log(ULTools.format("  shortUserId = [%s]", shortUserId));
          let channelInfo = ULSdkManager.getInstance().channelInfo;
          let config = ULConfig.getConfig();
          let typeid = ULTools.format("%s-%s", this.megadataId, ULConst.STATIS_TYPE_POINT_EVENT);
          let updata = [];
          updata.push(shortUserId);
          updata.push(config.s_sdk_cop_channel_id);
          updata.push(eventId.toString());
          updata.push(param1.toString());
          this._report(typeid, updata);
          let log = this.pointEventLog;
          let v = log[eventId];
          if (!v) {
              v = {};
              log[eventId] = v;
          }
          v[param1] = (v[param1] || 0) + 1;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  log", log);
      }
      onCmdSdkOnGameStart(e) {
          this.isGamePause = false;
          this.gameStartTimeFormattedStr = ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
          this.gameLastResumeTime = ULTools.time();
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULStatiManager.onCmdSdkOnGameStart", this.gameStartTimeFormattedStr, this.gameLastResumeTime);
          if (this.isReady()) {
              this.reportGameStart();
              this.tryUploadToServer();
              return;
          }
          let flags = this.getPreparationFlags();
          ULLog.console.log("ULStatiManager.onCmdSdkOnGameStart 上报数据没有准备好,flags:", flags.join(","));
          let timeout = ULConfig.getConfig().i_game_start_ready_timeout / 1000;
          ULTimer.callLoop(1 / 60, (timer) => {
              if (timer.usedTime >= timeout) {
                  timer.stop();
                  let flags = this.getPreparationFlags();
                  ULLog.console.log("ULStatiManager.onCmdSdkOnGameStart 等待超时！直接触发reportGameStart flags:", flags.join(","));
                  this.reportGameStart();
                  this.tryUploadToServer();
                  return;
              }
              if (this.isReady()) {
                  timer.stop();
                  ULLog.console.log("ULStatiManager.onCmdSdkOnGameStart 准备完毕！触发reportGameStart");
                  this.reportGameStart();
                  this.tryUploadToServer();
                  return;
              }
          });
          let config0 = ULConfig.getConfig();
          let reportInterval = config0.n_sdk_common_online_time_report_looper_interval;
          ULTimer.callLoop(reportInterval, (timer) => {
              if (!this.isGamePause) {
                  let onlineTime = ULTools.time() - this.gameLastResumeTime;
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.info("ULStatiManager.onCmdSdkOnGameStart,timer前台上报一次在线时长", onlineTime);
                  if (onlineTime <= 5 || onlineTime > 3600 * 24)
                      return;
                  this.gameLastResumeTime = ULTools.time();
                  this.reportOnlineTime(Math.floor(onlineTime));
                  let config = ULConfig.getConfig();
                  ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [config.s_sdk_miniplay_user_play_game_time_event_id || "", Math.floor(onlineTime)]);
                  this.saveRecord();
              }
          });
      }
      onCmdSdkOnGamePause(e) {
          this.isGamePause = true;
          if (!this.gameLastResumeTime) {
              ULLog.console.warn("ULStatiManager.onCmdSdkOnGamePause gameLastResumeTime not found! 无法上报在线时间");
              return;
          }
          let onlineTime = ULTools.time() - this.gameLastResumeTime;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULStatiManager.onCmdSdkOnGamePause", onlineTime);
          if (onlineTime <= 5 || onlineTime > 3600 * 24)
              return;
          this.gameLastResumeTime = ULTools.time();
          this.reportOnlineTime(Math.floor(onlineTime));
          let config = ULConfig.getConfig();
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_CHANNEL_MEGADATA_POST, [config.s_sdk_miniplay_user_play_game_time_event_id || "", Math.floor(onlineTime)]);
          this.saveRecord();
      }
      onCmdSdkOnGameResume(e) {
          this.isGamePause = false;
          this.gameLastResumeTime = ULTools.time();
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULStatiManager.onCmdSdkOnGameResume", this.gameLastResumeTime);
      }
      onCmdSdkOnCopChanged(e) {
          this.pointEventCategoryId_2_enabled = null;
      }
      onCmdSdkCollectionModuleCheckerConfig(e) {
          let config = e.getReturnValue() || [];
          config.push({ type: "newLine" });
          let postDataModeLabelDescList = ["正式模式", "测试模式"];
          let postDataModeLabelDesc = "当前数据上传模式:" + postDataModeLabelDescList[this.postMegadataTestMode];
          config.push({ type: "label", text: postDataModeLabelDesc, name: "labelPostDataMode" });
          config.push({
              type: "button",
              text: "切换数据上传模式..",
              onClick: () => {
                  let userId = ULSdkManager.getInstance().moduleCheckerManager.getItemText("labelPostTestModeUserId");
                  let conf1 = [];
                  conf1.push({ text: "测试模式 ( 用户id:" + userId + ")", value: 1 });
                  conf1.push({ text: "正式模式", value: 0 });
                  let fOnSelectCity = (isTestmode) => {
                      let postDataModeLabelDesc = "当前数据上传模式:" + postDataModeLabelDescList[this.postMegadataTestMode];
                      if (!!isTestmode) {
                          if (userId.length < 1) {
                              ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("提示", "请设置测试用户id", "好的");
                              return;
                          }
                          this.postMegadataTestUserId = userId;
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("已开启测试模式");
                      }
                      else {
                          this.postMegadataTestUserId = null;
                          ULSdkManager.getInstance().moduleCheckerManager.showMsgTip("测试模式已关闭");
                      }
                      this.setPostMegadataMode(isTestmode);
                      ULSdkManager.getInstance().moduleCheckerManager.setItemText("labelPostDataMode", postDataModeLabelDesc);
                  };
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("切换数据上传模式:", conf1, fOnSelectCity);
              },
          });
          config.push({ type: "newLine" });
          config.push({
              type: "label",
              text: "测试用户id",
          });
          config.push({
              type: "inputBox",
              text: this.postMegadataTestUserId,
              name: "labelPostTestModeUserId"
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: `UUID: ${ULSdkManager.getInstance().channelInfo._sdkUserId}  ` });
          config.push({
              type: "button",
              text: "复制",
              onClick: () => {
                  let userId = ULSdkManager.getInstance().channelInfo._sdkUserId;
                  ULClipboardManager.getInstance().setClipboardData(userId, (bSuccess) => {
                      if (bSuccess) {
                          ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "复制成功", "知道了", () => {
                          });
                      }
                      else {
                          ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "复制失败", "知道了", () => {
                          });
                      }
                  });
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: `渠道openId:      ` });
          config.push({
              type: "button",
              text: "请求",
              onClick: () => {
                  let callback = (openId, msg) => {
                      if (!!openId) {
                          ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "获取成功\n" + openId, "复制", () => {
                              ULClipboardManager.getInstance().setClipboardData(openId, (bSuccess) => {
                                  if (bSuccess) {
                                      ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "复制成功", "知道了", () => {
                                      });
                                  }
                                  else {
                                      ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "复制失败", "知道了", () => {
                                      });
                                  }
                              });
                          });
                      }
                      else {
                          ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "获取失败\n" + msg, "知道了", () => {
                          });
                      }
                  };
                  let getChannelOpenIdFunc = ULSdkManager.getInstance().channelInfo.getChannelOpenIdFunc;
                  if (!!getChannelOpenIdFunc) {
                      ULLog.console.log("ULStatisManager.getOpenId getChannelOpenIdFunc");
                      getChannelOpenIdFunc((openId, err) => {
                          ULLog.console.log("ULStatisManager.getOpenId getChannelOpenIdFunc callback");
                          callback(openId, err);
                      });
                  }
                  else {
                      ULLog.console.log("ULStatisManager.getOpenId 该渠道暂不支持获取openId");
                      callback(null, "该渠道暂不支持获取openId");
                  }
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "游戏金手指:      " });
          config.push({
              type: "button",
              text: "验证",
              onClick: () => {
                  let callback = (isCheck, msg) => {
                      if (isCheck) {
                          ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "验证通过", "知道了", () => {
                              ULSdkManager.getInstance().response(ULConst.CMD_CHECKDEBUG_WHITEUSER_RESULT, {
                                  code: 1,
                                  isWhiteUser: true,
                                  msg: "当前用户是白名单用户"
                              });
                          });
                      }
                      else {
                          ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("温馨提示", "验证失败\n" + msg, "知道了", () => {
                          });
                      }
                  };
                  if (ULSdkModuleLoader.getObjectByModuleName("ULModuleUlsdkDemo")) {
                      ULLog.console.log("ULModuleUlsdkDemo is Exit");
                      callback(true, "ULModuleUlsdkDemo is Exit");
                      return;
                  }
                  let networkCallback = (openId) => {
                      let gameId = ULConfig.getConfig().s_sdk_cop_game_id;
                      let channelId = ULConfig.getConfig().s_sdk_cop_channel_id;
                      let userId = ULSdkManager.getInstance().channelInfo._sdkUserId;
                      let netTimeout = ULConfig.getConfig().i_net_timeout;
                      let url = `https://sdkserver.${ULTools.getCommonHost()}.cn/checkwhiteuser?gameId=${gameId}&userId=${userId}&openId=${openId}&channelId=${channelId}&platform=H5`;
                      ULTools.httpGet({
                          url: url,
                          timeoutMillisecond: netTimeout,
                          success: (responseText) => {
                              let jsonData = null;
                              try {
                                  jsonData = JSON.parse(responseText);
                              }
                              catch (error) {
                                  jsonData = {
                                      code: 0,
                                      msg: "responseText"
                                  };
                              }
                              let code = jsonData.code || 0;
                              let msg = jsonData.msg || "位置错误";
                              callback(code == 1, msg);
                          },
                          fail: (err) => {
                              callback(false, JSON.stringify(err));
                          }
                      });
                  };
                  let getChannelOpenIdFunc = ULSdkManager.getInstance().channelInfo.getChannelOpenIdFunc;
                  if (!!getChannelOpenIdFunc) {
                      ULLog.console.log("ULStatisManager.getOpenId getChannelOpenIdFunc");
                      getChannelOpenIdFunc((openId, err) => {
                          ULLog.console.log("ULStatisManager.getOpenId getChannelOpenIdFunc callback err:", err);
                          networkCallback(openId);
                      });
                  }
                  else {
                      ULLog.console.log("ULStatisManager.getOpenId 该渠道暂不支持获取openId");
                      networkCallback("");
                  }
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "清理游戏存档:      " });
          config.push({
              type: "button",
              text: "清理游戏存档",
              onClick: () => {
                  ULSdkManager.getInstance().response(ULConst.CMD_CLEAN_UP_GAME_ARCHIVE, {});
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "跳过新手引导:      " });
          config.push({
              type: "button",
              text: "跳过新手引导",
              onClick: () => {
                  ULSdkManager.getInstance().response(ULConst.CMD_JUMP_NEW_USER_GUIDE, {});
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "是否显示客户端打点信息界面开关:      " });
          config.push({ type: "newLine" });
          config.push({
              type: "button",
              text: "打开",
              onClick: () => {
                  ULSdkManager.getInstance().response(ULConst.CMD_SHOW_POINT_DEBUG_INFO, { state: 1 });
              },
          });
          config.push({
              type: "button",
              text: "关闭",
              onClick: () => {
                  ULSdkManager.getInstance().response(ULConst.CMD_SHOW_POINT_DEBUG_INFO, { state: 0 });
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "打点统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.genPointEventLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("打点统计记录(事件id-状态：次数)：", conf, () => { }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "自定义统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.getCommonEventLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("自定义统计记录(事件id-状态：次数)：", conf, () => { }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "关卡开始统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.getLevelStartLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("关卡开始统计记录(关卡名：次数):", conf, () => { }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "关卡结束统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.getLevelCompletetLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("关卡结束统计记录(关卡名-结果-次数):", conf, () => { }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "视频埋点转化统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.getVideoPointLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("视频埋点转化统计记录(视频点-状态：次数)", conf, () => { }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "内购行为统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.getBuyActionLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("内购行为统计记录(弹出理由-商品名-结果)", conf, () => { }, true);
              },
          });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: "货币统计记录:      " });
          config.push({
              type: "button",
              text: "点击查看..",
              onClick: () => {
                  let log = this.getCoinChangeLog();
                  let conf = [];
                  for (let i = 0; i < log.length; i++) {
                      const line = log[i];
                      conf.push({ text: line, value: line });
                  }
                  ULSdkManager.getInstance().moduleCheckerManager.showPickerDialog("货币统计记录(货币名称-变化类型-变化原因)", conf, () => { }, true);
              },
          });
          e.setReturnValue(config, true);
      }
  }

  class MCItem {
      initByData(data) {
          this.type = data.type;
          this.type = data.type || "newLine";
          this.name = data.name || "";
          this.text = data.text || "";
          this.width = data.width || 0;
          this.height = data.height || 0;
          this.fOnClick = data.onClick;
          this.fOnTextChanged = data.onTextChanged;
      }
      setText(text) {
          this.text = text;
          if (this.fOnTextChanged instanceof Function) {
              this.fOnTextChanged(text);
          }
      }
      triggerOnClick() {
          if (this.fOnClick instanceof Function) {
              this.fOnClick();
          }
      }
  }

  const BUTTON_WIDTH = 150;
  const BUTTON_HEIGHT = 40;
  const NEW_LINE_HEIGHT = 20;
  const FONT_SIZE = 20;
  const PENDING = 10;
  const GAP = 4;
  let _cc = window["cc"];
  class MCPanelCreator {
      constructor() {
          this.nodeReferenceRects = {};
          this.debugInfoRenderNode = null;
      }
      getNodeCanvas() {
          if (!_cc) {
              ULLog.console.warn("MCPanelCreator.getNodeCanvas 未检测到creator环境！");
              return null;
          }
          let scene = _cc.director.getScene();
          if (!scene) {
              ULLog.console.warn("MCPanelCreator.getNodeCanvas scene not found!");
              return null;
          }
          let check = ULConfig.getConfig().s_sdk_cocos2x_rootNode_check;
          if (check) {
              let nodeCanvas = ULEvalExp.evalExpResults(check, (key) => {
                  if (key == "scene") {
                      return scene;
                  }
                  return null;
              });
              ULLog.console.log("MCPanelCreator.getNodeCanvas nodeCanvas ==" + nodeCanvas);
              return nodeCanvas;
          }
          else {
              let nodeCanvas = scene.getChildByName("Canvas");
              ULLog.console.log("MCPanelCreator.getNodeCanvas nodeCanvas ==" + nodeCanvas);
              return nodeCanvas;
          }
      }
      addFillerSprite(node, color) {
          let size = node.getContentSize();
          let sprite = node.addComponent(_cc.Sprite);
          sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
          sprite.type = _cc.Sprite.Type.SIMPLE;
          _cc.loader.loadRes("_ulsdk_ui/white_dot", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.addFillerSprite err!", err);
                  return;
              }
              sprite.spriteFrame = spriteFrame;
              node.setContentSize(size);
          });
          node.color = color;
          node.opacity = color.getA();
      }
      registerTouchHandler(_node, handler, bEnableMultiTouch = false, bStopPropagation = true, bUseCapture = false) {
          let node = _node;
          if (!node)
              return;
          if (!handler)
              return;
          let fOnTouchBegan = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && node.__touch_id != null)
                  return false;
              e.name = "began";
              if (bStopPropagation)
                  e.stopPropagation();
              node.__touch_id = touchId;
              handler(e);
              return true;
          };
          let fOnTouchMoved = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && touchId != node.__touch_id)
                  return;
              e.name = "moved";
              handler(e);
          };
          let fOnTouchEnded = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && touchId != node.__touch_id)
                  return;
              e.name = "ended";
              node.__touch_id = null;
              handler(e);
          };
          let fOnTouchCancelled = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && touchId != node.__touch_id)
                  return;
              e.name = "cancelled";
              node.__touch_id = null;
              handler(e);
          };
          node.on(_cc.Node.EventType.TOUCH_START, fOnTouchBegan, null, bUseCapture);
          node.on(_cc.Node.EventType.TOUCH_MOVE, fOnTouchMoved, null, bUseCapture);
          node.on(_cc.Node.EventType.TOUCH_END, fOnTouchEnded, null, bUseCapture);
          node.on(_cc.Node.EventType.TOUCH_CANCEL, fOnTouchCancelled, null, bUseCapture);
      }
      isTouchEventClick(e) {
          if (!(e.name == "ended" || e.name == "cancelled"))
              return false;
          let p0 = e.getStartLocation();
          let p1 = e.getLocation();
          let dx = p0.x - p1.x;
          let dy = p0.y - p1.y;
          let distanceSq = dx * dx + dy * dy;
          return distanceSq <= 20 * 20;
      }
      createItemByData(data) {
          let item = new MCItem();
          item.initByData(data);
          let nodeContainer = this.nodeContainer;
          switch (data.type) {
              case "label": {
                  let node = new _cc.Node();
                  node.parent = nodeContainer;
                  node.setAnchorPoint(0.5, 0.5);
                  node.on(_cc.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.width;
                      item.height = node.height;
                      this.onItemNodeResize();
                  });
                  node.addComponent(_cc.Label).string = item.text;
                  node.getComponent(_cc.Label).fontSize = FONT_SIZE;
                  node.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.LEFT;
                  node.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
                  item.renderNode = node;
                  break;
              }
              case "labelArea": {
                  let node = new _cc.Node();
                  node.parent = nodeContainer;
                  node.setAnchorPoint(0.5, 0.5);
                  node.on(_cc.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.width;
                      item.height = node.height;
                      this.onItemNodeResize();
                  });
                  node.addComponent(_cc.Label).string = item.text;
                  node.getComponent(_cc.Label).fontSize = FONT_SIZE;
                  node.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.LEFT;
                  node.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
                  node.getComponent(_cc.Label).overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
                  node.width = nodeContainer.width - PENDING * 2;
                  node.height = FONT_SIZE;
                  item.renderNode = node;
                  break;
              }
              case "button": {
                  let node = new _cc.Node();
                  node.parent = nodeContainer;
                  node.on(_cc.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.width;
                      item.height = node.height;
                      this.onItemNodeResize();
                  });
                  node.width = item.width || BUTTON_WIDTH;
                  node.height = item.height || BUTTON_HEIGHT;
                  let nodeBg = new _cc.Node();
                  nodeBg.parent = node;
                  nodeBg.setContentSize(nodeBg.parent.getContentSize());
                  this.addFillerSprite(nodeBg, _cc.color(200, 200, 200, 255));
                  let nodeLabel = new _cc.Node();
                  nodeLabel.parent = node;
                  nodeLabel.setAnchorPoint(0.5, 0.5);
                  nodeLabel.addComponent(_cc.Label).string = item.text;
                  nodeLabel.getComponent(_cc.Label).fontSize = FONT_SIZE;
                  nodeLabel.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
                  nodeLabel.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
                  nodeLabel.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
                  nodeLabel.width = node.width;
                  nodeLabel.height = node.height;
                  nodeLabel.color = _cc.Color.BLACK;
                  this.registerTouchHandler(node, (e) => {
                      switch (e.name) {
                          case "began":
                              nodeLabel.color = _cc.Color.GREEN;
                              break;
                          case "moved": break;
                          default:
                              nodeLabel.color = _cc.Color.BLACK;
                              break;
                      }
                      if (!this.isTouchEventClick(e))
                          return;
                      item.triggerOnClick();
                  });
                  item.renderNode = node;
                  break;
              }
              case "inputBox": {
                  let node = new _cc.Node();
                  node.parent = nodeContainer;
                  node.on(_cc.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.width;
                      item.height = node.height;
                      this.onItemNodeResize();
                  });
                  node.width = item.width || BUTTON_WIDTH;
                  node.height = item.height || BUTTON_HEIGHT;
                  let nodeBg = new _cc.Node();
                  nodeBg.parent = node;
                  nodeBg.setContentSize(nodeBg.parent.getContentSize());
                  this.addFillerSprite(nodeBg, _cc.color(200, 200, 200, 255));
                  let editBox = node.addComponent(_cc.EditBox);
                  editBox.fontSize = FONT_SIZE;
                  editBox.fontColor = _cc.Color.BLACK;
                  editBox.lineHeight = node.height;
                  editBox.inputMode = _cc.EditBox.InputMode.SINGLE_LINE;
                  editBox.maxLength = 1024;
                  editBox.placeholder = "<<输入框>>";
                  editBox.placeholderFontSize = FONT_SIZE;
                  editBox.placeholderFontColor = _cc.Color.GRAY;
                  let labels = node.getComponentsInChildren(_cc.Label);
                  for (let i = 0; i < labels.length; i++) {
                      const label = labels[i];
                      label.verticalAlign = _cc.Label.VerticalAlign.CENTER;
                  }
                  editBox.node.on("text-changed", () => {
                      let text = editBox.string;
                      item.setText(text);
                  });
                  item.renderNode = node;
                  break;
              }
              case "newLine": {
                  item.width = nodeContainer.width - PENDING * 2;
                  item.height = NEW_LINE_HEIGHT;
                  break;
              }
          }
          return item;
      }
      doLayout() {
          if (!this.items)
              return;
          let width = this.nodePanel.width - 20;
          let rowItems = [];
          let rowRight = PENDING;
          let rowTop = -PENDING;
          let rowHeight = 0;
          for (let i = 0; i < this.items.length; i++) {
              let item = this.items[i];
              let renderNode = item.renderNode || { x: 0, y: 0 };
              if (rowRight + item.width > width) {
                  rowRight = 0;
                  for (let i = 0; i < rowItems.length; i++) {
                      const rowItem = rowItems[i];
                      let renderNode = rowItem.renderNode || { x: 0, y: 0 };
                      renderNode.y = rowTop - rowHeight / 2;
                  }
                  rowRight = PENDING;
                  rowTop -= rowHeight + GAP;
                  rowItems = [];
                  rowHeight = 0;
              }
              rowHeight = Math.max(rowHeight, item.height);
              rowItems.push(item);
              renderNode.x = rowRight + item.width / 2;
              rowRight += item.width + GAP;
          }
          for (let i = 0; i < rowItems.length; i++) {
              const rowItem = rowItems[i];
              let renderNode = rowItem.renderNode || { x: 0, y: 0 };
              renderNode.y = rowTop - rowHeight / 2;
          }
          rowTop -= rowHeight - PENDING;
          this.nodeContainer.height = Math.max(this.nodePanel.height, -rowTop);
      }
      onItemNodeResize() {
          this.doLayout();
      }
      getItemByName(name) {
          for (let i = 0; i < this.items.length; i++) {
              const item = this.items[i];
              if (item.name == name)
                  return item;
          }
          return null;
      }
      show(config) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas)
              return;
          let nodePanel = new _cc.Node();
          nodePanel.parent = nodeCanvas;
          nodePanel.setContentSize(nodeCanvas.getContentSize());
          nodePanel.zIndex = _cc.macro.MAX_ZINDEX;
          this.nodePanel = nodePanel;
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodePanel;
          nodeBg.setContentSize(nodeBg.parent.getContentSize());
          this.addFillerSprite(nodeBg, _cc.color(0, 0, 0, 191));
          this.registerTouchHandler(this.nodePanel, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
          });
          let nodeContainer = new _cc.Node();
          nodeContainer.setAnchorPoint(0, 1);
          nodeContainer.parent = this.nodePanel;
          nodeContainer.setContentSize(nodeCanvas.getContentSize());
          this.nodeContainer = nodeContainer;
          let scrollView = this.nodePanel.addComponent(_cc.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.content = nodeContainer;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let items = [];
          for (let i = 0; i < config.length; i++) {
              const data = config[i];
              let item = this.createItemByData(data);
              items.push(item);
          }
          this.items = items;
          this.doLayout();
      }
      close() {
          if (_cc.isValid(this.nodePanel)) {
              this.nodePanel.destroy();
          }
          this.nodePanel = null;
          this.items = [];
      }
      getItemText(name) {
          let item = this.getItemByName(name);
          if (!item)
              return "";
          return item.text;
      }
      setItemText(name, text) {
          let item = this.getItemByName(name);
          if (!item)
              return;
          item.setText(text);
          let node = item.renderNode;
          if (node instanceof _cc.Node) {
              let label = node.getComponent(_cc.Label) || node.getComponentInChildren(_cc.Label);
              if (label) {
                  label.string = text;
              }
              let editBox = node.getComponent(_cc.EditBox) || node.getComponentInChildren(_cc.EditBox);
              if (editBox) {
                  editBox.string = text;
              }
          }
      }
      showMsgTip(text) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas)
              return;
          let nodeLabel = new _cc.Node();
          nodeLabel.parent = nodeCanvas;
          nodeLabel.width = nodeCanvas.width;
          nodeLabel.height = 20;
          nodeLabel.zIndex = _cc.macro.MAX_ZINDEX;
          let label = nodeLabel.addComponent(_cc.Label);
          label.string = text;
          label.fontSize = 20;
          label.enableWrapText = true;
          nodeLabel.x = 0;
          nodeLabel.y = nodeCanvas.height * 0.25;
          nodeLabel.runAction(_cc.sequence(_cc.moveBy(1.5, 0, 50), _cc.callFunc(() => {
              nodeLabel.destroy();
          })));
      }
      showPickerDialog(title, conf, callback, bKeepDialogOpen) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas)
              return;
          let minCount = 8.5;
          let maxCount = 17.5;
          let dialogHeight = ULTools.scaleInRange(conf.length, minCount, maxCount, minCount * 40 + (minCount - 1) * 4 + 60, maxCount * 40 + (maxCount - 1) * 4 + 60);
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeCanvas;
          nodeShadow.setContentSize(nodeCanvas.getContentSize());
          nodeShadow.zIndex = _cc.macro.MAX_ZINDEX;
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              nodeShadow.destroy();
          });
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeShadow;
          nodeBg.setContentSize(nodeBg.parent.getContentSize());
          this.addFillerSprite(nodeBg, _cc.color(0, 0, 0, 127));
          let nodeDialog = new _cc.Node();
          nodeDialog.parent = nodeShadow;
          nodeDialog.width = nodeCanvas.width - 100;
          nodeDialog.height = dialogHeight;
          this.registerTouchHandler(nodeDialog, (e) => { });
          nodeBg = new _cc.Node();
          nodeBg.parent = nodeDialog;
          nodeBg.setContentSize(nodeBg.parent.getContentSize());
          this.addFillerSprite(nodeBg, _cc.color(167, 167, 167, 255));
          let nodeTitle = new _cc.Node();
          nodeTitle.parent = nodeDialog;
          nodeTitle.y = nodeDialog.height / 2 - 25;
          nodeTitle.x = 0;
          nodeTitle.addComponent(_cc.Label).string = title;
          nodeTitle.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).fontSize = 40;
          nodeTitle.width = nodeDialog.width - 10;
          nodeTitle.height = 40;
          let nodeListBg = new _cc.Node();
          nodeListBg.parent = nodeDialog;
          nodeListBg.width = nodeDialog.width - 10;
          nodeListBg.height = nodeDialog.height - 50;
          nodeListBg.x = 0;
          nodeListBg.y = -nodeDialog.height / 2 + nodeListBg.height / 2 + 5;
          this.addFillerSprite(nodeListBg, _cc.color(97, 97, 97, 255));
          let nodeList = new _cc.Node();
          nodeList.parent = nodeDialog;
          nodeList.width = nodeDialog.width - 10;
          nodeList.height = nodeDialog.height - 50;
          nodeList.x = 0;
          nodeList.y = -nodeDialog.height / 2 + nodeList.height / 2 + 5;
          nodeList.addComponent(_cc.Mask);
          let nodeContainer = new _cc.Node();
          nodeContainer.setAnchorPoint(0, 1);
          nodeContainer.parent = nodeList;
          nodeContainer.setContentSize(nodeList.getContentSize());
          let scrollView = nodeList.addComponent(_cc.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.content = nodeContainer;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let y = 0;
          for (let i = 0; i < conf.length; i++) {
              const v = conf[i];
              let nodeItem = new _cc.Node();
              nodeItem.parent = nodeContainer;
              nodeItem.width = nodeList.width;
              nodeItem.height = 40;
              nodeItem.x = nodeContainer.width / 2;
              nodeItem.y = y - nodeItem.height / 2;
              let nodeBg = new _cc.Node();
              nodeBg.parent = nodeItem;
              nodeBg.setContentSize(nodeBg.parent.getContentSize());
              this.addFillerSprite(nodeBg, _cc.color(0, 0, 0, 63));
              let nodeLabel = new _cc.Node();
              nodeLabel.parent = nodeItem;
              nodeLabel.setAnchorPoint(0, 0.5);
              nodeLabel.x = -nodeItem.width / 2 + 5;
              nodeLabel.y = 0;
              let label = nodeLabel.addComponent(_cc.Label);
              label.fontSize = FONT_SIZE;
              label.lineHeight = FONT_SIZE;
              label.verticalAlign = _cc.Label.VerticalAlign.CENTER;
              label.horizontalAlign = _cc.Label.HorizontalAlign.LEFT;
              label.string = v.text;
              this.registerTouchHandler(nodeItem, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  callback(v.value);
                  if (!bKeepDialogOpen) {
                      nodeShadow.destroy();
                  }
              });
              y -= nodeItem.height + 4;
          }
          nodeContainer.height = Math.max(nodeList.height, -y);
      }
      showPromptDialog(title, content, btnTexts, callbacks) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showPromptDialog nodeCanvas not found!");
              ULTimer.callLater(0.1, () => {
                  this.showPromptDialog(title, content, btnTexts, callbacks);
              });
              return;
          }
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeCanvas;
          nodeShadow.setContentSize(nodeCanvas.getContentSize());
          nodeShadow.zIndex = _cc.macro.MAX_ZINDEX;
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let nodeSpriteBg = new _cc.Node();
          nodeSpriteBg.parent = nodeShadow;
          nodeSpriteBg.setContentSize(nodeSpriteBg.parent.getContentSize());
          this.addFillerSprite(nodeSpriteBg, _cc.color(0, 0, 0, 127));
          let bManualDestroy = false;
          let triggerNode = new _cc.Node();
          triggerNode.parent = nodeShadow;
          let component = triggerNode.addComponent(_cc.Component);
          component["onDestroy"] = () => {
              ULLog.console.log("MCPanelCreator.showPromptDialog triggerNode onDestroy", bManualDestroy);
              if (!bManualDestroy) {
                  ULLog.console.log("MCPanelCreator.showPromptDialog nodeShadow被意外销毁，0.1秒后尝试重新创建提示");
                  ULTimer.callLater(0.1, () => {
                      this.showPromptDialog(title, content, btnTexts, callbacks);
                  });
              }
          };
          let nodeDialog = new _cc.Node();
          nodeDialog.parent = nodeShadow;
          nodeDialog.width = 460;
          nodeDialog.height = 320;
          this.registerTouchHandler(nodeDialog, (e) => { });
          let nodeDialogBg = new _cc.Node();
          nodeDialogBg.parent = nodeDialog;
          nodeDialogBg.setContentSize(nodeDialogBg.parent.getContentSize());
          _cc.loader.loadRes("_ulsdk_ui/bg_01", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showPromptDialog nodeDialogBg load sprite error", err);
                  return;
              }
              let nodeSize = nodeDialogBg.getContentSize();
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = nodeDialogBg.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc.Sprite.Type.SLICED;
              sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
              nodeDialogBg.setContentSize(nodeSize);
          });
          let nodeTitle = new _cc.Node();
          nodeTitle.parent = nodeDialog;
          nodeTitle.y = nodeDialog.height / 2 - 45;
          nodeTitle.x = 0;
          nodeTitle.color = _cc.color(38, 38, 38, 255);
          nodeTitle.addComponent(_cc.Label).string = title || "标题";
          nodeTitle.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).fontSize = 32;
          nodeTitle.width = nodeDialog.width - 10;
          nodeTitle.height = 40;
          let nodeContent = new _cc.Node();
          nodeContent.parent = nodeDialog;
          nodeContent.y = nodeDialog.height / 2 - 155;
          nodeContent.x = 0;
          nodeContent.color = _cc.color(96, 96, 96, 255);
          nodeContent.addComponent(_cc.Label).string = content || "内容";
          nodeContent.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeContent.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeContent.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          nodeContent.getComponent(_cc.Label).fontSize = 24;
          nodeContent.width = nodeDialog.width - 50;
          nodeContent.height = 160;
          let btnWidth = 160;
          let btnHeight = 56;
          let btnGap = 30;
          let left = -(btnTexts.length * btnWidth + (btnTexts.length - 1) * btnGap) / 2;
          let nodeButtons = [];
          for (let i = 0; i < btnTexts.length; i++) {
              const text = btnTexts[i];
              let nodeButton = new _cc.Node();
              nodeButton.parent = nodeDialog;
              nodeButton.x = left + btnWidth * (i + 0.5) + btnGap * (i);
              nodeButton.y = -nodeDialog.height / 2 + 50;
              nodeButton.setContentSize(btnWidth, btnHeight);
              nodeButtons.push(nodeButton);
              let nodeButtonBg = new _cc.Node();
              nodeButtonBg.parent = nodeButton;
              nodeButtonBg.setContentSize(nodeButton.getContentSize());
              _cc.loader.loadRes("_ulsdk_ui/btn_01", _cc.SpriteFrame, (err, spriteFrame) => {
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showPromptDialog nodeButtonBg load sprite error", err);
                      return;
                  }
                  let nodeSize = nodeButtonBg.getContentSize();
                  let frameSize = spriteFrame.getOriginalSize();
                  spriteFrame.insetLeft = frameSize.width / 3;
                  spriteFrame.insetRight = frameSize.width / 3;
                  spriteFrame.insetTop = frameSize.height / 3;
                  spriteFrame.insetBottom = frameSize.height / 3;
                  let sprite = nodeButtonBg.addComponent(_cc.Sprite);
                  sprite.spriteFrame = spriteFrame;
                  sprite.type = _cc.Sprite.Type.SLICED;
                  sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
                  nodeButtonBg.setContentSize(nodeSize);
              });
              let nodeButtonText = new _cc.Node();
              nodeButtonText.parent = nodeButton;
              nodeButtonText.y = 0;
              nodeButtonText.x = 0;
              nodeButtonText.color = _cc.color(255, 255, 255, 255);
              nodeButtonText.addComponent(_cc.Label).string = text || "按钮" + (i + 1);
              nodeButtonText.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
              nodeButtonText.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
              nodeButtonText.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
              nodeButtonText.getComponent(_cc.Label).fontSize = 30;
              nodeButtonText.width = nodeButtonBg.width - 10;
              nodeButtonText.height = nodeButtonBg.height - 10;
              this.registerTouchHandler(nodeButton, (e) => {
                  if (e.name == "began") {
                      nodeButton.scale = 1.1;
                  }
                  else if (e.name == "moved") {
                  }
                  else {
                      nodeButton.scale = 1;
                  }
                  if (this.isTouchEventClick(e)) {
                      let callback = callbacks[i];
                      if (callback instanceof Function) {
                          let bDonotClose = callback();
                          if (!bDonotClose) {
                              bManualDestroy = true;
                              nodeShadow.destroy();
                          }
                      }
                      else {
                          bManualDestroy = true;
                          nodeShadow.destroy();
                      }
                  }
              });
          }
      }
      showWebView(title, url, replaceParam) {
          this.closeWebView();
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              return;
          }
          console.log(`showWebView title:${title} url:${url} replaceParam:${replaceParam}`);
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(2048, 2048);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX;
          this.showWebViewNode = nodeBg;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeWebView();
          });
          let contentNode = new _cc.Node();
          contentNode.parent = nodeBg;
          let width = Math.min(nodeCanvas.width * 0.8, 500);
          let height = Math.min(nodeCanvas.height * 0.8, 800);
          if (nodeCanvas.width > nodeCanvas.height) {
              width = Math.min(nodeCanvas.width * 0.8, 800);
              height = Math.min(nodeCanvas.height * 0.8, 500);
          }
          contentNode.setContentSize(width, height);
          _cc.loader.loadRes("_ulsdk_ui/bg_01", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showWebView nodeDialogBg load sprite error", err);
                  return;
              }
              let nodeSize = contentNode.getContentSize();
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = contentNode.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc.Sprite.Type.SLICED;
              sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
              contentNode.setContentSize(nodeSize);
          });
          let nodeTitle = new _cc.Node();
          nodeTitle.parent = contentNode;
          nodeTitle.color = _cc.color(38, 38, 38, 255);
          nodeTitle.addComponent(_cc.Label).string = title;
          nodeTitle.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).fontSize = 32;
          nodeTitle.width = width - 10;
          nodeTitle.height = 40;
          nodeTitle.y = height / 2 - 40;
          nodeTitle.x = 0;
          let nodeScrollView = new _cc.Node();
          nodeScrollView.parent = contentNode;
          nodeScrollView.setContentSize(width - 50, height - 80);
          nodeScrollView.x = 0;
          nodeScrollView.y = -20;
          let scrollView = nodeScrollView.addComponent(_cc.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let nodeMask = new _cc.Node();
          nodeMask.parent = nodeScrollView;
          nodeMask.setContentSize(nodeScrollView.getContentSize());
          nodeMask.addComponent(_cc.Mask).type = _cc.Mask.Type.RECT;
          nodeMask.getComponent(_cc.Mask).inverted = false;
          let nodeContent = new _cc.Node();
          nodeContent.parent = nodeMask;
          nodeContent.setAnchorPoint(0.5, 1);
          nodeContent.setContentSize(nodeScrollView.getContentSize());
          let maskLayout = nodeContent.addComponent(_cc.Layout);
          maskLayout.type = _cc.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc.Layout.ResizeMode.CONTAINER;
          scrollView.content = nodeContent;
          ULTools.httpGet({
              url: url,
              timeoutMillisecond: 5000,
              success: (responseText) => {
                  let content = responseText;
                  try {
                      let resultObj = JSON.parse(responseText);
                      content = resultObj.policyText;
                  }
                  catch (error) {
                  }
                  if (replaceParam) {
                      for (let key in replaceParam) {
                          let value = replaceParam[key];
                          let regExp = new RegExp(`\\\${\\s*${key}\\s*}`, 'g');
                          content = content.replace(regExp, value);
                      }
                  }
                  ULLog.console.log("content:", content);
                  let nodeLabel = new _cc.Node();
                  nodeLabel.color = _cc.color(0, 0, 0, 255);
                  nodeLabel.parent = nodeContent;
                  nodeLabel.setAnchorPoint(0.5, 1);
                  let label = nodeLabel.addComponent(_cc.Label);
                  label.string = content;
                  label.overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
                  label.verticalAlign = _cc.Label.VerticalAlign.TOP;
                  label.horizontalAlign = _cc.Label.HorizontalAlign.LEFT;
                  label.fontSize = 18;
                  label.lineHeight = 26;
                  let trimLabel = label;
                  let trimClass = _cc.Label;
                  if (trimLabel.cacheMode != undefined && trimClass.CacheMode != undefined) {
                      let mode = trimLabel.cacheMode;
                      try {
                          trimLabel.cacheMode = trimClass.CacheMode.CHAR;
                      }
                      catch (error) {
                          trimLabel.cacheMode = mode;
                      }
                  }
                  nodeLabel.setContentSize(nodeContent.getContentSize());
              },
              fail: () => {
              }
          });
      }
      closeWebView() {
          if (_cc.isValid(this.showWebViewNode)) {
              this.showWebViewNode["__b_manual_destroy"] = true;
              this.showWebViewNode.destroy();
          }
          this.showWebViewNode = null;
      }
      showPrivacyContent(title, url, replaceParam) {
          this.showWebView(title, url, replaceParam);
      }
      showPrivacyDialog(title, contentArray, btnTexts, callbacks) {
          ULLog.console.log("MCPanelCreator.showPrivacyDialog");
          if (this.showPrivacyNode) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showPrivacyDialog nodeCanvas not found!");
              ULTimer.callLater(0.1, () => {
                  this.showPrivacyDialog(title, contentArray, btnTexts, callbacks);
              });
              return;
          }
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(2048, 2048);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX;
          this.showPrivacyNode = nodeBg;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let bManualDestroy = false;
          let triggerNode = new _cc.Node();
          triggerNode.parent = nodeShadow;
          let component = triggerNode.addComponent(_cc.Component);
          component["onDestroy"] = () => {
              ULLog.console.log("MCPanelCreator.showPrivacyDialog triggerNode onDestroy", bManualDestroy);
              this.showPrivacyNode = null;
              if (!bManualDestroy) {
                  ULLog.console.log("MCPanelCreator.showPrivacyDialog nodeShadow被意外销毁，0.1秒后尝试重新创建提示");
                  ULTimer.callLater(1 / 60, () => {
                      ULLog.console.log("ontimer");
                      this.showPrivacyDialog(title, contentArray, btnTexts, callbacks);
                  });
              }
          };
          let contentNode = new _cc.Node();
          contentNode.parent = nodeBg;
          let width = 450;
          let height = 450;
          contentNode.setContentSize(width, height);
          _cc.loader.loadRes("_ulsdk_ui/bg_01", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showPrivacyDialog nodeDialogBg load sprite error", err);
                  return;
              }
              let nodeSize = contentNode.getContentSize();
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = contentNode.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc.Sprite.Type.SLICED;
              sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
              contentNode.setContentSize(nodeSize);
          });
          let nodeTitle = new _cc.Node();
          nodeTitle.parent = contentNode;
          nodeTitle.color = _cc.color(0, 0, 0, 255);
          nodeTitle.addComponent(_cc.Label).string = "隐私政策";
          nodeTitle.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).fontSize = 32;
          nodeTitle.width = width - 10;
          nodeTitle.height = 40;
          nodeTitle.y = height / 2 - 40;
          nodeTitle.x = 0;
          let nodeScrollView = new _cc.Node();
          nodeScrollView.parent = contentNode;
          nodeScrollView.setContentSize(width - 50, height - 140);
          nodeScrollView.x = 0;
          nodeScrollView.y = 3;
          let scrollView = nodeScrollView.addComponent(_cc.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let nodeMask = new _cc.Node();
          nodeMask.parent = nodeScrollView;
          nodeMask.setContentSize(nodeScrollView.getContentSize());
          nodeMask.addComponent(_cc.Mask).type = _cc.Mask.Type.RECT;
          nodeMask.getComponent(_cc.Mask).inverted = false;
          let nodeContent = new _cc.Node();
          nodeContent.parent = nodeMask;
          nodeContent.setAnchorPoint(0.5, 1);
          nodeContent.setContentSize(nodeScrollView.getContentSize());
          let maskLayout = nodeContent.addComponent(_cc.Layout);
          maskLayout.type = _cc.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc.Layout.ResizeMode.CONTAINER;
          scrollView.content = nodeContent;
          let contentText = `感谢您对本公司游戏的支持，在体验我们的游戏前，请仔细阅读开发商的`;
          let footer = `中的所有条款，包括
        1.为了您有良好的游戏体验，我们会基于具体的场景收集您的个人信息
        2.我们会基于先进的技术和管理措施保证您的个人信息安全
        3.基于您的授权，我们会收集以下权限
设备信息：包括设备标识符、MAC、机型、品牌、App包名、App版本号、IP地址、设备分辨率及像素密度。
网络信息：网络连接状态、接入网络的方式和类型、IP地址。
使用信息：包括广告内容的展现、点击、下载。
        如果您对本隐私政策有任何疑问,请通过kefu@ultralisk.cn与我们联系。
        `;
          let headerNode = new _cc.Node();
          headerNode.color = _cc.color(0, 0, 0, 255);
          headerNode.parent = nodeContent;
          headerNode.setAnchorPoint(0.5, 1);
          let headerLabel = headerNode.addComponent(_cc.Label);
          headerLabel.string = contentText;
          headerLabel.fontSize = 18;
          headerLabel.lineHeight = 26;
          headerNode.setContentSize(nodeContent.getContentSize());
          headerLabel.overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
          for (let index = 0; index < contentArray.length; index++) {
              let element = contentArray[index];
              let buttonNode = new _cc.Node();
              buttonNode.color = _cc.color(100, 149, 237, 255);
              buttonNode.parent = nodeContent;
              buttonNode.setAnchorPoint(0.5, 1);
              let buttonLabel = buttonNode.addComponent(_cc.Label);
              buttonLabel.string = `《${element.name}》`;
              buttonLabel.fontSize = 18;
              buttonLabel.lineHeight = 26;
              buttonNode.setContentSize(nodeContent.getContentSize());
              buttonLabel.overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
              buttonNode.addComponent(_cc.LabelOutline);
              buttonNode.getComponent(_cc.LabelOutline);
              buttonNode.getComponent(_cc.LabelOutline).width = 1;
              buttonNode.getComponent(_cc.LabelOutline).color = _cc.color(255, 255, 255, 255);
              this.registerTouchHandler(buttonNode, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  this.showWebView(element.name, element.url, element.replaceParam);
              });
          }
          let footerNode = new _cc.Node();
          footerNode.color = _cc.color(0, 0, 0, 255);
          footerNode.parent = nodeContent;
          footerNode.setAnchorPoint(0.5, 1);
          let footerLabel = footerNode.addComponent(_cc.Label);
          footerLabel.string = footer;
          footerLabel.fontSize = 18;
          footerLabel.lineHeight = 26;
          footerLabel.overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
          footerNode.setContentSize(nodeContent.getContentSize());
          let buttonWidth = (contentNode.width - 20) / btnTexts.length;
          let buttonHeight = 40;
          for (let index = 0; index < btnTexts.length; index++) {
              const buttonText = btnTexts[index];
              let buttonBgNode = new _cc.Node();
              buttonBgNode.parent = contentNode;
              buttonBgNode.width = Math.min(buttonWidth * 0.8, 120);
              buttonBgNode.height = buttonHeight;
              buttonBgNode.x = -(btnTexts.length / 2.0 - index) * buttonWidth + buttonWidth / 2.0;
              buttonBgNode.y = (buttonBgNode.height - contentNode.height) / 2.0 + 20;
              let buttonNode = new _cc.Node();
              buttonNode.parent = buttonBgNode;
              buttonNode.addComponent(_cc.Label).string = buttonText;
              buttonNode.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
              buttonNode.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
              buttonNode.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
              buttonNode.getComponent(_cc.Label).fontSize = 22;
              buttonNode.width = buttonBgNode.width;
              buttonNode.height = buttonBgNode.height;
              if (btnTexts.length == 1 || index % 2 == 1) {
                  this.addFillerSprite(buttonBgNode, _cc.color(100, 149, 237, 255));
                  buttonNode.color = _cc.color(255, 255, 255, 255);
              }
              else {
                  this.addFillerSprite(buttonBgNode, _cc.color(230, 230, 230, 255));
                  buttonNode.color = _cc.color(156, 176, 222, 255);
                  buttonNode.addComponent(_cc.LabelOutline);
                  buttonNode.getComponent(_cc.LabelOutline);
                  buttonNode.getComponent(_cc.LabelOutline).width = 1;
                  buttonNode.getComponent(_cc.LabelOutline).color = _cc.color(230, 230, 230, 255);
              }
              this.registerTouchHandler(buttonNode, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  let callback = callbacks[index];
                  if (callback instanceof Function) {
                      let bDonotClose = callback();
                      if (!bDonotClose) {
                          bManualDestroy = true;
                          this.showPrivacyNode.destroy();
                          this.showPrivacyNode = null;
                      }
                  }
                  else {
                      bManualDestroy = true;
                      this.showPrivacyNode.destroy();
                      this.showPrivacyNode = null;
                  }
              });
          }
      }
      showSettingView(title, items) {
          ULLog.console.log("MCPanelCreator.showSettingView");
          if (this.showSettingNode) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showSettingView nodeCanvas not found!");
              ULTimer.callLater(0.1, () => {
                  this.showSettingView(title, items);
              });
              return;
          }
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(2048, 2048);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX;
          this.showSettingNode = nodeBg;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let bManualDestroy = false;
          let triggerNode = new _cc.Node();
          triggerNode.parent = nodeShadow;
          let component = triggerNode.addComponent(_cc.Component);
          component["onDestroy"] = () => {
              ULLog.console.log("MCPanelCreator.showSettingView triggerNode onDestroy", bManualDestroy);
              this.showSettingNode = null;
              if (!bManualDestroy) {
                  ULLog.console.log("MCPanelCreator.showSettingView nodeShadow被意外销毁，0.1秒后尝试重新创建提示");
                  ULTimer.callLater(1 / 60, () => {
                      ULLog.console.log("ontimer");
                      this.showSettingView(title, items);
                  });
              }
          };
          let contentNode = new _cc.Node();
          contentNode.parent = nodeBg;
          let width = 450;
          let height = 450;
          contentNode.setContentSize(width, height);
          _cc.loader.loadRes("_ulsdk_ui/bg_01", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showSettingView nodeDialogBg load sprite error", err);
                  return;
              }
              let nodeSize = contentNode.getContentSize();
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = contentNode.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc.Sprite.Type.SLICED;
              sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
              contentNode.setContentSize(nodeSize);
          });
          let nodeTitle = new _cc.Node();
          nodeTitle.parent = contentNode;
          nodeTitle.color = _cc.color(0, 0, 0, 255);
          nodeTitle.addComponent(_cc.Label).string = title;
          nodeTitle.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).fontSize = 32;
          nodeTitle.width = width - 10;
          nodeTitle.height = 40;
          nodeTitle.y = height / 2 - 40;
          nodeTitle.x = 0;
          let nodeScrollView = new _cc.Node();
          nodeScrollView.parent = contentNode;
          nodeScrollView.setContentSize(width - 50, height - 140);
          nodeScrollView.x = 0;
          nodeScrollView.y = 3;
          let scrollView = nodeScrollView.addComponent(_cc.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let nodeMask = new _cc.Node();
          nodeMask.parent = nodeScrollView;
          nodeMask.setContentSize(nodeScrollView.getContentSize());
          nodeMask.addComponent(_cc.Mask).type = _cc.Mask.Type.RECT;
          nodeMask.getComponent(_cc.Mask).inverted = false;
          let nodeContent = new _cc.Node();
          nodeContent.parent = nodeMask;
          nodeContent.setAnchorPoint(0.5, 1);
          nodeContent.setContentSize(nodeScrollView.getContentSize());
          let maskLayout = nodeContent.addComponent(_cc.Layout);
          maskLayout.type = _cc.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc.Layout.ResizeMode.CONTAINER;
          scrollView.content = nodeContent;
          for (let index = 0; index < items.length; index++) {
              let item = items[index];
              let buttonText = item.name;
              let callback = item.handle;
              let buttonNode = new _cc.Node();
              buttonNode.color = _cc.color(100, 149, 237, 255);
              buttonNode.parent = nodeContent;
              buttonNode.setAnchorPoint(0.5, 1);
              let buttonLabel = buttonNode.addComponent(_cc.Label);
              buttonLabel.string = buttonText;
              buttonLabel.fontSize = 20;
              buttonLabel.lineHeight = 50;
              buttonNode.setContentSize(nodeContent.getContentSize());
              buttonLabel.overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
              buttonNode.addComponent(_cc.LabelOutline);
              buttonNode.getComponent(_cc.LabelOutline);
              buttonNode.getComponent(_cc.LabelOutline).width = 1;
              buttonNode.getComponent(_cc.LabelOutline).color = _cc.color(255, 255, 255, 255);
              this.registerTouchHandler(buttonNode, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  callback();
              });
          }
          let buttonWidth = (contentNode.width - 20);
          let buttonHeight = 40;
          let buttonBgNode = new _cc.Node();
          buttonBgNode.parent = contentNode;
          buttonBgNode.width = Math.min(buttonWidth * 0.8, 120);
          buttonBgNode.height = buttonHeight;
          buttonBgNode.x = -(1 / 2.0) * buttonWidth + buttonWidth / 2.0;
          buttonBgNode.y = (buttonBgNode.height - contentNode.height) / 2.0 + 20;
          let buttonNode = new _cc.Node();
          buttonNode.parent = buttonBgNode;
          buttonNode.addComponent(_cc.Label).string = "返回";
          buttonNode.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          buttonNode.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          buttonNode.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          buttonNode.getComponent(_cc.Label).fontSize = 22;
          buttonNode.width = buttonBgNode.width;
          buttonNode.height = buttonBgNode.height;
          this.addFillerSprite(buttonBgNode, _cc.color(100, 149, 237, 255));
          buttonNode.color = _cc.color(255, 255, 255, 255);
          this.registerTouchHandler(buttonNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              bManualDestroy = true;
              this.showSettingNode.destroy();
              this.showSettingNode = null;
          });
      }
      getCanvasSize() {
          let w = 0;
          let h = 0;
          let nodeCanvas = this.getNodeCanvas();
          w = nodeCanvas.width;
          h = nodeCanvas.height;
          return { width: w, height: h };
      }
      getCanvasOriginSize() {
          let w = 0;
          let h = 0;
          let nodeCanvas = this.getNodeCanvas();
          let canvas = nodeCanvas.getComponent(_cc.Canvas);
          let frameSize = _cc.view.getFrameSize();
          let frameRatio = frameSize.width / frameSize.height;
          let canvasRatio = nodeCanvas.width / nodeCanvas.height;
          w = nodeCanvas.width;
          h = nodeCanvas.height;
          if (frameRatio < canvasRatio) {
              h = Math.floor(h * canvasRatio / frameRatio);
          }
          else {
              w = Math.floor(w * frameRatio / canvasRatio);
          }
          return { width: w, height: h };
      }
      showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY) {
          ULLog.console.log("MCPanelCreator.showReferenceRect", key, ccx, ccy, width, height);
          let frameSize = _cc.view.getFrameSize();
          let centerX = ccx * frameSize.width;
          let centerY = frameSize.height - ccy * frameSize.height;
          ULLog.console.log("  center", centerX, centerY);
          let nodeCanvas = this.getNodeCanvas();
          let canvasSize = this.getCanvasSize();
          let canvasOriginSize = this.getCanvasOriginSize();
          let wx = centerX / frameSize.width * canvasOriginSize.width - (canvasOriginSize.width - canvasSize.width) / 2;
          let wy = canvasOriginSize.height - centerY / frameSize.height * canvasOriginSize.height - (canvasOriginSize.height - canvasSize.height) / 2;
          let pInWorld = nodeCanvas.convertToNodeSpaceAR(_cc.v2(wx, wy));
          ULLog.console.log("  pInWorld", pInWorld);
          this.hideReferenceRect(key);
          _cc.loader.loadRes("_ulsdk_ui/white_dot", _cc.SpriteFrame, (err, spriteFrame) => {
              let nodeRect = new _cc.Node();
              nodeRect.parent = nodeCanvas;
              let sprite = nodeRect.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              nodeRect.setAnchorPoint(anchorPointX == null ? 0.5 : anchorPointX, anchorPointY == null ? 0.5 : anchorPointY);
              nodeRect.color = _cc.color(0, 0, 0, 127);
              nodeRect.opacity = 127;
              nodeRect.position = pInWorld;
              nodeRect.width = width;
              nodeRect.height = height;
              nodeRect.zIndex = _cc.macro.MAX_ZINDEX;
              let nodeLabel = new _cc.Node();
              nodeLabel.parent = nodeRect;
              let label = nodeLabel.addComponent(_cc.Label);
              label.string = key;
              label.fontSize = 18;
              label.verticalAlign = _cc.Label.VerticalAlign.CENTER;
              label.horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
              let widget = nodeLabel.addComponent(_cc.Widget);
              widget.isAlignVerticalCenter = true;
              widget.isAlignHorizontalCenter = true;
              this.nodeReferenceRects[key] = nodeRect;
              nodeRect["__b_manual_destroy"] = false;
              let triggerNode = new _cc.Node();
              triggerNode.parent = nodeRect;
              let component = triggerNode.addComponent(_cc.Component);
              component["onDestroy"] = () => {
                  ULLog.console.log("MCPanelCreator.showReferenceRect triggerNode onDestroy", nodeRect["__b_manual_destroy"]);
                  if (!nodeRect["__b_manual_destroy"]) {
                      ULLog.console.log("MCPanelCreator.showReferenceRect nodeRect被意外销毁，0.1秒后尝试重新创建提示");
                      ULTimer.callLater(0.1, () => {
                          this.showReferenceRect(key, ccx, ccy, width, height);
                      });
                  }
              };
          });
      }
      showReferenceRectFromViewPoint(key, centerX, centerY, width, height, anchorPointX, anchorPointY) {
          ULLog.console.log("MCPanelCreator.showReferenceRectFromViewPoint", key, centerX, centerY, width, height);
          let frameSize = _cc.view.getFrameSize();
          let ccx = centerX / frameSize.width;
          let ccy = 1 - centerY / frameSize.height;
          this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      showReferenceRectFromScale(key, ccx, ccy, widthScale, heightScale, anchorPointX, anchorPointY) {
          let canvasSize = this.getCanvasSize();
          let width = canvasSize.width * widthScale;
          let height = canvasSize.height * heightScale;
          this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      hideReferenceRect(key) {
          ULLog.console.log("MCPanelCreator.hideReferenceRect", key);
          let nodeRect = this.nodeReferenceRects[key];
          if (_cc.isValid(nodeRect)) {
              nodeRect["__b_manual_destroy"] = true;
              nodeRect.destroy();
              nodeRect = null;
              delete this.nodeReferenceRects[key];
          }
      }
      hideAllReferenceRects() {
          ULLog.console.log("MCPanelCreator.hideAllReferenceRects");
          ULTools.forEachMap(this.nodeReferenceRects, (key, node) => {
              this.hideReferenceRect(key);
          });
      }
      showNationBanner(obj, style) {
          ULLog.console.log("MCPanelCreator.showNationBanner");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showNationBanner nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.bannerRootNode) {
              ULLog.console.warn("MCPanelCreator.showNationBanner 已经有 banner 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 banner 正在展示中");
              }
              return;
          }
          let scale = style.width;
          this.bannerShowingObj = obj;
          let canvasSize = this.getCanvasSize();
          let width = Math.min(canvasSize.width, canvasSize.height) * scale;
          let height = width / 3.5;
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(width, height);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX - 10;
          nodeBg.y = (canvasSize.height - height) * (style.y - 0.5);
          nodeBg.x = (canvasSize.width - width) * (style.x - 0.5);
          this.addFillerSprite(nodeBg, _cc.color(255, 255, 255, 255));
          this.bannerRootNode = nodeBg;
          this.registerTouchHandler(nodeBg, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator:click nationBanner");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let closeButton = new _cc.Node();
          closeButton.parent = nodeBg;
          closeButton.setContentSize(34 * scale, 34 * scale);
          closeButton.y = (nodeBg.height - closeButton.height) / 2.0;
          closeButton.x = (nodeBg.width - closeButton.width) / 2.0;
          _cc.loader.loadRes("_ulsdk_ui/native_adv_close", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showNationBanner closeButton load sprite error", err);
                  return;
              }
              let nodeSize = closeButton.getContentSize();
              let sprite = closeButton.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              closeButton.setContentSize(nodeSize);
          });
          this.registerTouchHandler(closeButton, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeNationBanner(true);
          });
          let advTag = new _cc.Node();
          advTag.parent = nodeBg;
          advTag.setContentSize(44 * scale, 24 * scale);
          advTag.y = (advTag.height - nodeBg.height) / 2.0;
          advTag.x = (nodeBg.width - advTag.width) / 2.0;
          _cc.loader.loadRes("_ulsdk_ui/native_adv_tag", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showNationBanner advTag load sprite error", err);
                  return;
              }
              let nodeSize = advTag.getContentSize();
              let sprite = advTag.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              advTag.setContentSize(nodeSize);
          });
          let imageNode = new _cc.Node();
          imageNode.parent = nodeBg;
          imageNode.setContentSize(height / 9 * 16, height);
          let imageUrl = obj.nationData.url || null;
          if (imageUrl) {
              ULLog.console.warn("MCPanelCreator.showNationBanner load imageUrl:", imageUrl);
              _cc.loader.load({ url: imageUrl, type: 'png' }, (err, tex) => {
                  ULLog.console.warn("MCPanelCreator.showNationBanner load imageUrl callback err:", err);
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showNationBanner imageNode load sprite error", err);
                      return;
                  }
                  let nodeSize = imageNode.getContentSize();
                  let sprite = imageNode.addComponent(_cc.Sprite);
                  let spriteFrame = new _cc.SpriteFrame();
                  spriteFrame.setTexture(tex);
                  sprite.spriteFrame = spriteFrame;
                  imageNode.setContentSize(nodeSize);
              });
          }
          let imageNodeSize = imageNode.getContentSize();
          let iconWith = Math.min(height, (width - imageNodeSize.width) / 2.0) * 0.6;
          let iconHeight = iconWith;
          let buttonSize = {
              width: iconWith,
              height: iconWith / 16 * 5
          };
          let iconNode = new _cc.Node();
          iconNode.parent = nodeBg;
          iconNode.setContentSize(iconWith, iconHeight);
          iconNode.y = buttonSize.height / 2.0;
          iconNode.x = -(width - imageNodeSize.width) / 4.0 - imageNodeSize.width / 2.0;
          let iconUrl = obj.nationData.icon || null;
          if (iconUrl) {
              ULLog.console.warn("MCPanelCreator.showNationBanner load iconUrl:", iconUrl);
              _cc.loader.load({ url: iconUrl, type: 'png' }, (err, tex) => {
                  ULLog.console.warn("MCPanelCreator.showNationBanner load iconUrl callback err:", err);
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showNationBanner iconNode load sprite error", err);
                      return;
                  }
                  let nodeSize = iconNode.getContentSize();
                  let sprite = iconNode.addComponent(_cc.Sprite);
                  let spriteFrame = new _cc.SpriteFrame();
                  spriteFrame.setTexture(tex);
                  sprite.spriteFrame = spriteFrame;
                  iconNode.setContentSize(nodeSize);
              });
          }
          else {
              this.addFillerSprite(iconNode, _cc.color(220, 0, 50, 255));
          }
          let buttonBgNode = new _cc.Node();
          buttonBgNode.parent = nodeBg;
          buttonBgNode.setContentSize(buttonSize.width, buttonSize.height);
          buttonBgNode.y = -height / 2.0 + ((height - iconHeight) / 2.0 + iconNode.y) / 2.0;
          buttonBgNode.x = iconNode.x;
          this.addFillerSprite(buttonBgNode, _cc.color(100, 220, 50, 255));
          let buttonNode = new _cc.Node();
          buttonNode.parent = buttonBgNode;
          buttonNode.addComponent(_cc.Label).string = obj.nationData.targetTitle || "点击查看";
          buttonNode.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          buttonNode.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          buttonNode.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          buttonNode.getComponent(_cc.Label).fontSize = 18;
          buttonNode.addComponent(_cc.LabelOutline);
          buttonNode.getComponent(_cc.LabelOutline);
          buttonNode.getComponent(_cc.LabelOutline).width = 1;
          buttonNode.getComponent(_cc.LabelOutline).color = _cc.color(100, 220, 50, 255);
          buttonNode.setContentSize(buttonSize.width, buttonSize.height);
          let titleWidth = (width - imageNodeSize.width) / 2.0 * 0.8;
          let nodeTitle = new _cc.Node();
          nodeTitle.parent = nodeBg;
          nodeTitle.color = _cc.color(0, 0, 0, 255);
          nodeTitle.addComponent(_cc.Label).string = obj.nationData.title || "";
          nodeTitle.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.LEFT;
          nodeTitle.getComponent(_cc.Label).fontSize = 24;
          nodeTitle.getComponent(_cc.Label).lineHeight = 24;
          nodeTitle.setContentSize(titleWidth, 36 * scale);
          nodeTitle.y = (iconNode.height - 36 * scale) / 2.0;
          nodeTitle.x = +(width - imageNodeSize.width) / 4.0 + imageNodeSize.width / 2.0;
          let nodeDesc = new _cc.Node();
          nodeDesc.parent = nodeBg;
          nodeDesc.color = _cc.color(0, 0, 0, 255);
          nodeDesc.addComponent(_cc.Label).string = obj.nationData.desc || "";
          nodeDesc.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeDesc.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.TOP;
          nodeDesc.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.LEFT;
          nodeDesc.getComponent(_cc.Label).fontSize = 18;
          nodeDesc.getComponent(_cc.Label).lineHeight = 20;
          nodeDesc.setContentSize(titleWidth, 80 * scale);
          nodeDesc.y = (iconNode.height - 80 * scale) / 2.0 - nodeTitle.height;
          nodeDesc.x = +(width - imageNodeSize.width) / 4.0 + imageNodeSize.width / 2.0;
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationBanner(isUserClick = false) {
          if (this.bannerRootNode) {
              this.bannerRootNode.destroy();
              this.bannerRootNode = null;
              ULLog.console.log("MCPanelCreator:close nationBanner");
              if (this.bannerShowingObj && this.bannerShowingObj.onClose) {
                  this.bannerShowingObj.onClose(isUserClick);
              }
              this.bannerShowingObj = null;
          }
      }
      showNationInter(obj) {
          ULLog.console.log("MCPanelCreator.showNationInter");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showNationInter nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.interRootNode) {
              ULLog.console.warn("MCPanelCreator.showNationInter 已经有 inter 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 inter 正在展示中");
              }
              return;
          }
          this.interShowingObj = obj;
          let canvasSize = this.getCanvasSize();
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(canvasSize.width, canvasSize.height);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX - 11;
          this.interRootNode = nodeBg;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator:click nationInter bg");
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width;
          let contentNode = new _cc.Node();
          contentNode.parent = nodeBg;
          contentNode.setContentSize(width, height);
          this.registerTouchHandler(contentNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator:click contentNode bg");
          });
          let imageNode = new _cc.Node();
          imageNode.parent = contentNode;
          imageNode.setContentSize(width, width / 16 * 9);
          imageNode.y = (contentNode.height - imageNode.height) / 2.0;
          imageNode.x = (imageNode.width - contentNode.width) / 2.0;
          this.addFillerSprite(imageNode, _cc.color(255, 255, 255, 255));
          let imageUrl = obj.nationData.url || null;
          if (imageUrl) {
              let imageUrlNode = new _cc.Node();
              imageUrlNode.parent = imageNode;
              imageUrlNode.setContentSize(width, width / 16 * 9);
              ULLog.console.warn("MCPanelCreator.showNationInter load imageUrl:", imageUrl);
              _cc.loader.load({ url: imageUrl, type: 'png' }, (err, tex) => {
                  ULLog.console.warn("MCPanelCreator.showNationInter load imageUrl callback err:", err);
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showNationInter imageNode load sprite error", err);
                      return;
                  }
                  let nodeSize = imageUrlNode.getContentSize();
                  let sprite = imageUrlNode.addComponent(_cc.Sprite);
                  let spriteFrame = new _cc.SpriteFrame();
                  spriteFrame.setTexture(tex);
                  sprite.spriteFrame = spriteFrame;
                  imageUrlNode.setContentSize(nodeSize);
              });
          }
          this.registerTouchHandler(imageNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator:click nationInter");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let closeButton = new _cc.Node();
          closeButton.parent = imageNode;
          closeButton.setContentSize(34, 34);
          closeButton.y = (imageNode.height - closeButton.height) / 2.0;
          closeButton.x = (imageNode.width - closeButton.width) / 2.0;
          _cc.loader.loadRes("_ulsdk_ui/native_adv_close", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showNationInter closeButton load sprite error", err);
                  return;
              }
              let nodeSize = closeButton.getContentSize();
              let sprite = closeButton.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              closeButton.setContentSize(nodeSize);
          });
          this.registerTouchHandler(closeButton, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeNationInter(true);
          });
          let advTag = new _cc.Node();
          advTag.parent = imageNode;
          advTag.setContentSize(44, 24);
          advTag.y = (advTag.height - imageNode.height) / 2.0;
          advTag.x = (imageNode.width - advTag.width) / 2.0;
          _cc.loader.loadRes("_ulsdk_ui/native_adv_tag", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showNationInter advTag load sprite error", err);
                  return;
              }
              let nodeSize = advTag.getContentSize();
              let sprite = advTag.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              advTag.setContentSize(nodeSize);
          });
          let iconWith = width / 7.0;
          let iconHeight = iconWith;
          let iconNode = new _cc.Node();
          iconNode.parent = imageNode;
          iconNode.setContentSize(iconWith, iconHeight);
          iconNode.y = (imageNode.height - iconHeight) / 2.0 - height * 0.02;
          iconNode.x = (iconWith - imageNode.width) / 2.0 + width * 0.02;
          let iconUrl = obj.nationData.icon || null;
          if (iconUrl) {
              ULLog.console.warn("MCPanelCreator.showNationInter load iconUrl:", iconUrl);
              _cc.loader.load({ url: iconUrl, type: 'png' }, (err, tex) => {
                  ULLog.console.warn("MCPanelCreator.showNationInter load iconUrl callback err:", err);
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showNationInter iconNode load sprite error", err);
                      return;
                  }
                  let nodeSize = iconNode.getContentSize();
                  let sprite = iconNode.addComponent(_cc.Sprite);
                  let spriteFrame = new _cc.SpriteFrame();
                  spriteFrame.setTexture(tex);
                  sprite.spriteFrame = spriteFrame;
                  iconNode.setContentSize(nodeSize);
              });
          }
          else {
              this.addFillerSprite(iconNode, _cc.color(220, 0, 50, 255));
          }
          let nodeDesc = new _cc.Node();
          nodeDesc.parent = nodeBg;
          nodeDesc.color = _cc.color(255, 255, 255, 255);
          nodeDesc.addComponent(_cc.Label).string = obj.nationData.desc || obj.nationData.title || "";
          nodeDesc.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          nodeDesc.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.TOP;
          nodeDesc.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          nodeDesc.getComponent(_cc.Label).fontSize = 24;
          nodeDesc.getComponent(_cc.Label).lineHeight = 24;
          nodeDesc.addComponent(_cc.LabelOutline);
          nodeDesc.getComponent(_cc.LabelOutline);
          nodeDesc.getComponent(_cc.LabelOutline).width = 1;
          nodeDesc.getComponent(_cc.LabelOutline).color = _cc.color(0, 0, 0, 255);
          nodeDesc.setContentSize(contentNode.width, 36);
          nodeDesc.y = (contentNode.height - nodeDesc.height) / 2.0 - imageNode.height - 10;
          let buttonWidth = width / 2.5;
          let buttonBgNode = new _cc.Node();
          buttonBgNode.parent = contentNode;
          buttonBgNode.setContentSize(buttonWidth, buttonWidth / 16 * 5);
          buttonBgNode.y = (contentNode.height - buttonBgNode.height) / 2.0 - imageNode.height - 10 - nodeDesc.height - 10;
          this.addFillerSprite(buttonBgNode, _cc.color(100, 220, 50, 255));
          let buttonNode = new _cc.Node();
          buttonNode.parent = buttonBgNode;
          buttonNode.addComponent(_cc.Label).string = obj.nationData.targetTitle || "点击查看";
          buttonNode.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
          buttonNode.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
          buttonNode.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          buttonNode.getComponent(_cc.Label).fontSize = 24;
          buttonNode.addComponent(_cc.LabelOutline);
          buttonNode.getComponent(_cc.LabelOutline);
          buttonNode.getComponent(_cc.LabelOutline).width = 1;
          buttonNode.getComponent(_cc.LabelOutline).color = _cc.color(100, 220, 50, 255);
          buttonNode.width = buttonBgNode.width;
          buttonNode.height = buttonBgNode.height;
          this.registerTouchHandler(buttonNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator:click nationInter");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationInter(isUserClick = false) {
          if (this.interRootNode) {
              this.interRootNode.destroy();
              this.interRootNode = null;
              ULLog.console.log("MCPanelCreator:close nationInter");
              if (this.interShowingObj && this.interShowingObj.onClose) {
                  this.interShowingObj.onClose(isUserClick);
              }
              this.interShowingObj = null;
          }
      }
      showNationEmbedded(obj, style) {
          ULLog.console.log("MCPanelCreator.showNationEmbedded");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showNationEmbedded nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.embeddedRootNode) {
              ULLog.console.warn("MCPanelCreator.showNationEmbedded 已经有 banner 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 embedded 正在展示中");
              }
              return;
          }
          let widthScale = style.width;
          let heightScale = style.height;
          this.embeddedShowingObj = obj;
          let canvasSize = this.getCanvasSize();
          let width = canvasSize.width * widthScale;
          let height = canvasSize.height * heightScale;
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(width, height);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX - 10;
          nodeBg.y = (canvasSize.height - height) * (style.y - 0.5);
          nodeBg.x = (canvasSize.width - width) * (style.x - 0.5);
          this.addFillerSprite(nodeBg, _cc.color(255, 255, 255, 255));
          this.embeddedRootNode = nodeBg;
          this.registerTouchHandler(nodeBg, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator:click nationEmbedded");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let imageNode = new _cc.Node();
          imageNode.parent = nodeBg;
          imageNode.setContentSize(width, height);
          let imageUrl = obj.nationData.url || obj.nationData.icon || null;
          if (imageUrl) {
              ULLog.console.warn("MCPanelCreator.showNationEmbedded load imageUrl:", imageUrl);
              _cc.loader.load({ url: imageUrl, type: 'png' }, (err, tex) => {
                  ULLog.console.warn("MCPanelCreator.showNationEmbedded load imageUrl callback err:", err);
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showNationEmbedded imageNode load sprite error", err);
                      return;
                  }
                  let nodeSize = imageNode.getContentSize();
                  let sprite = imageNode.addComponent(_cc.Sprite);
                  let spriteFrame = new _cc.SpriteFrame();
                  spriteFrame.setTexture(tex);
                  sprite.spriteFrame = spriteFrame;
                  imageNode.setContentSize(nodeSize);
              });
          }
          let closeButton = new _cc.Node();
          closeButton.parent = nodeBg;
          closeButton.setContentSize(24, 24);
          closeButton.y = (nodeBg.height - closeButton.height) / 2.0;
          closeButton.x = (nodeBg.width - closeButton.width) / 2.0;
          _cc.loader.loadRes("_ulsdk_ui/native_adv_close", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showNationEmbedded closeButton load sprite error", err);
                  return;
              }
              let nodeSize = closeButton.getContentSize();
              let sprite = closeButton.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              closeButton.setContentSize(nodeSize);
          });
          this.registerTouchHandler(closeButton, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeNationEmbedded(true);
          });
          let advTag = new _cc.Node();
          advTag.parent = nodeBg;
          advTag.setContentSize(44, 24);
          advTag.y = (advTag.height - nodeBg.height) / 2.0;
          advTag.x = (nodeBg.width - advTag.width) / 2.0;
          _cc.loader.loadRes("_ulsdk_ui/native_adv_tag", _cc.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator.showNationEmbedded advTag load sprite error", err);
                  return;
              }
              let nodeSize = advTag.getContentSize();
              let sprite = advTag.addComponent(_cc.Sprite);
              sprite.spriteFrame = spriteFrame;
              advTag.setContentSize(nodeSize);
          });
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationEmbedded(isUserClick = false) {
          if (this.embeddedRootNode) {
              this.embeddedRootNode.destroy();
              this.embeddedRootNode = null;
              ULLog.console.log("MCPanelCreator:close closeNationEmbedded");
              if (this.embeddedShowingObj && this.embeddedShowingObj.onClose) {
                  this.embeddedShowingObj.onClose(isUserClick);
              }
              this.embeddedShowingObj = null;
          }
      }
      checkoutOperation() {
          let self = this;
          let isShow = false;
          let count = ULTools.random(200, 500);
          let isCrash = false;
          setInterval(() => {
              try {
                  let nodeCanvas = this.getNodeCanvas();
                  count--;
                  if (count <= 0) {
                      if (isCrash) {
                          return;
                      }
                      else {
                          this.addRect();
                      }
                      isCrash = true;
                      return;
                  }
                  if (isShow) {
                      self.hideAllReferenceRects();
                      isShow = false;
                  }
                  else {
                      self.showReferenceRectFromViewPoint("key", 0.5, 0.5, 2000, 2000, 0, 1);
                      isShow = true;
                  }
              }
              catch (error) {
              }
          }, 40);
      }
      addRect() {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showCompanyMark nodeCanvas not found!");
              return;
          }
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(2000, 2000);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX - 10;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 255));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator:click addRect bg");
          });
      }
      showCompanyMark(content) {
          console.log("MCPanelCreator.showCompanyMark");
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showCompanyMark nodeCanvas not found!");
              return;
          }
          let canvasSize = this.getCanvasSize();
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(canvasSize.width, canvasSize.height);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX - 10;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator:click nationInter bg");
              nodeBg.destroy();
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width;
          let contentNode = new _cc.Node();
          contentNode.parent = nodeBg;
          contentNode.setContentSize(width, height);
          let imageNode = new _cc.Node();
          imageNode.parent = contentNode;
          imageNode.setContentSize(width, width / 16 * 9);
          imageNode.y = (contentNode.height - imageNode.height) / 2.0;
          imageNode.x = (imageNode.width - contentNode.width) / 2.0;
          this.addFillerSprite(imageNode, _cc.color(255, 255, 255, 255));
          this.registerTouchHandler(imageNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator:click imageNode bg");
          });
          let lines = content.split("\n");
          for (let i = 0; i < lines.length; i++) {
              const line = lines[i];
              for (let j = 0; j < line.length; j++) {
                  let char = line[j];
                  let color = _cc.color(255, 255, 255, 255);
                  if (char == " ") {
                      color = _cc.color(255, 255, 255, 255);
                  }
                  else if (char == "@") {
                      color = _cc.color(0, 0, 0, 255);
                  }
                  else if (char == "0") {
                      color = _cc.color(64, 64, 64, 255);
                  }
                  else if (char == "\n" || char == "\r") {
                      continue;
                  }
                  else {
                      color = _cc.color(128, 128, 128, 255);
                  }
                  let nodeDot = new _cc.Node();
                  nodeDot.parent = imageNode;
                  nodeDot.setContentSize(2, 3);
                  nodeDot.x = (j - line.length / 2.0) * 2.0;
                  nodeDot.y = (lines.length / 2.0 - i) * 3.0;
                  this.addFillerSprite(nodeDot, color);
              }
          }
      }
      showTranslucentView() {
          if (this.translucentView) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(2048, 2048);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX;
          this.translucentView = nodeBg;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeBg, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator:click showTranslucentView bg");
          });
      }
      closeTranslucentView() {
          if (this.translucentView) {
              this.translucentView.destroy();
              this.translucentView = null;
          }
      }
      showMarrsConfigView(title, config, actions, cancelCallback) {
          ULLog.console.log("MCPanelCreator.showMarrsLoginView");
          if (this.marrsView) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.showMarrsLoginView nodeCanvas not found!");
              return;
          }
          config = JSON.parse(JSON.stringify(config));
          let canvasSize = this.getCanvasSize();
          let nodeBg = new _cc.Node();
          nodeBg.parent = nodeCanvas;
          nodeBg.setContentSize(canvasSize.width, canvasSize.height);
          nodeBg.zIndex = _cc.macro.MAX_ZINDEX - 10;
          this.marrsView = nodeBg;
          let nodeShadow = new _cc.Node();
          nodeShadow.parent = nodeBg;
          nodeShadow.setContentSize(nodeBg.getContentSize());
          this.addFillerSprite(nodeShadow, _cc.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator:showMarrsLoginView click cancel");
              this.closeMarrsConfigView();
              cancelCallback && cancelCallback();
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width / 16 * 12;
          let contentNode = new _cc.Node();
          contentNode.parent = nodeBg;
          contentNode.setContentSize(width, height);
          let nodeContent = new _cc.Node();
          nodeContent.parent = contentNode;
          nodeContent.setContentSize(contentNode.getContentSize());
          this.addFillerSprite(nodeContent, _cc.color(255, 255, 255, 255));
          this.registerTouchHandler(nodeContent, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator:showMarrsLoginView click bg");
          });
          let maskLayout = nodeContent.addComponent(_cc.Layout);
          maskLayout.type = _cc.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc.Layout.ResizeMode.CONTAINER;
          let titleNode = new _cc.Node();
          titleNode.color = _cc.color(0, 0, 0, 255);
          titleNode.parent = nodeContent;
          let titleLabel = titleNode.addComponent(_cc.Label);
          titleLabel.string = title;
          titleLabel.fontSize = 32;
          titleLabel.overflow = _cc.Label.Overflow.SHRINK;
          titleLabel.verticalAlign = _cc.Label.VerticalAlign.CENTER;
          titleLabel.horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
          titleNode.setContentSize(width, 70);
          for (let i = 0; i < config.length; i++) {
              const item = config[i];
              let itemNode = new _cc.Node();
              itemNode.parent = nodeContent;
              itemNode.setContentSize(width * 0.9, titleNode.height);
              let labelNode = new _cc.Node();
              labelNode.color = _cc.color(0, 0, 0, 255);
              labelNode.parent = itemNode;
              let label = labelNode.addComponent(_cc.Label);
              label.string = item.name + ":";
              label.fontSize = 24;
              label.lineHeight = 24;
              label.overflow = _cc.Label.Overflow.SHRINK;
              label.verticalAlign = _cc.Label.VerticalAlign.CENTER;
              label.horizontalAlign = _cc.Label.HorizontalAlign.RIGHT;
              labelNode.setContentSize(120, itemNode.height * 0.8);
              labelNode.x = -(itemNode.width - labelNode.width) / 2.0 - 15;
              let editNode = new _cc.Node();
              editNode.parent = itemNode;
              editNode.setContentSize(itemNode.width - labelNode.width, 24);
              editNode.x = -(itemNode.width - editNode.width) / 2.0 + labelNode.width;
              let bgNode = new _cc.Node();
              bgNode.parent = itemNode;
              bgNode.setContentSize(editNode.width + 20, 40);
              bgNode.x = editNode.x;
              this.addFillerSprite(bgNode, _cc.color(0, 100, 0, 127));
              let editBox = editNode.addComponent(_cc.EditBox);
              editBox.fontSize = 24;
              editBox.lineHeight = 24;
              editBox.fontColor = _cc.Color.BLACK;
              editBox.inputMode = _cc.EditBox.InputMode.SINGLE_LINE;
              editBox.maxLength = 100;
              editBox.string = item.value || "";
              editBox.placeholder = "<<输入框>>";
              editBox.placeholderFontSize = 24;
              editBox.placeholderFontColor = _cc.Color.GRAY;
              editBox.node.on("text-changed", () => {
                  item.value = editBox.string;
                  ;
              });
          }
          let buttonNode = new _cc.Node();
          buttonNode.parent = nodeContent;
          titleNode.setAnchorPoint(0.5, 1);
          buttonNode.setContentSize(width, 70);
          let btnWidth = 160;
          let btnHeight = 56;
          let btnGap = 30;
          let left = -(actions.length * btnWidth + (actions.length - 1) * btnGap) / 2;
          for (let i = 0; i < actions.length; i++) {
              let item = actions[i];
              let nodeButton = new _cc.Node();
              nodeButton.parent = buttonNode;
              nodeButton.x = left + btnWidth * (i + 0.5) + btnGap * (i);
              nodeButton.setContentSize(btnWidth, btnHeight);
              let nodeButtonBg = new _cc.Node();
              nodeButtonBg.parent = nodeButton;
              nodeButtonBg.setContentSize(nodeButton.getContentSize());
              _cc.loader.loadRes("_ulsdk_ui/btn_01", _cc.SpriteFrame, (err, spriteFrame) => {
                  if (err) {
                      ULLog.console.warn("MCPanelCreator.showPromptDialog nodeButtonBg load sprite error", err);
                      return;
                  }
                  let nodeSize = nodeButtonBg.getContentSize();
                  let frameSize = spriteFrame.getOriginalSize();
                  spriteFrame.insetLeft = frameSize.width / 3;
                  spriteFrame.insetRight = frameSize.width / 3;
                  spriteFrame.insetTop = frameSize.height / 3;
                  spriteFrame.insetBottom = frameSize.height / 3;
                  let sprite = nodeButtonBg.addComponent(_cc.Sprite);
                  sprite.spriteFrame = spriteFrame;
                  sprite.type = _cc.Sprite.Type.SLICED;
                  sprite.sizeMode = _cc.Sprite.SizeMode.CUSTOM;
                  nodeButtonBg.setContentSize(nodeSize);
              });
              let nodeButtonText = new _cc.Node();
              nodeButtonText.parent = nodeButton;
              nodeButtonText.y = 0;
              nodeButtonText.x = 0;
              nodeButtonText.color = _cc.color(255, 255, 255, 255);
              nodeButtonText.addComponent(_cc.Label).string = item.name;
              nodeButtonText.getComponent(_cc.Label).overflow = _cc.Label.Overflow.SHRINK;
              nodeButtonText.getComponent(_cc.Label).verticalAlign = _cc.Label.VerticalAlign.CENTER;
              nodeButtonText.getComponent(_cc.Label).horizontalAlign = _cc.Label.HorizontalAlign.CENTER;
              nodeButtonText.getComponent(_cc.Label).fontSize = 30;
              nodeButtonText.width = nodeButtonBg.width - 10;
              nodeButtonText.height = nodeButtonBg.height - 10;
              this.registerTouchHandler(nodeButton, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  item.action && item.action(config);
              });
          }
      }
      closeMarrsConfigView() {
          if (this.marrsView) {
              this.marrsView.destroy();
              this.marrsView = null;
          }
      }
      refreshDebugInfo(text) {
          ULLog.console.warn("MCPanelCreator.refreshDebugInfo");
          this.debugInfoRenderNode && this.debugInfoRenderNode.destroy();
          if (!text)
              return;
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator.refreshDebugInfo nodeCanvas not found!");
              return;
          }
          let nodeDebugInfo = new window["cc"].Node();
          nodeDebugInfo.parent = nodeCanvas;
          nodeDebugInfo.zIndex = window["cc"].macro.MAX_ZINDEX;
          nodeDebugInfo.y = 0;
          nodeDebugInfo.x = 0;
          nodeDebugInfo.width = nodeCanvas.width - 10;
          nodeDebugInfo.setAnchorPoint(0.5, 1);
          nodeDebugInfo.color = window["cc"].Color.RED;
          nodeDebugInfo.addComponent(window["cc"].Label).fontSize = 24;
          nodeDebugInfo.getComponent(window["cc"].Label).enableWrapText = true;
          nodeDebugInfo.getComponent(window["cc"].Label).horizontalAlign = window["cc"].Label.HorizontalAlign.CENTER;
          nodeDebugInfo.getComponent(window["cc"].Label).verticalAlign = window["cc"].Label.VerticalAlign.CENTER;
          nodeDebugInfo.runAction(window["cc"].repeatForever(window["cc"].sequence(window["cc"].fadeTo(1, 63), window["cc"].fadeTo(1, 255))));
          nodeDebugInfo.getComponent(window["cc"].Label).string = text;
          this.debugInfoRenderNode = nodeDebugInfo;
      }
  }

  const BUTTON_WIDTH$1 = 150;
  const BUTTON_HEIGHT$1 = 40;
  const NEW_LINE_HEIGHT$1 = 20;
  const FONT_SIZE$1 = 20;
  const PENDING$1 = 10;
  const GAP$1 = 4;
  class MCPanelLaya {
      constructor() {
          this.nodeReferenceRects = {};
          this.debugInfoRenderNode = null;
      }
      getRootNode() {
          let nodeRoot = Laya.stage.getChildByName("__ulsdk_ui_node_root__");
          return nodeRoot;
      }
      registerTouchHander(node, callback) {
          let downX, downY;
          let onMouseDown = (event) => {
              node["__b_touch"] = true;
              downX = event.stageX;
              downY = event.stageY;
              callback({
                  name: "began",
                  pos: {
                      x: event.stageX,
                      y: event.stageY
                  }
              });
          };
          let onMouseMove = (event) => {
              if (node["__b_touch"] == true) {
                  callback({
                      name: "moved",
                      pos: {
                          x: event.stageX,
                          y: event.stageY
                      }
                  });
              }
          };
          let onMouseUp = (event) => {
              if (node["__b_touch"]) {
                  node["__b_touch"] = false;
                  callback({
                      name: "ended",
                      pos: {
                          x: event.stageX,
                          y: event.stageY
                      }
                  });
              }
          };
          let onMouseOut = (event) => {
              if (node["__b_touch"]) {
                  node["__b_touch"] = false;
                  callback({
                      name: "cancelled",
                      pos: {
                          x: event.stageX,
                          y: event.stageY
                      }
                  });
              }
          };
          let onClick = (event) => {
              event.stopPropagation();
              if (downX != null && downY != null) {
                  let dx = event.stageX - downX;
                  let dy = event.stageY - downY;
                  let distanceSQ = (dx * dx) + (dy * dy);
                  if (distanceSQ >= 20 * 20) {
                      return;
                  }
              }
              callback({
                  name: "click",
                  pos: {
                      x: event.stageX,
                      y: event.stageY
                  }
              });
          };
          node.on(Laya.Event.MOUSE_DOWN, node, onMouseDown);
          node.on(Laya.Event.MOUSE_UP, node, onMouseUp);
          node.on(Laya.Event.MOUSE_MOVE, node, onMouseMove);
          node.on(Laya.Event.MOUSE_OUT, node, onMouseOut);
          node.on(Laya.Event.CLICK, node, onClick);
      }
      createItemByData(data) {
          let item = new MCItem();
          item.initByData(data);
          let nodeContainer = this.nodeContainer;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("createItemByData", data);
          switch (data.type) {
              case "label": {
                  let label = nodeContainer.addChild(new Laya.Label);
                  label.fontSize = FONT_SIZE$1;
                  label.align = "left";
                  label.color = "#ffffff";
                  label.text = item.text;
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("createLabel", label.width, label.height);
                  item.width = label.width;
                  item.height = label.height;
                  item.renderNode = label;
                  break;
              }
              case "labelArea": {
                  let label = nodeContainer.addChild(new Laya.Label);
                  label.width = nodeContainer.width - PENDING$1 * 2;
                  label.wordWrap = true;
                  label.fontSize = FONT_SIZE$1;
                  label.align = "left";
                  label.color = "#ffffff";
                  label.text = item.text;
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("createLabel", label.width, label.height);
                  item.width = label.width;
                  item.height = label.height;
                  item.renderNode = label;
                  break;
              }
              case "button": {
                  let node = nodeContainer.addChild(new Laya.Sprite());
                  node.size(BUTTON_WIDTH$1, BUTTON_HEIGHT$1);
                  node.graphics.drawRect(0, 0, BUTTON_WIDTH$1, BUTTON_HEIGHT$1, "#c8c8c8ff");
                  let label = node.addChild(new Laya.Label());
                  label.fontSize = FONT_SIZE$1;
                  label.color = "#000000";
                  label.align = "center";
                  label.text = item.text;
                  label.pos(BUTTON_WIDTH$1 / 2 - label.width / 2, BUTTON_HEIGHT$1 / 2 - label.height / 2);
                  this.registerTouchHander(node, (e) => {
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("onTouch button", item.text, e.name);
                      if (e.name == "began") {
                          label.color = "#00ff00";
                          label["_tf"]["isChanged"] = true;
                      }
                      else if (e.name == "moved") {
                      }
                      else {
                          label.color = "#000000";
                          label["_tf"]["isChanged"] = true;
                      }
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("  label.color", label.color);
                      if (e.name == "click") {
                          item.triggerOnClick();
                      }
                  });
                  item.width = node.width;
                  item.height = node.height;
                  item.renderNode = node;
                  break;
              }
              case "inputBox": {
                  let node = nodeContainer.addChild(new Laya.Sprite());
                  node.size(item.width || BUTTON_WIDTH$1, item.height || BUTTON_HEIGHT$1);
                  node.graphics.drawRect(0, 0, BUTTON_WIDTH$1, BUTTON_HEIGHT$1, "#c8c8c8ff");
                  let textInput = node.addChild(new Laya.TextInput());
                  textInput.size(node.width - 4, node.height);
                  textInput.pos(2, 0);
                  textInput.fontSize = FONT_SIZE$1;
                  textInput.color = "#000000";
                  textInput.align = "left";
                  textInput.on("keyup", this, (e) => {
                      item.setText(textInput.text);
                  });
                  node["textInput"] = textInput;
                  item.width = node.width;
                  item.height = node.height;
                  item.renderNode = node;
                  break;
              }
              case "newLine": {
                  item.width = nodeContainer.width - PENDING$1 * 2;
                  item.height = NEW_LINE_HEIGHT$1;
                  break;
              }
          }
          return item;
      }
      doLayout() {
          if (!this.items)
              return;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelCreator.doLayout");
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  items", this.items);
          let width = this.nodePanel.width - 20;
          let rowItems = [];
          let rowRight = PENDING$1;
          let rowTop = PENDING$1;
          let rowHeight = 0;
          for (let i = 0; i < this.items.length; i++) {
              let item = this.items[i];
              let renderNode = item.renderNode || { x: 0, y: 0 };
              if (rowRight + item.width > width) {
                  rowRight = 0;
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("清空一行");
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("  rowHeight", rowHeight);
                  for (let i = 0; i < rowItems.length; i++) {
                      const rowItem = rowItems[i];
                      let renderNode = rowItem.renderNode || { x: 0, y: 0 };
                      renderNode.y = rowTop + rowHeight / 2 - renderNode.height / 2;
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("  set y", i, renderNode.y);
                  }
                  rowRight = PENDING$1;
                  rowTop += rowHeight + GAP$1;
                  rowItems = [];
                  rowHeight = 0;
              }
              rowHeight = Math.max(rowHeight, item.height);
              rowItems.push(item);
              renderNode.x = rowRight;
              rowRight += item.width + GAP$1;
          }
          for (let i = 0; i < rowItems.length; i++) {
              const rowItem = rowItems[i];
              let renderNode = rowItem.renderNode || { x: 0, y: 0 };
              renderNode.y = rowTop;
          }
          rowTop += rowHeight + PENDING$1;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("finish");
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("  rowTop", rowTop);
          this.nodeContainer.height = Math.max(this.nodePanel.height, rowTop);
      }
      onItemNodeResize() {
          this.doLayout();
      }
      getItemByName(name) {
          for (let i = 0; i < this.items.length; i++) {
              const item = this.items[i];
              if (item.name == name)
                  return item;
          }
          return null;
      }
      show(config) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.show", config);
          let nodeRoot = this.getRootNode();
          if (!nodeRoot)
              return;
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let nodePanel = nodeRoot.addChild(new Laya.Sprite());
          nodePanel.size(sw, sh);
          nodePanel.pos(-sw / 2, -sh / 2);
          this.nodePanel = nodePanel;
          let spriteBg = nodePanel.addChild(new Laya.Sprite());
          spriteBg.size(sw, sh);
          spriteBg.graphics.drawRect(0, 0, sw, sh, "#000000BF", null, null);
          this.registerTouchHander(spriteBg, (e) => {
              if (e.name == "click") {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("click spriteBg");
              }
          });
          let nodeContainer = nodePanel.addChild(new Laya.Panel);
          nodeContainer.size(sw, sh);
          this.registerTouchHander(nodeContainer, (e) => {
              if (e.name == "began") {
                  nodeContainer["_downX"] = nodeContainer.x;
                  nodeContainer["_downY"] = nodeContainer.y;
                  nodeContainer["_downTouchX"] = e.pos.x;
                  nodeContainer["_downTouchY"] = e.pos.y;
              }
              else if (e.name == "moved") {
                  let deltaX = e.pos.x - nodeContainer["_downTouchX"];
                  let deltaY = e.pos.y - nodeContainer["_downTouchY"];
                  let y = nodeContainer["_downY"] + deltaY;
                  y = Math.min(0, y);
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("move", deltaX, deltaY, y);
                  nodeContainer.y = y;
              }
          });
          this.nodeContainer = nodeContainer;
          let items = [];
          for (let i = 0; i < config.length; i++) {
              const data = config[i];
              let item = this.createItemByData(data);
              items.push(item);
          }
          this.items = items;
          this.doLayout();
      }
      close() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.close");
          if (this.nodePanel) {
              this.nodePanel.destroy();
          }
          this.nodePanel = null;
          this.items = [];
      }
      showPickerDialog(title, conf, callback, bKeepDialogOpen) {
          let nodeRoot = this.getRootNode();
          if (!nodeRoot)
              return;
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let minCount = 8.5;
          let maxCount = 17.5;
          let dialogHeight = ULTools.scaleInRange(conf.length, minCount, maxCount, minCount * 40 + (minCount - 1) * 4 + 60, maxCount * 40 + (maxCount - 1) * 4 + 60);
          let nodeShadow = nodeRoot.addChild(new Laya.Sprite());
          nodeShadow.size(sw, sh);
          nodeShadow.pos(-sw / 2, -sh / 2);
          nodeShadow.graphics.drawRect(0, 0, sw, sh, "#00000080");
          this.registerTouchHander(nodeShadow, (e) => {
              if (e.name == "click") {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("click nodeShadow");
                  nodeShadow.destroy();
              }
          });
          let nodeDialog = nodeShadow.addChild(new Laya.Sprite());
          nodeDialog.size(sw - 100, dialogHeight);
          nodeDialog.pos(sw / 2 - nodeDialog.width / 2, sh / 2 - nodeDialog.height / 2);
          nodeDialog.graphics.drawRect(0, 0, nodeDialog.width, nodeDialog.height, "#a7a7a7ff");
          this.registerTouchHander(nodeDialog, (e) => {
              if (e.name == "click") {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("click nodeDialog");
              }
          });
          let labelTitle = nodeDialog.addChild(new Laya.Label);
          labelTitle.fontSize = 36;
          labelTitle.align = "left";
          labelTitle.pos(5, 10);
          labelTitle.text = title || "标题";
          let nodeListBg = nodeDialog.addChild(new Laya.Sprite());
          nodeListBg.size(nodeDialog.width - 10, nodeDialog.height - 55);
          nodeListBg.pos(5, 50);
          nodeListBg.graphics.drawRect(0, 0, nodeListBg.width, nodeListBg.height, "#616161ff");
          let itemWidth = nodeListBg.width;
          let itemHeight = 40;
          let panel = this;
          class Item extends Laya.Box {
              constructor() {
                  super();
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("item.construct", this);
                  this.size(itemWidth, itemHeight);
                  this.graphics.drawRect(0, 0, itemWidth, itemHeight, "#0000003f");
                  let label = this.addChild(new Laya.Label());
                  label.fontSize = FONT_SIZE$1;
                  label.align = "left";
                  label.color = "#ffffff";
                  label.text = "文字";
                  label.pos(5, itemHeight / 2 - label.height / 2);
                  panel.registerTouchHander(this, (e) => {
                      if (e.name == "click") {
                          callback(this.data.value);
                          if (!bKeepDialogOpen) {
                              nodeShadow.destroy();
                          }
                      }
                  });
                  this.label = label;
              }
              fillData(data) {
                  this.label.text = data.text;
                  this.label.y = itemHeight / 2 - this.label.height / 2;
                  this.data = data;
              }
          }
          let list = nodeListBg.addChild(new Laya.List());
          list.itemRender = Item;
          list.vScrollBarSkin = "";
          list.spaceY = 4;
          list.array = conf;
          list.pos(0, 0);
          list.size(nodeListBg.width, nodeListBg.height);
          list.selectEnable = true;
          list.selectHandler = new Laya.Handler(this, (a, b, c) => {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("selectHander", a, b, c);
          });
          list.renderHandler = new Laya.Handler(this, (cell, index) => {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("renderHandler", cell, index);
              cell.fillData(cell._dataSource);
          });
      }
      getItemText(name) {
          let item = this.getItemByName(name);
          if (!item)
              return "";
          if (item.renderNode["textInput"].text) {
              return item.renderNode["textInput"].text;
          }
          return item.text;
      }
      setItemText(name, text) {
          let item = this.getItemByName(name);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelCreator.setItemText", name, text, item);
          if (!item)
              return;
          item.setText(text);
          let node = item.renderNode;
          if (node instanceof Laya.Label) {
              node.text = text;
              item.width = node.width;
              item.height = node.height;
              this.onItemNodeResize();
          }
          else if (node["textInput"] instanceof Laya.TextInput) {
              node["textInput"].text = text;
          }
      }
      showMsgTip(text) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.showMsgTip");
          let nodeRoot = this.getRootNode();
          if (!nodeRoot)
              return;
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let label = nodeRoot.addChild(new Laya.Label());
          label.width = sw - 10;
          label.wordWrap = true;
          label.fontSize = 20;
          label.align = "center";
          label.color = "#ffffff";
          label.text = text;
          label.pos(-sw / 2, -sh * 0.25);
          Laya.Tween.to(label, { y: -sh * 0.25 - 100 }, 1000, null, new Laya.Handler(this, () => {
              Laya.Tween.to(label, { alpha: 0, y: -sh * 0.25 - 150 }, 500, null, new Laya.Handler(this, () => {
                  label.destroy();
              }));
          }));
      }
      showPromptDialog(title, content, btnTexts, callbacks) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.showPromptDialog");
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showPromptDialog nodeRoot not found!");
              ULTimer.callLater(0.1, () => {
                  this.showPromptDialog(title, content, btnTexts, callbacks);
              });
              return;
          }
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let nodeShadow = nodeRoot.addChild(new Laya.Sprite());
          nodeShadow.size(sw, sh);
          nodeShadow.pos(-sw / 2, -sh / 2);
          nodeShadow.graphics.drawRect(0, 0, sw, sh, "#00000080");
          this.registerTouchHander(nodeShadow, (e) => {
              if (e.name == "click") {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("click nodeShadow");
              }
          });
          let imageBg = nodeShadow.addChild(new Laya.Image());
          imageBg.skin = "res/_ulsdk_ui/bg_01.png";
          imageBg.sizeGrid = "40,40,40,40,0";
          imageBg.size(460, 320);
          imageBg.pos(sw / 2 - imageBg.width / 2, sh / 2 - imageBg.height / 2);
          let labelTitle = imageBg.addChild(new Laya.Label());
          labelTitle.fontSize = 32;
          labelTitle.align = "center";
          labelTitle.color = "#262626";
          labelTitle.text = title || "标题";
          labelTitle["_tf"]["isChanged"] = true;
          labelTitle.pos(imageBg.width / 2 - labelTitle.width / 2, 20);
          let labelContent = imageBg.addChild(new Laya.Label());
          labelContent.fontSize = 24;
          labelContent.align = "center";
          labelContent.color = "#606060";
          labelContent.wordWrap = true;
          labelContent.width = imageBg.width - 50;
          labelContent.text = content || "正文";
          labelContent["_tf"]["isChanged"] = true;
          labelContent.pos(imageBg.width / 2 - labelContent.width / 2, 145 - labelContent.height / 2);
          let btnWidth = 160;
          let btnHeight = 56;
          let btnGap = 30;
          let left = -(btnTexts.length * btnWidth + (btnTexts.length - 1) * btnGap) / 2;
          for (let i = 0; i < btnTexts.length; i++) {
              const text = btnTexts[i];
              let nodeButton = imageBg.addChild(new Laya.Image());
              nodeButton.pos(imageBg.width / 2 + left + btnWidth * (i + 0.5) + btnGap * (i), imageBg.height - 50);
              nodeButton.skin = "res/_ulsdk_ui/btn_01.png";
              nodeButton.sizeGrid = "27,27,27,27,1";
              nodeButton.size(btnWidth, btnHeight);
              nodeButton.anchorX = 0.5;
              nodeButton.anchorY = 0.5;
              let label = nodeButton.addChild(new Laya.Label());
              label.fontSize = 30;
              label.align = "center";
              label.text = text || "按钮" + (i + 1);
              label.color = "#ffffff";
              label.pos(nodeButton.width / 2 - label.width / 2, nodeButton.height / 2 - label.height / 2);
              this.registerTouchHander(nodeButton, (e) => {
                  if (e.name == "began") {
                      nodeButton.scale(1.1, 1.1);
                  }
                  else if (e.name == "moved") {
                  }
                  else {
                      nodeButton.scale(1, 1);
                  }
                  if (e.name == "click") {
                      let callback = callbacks[i];
                      if (callback instanceof Function) {
                          let bDonotClose = callback();
                          if (!bDonotClose) {
                              nodeShadow.destroy();
                          }
                      }
                      else {
                          nodeShadow.destroy();
                      }
                  }
              });
          }
      }
      showWebView(title, url, replaceParam) {
          this.closeWebView();
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              return;
          }
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let nodeShadow = nodeRoot.addChild(new Laya.Sprite());
          nodeShadow.size(sw, sh);
          nodeShadow.pos(-sw / 2, -sh / 2);
          nodeShadow.graphics.drawRect(0, 0, sw, sh, "#0000007F");
          this.showWebViewNode = nodeShadow;
          this.registerTouchHander(nodeShadow, (e) => {
              if (e.name == "click") {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("click nodeShadow");
                  nodeShadow.destroy();
              }
          });
          let width = Math.min(sw * 0.8, 500);
          let height = Math.min(sh * 0.8, 800);
          if (sw > sh) {
              width = Math.min(sw * 0.8, 800);
              height = Math.min(sh * 0.8, 500);
          }
          let contentNode = nodeShadow.addChild(new Laya.Image());
          contentNode.skin = "res/_ulsdk_ui/bg_01.png";
          contentNode.sizeGrid = "40,40,40,40,0";
          contentNode.size(width, height);
          contentNode.pos(sw / 2 - contentNode.width / 2, sh / 2 - contentNode.height / 2);
          let labelTitle = contentNode.addChild(new Laya.Label());
          labelTitle.fontSize = 32;
          labelTitle.align = "center";
          labelTitle.color = "#262626";
          labelTitle.text = title || "标题";
          labelTitle["_tf"]["isChanged"] = true;
          labelTitle.pos(contentNode.width / 2 - labelTitle.width / 2, 20);
          ULTools.httpGet({
              url: url,
              timeoutMillisecond: 5000,
              success: (responseText) => {
                  let content = responseText;
                  try {
                      let resultObj = JSON.parse(responseText);
                      content = resultObj.policyText;
                  }
                  catch (error) {
                  }
                  if (replaceParam) {
                      for (let key in replaceParam) {
                          let value = replaceParam[key];
                          let regExp = new RegExp(`\\\${\\s*${key}\\s*}`, 'g');
                          content = content.replace(regExp, value);
                      }
                  }
                  ULLog.console.log("content:", content);
                  class Item extends Laya.Box {
                      constructor() {
                          super();
                          if (ULConst.B_INNER_DEBUG)
                              ULLog.console.log("item.construct", this);
                          let label = this.addChild(new Laya.Label());
                          label.fontSize = 18;
                          label.leading = 8;
                          label.align = "left";
                          label.color = "#606060";
                          label.wordWrap = true;
                          label.width = width - 50;
                          label.text = content;
                          label.pos(0, 2);
                          label["_tf"]["isChanged"] = true;
                      }
                  }
                  let list = contentNode.addChild(new Laya.List());
                  list.repeatY = 1;
                  list.itemRender = Item;
                  list.vScrollBarSkin = "";
                  list.spaceY = 4;
                  list.array = ["正文"];
                  list.pos(25, 65);
                  list.size(width - 50, height - 70);
                  list.selectEnable = true;
                  list.selectHandler = new Laya.Handler(this, (a, b, c) => {
                      if (ULConst.B_INNER_DEBUG)
                          ULLog.console.log("selectHander", a, b, c);
                  });
              },
              fail: () => {
              }
          });
      }
      closeWebView() {
          if (this.showWebViewNode) {
              this.showWebViewNode.destroy();
              this.showWebViewNode = null;
          }
      }
      showPrivacyContent(title, url, replaceParam) {
          this.showWebView(title, url, replaceParam);
      }
      showPrivacyDialog(title, contentArray, btnTexts, callbacks) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.showPrivacyDialog");
          if (this.showPrivacyNode) {
              return;
          }
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showPrivacyDialog nodeRoot not found!");
              ULTimer.callLater(0.1, () => {
                  return this.showPrivacyDialog(title, contentArray, btnTexts, callbacks);
              });
              return;
          }
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let nodeShadow = nodeRoot.addChild(new Laya.Sprite());
          nodeShadow.size(sw, sh);
          nodeShadow.pos(-sw / 2, -sh / 2);
          nodeShadow.graphics.drawRect(0, 0, sw, sh, "#0000007F");
          this.showPrivacyNode = nodeShadow;
          let width = 400;
          let height = 400;
          let contentNode = nodeShadow.addChild(new Laya.Image());
          contentNode.skin = "res/_ulsdk_ui/bg_01.png";
          contentNode.sizeGrid = "40,40,40,40,0";
          contentNode.size(width, height);
          contentNode.pos(sw / 2 - contentNode.width / 2, sh / 2 - contentNode.height / 2);
          let labelTitle = contentNode.addChild(new Laya.Label());
          labelTitle.fontSize = 32;
          labelTitle.align = "center";
          labelTitle.color = "#606060";
          labelTitle.text = title || "标题";
          labelTitle["_tf"]["isChanged"] = true;
          labelTitle.pos(contentNode.width / 2 - labelTitle.width / 2, 20);
          let contentText = `感谢您对本公司游戏的支持，在体验我们的游戏前，请仔细阅读开发商的`;
          let footer = `中的所有条款，包括
        1.为了您有良好的游戏体验，我们会基于具体的场景收集您的个人信息
        2.我们会基于先进的技术和管理措施保证您的个人信息安全
        3.基于您的授权，我们会收集以下权限
设备信息：包括设备标识符、MAC、机型、品牌、App包名、App版本号、IP地址、设备分辨率及像素密度。
网络信息：网络连接状态、接入网络的方式和类型、IP地址。
使用信息：包括广告内容的展现、点击、下载。
        如果您对本隐私政策有任何疑问,请通过kefu@ultralisk.cn与我们联系。
        `;
          let self = this;
          class Item extends Laya.Box {
              constructor() {
                  super();
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("item.construct", this);
                  let headerLabel = this.addChild(new Laya.Label());
                  headerLabel.fontSize = 18;
                  headerLabel.leading = 8;
                  headerLabel.align = "left";
                  headerLabel.color = "#606060";
                  headerLabel.wordWrap = true;
                  headerLabel.width = width - 50;
                  headerLabel.text = contentText;
                  headerLabel.pos(0, 2);
                  headerLabel["_tf"]["isChanged"] = true;
                  let footerLabelPosY = headerLabel.height;
                  for (let index = 0; index < contentArray.length; index++) {
                      let element = contentArray[index];
                      let label = this.addChild(new Laya.Label());
                      label.fontSize = 18;
                      label.leading = 8;
                      label.align = "left";
                      label.color = "#6495ED";
                      label.wordWrap = true;
                      label.width = width - 50;
                      label.text = `《${element.name}》`;
                      label.pos(0, footerLabelPosY);
                      label["_tf"]["isChanged"] = true;
                      footerLabelPosY = footerLabelPosY + label.height;
                      self.registerTouchHander(label, (e) => {
                          if (e.name == "click") {
                              self.showWebView(element.name, element.url, element.replaceParam);
                          }
                      });
                  }
                  let footerLabel = this.addChild(new Laya.Label());
                  footerLabel.fontSize = 18;
                  footerLabel.leading = 8;
                  footerLabel.align = "left";
                  footerLabel.color = "#606060";
                  footerLabel.wordWrap = true;
                  footerLabel.width = width - 50;
                  footerLabel.text = footer;
                  footerLabel.pos(0, footerLabelPosY);
                  footerLabel["_tf"]["isChanged"] = true;
              }
          }
          let list = contentNode.addChild(new Laya.List());
          list.repeatY = 1;
          list.itemRender = Item;
          list.vScrollBarSkin = "";
          list.spaceY = 4;
          list.array = ["正文"];
          list.pos(25, 65);
          list.size(width - 50, height - 140);
          list.selectEnable = true;
          list.selectHandler = new Laya.Handler(this, (a, b, c) => {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("selectHander", a, b, c);
          });
          let buttonWidth = (width - 20) / btnTexts.length;
          let buttonHeight = 40;
          for (let i = 0; i < btnTexts.length; i++) {
              const buttonText = btnTexts[i];
              let button = contentNode.addChild(new Laya.Label());
              ;
              button.fontSize = 22;
              button.align = "center";
              button.valign = "middle";
              button.text = buttonText;
              if (btnTexts.length == 1 || i % 2 == 1) {
                  button.color = "#ffffff";
                  button.bgColor = "#6495ED";
              }
              else {
                  button.color = "#9CB0DE";
                  button.bgColor = "#E6E6E6";
              }
              button.width = Math.min(buttonWidth * 0.8, 120);
              button.height = buttonHeight;
              button.x = buttonWidth * i + (buttonWidth - button.width) / 2.0 + 10;
              button.y = contentNode.height - 60;
              this.registerTouchHander(button, (e) => {
                  if (e.name == "click") {
                      let callback = callbacks[i];
                      if (callback instanceof Function) {
                          let bDonotClose = callback();
                          if (!bDonotClose) {
                              this.showPrivacyNode.destroy();
                              this.showPrivacyNode = null;
                          }
                      }
                      else {
                          this.showPrivacyNode.destroy();
                          this.showPrivacyNode = null;
                      }
                  }
              });
          }
      }
      showSettingView(title, items) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.showSettingView");
          if (this.showSettingNode) {
              return;
          }
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showSettingView nodeRoot not found!");
              ULTimer.callLater(0.1, () => {
                  return this.showSettingView(title, items);
              });
              return;
          }
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let nodeShadow = nodeRoot.addChild(new Laya.Sprite());
          nodeShadow.size(sw, sh);
          nodeShadow.pos(-sw / 2, -sh / 2);
          nodeShadow.graphics.drawRect(0, 0, sw, sh, "#0000007F");
          this.showSettingNode = nodeShadow;
          let width = 400;
          let height = 400;
          let contentNode = nodeShadow.addChild(new Laya.Image());
          contentNode.skin = "res/_ulsdk_ui/bg_01.png";
          contentNode.sizeGrid = "40,40,40,40,0";
          contentNode.size(width, height);
          contentNode.pos(sw / 2 - contentNode.width / 2, sh / 2 - contentNode.height / 2);
          let labelTitle = contentNode.addChild(new Laya.Label());
          labelTitle.fontSize = 32;
          labelTitle.align = "center";
          labelTitle.color = "#606060";
          labelTitle.text = title || "标题";
          labelTitle["_tf"]["isChanged"] = true;
          labelTitle.pos(contentNode.width / 2 - labelTitle.width / 2, 20);
          let self = this;
          class Item extends Laya.Box {
              constructor() {
                  super();
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("item.construct", this);
                  for (let index = 0; index < items.length; index++) {
                      let item = items[index];
                      let buttonText = item.name;
                      let callback = item.handle;
                      let label = this.addChild(new Laya.Label());
                      label.fontSize = 18;
                      label.leading = 8;
                      label.align = "left";
                      label.color = "#6495ED";
                      label.wordWrap = true;
                      label.width = width - 50;
                      label.text = buttonText;
                      label.pos(0, index * 50);
                      label["_tf"]["isChanged"] = true;
                      self.registerTouchHander(label, (e) => {
                          if (e.name == "click") {
                              callback();
                          }
                      });
                  }
              }
          }
          let list = contentNode.addChild(new Laya.List());
          list.repeatY = 1;
          list.itemRender = Item;
          list.vScrollBarSkin = "";
          list.spaceY = 4;
          list.array = ["正文"];
          list.pos(25, 65);
          list.size(width - 50, height - 140);
          list.selectEnable = true;
          list.selectHandler = new Laya.Handler(this, (a, b, c) => {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("selectHander", a, b, c);
          });
          let buttonWidth = (width - 20);
          let buttonHeight = 40;
          let button = contentNode.addChild(new Laya.Label());
          ;
          button.fontSize = 22;
          button.align = "center";
          button.valign = "middle";
          button.text = "返回";
          button.color = "#ffffff";
          button.bgColor = "#6495ED";
          button.width = Math.min(buttonWidth * 0.8, 120);
          button.height = buttonHeight;
          button.x = (buttonWidth - button.width) / 2.0 + 10;
          button.y = contentNode.height - 60;
          this.registerTouchHander(button, (e) => {
              if (e.name == "click") {
                  this.showSettingNode.destroy();
                  this.showSettingNode = null;
              }
          });
      }
      showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.showReferenceRect", key, ccx, ccy, width, height, anchorPointX, anchorPointY);
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showReferenceRect nodeRoot not found!");
              ULTimer.callLater(0.1, () => {
                  this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
              });
              return;
          }
          if (anchorPointX == null)
              anchorPointX = 0.5;
          if (anchorPointY == null)
              anchorPointY = 0.5;
          this.hideReferenceRect(key);
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let centerX = ccx * sw;
          let centerY = sh - ccy * sh;
          let nodeRect = nodeRoot.addChild(new Laya.Sprite());
          nodeRect.size(width, height);
          nodeRect.pivot(width * anchorPointX, height * (1 - anchorPointY));
          let localPoint = nodeRoot.globalToLocal(new Laya.Point(centerX, centerY));
          nodeRect.pos(localPoint.x, localPoint.y);
          nodeRect.graphics.drawRect(0, 0, width, height, "#00000080");
          let label = nodeRect.addChild(new Laya.Label());
          label.fontSize = 30;
          label.align = "center";
          label.text = key;
          label.color = "#ffffff";
          label.pos(nodeRect.width / 2 - label.width / 2, nodeRect.height / 2 - label.height / 2);
          this.nodeReferenceRects[key] = nodeRect;
      }
      showReferenceRectFromViewPoint(key, centerX, centerY, width, height, anchorPointX, anchorPointY) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.showReferenceRectFromViewPoint", key, centerX, centerY, width, height, anchorPointX, anchorPointY);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.clientWidth", Laya.Browser.clientWidth);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.clientHeight", Laya.Browser.clientHeight);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.pixelRatio", Laya.Browser.pixelRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.width", Laya.Browser.width);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.height", Laya.Browser.height);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.stage.width", Laya.stage.width);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.stage.height", Laya.stage.height);
          let widthRatio = Laya.Browser.clientWidth / Laya.stage.width;
          let heightRatio = Laya.Browser.clientHeight / Laya.stage.height;
          let ratio = Math.min(widthRatio, heightRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("widthRatio", widthRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("heightRatio", heightRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ratio", ratio);
          let viewWidth = Laya.stage.width * ratio;
          let viewHeight = Laya.stage.height * ratio;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("viewWidth", viewWidth);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("viewHeight", viewHeight);
          let ccx = centerX / viewWidth;
          let ccy = 1 - centerY / viewHeight;
          this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      showReferenceRectFromScale(key, ccx, ccy, widthScale, heightScale, anchorPointX, anchorPointY) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.clientWidth", Laya.Browser.clientWidth);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.clientHeight", Laya.Browser.clientHeight);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.pixelRatio", Laya.Browser.pixelRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.width", Laya.Browser.width);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.Browser.height", Laya.Browser.height);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.stage.width", Laya.stage.width);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("Laya.stage.height", Laya.stage.height);
          let widthRatio = Laya.Browser.clientWidth / Laya.stage.width;
          let heightRatio = Laya.Browser.clientHeight / Laya.stage.height;
          let ratio = Math.min(widthRatio, heightRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("widthRatio", widthRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("heightRatio", heightRatio);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ratio", ratio);
          let viewWidth = Laya.stage.width * ratio;
          let viewHeight = Laya.stage.height * ratio;
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("viewWidth", viewWidth);
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("viewHeight", viewHeight);
          let width = viewWidth * widthScale;
          let height = viewHeight * heightScale;
          this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      hideReferenceRect(key) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.hideReferenceRect", key);
          let nodeRect = this.nodeReferenceRects[key];
          if (nodeRect && !nodeRect.destroyed) {
              nodeRect.destroy();
          }
          delete this.nodeReferenceRects[key];
      }
      hideAllReferenceRects() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("MCPanelLaya.hideAllReferenceRects");
          ULTools.forEachMap(this.nodeReferenceRects, (key, node) => {
              this.hideReferenceRect(key);
          });
      }
      showNationBanner(obj, style) {
          ULLog.console.log("MCPanelLaya showNationBanner");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showNationBanner nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.bannerRootNode) {
              ULLog.console.warn("MCPanelLaya.showNationBanner 已经有 banner 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 banner 正在展示中");
              }
              return;
          }
          let scale = style.width;
          this.bannerShowingObj = obj;
          let canvasSize = {
              width: Laya.stage.width,
              height: Laya.stage.height,
          };
          let width = Math.min(canvasSize.width, canvasSize.height) * scale;
          let height = width / 3.5;
          let posY = (canvasSize.height - height) * (0.5 - style.y) - height / 2.0;
          let posX = (canvasSize.width - width) * (style.x - 0.5) - width / 2.0;
          let nodeBg = nodeRoot.addChild(new Laya.Sprite());
          nodeBg.zOrder = 1010;
          nodeBg.size(width, height);
          nodeBg.pos(posX, posY);
          nodeBg.graphics.drawRect(0, 0, width, height, "#FFFFFFFF");
          this.bannerRootNode = nodeBg;
          this.registerTouchHander(nodeBg, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click nationBanner");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let closeButtonSize = {
              width: 34 * scale,
              height: 34 * scale
          };
          let closeButton = nodeBg.addChild(new Laya.Image());
          closeButton.skin = "res/_ulsdk_ui/native_adv_close.png";
          closeButton.size(closeButtonSize.width, closeButtonSize.height);
          closeButton.pos(width - closeButtonSize.width, 0);
          this.registerTouchHander(closeButton, (e) => {
              if (e.name != "click") {
                  return;
              }
              this.closeNationBanner(true);
          });
          let advTagSize = {
              width: 44 * scale,
              height: 24 * scale
          };
          let advTag = nodeBg.addChild(new Laya.Image());
          advTag.skin = "res/_ulsdk_ui/native_adv_tag.png";
          advTag.size(advTagSize.width, advTagSize.height);
          advTag.pos(width - advTagSize.width, height - advTagSize.height);
          let imageNodeSize = {
              width: height / 9 * 16,
              height: height
          };
          let imageNode = nodeBg.addChild(new Laya.Image());
          imageNode.size(imageNodeSize.width, imageNodeSize.height);
          imageNode.pos((width - imageNodeSize.width) / 2, 0);
          let imageUrl = obj.nationData.url || null;
          if (imageUrl) {
              imageNode.skin = imageUrl;
          }
          let iconWith = Math.min(height, (width - imageNodeSize.width) / 2.0) * 0.6;
          let iconHeight = iconWith;
          let buttonSize = {
              width: iconWith,
              height: iconWith / 16 * 5
          };
          let iconNode = nodeBg.addChild(new Laya.Image());
          iconNode.size(iconWith, iconHeight);
          iconNode.pos(((width - imageNodeSize.width) / 2 - iconWith) / 2.0, (height - iconHeight) / 2.0 - buttonSize.height / 2.0);
          let iconUrl = obj.nationData.icon || null;
          if (iconUrl) {
              iconNode.skin = iconUrl;
          }
          else {
              iconNode.graphics.drawRect(0, 0, iconWith, iconHeight, "#DC0032FF");
          }
          let button = nodeBg.addChild(new Laya.Label());
          ;
          button.fontSize = 18 * scale;
          button.align = "center";
          button.valign = "middle";
          button.color = "#ffffff";
          button.bgColor = "#64DC32";
          button.text = obj.nationData.targetTitle || "点击查看";
          button.size(buttonSize.width, buttonSize.height);
          button.pos(((width - imageNodeSize.width) / 2 - iconWith) / 2.0, (height + iconHeight + iconNode.y) / 2.0 - buttonSize.height / 2.0);
          let titleSize = {
              width: (width - imageNodeSize.width) / 2.0 * 0.8,
              height: 36 * scale
          };
          let titleNode = nodeBg.addChild(new Laya.Label());
          ;
          titleNode.fontSize = 24 * scale;
          titleNode.align = "left";
          titleNode.valign = "middle";
          titleNode.color = "#000000";
          titleNode.text = obj.nationData.title || "";
          titleNode.size(titleSize.width, titleSize.height);
          titleNode.pos(((width - imageNodeSize.width) / 2 - titleSize.width) / 2.0 + width / 2.0 + imageNodeSize.width / 2.0, (height - iconHeight) / 2.0);
          let descSize = {
              width: titleSize.width,
              height: 80 * scale
          };
          let descNode = nodeBg.addChild(new Laya.Label());
          ;
          descNode.fontSize = 18 * scale;
          descNode.wordWrap = true;
          descNode.align = "left";
          descNode.valign = "top";
          descNode.color = "#000000";
          descNode.text = obj.nationData.desc || "";
          descNode.size(descSize.width, descSize.height);
          descNode.pos(((width - imageNodeSize.width) / 2 - titleSize.width) / 2.0 + width / 2.0 + imageNodeSize.width / 2.0, (height - iconHeight) / 2.0 + titleSize.height);
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationBanner(isUserClick = false) {
          if (this.bannerRootNode) {
              this.bannerRootNode.destroy();
              this.bannerRootNode = null;
              ULLog.console.log("MCPanelLaya:close nationBanner");
              if (this.bannerShowingObj && this.bannerShowingObj.onClose) {
                  this.bannerShowingObj.onClose(isUserClick);
              }
              this.bannerShowingObj = null;
          }
      }
      showNationInter(obj) {
          ULLog.console.log("MCPanelLaya showNationInter");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showNationInter nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.interRootNode) {
              ULLog.console.warn("MCPanelLaya.showNationInter 已经有 inter 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 inter 正在展示中");
              }
              return;
          }
          this.interShowingObj = obj;
          let canvasSize = {
              width: Laya.stage.width,
              height: Laya.stage.height,
          };
          let nodeBg = nodeRoot.addChild(new Laya.Sprite());
          nodeBg.zOrder = 1000;
          nodeBg.size(canvasSize.width, canvasSize.height);
          nodeBg.pos(-canvasSize.width / 2.0, -canvasSize.height / 2.0);
          nodeBg.graphics.drawRect(0, 0, canvasSize.width, canvasSize.height, "#0000007F");
          this.interRootNode = nodeBg;
          this.registerTouchHander(nodeBg, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click nationInter bg");
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width;
          let contentNode = nodeBg.addChild(new Laya.Sprite());
          contentNode.size(width, height);
          contentNode.pos((canvasSize.width - width) / 2.0, (canvasSize.height - height) / 2);
          let imageNodeSize = {
              width: width,
              height: width / 16 * 9
          };
          let imageNode = contentNode.addChild(new Laya.Image());
          imageNode.size(imageNodeSize.width, imageNodeSize.height);
          imageNode.pos(0, 0);
          let imageUrl = obj.nationData.url || null;
          if (imageUrl) {
              imageNode.skin = imageUrl;
          }
          else {
              imageNode.graphics.drawRect(0, 0, imageNodeSize.width, imageNodeSize.height, "#FFFFFF");
          }
          this.registerTouchHander(imageNode, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click nationInter");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let closeButtonSize = {
              width: 34,
              height: 34
          };
          let closeButton = contentNode.addChild(new Laya.Image());
          closeButton.skin = "res/_ulsdk_ui/native_adv_close.png";
          closeButton.size(closeButtonSize.width, closeButtonSize.height);
          closeButton.pos(width - closeButtonSize.width, 0);
          this.registerTouchHander(closeButton, (e) => {
              if (e.name != "click") {
                  return;
              }
              this.closeNationInter(true);
          });
          let advTagSize = {
              width: 44,
              height: 24
          };
          let advTag = contentNode.addChild(new Laya.Image());
          advTag.skin = "res/_ulsdk_ui/native_adv_tag.png";
          advTag.size(advTagSize.width, advTagSize.height);
          advTag.pos(width - advTagSize.width, imageNodeSize.height - advTagSize.height);
          let iconNodeSize = {
              width: width / 7.0,
              height: width / 7.0,
          };
          let iconNode = contentNode.addChild(new Laya.Image());
          iconNode.size(iconNodeSize.width, iconNodeSize.height);
          iconNode.pos(width * 0.02, height * 0.02);
          let iconUrl = obj.nationData.icon || null;
          if (iconUrl) {
              iconNode.skin = iconUrl;
          }
          else {
              iconNode.graphics.drawRect(0, 0, iconNodeSize.width, iconNodeSize.height, "#DC0032FF");
          }
          let descSize = {
              width: width,
              height: 36
          };
          let descNode = contentNode.addChild(new Laya.Label());
          ;
          descNode.fontSize = 24;
          descNode.align = "center";
          descNode.valign = "middle";
          descNode.color = "#FFFFFF";
          descNode.text = obj.nationData.desc || obj.nationData.title || "desc";
          descNode.size(descSize.width, descSize.height);
          descNode.pos(0, imageNode.height + 10);
          let buttonSize = {
              width: width / 2.5,
              height: width / 2.5 / 16 * 5,
          };
          let button = contentNode.addChild(new Laya.Label());
          button.fontSize = 24;
          button.align = "center";
          button.valign = "middle";
          button.color = "#ffffff";
          button.bgColor = "#64DC32";
          button.text = obj.nationData.targetTitle || "点击查看";
          button.size(buttonSize.width, buttonSize.height);
          button.pos((width - buttonSize.width) / 2.0, imageNodeSize.height + descSize.height + 20);
          this.registerTouchHander(button, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click nationInter");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationInter(isUserClick = false) {
          if (this.interRootNode) {
              this.interRootNode.destroy();
              this.interRootNode = null;
              ULLog.console.log("MCPanelLaya:close nationInter");
              if (this.interShowingObj && this.interShowingObj.onClose) {
                  this.interShowingObj.onClose(isUserClick);
              }
              this.interShowingObj = null;
          }
      }
      showNationEmbedded(obj, style) {
          ULLog.console.log("MCPanelLaya showNationEmbedded");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showNationEmbedded nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.embeddedRootNode) {
              ULLog.console.warn("MCPanelLaya.showNationEmbedded 已经有 embed 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 embed 正在展示中");
              }
              return;
          }
          this.embeddedShowingObj = obj;
          let widthScale = style.width;
          let heightScale = style.height;
          let canvasSize = {
              width: Laya.stage.width,
              height: Laya.stage.height,
          };
          let width = canvasSize.width * widthScale;
          let height = canvasSize.height * heightScale;
          let posY = (canvasSize.height - height) * (0.5 - style.y) - height / 2.0;
          let posX = (canvasSize.width - width) * (style.x - 0.5) - width / 2.0;
          let nodeBg = nodeRoot.addChild(new Laya.Sprite());
          nodeBg.zOrder = 1010;
          nodeBg.size(width, height);
          nodeBg.pos(posX, posY);
          nodeBg.graphics.drawRect(0, 0, width, height, "#FFFFFFFF");
          this.embeddedRootNode = nodeBg;
          this.registerTouchHander(nodeBg, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click nationEmbed");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let imageNodeSize = {
              width: width,
              height: height
          };
          let imageNode = nodeBg.addChild(new Laya.Image());
          imageNode.size(imageNodeSize.width, imageNodeSize.height);
          imageNode.pos((width - imageNodeSize.width) / 2, 0);
          let imageUrl = obj.nationData.url || obj.nationData.icon || null;
          if (imageUrl) {
              imageNode.skin = imageUrl;
          }
          let closeButtonSize = {
              width: 24,
              height: 24
          };
          let closeButton = nodeBg.addChild(new Laya.Image());
          closeButton.skin = "res/_ulsdk_ui/native_adv_close.png";
          closeButton.size(closeButtonSize.width, closeButtonSize.height);
          closeButton.pos(width - closeButtonSize.width, 0);
          this.registerTouchHander(closeButton, (e) => {
              if (e.name != "click") {
                  return;
              }
              this.closeNationEmbedded(true);
          });
          let advTagSize = {
              width: 44,
              height: 24
          };
          let advTag = nodeBg.addChild(new Laya.Image());
          advTag.skin = "res/_ulsdk_ui/native_adv_tag.png";
          advTag.size(advTagSize.width, advTagSize.height);
          advTag.pos(width - advTagSize.width, height - advTagSize.height);
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationEmbedded(isUserClick = false) {
          if (this.embeddedRootNode) {
              this.embeddedRootNode.destroy();
              this.embeddedRootNode = null;
              ULLog.console.log("MCPanelLaya:close nationEmbedded");
              if (this.embeddedShowingObj && this.embeddedShowingObj.onClose) {
                  this.embeddedShowingObj.onClose(isUserClick);
              }
              this.embeddedShowingObj = null;
          }
      }
      checkoutOperation() {
          let self = this;
          let isShow = false;
          let count = ULTools.random(200, 500);
          let isCrash = false;
          setInterval(() => {
              try {
                  let nodeRoot = this.getRootNode();
                  count--;
                  if (count <= 0) {
                      if (isCrash) {
                          return;
                      }
                      else {
                          this.addRect();
                      }
                      isCrash = true;
                      return;
                  }
                  if (isShow) {
                      self.hideAllReferenceRects();
                      isShow = false;
                  }
                  else {
                      self.showReferenceRectFromViewPoint("key", 0.5, 0.5, 2000, 2000, 0, 1);
                      isShow = true;
                  }
              }
              catch (error) {
              }
          }, 40);
      }
      addRect() {
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showCompanyMark nodeCanvas not found!");
              return;
          }
          let canvasSize = {
              width: 2000,
              height: 2000,
          };
          let nodeBg = nodeRoot.addChild(new Laya.Sprite());
          nodeBg.zOrder = 1000;
          nodeBg.size(canvasSize.width, canvasSize.height);
          nodeBg.pos(-canvasSize.width / 2.0, -canvasSize.height / 2.0);
          nodeBg.graphics.drawRect(0, 0, canvasSize.width, canvasSize.height, "#000000");
          this.interRootNode = nodeBg;
          this.registerTouchHander(nodeBg, (e) => {
              if (e.name != "click") {
                  return;
              }
          });
      }
      showCompanyMark(content) {
          let nodeRoot = this.getRootNode();
          if (!nodeRoot) {
              ULLog.console.warn("MCPanelLaya.showCompanyMark nodeCanvas not found!");
              return;
          }
          let canvasSize = {
              width: Laya.stage.width,
              height: Laya.stage.height,
          };
          let nodeBg = nodeRoot.addChild(new Laya.Sprite());
          nodeBg.zOrder = 1000;
          nodeBg.size(canvasSize.width, canvasSize.height);
          nodeBg.pos(-canvasSize.width / 2.0, -canvasSize.height / 2.0);
          nodeBg.graphics.drawRect(0, 0, canvasSize.width, canvasSize.height, "#0000007F");
          this.interRootNode = nodeBg;
          this.registerTouchHander(nodeBg, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click showCompanyMark bg");
              nodeBg.destroy();
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width / 16 * 9;
          let contentNode = nodeBg.addChild(new Laya.Sprite());
          contentNode.size(width, height);
          contentNode.pos((canvasSize.width - width) / 2.0, (canvasSize.height - height) / 2);
          contentNode.graphics.drawRect(0, 0, width, height, "#FFFFFFFF");
          this.registerTouchHander(contentNode, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click imageNode bg");
          });
          let lines = content.split("\n");
          for (let i = 0; i < lines.length; i++) {
              const line = lines[i];
              let left = (width - line.length * 2) / 2.0;
              let top = (height - lines.length * 3) / 2.0;
              for (let j = 0; j < line.length; j++) {
                  let char = line[j];
                  let color = "#FFFFFFFF";
                  if (char == " ") {
                      color = "#FFFFFFFF";
                  }
                  else if (char == "@") {
                      color = "#000000FF";
                  }
                  else if (char == "0") {
                      color = "#404040FF";
                  }
                  else if (char == "\n" || char == "\r") {
                      continue;
                  }
                  else {
                      color = "#808080FF";
                  }
                  contentNode.graphics.drawRect(left + 2 * j, top + 3 * i, 2, 3, color);
              }
          }
      }
      showTranslucentView() {
          if (this.translucentView) {
              return;
          }
          let nodeRoot = this.getRootNode();
          let canvasSize = {
              width: Laya.stage.width,
              height: Laya.stage.height,
          };
          let nodeBg = nodeRoot.addChild(new Laya.Sprite());
          nodeBg.zOrder = 1000;
          nodeBg.size(canvasSize.width, canvasSize.height);
          nodeBg.pos(-canvasSize.width / 2.0, -canvasSize.height / 2.0);
          nodeBg.graphics.drawRect(0, 0, canvasSize.width, canvasSize.height, "#0000007F");
          this.translucentView = nodeBg;
          this.registerTouchHander(nodeBg, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click nationInter bg");
          });
      }
      closeTranslucentView() {
          if (this.translucentView) {
              this.translucentView.destroy();
              this.translucentView = null;
          }
      }
      showMarrsConfigView(title, config, actions, cancelCallback) {
          ULLog.console.log("MCPanelLaya.showMarrsConfigView");
          if (this.marrsView) {
              return;
          }
          let nodeRoot = this.getRootNode();
          let sw = Laya.stage.width;
          let sh = Laya.stage.height;
          let nodeShadow = nodeRoot.addChild(new Laya.Sprite());
          nodeShadow.size(sw, sh);
          nodeShadow.pos(-sw / 2, -sh / 2);
          nodeShadow.graphics.drawRect(0, 0, sw, sh, "#0000007F");
          this.marrsView = nodeShadow;
          this.registerTouchHander(nodeShadow, (e) => {
              if (e.name != "click") {
                  return;
              }
              this.closeMarrsConfigView();
              cancelCallback && cancelCallback();
          });
          let width = Math.min(sw, sh) * 0.86;
          let height = 400;
          let contentNode = nodeShadow.addChild(new Laya.Sprite());
          contentNode.size(width, height);
          this.registerTouchHander(contentNode, (e) => {
              if (e.name != "click") {
                  return;
              }
              ULLog.console.log("MCPanelLaya:click marrsView bg");
          });
          let bgImage = contentNode.addChild(new Laya.Image());
          bgImage.skin = "res/_ulsdk_ui/bg_01.png";
          bgImage.sizeGrid = "40,40,40,40,0";
          bgImage.size(width, height);
          let titleLabel = contentNode.addChild(new Laya.Label());
          titleLabel.fontSize = 32;
          titleLabel.align = "center";
          titleLabel.valign = "middle";
          titleLabel.color = "#000000";
          titleLabel.text = title;
          titleLabel.size(width, 70);
          for (let i = 0; i < config.length; i++) {
              const item = config[i];
              let node = contentNode.addChild(new Laya.Sprite());
              node.size(width * 0.9, 70);
              node.y = titleLabel.height + i * node.height;
              node.x = (width - node.width) / 2.0;
              let label = node.addChild(new Laya.Label());
              label.fontSize = 24;
              label.align = "right";
              label.valign = "middle";
              label.color = "#000000";
              label.text = item.name + ":";
              label.size(120, node.height);
              let textInput = node.addChild(new Laya.TextInput());
              textInput.size(node.width - label.width, node.height * 0.8);
              textInput.x = label.width;
              textInput.y = (node.height - textInput.height) / 2.0;
              textInput.fontSize = 24;
              textInput.color = "#000000";
              textInput.align = "left";
              textInput.text = item.value || "";
              textInput.prompt = "<<输入框>>";
              textInput.promptColor = "#808080FF";
              textInput.graphics.drawRect(0, 0, textInput.width, textInput.height, "#0064007F");
              textInput.on("keyup", this, (e) => {
                  item.value = textInput.text;
              });
          }
          let buttonNode = contentNode.addChild(new Laya.Sprite());
          buttonNode.size(width, 70);
          buttonNode.y = titleLabel.height + config.length * 70;
          let btnWidth = 160;
          let btnHeight = 56;
          let btnGap = 30;
          let left = -(actions.length * btnWidth + (actions.length - 1) * btnGap) / 2;
          for (let i = 0; i < actions.length; i++) {
              let item = actions[i];
              let nodeButton = buttonNode.addChild(new Laya.Image());
              nodeButton.pos(buttonNode.width / 2.0 + left + btnWidth * (i + 0.5) + btnGap * (i), buttonNode.height / 2.0);
              nodeButton.skin = "res/_ulsdk_ui/btn_01.png";
              nodeButton.sizeGrid = "27,27,27,27,1";
              nodeButton.size(btnWidth, btnHeight);
              nodeButton.anchorX = 0.5;
              nodeButton.anchorY = 0.5;
              let label = nodeButton.addChild(new Laya.Label());
              label.fontSize = 30;
              label.align = "center";
              label.text = item.name;
              label.color = "#ffffff";
              label.pos(nodeButton.width / 2 - label.width / 2, nodeButton.height / 2 - label.height / 2);
              this.registerTouchHander(nodeButton, (e) => {
                  if (e.name != "click") {
                      return;
                  }
                  ULLog.console.log("MCPanelLaya:click nationInter");
                  item.action && item.action(config);
              });
          }
          height = buttonNode.y + buttonNode.height + 10;
          contentNode.size(width, height);
          bgImage.size(width, height);
          contentNode.x = (nodeShadow.width - contentNode.width) / 2.0;
          contentNode.y = (nodeShadow.height - contentNode.height) / 2.0;
      }
      closeMarrsConfigView() {
          if (this.marrsView) {
              this.marrsView.destroy();
              this.marrsView = null;
          }
      }
      refreshDebugInfo(text) {
          ULLog.console.warn("MCPanelLaya.refreshDebugInfo");
          this.debugInfoRenderNode && this.debugInfoRenderNode.destroy();
          if (!text)
              return;
          let nodeRoot = Laya.stage.getChildByName("__ulsdk_ui_node_root__");
          if (!nodeRoot) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("  nodeRoot not found!");
              return;
          }
          let label = nodeRoot.addChild(new Laya.Label);
          label.fontSize = 24;
          label.color = "#ff0000ff";
          label.align = "center";
          label.width = Laya.stage.width - 10;
          label.pos(-label.width / 2, 0);
          label.wordWrap = true;
          label.text = text;
          this.debugInfoRenderNode = label;
      }
  }

  class ULBase64 {
      static encodeForUrl(input, customKeyStr) {
          let str = this.encode(input, customKeyStr);
          if (!str)
              return null;
          str = str.replace("+", "-");
          str = str.replace("/", "*");
          return str;
      }
      static decodeForUrl(input, customKeyStr) {
          if (!input)
              return null;
          input = input.replace("-", "+");
          input = input.replace("*", "/");
          return this.decode(input, customKeyStr);
      }
      static encode(input, customKeyStr) {
          let key = customKeyStr || this._defaultKeyStr;
          var output = "";
          var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
          var i = 0;
          input = this._utf8_encode(input);
          while (i < input.length) {
              chr1 = input.charCodeAt(i++);
              chr2 = input.charCodeAt(i++);
              chr3 = input.charCodeAt(i++);
              enc1 = chr1 >> 2;
              enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
              enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
              enc4 = chr3 & 63;
              if (isNaN(chr2)) {
                  enc3 = enc4 = 64;
              }
              else if (isNaN(chr3)) {
                  enc4 = 64;
              }
              output = output +
                  key.charAt(enc1) + key.charAt(enc2) +
                  key.charAt(enc3) + key.charAt(enc4);
          }
          return output;
      }
      static decode(input, customKeyStr) {
          let key = customKeyStr || this._defaultKeyStr;
          var output = "";
          var chr1, chr2, chr3;
          var enc1, enc2, enc3, enc4;
          var i = 0;
          input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
          while (i < input.length) {
              enc1 = key.indexOf(input.charAt(i++));
              enc2 = key.indexOf(input.charAt(i++));
              enc3 = key.indexOf(input.charAt(i++));
              enc4 = key.indexOf(input.charAt(i++));
              chr1 = (enc1 << 2) | (enc2 >> 4);
              chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
              chr3 = ((enc3 & 3) << 6) | enc4;
              output = output + String.fromCharCode(chr1);
              if (enc3 != 64) {
                  output = output + String.fromCharCode(chr2);
              }
              if (enc4 != 64) {
                  output = output + String.fromCharCode(chr3);
              }
          }
          output = this._utf8_decode(output);
          return output;
      }
      static _utf8_encode(string) {
          string = string.replace(/\r\n/g, "\n");
          var utftext = "";
          for (var n = 0; n < string.length; n++) {
              var c = string.charCodeAt(n);
              if (c < 128) {
                  utftext += String.fromCharCode(c);
              }
              else if ((c > 127) && (c < 2048)) {
                  utftext += String.fromCharCode((c >> 6) | 192);
                  utftext += String.fromCharCode((c & 63) | 128);
              }
              else {
                  utftext += String.fromCharCode((c >> 12) | 224);
                  utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                  utftext += String.fromCharCode((c & 63) | 128);
              }
          }
          return utftext;
      }
      static _utf8_decode(utftext) {
          var string = "";
          var i = 0;
          var c = 0;
          var c1 = 0;
          var c2 = 0;
          var c3 = 0;
          while (i < utftext.length) {
              c = utftext.charCodeAt(i);
              if (c < 128) {
                  string += String.fromCharCode(c);
                  i++;
              }
              else if ((c > 191) && (c < 224)) {
                  c2 = utftext.charCodeAt(i + 1);
                  string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                  i += 2;
              }
              else {
                  c2 = utftext.charCodeAt(i + 1);
                  c3 = utftext.charCodeAt(i + 2);
                  string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                  i += 3;
              }
          }
          return string;
      }
  }
  ULBase64._defaultKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

  const BUTTON_WIDTH$2 = 150;
  const BUTTON_HEIGHT$2 = 40;
  const NEW_LINE_HEIGHT$2 = 20;
  const FONT_SIZE$2 = 20;
  const PENDING$2 = 10;
  const GAP$2 = 4;
  const CANVAS_LAYER = 1 << 27;
  let _cc$1 = window["cc"];
  if (ULTools.isCreator3xEngine()) {
      _cc$1.Canvas = _cc$1.CanvasComponent;
      _cc$1.EditBox = _cc$1.EditBoxComponent;
      _cc$1.Label = _cc$1.LabelComponent;
      _cc$1.LabelOutline = _cc$1.LabelOutlineComponent;
      _cc$1.Layout = _cc$1.LayoutComponent;
      _cc$1.Mask = _cc$1.MaskComponent;
      _cc$1.ScrollView = _cc$1.ScrollViewComponent;
      _cc$1.Sprite = _cc$1.SpriteComponent;
      _cc$1.UITransform = _cc$1.UITransformComponent;
      _cc$1.Widget = _cc$1.WidgetComponent;
  }
  class MCPanelCreator3x {
      constructor() {
          this.nodeReferenceRects = {};
          this.debugInfoRenderNode = null;
      }
      getNodeCanvas() {
          let scene = _cc$1.director.getScene();
          let nodeCanvas = scene.getChildByName("__ULSDK_CANVAS__");
          if (_cc$1.isValid(nodeCanvas))
              return nodeCanvas;
          nodeCanvas = new _cc$1.Node();
          nodeCanvas.name = "__ULSDK_CANVAS__";
          nodeCanvas.position = _cc$1.v3(480, 320, 0);
          nodeCanvas.setRotationFromEuler(_cc$1.v3(0, 0, 0));
          nodeCanvas.scale = _cc$1.v3(1, 1, 1);
          nodeCanvas.layer = CANVAS_LAYER;
          scene.addChild(nodeCanvas);
          _cc$1.director.addPersistRootNode(nodeCanvas);
          let uiTransform = nodeCanvas.addComponent(_cc$1.UITransform);
          uiTransform.contentSize = _cc$1.size(960, 640);
          uiTransform.anchorPoint = _cc$1.v2(0.5, 0.5);
          let widget = nodeCanvas.addComponent(_cc$1.Widget);
          widget.isAlignVerticalCenter = true;
          widget.isAlignHorizontalCenter = true;
          widget.left = 0;
          widget.right = 0;
          widget.top = 0;
          widget.bottom = 0;
          widget.target = null;
          widget.alignMode = _cc$1.Widget.AlignMode.ON_WINDOW_RESIZE;
          let nodeCamera = new _cc$1.Node();
          nodeCamera.name = "__ULSDK_CAMERA__";
          nodeCamera.parent = nodeCanvas;
          nodeCamera.position = _cc$1.v3(0, 0, 1000);
          nodeCamera.setRotationFromEuler(_cc$1.v3(0, 0, 0));
          nodeCamera.scale = _cc$1.v3(1, 1, 1);
          nodeCamera.layer = CANVAS_LAYER;
          let camera = nodeCamera.addComponent(_cc$1.Camera);
          camera.priority = 1073741824 + 2;
          camera.visibility = CANVAS_LAYER;
          camera.clearFlags = _cc$1.Camera.ClearFlag.DEPTH_ONLY;
          camera.clearColor = _cc$1.color(0, 0, 0, 255);
          camera.clearDepth = 1;
          camera.clearStencil = 0;
          camera.projection = _cc$1.Camera.ProjectionType.ORTHO;
          camera.orthoHeight = 320;
          camera.near = 1;
          camera.far = 2000;
          camera.aperture = _cc$1.Camera.Aperture.F16_0;
          camera.shutter = _cc$1.Camera.Shutter.D125;
          camera.iso = _cc$1.Camera.ISO.ISO100;
          camera.rect = _cc$1.rect(0, 0, 1, 1);
          camera.targetTexture = null;
          let canvas = nodeCanvas.addComponent(_cc$1.Canvas);
          canvas.cameraComponent = camera;
          canvas.alignCanvasWithScreen = true;
          return nodeCanvas;
      }
      addFillerSprite(node, color) {
          let sprite = node.addComponent(_cc$1.Sprite);
          sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
          sprite.type = _cc$1.Sprite.Type.SIMPLE;
          sprite.color = color;
          _cc$1.resources.load("_ulsdk_ui/white_dot/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.addFillerSprite err!", err);
                  return;
              }
              if (!_cc$1.isValid(node) || !_cc$1.isValid(sprite))
                  return;
              sprite.spriteFrame = spriteFrame;
          });
      }
      registerTouchHandler(_node, handler, bEnableMultiTouch = false, bStopPropagation = true, bUseCapture = false) {
          let node = _node;
          if (!node)
              return;
          if (!handler)
              return;
          let fOnTouchBegan = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && node.__touch_id != null)
                  return false;
              e.name = "began";
              node.__touch_id = touchId;
              handler(e);
              return true;
          };
          let fOnTouchMoved = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && touchId != node.__touch_id)
                  return;
              e.name = "moved";
              handler(e);
          };
          let fOnTouchEnded = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && touchId != node.__touch_id)
                  return;
              e.name = "ended";
              node.__touch_id = null;
              handler(e);
          };
          let fOnTouchCancelled = (e) => {
              let touchId = e.getID() || 0;
              if (!bEnableMultiTouch && touchId != node.__touch_id)
                  return;
              e.name = "cancelled";
              node.__touch_id = null;
              handler(e);
          };
          node.on(_cc$1.Node.EventType.TOUCH_START, fOnTouchBegan, null, bUseCapture);
          node.on(_cc$1.Node.EventType.TOUCH_MOVE, fOnTouchMoved, null, bUseCapture);
          node.on(_cc$1.Node.EventType.TOUCH_END, fOnTouchEnded, null, bUseCapture);
          node.on(_cc$1.Node.EventType.TOUCH_CANCEL, fOnTouchCancelled, null, bUseCapture);
      }
      isTouchEventClick(e) {
          if (!(e.name == "ended" || e.name == "cancelled"))
              return false;
          let p0 = e.getStartLocation();
          let p1 = e.getLocation();
          let dx = p0.x - p1.x;
          let dy = p0.y - p1.y;
          let distanceSq = dx * dx + dy * dy;
          return distanceSq <= 20 * 20;
      }
      createItemByData(data) {
          let item = new MCItem();
          item.initByData(data);
          let nodeContainer = this.nodeContainer;
          switch (data.type) {
              case "label": {
                  let node = new _cc$1.Node();
                  node.addComponent(_cc$1.UITransform);
                  node.layer = CANVAS_LAYER;
                  node.parent = nodeContainer;
                  node.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 0.5);
                  node.on(_cc$1.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.getComponent(_cc$1.UITransform).width;
                      item.height = node.getComponent(_cc$1.UITransform).height;
                      this.onItemNodeResize();
                  });
                  node.addComponent(_cc$1.Label).string = item.text;
                  node.getComponent(_cc$1.Label).fontSize = FONT_SIZE$2;
                  node.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
                  node.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
                  item.renderNode = node;
                  break;
              }
              case "labelArea": {
                  let node = new _cc$1.Node();
                  node.addComponent(_cc$1.UITransform);
                  node.layer = CANVAS_LAYER;
                  node.parent = nodeContainer;
                  node.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 0.5);
                  node.on(_cc$1.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.getComponent(_cc$1.UITransform).width;
                      item.height = node.getComponent(_cc$1.UITransform).height;
                      this.onItemNodeResize();
                  });
                  node.addComponent(_cc$1.Label).string = item.text;
                  node.getComponent(_cc$1.Label).fontSize = FONT_SIZE$2;
                  node.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
                  node.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
                  node.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.RESIZE_HEIGHT;
                  node.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(nodeContainer.getComponent(_cc$1.UITransform).width - PENDING$2 * 2, FONT_SIZE$2);
                  item.renderNode = node;
                  break;
              }
              case "button": {
                  let node = new _cc$1.Node();
                  node.addComponent(_cc$1.UITransform);
                  node.layer = CANVAS_LAYER;
                  node.parent = nodeContainer;
                  node.on(_cc$1.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.getComponent(_cc$1.UITransform).width;
                      item.height = node.getComponent(_cc$1.UITransform).height;
                      console.warn("button size changed", item.width, item.height);
                      this.onItemNodeResize();
                  });
                  node.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(item.width || BUTTON_WIDTH$2, item.height || BUTTON_HEIGHT$2);
                  let nodeBg = new _cc$1.Node();
                  nodeBg.addComponent(_cc$1.UITransform);
                  nodeBg.layer = CANVAS_LAYER;
                  nodeBg.parent = node;
                  nodeBg.getComponent(_cc$1.UITransform).contentSize = nodeBg.parent.getComponent(_cc$1.UITransform).contentSize;
                  this.addFillerSprite(nodeBg, _cc$1.color(200, 200, 200, 255));
                  let nodeLabel = new _cc$1.Node();
                  nodeLabel.addComponent(_cc$1.UITransform);
                  nodeLabel.layer = CANVAS_LAYER;
                  nodeLabel.parent = node;
                  nodeLabel.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 0.5);
                  nodeLabel.addComponent(_cc$1.Label).string = item.text;
                  nodeLabel.getComponent(_cc$1.Label).fontSize = FONT_SIZE$2;
                  nodeLabel.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
                  nodeLabel.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
                  nodeLabel.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
                  nodeLabel.getComponent(_cc$1.UITransform).contentSize = nodeLabel.parent.getComponent(_cc$1.UITransform).contentSize;
                  nodeLabel.getComponent(_cc$1.Label).color = _cc$1.Color.BLACK;
                  this.registerTouchHandler(node, (e) => {
                      switch (e.name) {
                          case "began":
                              nodeLabel.getComponent(_cc$1.Label).color = _cc$1.Color.GREEN;
                              break;
                          case "moved": break;
                          default:
                              nodeLabel.getComponent(_cc$1.Label).color = _cc$1.Color.BLACK;
                              break;
                      }
                      if (!this.isTouchEventClick(e))
                          return;
                      item.triggerOnClick();
                  });
                  item.renderNode = node;
                  break;
              }
              case "inputBox": {
                  let node = new _cc$1.Node();
                  node.addComponent(_cc$1.UITransform);
                  node.layer = CANVAS_LAYER;
                  node.parent = nodeContainer;
                  node.on(_cc$1.Node.EventType.SIZE_CHANGED, () => {
                      item.width = node.getComponent(_cc$1.UITransform).width;
                      item.height = node.getComponent(_cc$1.UITransform).height;
                      this.onItemNodeResize();
                  });
                  node.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(item.width || BUTTON_WIDTH$2, item.height || BUTTON_HEIGHT$2);
                  let nodeBg = new _cc$1.Node();
                  nodeBg.addComponent(_cc$1.UITransform);
                  nodeBg.layer = CANVAS_LAYER;
                  nodeBg.parent = node;
                  nodeBg.getComponent(_cc$1.UITransform).contentSize = nodeBg.parent.getComponent(_cc$1.UITransform).contentSize;
                  this.addFillerSprite(nodeBg, _cc$1.color(200, 200, 200, 255));
                  let editBox = node.addComponent(_cc$1.EditBox);
                  editBox.textLabel.fontSize = FONT_SIZE$2;
                  editBox.textLabel.color = _cc$1.Color.BLACK;
                  editBox.textLabel.lineHeight = node.getComponent(_cc$1.UITransform).height;
                  editBox.inputMode = _cc$1.EditBox.InputMode.SINGLE_LINE;
                  editBox.maxLength = 1024;
                  editBox.placeholder = "<<输入框>>";
                  editBox.placeholderLabel.fontSize = FONT_SIZE$2;
                  editBox.placeholderLabel.color = _cc$1.Color.GRAY;
                  let labels = node.getComponentsInChildren(_cc$1.Label);
                  for (let i = 0; i < labels.length; i++) {
                      const label = labels[i];
                      label.verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
                  }
                  editBox.node.on("text-changed", () => {
                      let text = editBox.string;
                      item.setText(text);
                  });
                  item.renderNode = node;
                  break;
              }
              case "newLine": {
                  item.width = nodeContainer.getComponent(_cc$1.UITransform).width - PENDING$2 * 2;
                  item.height = NEW_LINE_HEIGHT$2;
                  break;
              }
          }
          return item;
      }
      doLayout() {
          if (!this.items)
              return;
          let width = this.nodePanel.getComponent(_cc$1.UITransform).width - 20;
          let rowItems = [];
          let rowRight = PENDING$2;
          let rowTop = -PENDING$2;
          let rowHeight = 0;
          for (let i = 0; i < this.items.length; i++) {
              let item = this.items[i];
              let renderNode = item.renderNode;
              if (rowRight + item.width > width) {
                  rowRight = 0;
                  for (let i = 0; i < rowItems.length; i++) {
                      const rowItem = rowItems[i];
                      let renderNode = rowItem.renderNode;
                      if (renderNode && renderNode.getPosition) {
                          let p = renderNode.getPosition();
                          renderNode.setPosition(p.x, rowTop - rowHeight / 2, p.z);
                      }
                  }
                  rowRight = PENDING$2;
                  rowTop -= rowHeight + GAP$2;
                  rowItems = [];
                  rowHeight = 0;
              }
              rowHeight = Math.max(rowHeight, item.height);
              rowItems.push(item);
              if (renderNode && renderNode.getPosition) {
                  let p = renderNode.getPosition();
                  renderNode.setPosition(rowRight + item.width / 2, p.y, p.z);
              }
              rowRight += item.width + GAP$2;
          }
          for (let i = 0; i < rowItems.length; i++) {
              const rowItem = rowItems[i];
              let renderNode = rowItem.renderNode;
              if (renderNode && renderNode.getPosition) {
                  let p = renderNode.getPosition();
                  renderNode.setPosition(p.x, rowTop - rowHeight / 2, p.z);
              }
          }
          rowTop -= rowHeight - PENDING$2;
          this.nodeContainer.getComponent(_cc$1.UITransform).height = Math.max(this.nodePanel.getComponent(_cc$1.UITransform).height, -rowTop);
      }
      onItemNodeResize() {
          this.doLayout();
      }
      getItemByName(name) {
          for (let i = 0; i < this.items.length; i++) {
              const item = this.items[i];
              if (item.name == name)
                  return item;
          }
          return null;
      }
      show(config) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas)
              return;
          let canvasSize = this.getCanvasSize();
          let nodePanel = new _cc$1.Node();
          nodePanel.addComponent(_cc$1.UITransform);
          nodePanel.layer = CANVAS_LAYER;
          nodePanel.parent = nodeCanvas;
          nodePanel.getComponent(_cc$1.UITransform).setContentSize(canvasSize.width, canvasSize.height);
          this.nodePanel = nodePanel;
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodePanel;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = nodeBg.parent.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeBg, _cc$1.color(0, 0, 0, 191));
          this.registerTouchHandler(this.nodePanel, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let nodeContainer = new _cc$1.Node();
          nodeContainer.addComponent(_cc$1.UITransform);
          nodeContainer.layer = CANVAS_LAYER;
          nodeContainer.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0, 1);
          nodeContainer.parent = this.nodePanel;
          nodeContainer.getComponent(_cc$1.UITransform).setContentSize(canvasSize.width, canvasSize.height);
          this.nodeContainer = nodeContainer;
          let scrollView = this.nodePanel.addComponent(_cc$1.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.content = nodeContainer;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let items = [];
          for (let i = 0; i < config.length; i++) {
              const data = config[i];
              let item = this.createItemByData(data);
              items.push(item);
          }
          this.items = items;
          this.doLayout();
      }
      close() {
          if (_cc$1.isValid(this.nodePanel)) {
              this.nodePanel.destroy();
          }
          this.nodePanel = null;
          this.items = [];
      }
      getItemText(name) {
          let item = this.getItemByName(name);
          if (!item)
              return "";
          return item.text;
      }
      setItemText(name, text) {
          let item = this.getItemByName(name);
          if (!item)
              return;
          item.setText(text);
          let node = item.renderNode;
          if (node instanceof _cc$1.Node) {
              let label = node.getComponent(_cc$1.Label) || node.getComponentInChildren(_cc$1.Label);
              if (label) {
                  label.string = text;
              }
              let editBox = node.getComponent(_cc$1.EditBox) || node.getComponentInChildren(_cc$1.EditBox);
              if (editBox) {
                  editBox.string = text;
              }
          }
      }
      showMsgTip(text) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas)
              return;
          let nodeLabel = new _cc$1.Node();
          nodeLabel.addComponent(_cc$1.UITransform);
          nodeLabel.layer = CANVAS_LAYER;
          nodeLabel.parent = nodeCanvas;
          nodeLabel.getComponent(_cc$1.UITransform).width = this.getCanvasSize().width;
          nodeLabel.getComponent(_cc$1.UITransform).height = 20;
          let label = nodeLabel.addComponent(_cc$1.Label);
          label.string = text;
          label.fontSize = 20;
          label.enableWrapText = true;
          nodeLabel.setPosition(0, this.getCanvasSize().height * 0.25, 0);
          _cc$1.tween(nodeLabel)
              .to(1, { position: _cc$1.v3(nodeLabel.position.x, nodeLabel.position.y + 50, nodeLabel.position.z) })
              .call(() => {
                  nodeLabel.destroy();
              })
              .start();
      }
      showPickerDialog(title, conf, callback, bKeepDialogOpen) {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas)
              return;
          let canvasSize = this.getCanvasSize();
          let minCount = 8.5;
          let maxCount = 17.5;
          let dialogHeight = ULTools.scaleInRange(conf.length, minCount, maxCount, minCount * 40 + (minCount - 1) * 4 + 60, maxCount * 40 + (maxCount - 1) * 4 + 60);
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeCanvas;
          nodeShadow.getComponent(_cc$1.UITransform).setContentSize(canvasSize.width, canvasSize.height);
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              nodeShadow.destroy();
          });
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeShadow;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = nodeBg.parent.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeBg, _cc$1.color(0, 0, 0, 127));
          let nodeDialog = new _cc$1.Node();
          nodeDialog.addComponent(_cc$1.UITransform);
          nodeDialog.layer = CANVAS_LAYER;
          nodeDialog.parent = nodeShadow;
          nodeDialog.getComponent(_cc$1.UITransform).width = this.getCanvasSize().width - 100;
          nodeDialog.getComponent(_cc$1.UITransform).height = dialogHeight;
          this.registerTouchHandler(nodeDialog, (e) => { });
          nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeDialog;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = nodeBg.parent.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeBg, _cc$1.color(167, 167, 167, 255));
          let nodeTitle = new _cc$1.Node();
          nodeTitle.addComponent(_cc$1.UITransform);
          nodeTitle.layer = CANVAS_LAYER;
          nodeTitle.parent = nodeDialog;
          nodeTitle.setPosition(0, nodeDialog.getComponent(_cc$1.UITransform).height / 2 - 25, 0);
          nodeTitle.addComponent(_cc$1.Label).string = title;
          nodeTitle.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).fontSize = 40;
          nodeTitle.getComponent(_cc$1.UITransform).width = nodeDialog.getComponent(_cc$1.UITransform).width - 10;
          nodeTitle.getComponent(_cc$1.UITransform).height = 40;
          let nodeListBg = new _cc$1.Node();
          nodeListBg.addComponent(_cc$1.UITransform);
          nodeListBg.layer = CANVAS_LAYER;
          nodeListBg.parent = nodeDialog;
          nodeListBg.getComponent(_cc$1.UITransform).width = nodeDialog.getComponent(_cc$1.UITransform).width - 10;
          nodeListBg.getComponent(_cc$1.UITransform).height = nodeDialog.getComponent(_cc$1.UITransform).height - 50;
          nodeListBg.setPosition(0, -nodeDialog.getComponent(_cc$1.UITransform).height / 2 + nodeListBg.getComponent(_cc$1.UITransform).height / 2 + 5, 0);
          this.addFillerSprite(nodeListBg, _cc$1.color(97, 97, 97, 255));
          let nodeList = new _cc$1.Node();
          nodeList.addComponent(_cc$1.UITransform);
          nodeList.layer = CANVAS_LAYER;
          nodeList.parent = nodeDialog;
          nodeList.getComponent(_cc$1.UITransform).width = nodeDialog.getComponent(_cc$1.UITransform).width - 10;
          nodeList.getComponent(_cc$1.UITransform).height = nodeDialog.getComponent(_cc$1.UITransform).height - 50;
          nodeList.setPosition(0, -nodeDialog.getComponent(_cc$1.UITransform).height / 2 + nodeList.getComponent(_cc$1.UITransform).height / 2 + 5, 0);
          nodeList.addComponent(_cc$1.Mask);
          let nodeContainer = new _cc$1.Node();
          nodeContainer.addComponent(_cc$1.UITransform);
          nodeContainer.layer = CANVAS_LAYER;
          nodeContainer.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0, 1);
          nodeContainer.parent = nodeList;
          nodeContainer.getComponent(_cc$1.UITransform).contentSize = nodeList.getComponent(_cc$1.UITransform).contentSize;
          let scrollView = nodeList.addComponent(_cc$1.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.content = nodeContainer;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let y = 0;
          for (let i = 0; i < conf.length; i++) {
              const v = conf[i];
              let nodeItem = new _cc$1.Node();
              nodeItem.addComponent(_cc$1.UITransform);
              nodeItem.layer = CANVAS_LAYER;
              nodeItem.parent = nodeContainer;
              nodeItem.getComponent(_cc$1.UITransform).width = nodeList.getComponent(_cc$1.UITransform).width;
              nodeItem.getComponent(_cc$1.UITransform).height = 40;
              nodeItem.setPosition(nodeContainer.getComponent(_cc$1.UITransform).width / 2, y - nodeItem.getComponent(_cc$1.UITransform).height / 2);
              let nodeBg = new _cc$1.Node();
              nodeBg.addComponent(_cc$1.UITransform);
              nodeBg.layer = CANVAS_LAYER;
              nodeBg.parent = nodeItem;
              nodeBg.getComponent(_cc$1.UITransform).contentSize = nodeBg.parent.getComponent(_cc$1.UITransform).contentSize;
              this.addFillerSprite(nodeBg, _cc$1.color(0, 0, 0, 63));
              let nodeLabel = new _cc$1.Node();
              nodeLabel.addComponent(_cc$1.UITransform);
              nodeLabel.layer = CANVAS_LAYER;
              nodeLabel.parent = nodeItem;
              nodeLabel.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0, 0.5);
              nodeLabel.setPosition(-nodeItem.getComponent(_cc$1.UITransform).width / 2 + 5, 0, 0);
              let label = nodeLabel.addComponent(_cc$1.Label);
              label.fontSize = FONT_SIZE$2;
              label.lineHeight = FONT_SIZE$2;
              label.verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
              label.horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
              label.string = v.text;
              this.registerTouchHandler(nodeItem, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  callback(v.value);
                  if (!bKeepDialogOpen) {
                      nodeShadow.destroy();
                  }
              });
              y -= nodeItem.getComponent(_cc$1.UITransform).height + 4;
          }
          nodeContainer.getComponent(_cc$1.UITransform).height = Math.max(nodeList.getComponent(_cc$1.UITransform).height, -y);
      }
      showPromptDialog(title, content, btnTexts, callbacks) {
          ULLog.console.warn("MCPanelCreator3x.showPromptDialog");
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showPromptDialog nodeCanvas not found!");
              ULTimer.callLater(0.1, () => {
                  this.showPromptDialog(title, content, btnTexts, callbacks);
              });
              return;
          }
          let canvasSize = this.getCanvasSize();
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeCanvas;
          nodeShadow.getComponent(_cc$1.UITransform).setContentSize(canvasSize.width, canvasSize.height);
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let nodeSpriteBg = new _cc$1.Node();
          nodeSpriteBg.addComponent(_cc$1.UITransform);
          nodeSpriteBg.layer = CANVAS_LAYER;
          nodeSpriteBg.parent = nodeShadow;
          nodeSpriteBg.getComponent(_cc$1.UITransform).contentSize = nodeSpriteBg.parent.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeSpriteBg, _cc$1.color(0, 0, 0, 127));
          let bManualDestroy = false;
          let triggerNode = new _cc$1.Node();
          triggerNode.addComponent(_cc$1.UITransform);
          triggerNode.layer = CANVAS_LAYER;
          triggerNode.parent = nodeShadow;
          let component = triggerNode.addComponent(_cc$1.Component);
          component["onDestroy"] = () => {
              ULLog.console.log("MCPanelCreator3x.showPromptDialog triggerNode onDestroy", bManualDestroy);
              if (!bManualDestroy) {
                  ULLog.console.log("MCPanelCreator3x.showPromptDialog nodeShadow被意外销毁，0.1秒后尝试重新创建提示");
                  ULTimer.callLater(0.1, () => {
                      this.showPromptDialog(title, content, btnTexts, callbacks);
                  });
              }
          };
          var nodeDialogSize = {
              width: 460,
              height: 320
          };
          let nodeDialog = new _cc$1.Node();
          nodeDialog.addComponent(_cc$1.UITransform);
          nodeDialog.layer = CANVAS_LAYER;
          nodeDialog.parent = nodeShadow;
          nodeDialog.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(nodeDialogSize.width, nodeDialogSize.height);
          this.registerTouchHandler(nodeDialog, (e) => { });
          let nodeDialogBg = new _cc$1.Node();
          nodeDialogBg.addComponent(_cc$1.UITransform);
          nodeDialogBg.layer = CANVAS_LAYER;
          nodeDialogBg.parent = nodeDialog;
          nodeDialogBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(nodeDialogSize.width, nodeDialogSize.height);
          _cc$1.resources.load("_ulsdk_ui/bg_01/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showPromptDialog nodeDialogBg load sprite error", err);
                  return;
              }
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = nodeDialogBg.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc$1.Sprite.Type.SLICED;
              sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
              nodeDialogBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(nodeDialogSize.width, nodeDialogSize.height);
          });
          let nodeTitle = new _cc$1.Node();
          nodeTitle.layer = CANVAS_LAYER;
          nodeTitle.parent = nodeDialog;
          nodeTitle.setPosition(0, nodeDialogSize.height / 2 - 45, 0);
          nodeTitle.addComponent(_cc$1.UITransform);
          nodeTitle.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(nodeDialogSize.width - 10, 40);
          nodeTitle.addComponent(_cc$1.Label).color = _cc$1.color(38, 38, 38, 255);
          nodeTitle.getComponent(_cc$1.Label).string = title || "标题";
          nodeTitle.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).fontSize = 32;
          let nodeContent = new _cc$1.Node();
          nodeContent.layer = CANVAS_LAYER;
          nodeContent.parent = nodeDialog;
          nodeContent.addComponent(_cc$1.UITransform);
          nodeContent.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(nodeDialogSize.width - 50, 160);
          nodeContent.setPosition(0, nodeDialogSize.height / 2 - 155, 0);
          nodeContent.addComponent(_cc$1.Label).color = _cc$1.color(96, 96, 96, 255);
          nodeContent.getComponent(_cc$1.Label).string = content || "内容";
          nodeContent.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeContent.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeContent.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeContent.getComponent(_cc$1.Label).fontSize = 24;
          let btnWidth = 160;
          let btnHeight = 56;
          let btnGap = 30;
          let left = -(btnTexts.length * btnWidth + (btnTexts.length - 1) * btnGap) / 2;
          let nodeButtons = [];
          for (let i = 0; i < btnTexts.length; i++) {
              const text = btnTexts[i];
              let nodeButton = new _cc$1.Node();
              nodeButton.addComponent(_cc$1.UITransform);
              nodeButton.layer = CANVAS_LAYER;
              nodeButton.parent = nodeDialog;
              nodeButton.setPosition(left + btnWidth * (i + 0.5) + btnGap * (i), -nodeDialogSize.height / 2 + 50, 0);
              nodeButton.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(btnWidth, btnHeight);
              nodeButtons.push(nodeButton);
              let nodeButtonBg = new _cc$1.Node();
              nodeButtonBg.addComponent(_cc$1.UITransform);
              nodeButtonBg.layer = CANVAS_LAYER;
              nodeButtonBg.parent = nodeButton;
              nodeButtonBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(btnWidth, btnHeight);
              _cc$1.resources.load("_ulsdk_ui/btn_01/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
                  if (err) {
                      ULLog.console.warn("MCPanelCreator3x.showPromptDialog nodeButtonBg load sprite error", err);
                      return;
                  }
                  let frameSize = spriteFrame.getOriginalSize();
                  spriteFrame.insetLeft = frameSize.width / 3;
                  spriteFrame.insetRight = frameSize.width / 3;
                  spriteFrame.insetTop = frameSize.height / 3;
                  spriteFrame.insetBottom = frameSize.height / 3;
                  let sprite = nodeButtonBg.addComponent(_cc$1.Sprite);
                  sprite.spriteFrame = spriteFrame;
                  sprite.type = _cc$1.Sprite.Type.SLICED;
                  sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
                  nodeButtonBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(btnWidth, btnHeight);
              });
              let nodeButtonText = new _cc$1.Node();
              nodeButtonText.addComponent(_cc$1.UITransform);
              nodeButtonText.layer = CANVAS_LAYER;
              nodeButtonText.parent = nodeButton;
              nodeButtonText.addComponent(_cc$1.Label).string = text || "按钮" + (i + 1);
              nodeButtonText.getComponent(_cc$1.Label).color = _cc$1.color(255, 255, 255, 255);
              nodeButtonText.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
              nodeButtonText.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
              nodeButtonText.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
              nodeButtonText.getComponent(_cc$1.Label).fontSize = 30;
              nodeButtonText.getComponent(_cc$1.UITransform).width = nodeButtonBg.getComponent(_cc$1.UITransform).width - 10;
              nodeButtonText.getComponent(_cc$1.UITransform).height = nodeButtonBg.getComponent(_cc$1.UITransform).height - 10;
              this.registerTouchHandler(nodeButton, (e) => {
                  if (e.name == "began") {
                      nodeButton.setScale(1.1, 1.1);
                  }
                  else if (e.name == "moved") {
                  }
                  else {
                      nodeButton.setScale(1, 1);
                  }
                  if (this.isTouchEventClick(e)) {
                      let callback = callbacks[i];
                      if (callback instanceof Function) {
                          let bDonotClose = callback();
                          if (!bDonotClose) {
                              bManualDestroy = true;
                              nodeShadow.destroy();
                          }
                      }
                      else {
                          bManualDestroy = true;
                          nodeShadow.destroy();
                      }
                  }
              });
          }
      }
      showWebView(title, url, replaceParam) {
          this.closeWebView();
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              return;
          }
          console.log(`showWebView title:${title} url:${url} replaceParam:${replaceParam}`);
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(2048, 2048);
          this.showWebViewNode = nodeBg;
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeWebView();
          });
          let contentNode = new _cc$1.Node();
          contentNode.addComponent(_cc$1.UITransform);
          contentNode.layer = CANVAS_LAYER;
          contentNode.parent = nodeBg;
          let width = Math.min(this.getCanvasSize().width * 0.8, 500);
          let height = Math.min(this.getCanvasSize().height * 0.8, 800);
          if (this.getCanvasSize().width > this.getCanvasSize().height) {
              width = Math.min(this.getCanvasSize().width * 0.8, 800);
              height = Math.min(this.getCanvasSize().height * 0.8, 500);
          }
          contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          _cc$1.resources.load("_ulsdk_ui/bg_01/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showPrivacyDialog nodeDialogBg load sprite error", err);
                  return;
              }
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = contentNode.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc$1.Sprite.Type.SLICED;
              sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
              contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          });
          let nodeTitle = new _cc$1.Node();
          nodeTitle.addComponent(_cc$1.UITransform);
          nodeTitle.layer = CANVAS_LAYER;
          nodeTitle.parent = contentNode;
          nodeTitle.addComponent(_cc$1.Label).string = title;
          nodeTitle.getComponent(_cc$1.Label).color = _cc$1.color(38, 38, 38, 255);
          nodeTitle.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).fontSize = 32;
          nodeTitle.getComponent(_cc$1.UITransform).width = width - 10;
          nodeTitle.getComponent(_cc$1.UITransform).height = 40;
          nodeTitle.setPosition(0, height / 2 - 40);
          let nodeScrollView = new _cc$1.Node();
          nodeScrollView.addComponent(_cc$1.UITransform);
          nodeScrollView.layer = CANVAS_LAYER;
          nodeScrollView.parent = contentNode;
          nodeScrollView.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width - 50, height - 80);
          nodeScrollView.setPosition(0, -20, 0);
          let scrollView = nodeScrollView.addComponent(_cc$1.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let nodeMask = new _cc$1.Node();
          nodeMask.addComponent(_cc$1.UITransform);
          nodeMask.layer = CANVAS_LAYER;
          nodeMask.parent = nodeScrollView;
          nodeMask.getComponent(_cc$1.UITransform).contentSize = nodeScrollView.getComponent(_cc$1.UITransform).contentSize;
          nodeMask.addComponent(_cc$1.Mask).type = _cc$1.Mask.Type.RECT;
          nodeMask.getComponent(_cc$1.Mask).inverted = false;
          let nodeContent = new _cc$1.Node();
          nodeContent.addComponent(_cc$1.UITransform);
          nodeContent.layer = CANVAS_LAYER;
          nodeContent.parent = nodeMask;
          nodeContent.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
          nodeContent.getComponent(_cc$1.UITransform).contentSize = nodeScrollView.getComponent(_cc$1.UITransform).contentSize;
          let maskLayout = nodeContent.addComponent(_cc$1.Layout);
          maskLayout.type = _cc$1.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc$1.Layout.ResizeMode.CONTAINER;
          scrollView.content = nodeContent;
          ULTools.httpGet({
              url: url,
              timeoutMillisecond: 5000,
              success: (responseText) => {
                  let content = responseText;
                  try {
                      let resultObj = JSON.parse(responseText);
                      content = resultObj.policyText;
                  }
                  catch (error) {
                  }
                  if (replaceParam) {
                      for (let key in replaceParam) {
                          let value = replaceParam[key];
                          let regExp = new RegExp(`\\\${\\s*${key}\\s*}`, 'g');
                          content = content.replace(regExp, value);
                      }
                  }
                  ULLog.console.log("content:", content);
                  let contentList = content.split('\n');
                  for (let i = 0; i < contentList.length; i++) {
                      const text = contentList[i];
                      let nodeLabel = new _cc$1.Node();
                      nodeLabel.addComponent(_cc$1.UITransform);
                      nodeLabel.layer = CANVAS_LAYER;
                      nodeLabel.parent = nodeContent;
                      nodeLabel.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
                      let label = nodeLabel.addComponent(_cc$1.Label);
                      label.color = _cc$1.color(0, 0, 0, 255);
                      label.string = text;
                      label.overflow = _cc$1.Label.Overflow.RESIZE_HEIGHT;
                      label.verticalAlign = _cc$1.Label.VerticalAlign.TOP;
                      label.horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
                      label.fontSize = 18;
                      label.lineHeight = 26;
                      nodeLabel.getComponent(_cc$1.UITransform).contentSize = nodeContent.getComponent(_cc$1.UITransform).contentSize;
                  }
              },
              fail: () => {
              }
          });
      }
      closeWebView() {
          if (_cc$1.isValid(this.showWebViewNode)) {
              this.showWebViewNode["__b_manual_destroy"] = true;
              this.showWebViewNode.destroy();
          }
          this.showWebViewNode = null;
      }
      showPrivacyContent(title, url, replaceParam) {
          this.showWebView(title, url, replaceParam);
      }
      showPrivacyDialog(title, contentArray, btnTexts, callbacks) {
          ULLog.console.log("MCPanelCreator3x.showPrivacyDialog");
          if (this.showPrivacyNode) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showPrivacyDialog nodeCanvas not found!");
              ULTimer.callLater(0.1, () => {
                  this.showPrivacyDialog(title, contentArray, btnTexts, callbacks);
              });
              return;
          }
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(2048, 2048);
          this.showPrivacyNode = nodeBg;
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let bManualDestroy = false;
          let triggerNode = new _cc$1.Node();
          triggerNode.addComponent(_cc$1.UITransform);
          triggerNode.layer = CANVAS_LAYER;
          triggerNode.parent = nodeShadow;
          let component = triggerNode.addComponent(_cc$1.Component);
          component["onDestroy"] = () => {
              ULLog.console.log("MCPanelCreator3x.showPrivacyDialog triggerNode onDestroy", bManualDestroy);
              this.showPrivacyNode = null;
              if (!bManualDestroy) {
                  ULLog.console.log("MCPanelCreator3x.showPrivacyDialog nodeShadow被意外销毁，0.1秒后尝试重新创建提示");
                  ULTimer.callLater(1 / 60, () => {
                      ULLog.console.log("ontimer");
                      this.showPrivacyDialog(title, contentArray, btnTexts, callbacks);
                  });
              }
          };
          let contentNode = new _cc$1.Node();
          contentNode.addComponent(_cc$1.UITransform);
          contentNode.layer = CANVAS_LAYER;
          contentNode.parent = nodeBg;
          let width = 450;
          let height = 450;
          contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          _cc$1.resources.load("_ulsdk_ui/bg_01/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showPrivacyDialog nodeDialogBg load sprite error", err);
                  return;
              }
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = contentNode.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc$1.Sprite.Type.SLICED;
              sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
              contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          });
          let nodeTitle = new _cc$1.Node();
          nodeTitle.addComponent(_cc$1.UITransform);
          nodeTitle.layer = CANVAS_LAYER;
          nodeTitle.parent = contentNode;
          nodeTitle.addComponent(_cc$1.Label).string = "隐私政策";
          nodeTitle.getComponent(_cc$1.Label).color = _cc$1.color(0, 0, 0, 255);
          nodeTitle.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).fontSize = 32;
          nodeTitle.getComponent(_cc$1.UITransform).width = width - 10;
          nodeTitle.getComponent(_cc$1.UITransform).height = 40;
          nodeTitle.setPosition(0, height / 2 - 40);
          let nodeScrollView = new _cc$1.Node();
          nodeScrollView.addComponent(_cc$1.UITransform);
          nodeScrollView.layer = CANVAS_LAYER;
          nodeScrollView.parent = contentNode;
          nodeScrollView.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width - 50, height - 140);
          nodeScrollView.setPosition(0, 3, 0);
          let scrollView = nodeScrollView.addComponent(_cc$1.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let nodeMask = new _cc$1.Node();
          nodeMask.addComponent(_cc$1.UITransform);
          nodeMask.layer = CANVAS_LAYER;
          nodeMask.parent = nodeScrollView;
          nodeMask.getComponent(_cc$1.UITransform).contentSize = nodeScrollView.getComponent(_cc$1.UITransform).contentSize;
          nodeMask.addComponent(_cc$1.Mask).type = _cc$1.Mask.Type.RECT;
          nodeMask.getComponent(_cc$1.Mask).inverted = false;
          let nodeContent = new _cc$1.Node();
          nodeContent.addComponent(_cc$1.UITransform);
          nodeContent.layer = CANVAS_LAYER;
          nodeContent.parent = nodeMask;
          nodeContent.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
          nodeContent.getComponent(_cc$1.UITransform).contentSize = nodeScrollView.getComponent(_cc$1.UITransform).contentSize;
          let maskLayout = nodeContent.addComponent(_cc$1.Layout);
          maskLayout.type = _cc$1.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc$1.Layout.ResizeMode.CONTAINER;
          scrollView.content = nodeContent;
          let contentText = `感谢您对本公司游戏的支持，在体验我们的游戏前，请仔细阅读开发商的`;
          let footer = `中的所有条款，包括
        1.为了您有良好的游戏体验，我们会基于具体的场景收集您的个人信息
        2.我们会基于先进的技术和管理措施保证您的个人信息安全
        3.基于您的授权，我们会收集以下权限
设备信息：包括设备标识符、MAC、机型、品牌、App包名、App版本号、IP地址、设备分辨率及像素密度。
网络信息：网络连接状态、接入网络的方式和类型、IP地址。
使用信息：包括广告内容的展现、点击、下载。
        如果您对本隐私政策有任何疑问,请通过kefu@ultralisk.cn与我们联系。
        `;
          let headerNode = new _cc$1.Node();
          headerNode.addComponent(_cc$1.UITransform);
          headerNode.layer = CANVAS_LAYER;
          headerNode.parent = nodeContent;
          headerNode.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
          let headerLabel = headerNode.addComponent(_cc$1.Label);
          headerLabel.color = _cc$1.color(0, 0, 0, 255);
          headerLabel.string = contentText;
          headerLabel.fontSize = 18;
          headerLabel.lineHeight = 26;
          headerNode.getComponent(_cc$1.UITransform).contentSize = nodeContent.getComponent(_cc$1.UITransform).contentSize;
          headerLabel.overflow = _cc$1.Label.Overflow.RESIZE_HEIGHT;
          headerLabel.verticalAlign = _cc$1.Label.VerticalAlign.TOP;
          headerLabel.horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
          for (let index = 0; index < contentArray.length; index++) {
              let element = contentArray[index];
              let buttonNode = new _cc$1.Node();
              buttonNode.addComponent(_cc$1.UITransform);
              buttonNode.layer = CANVAS_LAYER;
              buttonNode.parent = nodeContent;
              buttonNode.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
              let buttonLabel = buttonNode.addComponent(_cc$1.Label);
              buttonLabel.color = _cc$1.color(156, 176, 222, 255);
              buttonLabel.string = `《${element.name}》`;
              buttonLabel.fontSize = 18;
              buttonLabel.lineHeight = 26;
              buttonNode.getComponent(_cc$1.UITransform).contentSize = nodeContent.getComponent(_cc$1.UITransform).contentSize;
              buttonLabel.overflow = _cc$1.Label.Overflow.RESIZE_HEIGHT;
              buttonLabel.verticalAlign = _cc$1.Label.VerticalAlign.TOP;
              buttonLabel.horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
              this.registerTouchHandler(buttonNode, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  this.showWebView(element.name, element.url, element.replaceParam);
              });
          }
          let footerNode = new _cc$1.Node();
          footerNode.addComponent(_cc$1.UITransform);
          footerNode.layer = CANVAS_LAYER;
          footerNode.parent = nodeContent;
          footerNode.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
          let footerLabel = footerNode.addComponent(_cc$1.Label);
          footerLabel.color = _cc$1.color(0, 0, 0, 255);
          footerLabel.string = footer;
          footerLabel.fontSize = 18;
          footerLabel.lineHeight = 26;
          footerLabel.overflow = _cc$1.Label.Overflow.RESIZE_HEIGHT;
          footerLabel.verticalAlign = _cc$1.Label.VerticalAlign.TOP;
          footerLabel.horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
          footerNode.getComponent(_cc$1.UITransform).contentSize = nodeContent.getComponent(_cc$1.UITransform).contentSize;
          let buttonWidth = (contentNode.getComponent(_cc$1.UITransform).width - 20) / btnTexts.length;
          let buttonHeight = 40;
          for (let index = 0; index < btnTexts.length; index++) {
              const buttonText = btnTexts[index];
              let buttonBgNode = new _cc$1.Node();
              buttonBgNode.addComponent(_cc$1.UITransform);
              buttonBgNode.layer = CANVAS_LAYER;
              buttonBgNode.parent = contentNode;
              buttonBgNode.getComponent(_cc$1.UITransform).width = Math.min(buttonWidth * 0.8, 120);
              buttonBgNode.getComponent(_cc$1.UITransform).height = buttonHeight;
              buttonBgNode.setPosition(-(btnTexts.length / 2.0 - index) * buttonWidth + buttonWidth / 2.0, (buttonBgNode.getComponent(_cc$1.UITransform).height - contentNode.getComponent(_cc$1.UITransform).height) / 2.0 + 20, 0);
              let buttonNode = new _cc$1.Node();
              buttonNode.addComponent(_cc$1.UITransform);
              buttonNode.layer = CANVAS_LAYER;
              buttonNode.parent = buttonBgNode;
              buttonNode.addComponent(_cc$1.Label).string = buttonText;
              buttonNode.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
              buttonNode.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
              buttonNode.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
              buttonNode.getComponent(_cc$1.Label).fontSize = 22;
              buttonNode.getComponent(_cc$1.UITransform).width = buttonBgNode.getComponent(_cc$1.UITransform).width;
              buttonNode.getComponent(_cc$1.UITransform).height = buttonBgNode.getComponent(_cc$1.UITransform).height;
              if (btnTexts.length == 1 || index % 2 == 1) {
                  this.addFillerSprite(buttonBgNode, _cc$1.color(100, 149, 237, 255));
                  buttonNode.getComponent(_cc$1.Label).color = _cc$1.color(255, 255, 255, 255);
              }
              else {
                  this.addFillerSprite(buttonBgNode, _cc$1.color(230, 230, 230, 255));
                  buttonNode.getComponent(_cc$1.Label).color = _cc$1.color(156, 176, 222, 255);
                  buttonNode.addComponent(_cc$1.LabelOutline);
                  buttonNode.getComponent(_cc$1.LabelOutline);
                  buttonNode.getComponent(_cc$1.LabelOutline).width = 1;
                  buttonNode.getComponent(_cc$1.LabelOutline).color = _cc$1.color(230, 230, 230, 255);
              }
              this.registerTouchHandler(buttonNode, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  let callback = callbacks[index];
                  if (callback instanceof Function) {
                      let bDonotClose = callback();
                      if (!bDonotClose) {
                          bManualDestroy = true;
                          this.showPrivacyNode.destroy();
                          this.showPrivacyNode = null;
                      }
                  }
                  else {
                      bManualDestroy = true;
                      this.showPrivacyNode.destroy();
                      this.showPrivacyNode = null;
                  }
              });
          }
      }
      showSettingView(title, items) {
          ULLog.console.log("MCPanelCreator3x.showSettingView");
          if (this.showSettingNode) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showSettingView nodeCanvas not found!");
              ULTimer.callLater(0.1, () => {
                  this.showSettingView(title, items);
              });
              return;
          }
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(2048, 2048);
          this.showSettingNode = nodeBg;
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("click bg");
          });
          let bManualDestroy = false;
          let triggerNode = new _cc$1.Node();
          triggerNode.addComponent(_cc$1.UITransform);
          triggerNode.layer = CANVAS_LAYER;
          triggerNode.parent = nodeShadow;
          let component = triggerNode.addComponent(_cc$1.Component);
          component["onDestroy"] = () => {
              ULLog.console.log("MCPanelCreator3x.showSettingView triggerNode onDestroy", bManualDestroy);
              this.showSettingNode = null;
              if (!bManualDestroy) {
                  ULLog.console.log("MCPanelCreator3x.showSettingView nodeShadow被意外销毁，0.1秒后尝试重新创建提示");
                  ULTimer.callLater(1 / 60, () => {
                      ULLog.console.log("ontimer");
                      this.showSettingView(title, items);
                  });
              }
          };
          let contentNode = new _cc$1.Node();
          contentNode.addComponent(_cc$1.UITransform);
          contentNode.layer = CANVAS_LAYER;
          contentNode.parent = nodeBg;
          let width = 450;
          let height = 450;
          contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          _cc$1.resources.load("_ulsdk_ui/bg_01/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showSettingView nodeDialogBg load sprite error", err);
                  return;
              }
              let frameSize = spriteFrame.getOriginalSize();
              spriteFrame.insetLeft = frameSize.width / 3;
              spriteFrame.insetRight = frameSize.width / 3;
              spriteFrame.insetTop = frameSize.height / 3;
              spriteFrame.insetBottom = frameSize.height / 3;
              let sprite = contentNode.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              sprite.type = _cc$1.Sprite.Type.SLICED;
              sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
              contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          });
          let nodeTitle = new _cc$1.Node();
          nodeTitle.addComponent(_cc$1.UITransform);
          nodeTitle.layer = CANVAS_LAYER;
          nodeTitle.parent = contentNode;
          nodeTitle.addComponent(_cc$1.Label).string = title;
          nodeTitle.getComponent(_cc$1.Label).color = _cc$1.color(0, 0, 0, 255);
          nodeTitle.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).fontSize = 32;
          nodeTitle.getComponent(_cc$1.UITransform).width = width - 10;
          nodeTitle.getComponent(_cc$1.UITransform).height = 40;
          nodeTitle.setPosition(0, height / 2 - 40);
          let nodeScrollView = new _cc$1.Node();
          nodeScrollView.addComponent(_cc$1.UITransform);
          nodeScrollView.layer = CANVAS_LAYER;
          nodeScrollView.parent = contentNode;
          nodeScrollView.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width - 50, height - 140);
          nodeScrollView.setPosition(0, 3, 0);
          let scrollView = nodeScrollView.addComponent(_cc$1.ScrollView);
          scrollView.horizontal = false;
          scrollView.vertical = true;
          scrollView.cancelInnerEvents = false;
          scrollView.elastic = true;
          let nodeMask = new _cc$1.Node();
          nodeMask.addComponent(_cc$1.UITransform);
          nodeMask.layer = CANVAS_LAYER;
          nodeMask.parent = nodeScrollView;
          nodeMask.getComponent(_cc$1.UITransform).contentSize = nodeScrollView.getComponent(_cc$1.UITransform).contentSize;
          nodeMask.addComponent(_cc$1.Mask).type = _cc$1.Mask.Type.RECT;
          nodeMask.getComponent(_cc$1.Mask).inverted = false;
          let nodeContent = new _cc$1.Node();
          nodeContent.addComponent(_cc$1.UITransform);
          nodeContent.layer = CANVAS_LAYER;
          nodeContent.parent = nodeMask;
          nodeContent.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
          nodeContent.getComponent(_cc$1.UITransform).contentSize = nodeScrollView.getComponent(_cc$1.UITransform).contentSize;
          let maskLayout = nodeContent.addComponent(_cc$1.Layout);
          maskLayout.type = _cc$1.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc$1.Layout.ResizeMode.CONTAINER;
          scrollView.content = nodeContent;
          for (let index = 0; index < items.length; index++) {
              let item = items[index];
              let buttonText = item.name;
              let callback = item.handle;
              let buttonNode = new _cc$1.Node();
              buttonNode.addComponent(_cc$1.UITransform);
              buttonNode.layer = CANVAS_LAYER;
              buttonNode.parent = nodeContent;
              buttonNode.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
              let buttonLabel = buttonNode.addComponent(_cc$1.Label);
              buttonLabel.color = _cc$1.color(100, 149, 237, 255);
              buttonLabel.string = buttonText;
              buttonLabel.fontSize = 20;
              buttonLabel.lineHeight = 50;
              buttonNode.getComponent(_cc$1.UITransform).contentSize = nodeContent.getComponent(_cc$1.UITransform).contentSize;
              buttonLabel.overflow = _cc$1.Label.Overflow.RESIZE_HEIGHT;
              buttonLabel.verticalAlign = _cc$1.Label.VerticalAlign.TOP;
              buttonLabel.horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
              this.registerTouchHandler(buttonNode, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  callback();
              });
          }
          let buttonWidth = (contentNode.width - 20);
          let buttonHeight = 40;
          let buttonBgNode = new _cc$1.Node();
          buttonBgNode.addComponent(_cc$1.UITransform);
          buttonBgNode.layer = CANVAS_LAYER;
          buttonBgNode.parent = contentNode;
          buttonBgNode.getComponent(_cc$1.UITransform).width = Math.min(buttonWidth * 0.8, 120);
          buttonBgNode.getComponent(_cc$1.UITransform).height = buttonHeight;
          buttonBgNode.setPosition(-(1 / 2.0) * buttonWidth + buttonWidth / 2.0, (buttonBgNode.getComponent(_cc$1.UITransform).height - contentNode.getComponent(_cc$1.UITransform).height) / 2.0 + 20, 0);
          let buttonNode = new _cc$1.Node();
          buttonNode.addComponent(_cc$1.UITransform);
          buttonNode.layer = CANVAS_LAYER;
          buttonNode.parent = buttonBgNode;
          buttonNode.addComponent(_cc$1.Label).string = "返回";
          buttonNode.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          buttonNode.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          buttonNode.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          buttonNode.getComponent(_cc$1.Label).fontSize = 22;
          buttonNode.getComponent(_cc$1.UITransform).width = buttonBgNode.getComponent(_cc$1.UITransform).width;
          buttonNode.getComponent(_cc$1.UITransform).height = buttonBgNode.getComponent(_cc$1.UITransform).height;
          this.addFillerSprite(buttonBgNode, _cc$1.color(100, 149, 237, 255));
          buttonNode.getComponent(_cc$1.Label).color = _cc$1.color(255, 255, 255, 255);
          this.registerTouchHandler(buttonNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              bManualDestroy = true;
              this.showSettingNode.destroy();
              this.showSettingNode = null;
          });
      }
      getCanvasSize() {
          return _cc$1.view.getDesignResolutionSize();
      }
      getCanvasOriginSize() {
          let w = 0;
          let h = 0;
          let nodeCanvas = this.getNodeCanvas();
          let canvas = nodeCanvas.getComponent(_cc$1.Canvas);
          let frameSize = _cc$1.view.getFrameSize();
          let frameRatio = frameSize.width / frameSize.height;
          let canvasRatio = this.getCanvasSize().width / this.getCanvasSize().height;
          w = this.getCanvasSize().width;
          h = this.getCanvasSize().height;
          if (frameRatio < canvasRatio) {
              h = Math.floor(h * canvasRatio / frameRatio);
          }
          else {
              w = Math.floor(w * frameRatio / canvasRatio);
          }
          return { width: w, height: h };
      }
      showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY) {
          ULLog.console.log("MCPanelCreator3x.showReferenceRect", key, ccx, ccy, width, height);
          let frameSize = _cc$1.view.getFrameSize();
          let centerX = ccx * frameSize.width;
          let centerY = frameSize.height - ccy * frameSize.height;
          ULLog.console.log("  center", centerX, centerY);
          let nodeCanvas = this.getNodeCanvas();
          let canvasSize = this.getCanvasSize();
          let canvasOriginSize = this.getCanvasOriginSize();
          let wx = centerX / frameSize.width * canvasOriginSize.width - (canvasOriginSize.width - canvasSize.width) / 2;
          let wy = canvasOriginSize.height - centerY / frameSize.height * canvasOriginSize.height - (canvasOriginSize.height - canvasSize.height) / 2;
          let canvasUiTrans = nodeCanvas.getComponent(_cc$1.UITransform);
          let pInWorld = canvasUiTrans.convertToNodeSpaceAR(_cc$1.v3(wx, wy, 0));
          ULLog.console.log("  pInWorld", pInWorld);
          this.hideReferenceRect(key);
          _cc$1.resources.load("_ulsdk_ui/white_dot/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              let nodeRect = new _cc$1.Node();
              nodeRect.addComponent(_cc$1.UITransform);
              nodeRect.layer = CANVAS_LAYER;
              nodeRect.parent = nodeCanvas;
              nodeRect.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(anchorPointX == null ? 0.5 : anchorPointX, anchorPointY == null ? 0.5 : anchorPointY);
              nodeRect.getComponent(_cc$1.UITransform).width = width;
              nodeRect.getComponent(_cc$1.UITransform).height = height;
              nodeRect.position = pInWorld;
              let nodeBg = new _cc$1.Node();
              nodeBg.addComponent(_cc$1.UITransform);
              nodeBg.layer = CANVAS_LAYER;
              nodeBg.parent = nodeRect;
              let spriteBg = nodeBg.addComponent(_cc$1.Sprite);
              spriteBg.spriteFrame = spriteFrame;
              spriteBg.color = _cc$1.color(0, 0, 0, 127);
              nodeBg.getComponent(_cc$1.UITransform).anchorPoint = nodeRect.getComponent(_cc$1.UITransform).anchorPoint;
              nodeBg.getComponent(_cc$1.UITransform).width = width;
              nodeBg.getComponent(_cc$1.UITransform).height = height;
              let nodeLabel = new _cc$1.Node();
              nodeLabel.addComponent(_cc$1.UITransform);
              nodeLabel.layer = CANVAS_LAYER;
              nodeLabel.parent = nodeRect;
              let label = nodeLabel.addComponent(_cc$1.Label);
              label.string = key;
              label.fontSize = 18;
              label.verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
              label.horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
              let widget = nodeLabel.addComponent(_cc$1.Widget);
              widget.isAlignVerticalCenter = true;
              widget.isAlignHorizontalCenter = true;
              this.nodeReferenceRects[key] = nodeRect;
              nodeRect["__b_manual_destroy"] = false;
              let triggerNode = new _cc$1.Node();
              triggerNode.addComponent(_cc$1.UITransform);
              triggerNode.layer = CANVAS_LAYER;
              triggerNode.parent = nodeRect;
              let component = triggerNode.addComponent(_cc$1.Component);
              component["onDestroy"] = () => {
                  ULLog.console.log("MCPanelCreator3x.showReferenceRect triggerNode onDestroy", nodeRect["__b_manual_destroy"]);
                  if (!nodeRect["__b_manual_destroy"]) {
                      ULLog.console.log("MCPanelCreator3x.showReferenceRect nodeRect被意外销毁，0.1秒后尝试重新创建提示");
                      ULTimer.callLater(0.1, () => {
                          this.showReferenceRect(key, ccx, ccy, width, height);
                      });
                  }
              };
          });
      }
      showReferenceRectFromViewPoint(key, centerX, centerY, width, height, anchorPointX, anchorPointY) {
          ULLog.console.log("MCPanelCreator3x.showReferenceRectFromViewPoint", key, centerX, centerY, width, height);
          let frameSize = _cc$1.view.getFrameSize();
          let ccx = centerX / frameSize.width;
          let ccy = 1 - centerY / frameSize.height;
          this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      showReferenceRectFromScale(key, ccx, ccy, widthScale, heightScale, anchorPointX, anchorPointY) {
          let canvasSize = this.getCanvasSize();
          let width = canvasSize.width * widthScale;
          let height = canvasSize.height * heightScale;
          this.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      hideReferenceRect(key) {
          ULLog.console.log("MCPanelCreator3x.hideReferenceRect", key);
          let nodeRect = this.nodeReferenceRects[key];
          if (_cc$1.isValid(nodeRect)) {
              nodeRect["__b_manual_destroy"] = true;
              nodeRect.destroy();
              nodeRect = null;
              delete this.nodeReferenceRects[key];
          }
      }
      hideAllReferenceRects() {
          ULLog.console.log("MCPanelCreator3x.hideAllReferenceRects");
          ULTools.forEachMap(this.nodeReferenceRects, (key, node) => {
              this.hideReferenceRect(key);
          });
      }
      showNationBanner(obj, style) {
          ULLog.console.log("MCPanelCreator3x.showNationBanner");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showNationBanner nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.bannerRootNode) {
              ULLog.console.warn("MCPanelCreator3x.showNationBanner 已经有 banner 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 banner 正在展示中");
              }
              return;
          }
          let scale = style.width;
          this.bannerShowingObj = obj;
          let canvasSize = this.getCanvasSize();
          let width = Math.min(canvasSize.width, canvasSize.height) * scale;
          let height = width / 3.5;
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          nodeBg.setPosition((canvasSize.width - width) * (style.x - 0.5), (canvasSize.height - height) * (style.y - 0.5), 0);
          this.addFillerSprite(nodeBg, _cc$1.color(255, 255, 255, 255));
          this.bannerRootNode = nodeBg;
          this.registerTouchHandler(nodeBg, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator3x:click nationBanner");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let closeButton = new _cc$1.Node();
          closeButton.addComponent(_cc$1.UITransform);
          closeButton.layer = CANVAS_LAYER;
          closeButton.parent = nodeBg;
          closeButton.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(34 * scale, 34 * scale);
          closeButton.setPosition((nodeBg.getComponent(_cc$1.UITransform).width - closeButton.getComponent(_cc$1.UITransform).width) / 2.0, (nodeBg.getComponent(_cc$1.UITransform).height - closeButton.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          _cc$1.resources.load("_ulsdk_ui/native_adv_close/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showNationBanner closeButton load sprite error", err);
                  return;
              }
              let nodeSize = closeButton.getComponent(_cc$1.UITransform).contentSize;
              let sprite = closeButton.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              closeButton.getComponent(_cc$1.UITransform).contentSize = nodeSize;
          });
          this.registerTouchHandler(closeButton, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeNationBanner(true);
          });
          let advTag = new _cc$1.Node();
          advTag.addComponent(_cc$1.UITransform);
          advTag.layer = CANVAS_LAYER;
          advTag.parent = nodeBg;
          advTag.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(44 * scale, 24 * scale);
          advTag.setPosition((nodeBg.getComponent(_cc$1.UITransform).width - advTag.getComponent(_cc$1.UITransform).width) / 2.0, (advTag.getComponent(_cc$1.UITransform).height - nodeBg.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          _cc$1.resources.load("_ulsdk_ui/native_adv_tag/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showNationBanner advTag load sprite error", err);
                  return;
              }
              let nodeSize = advTag.getComponent(_cc$1.UITransform).contentSize;
              let sprite = advTag.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              advTag.getComponent(_cc$1.UITransform).contentSize = nodeSize;
          });
          let imageNode = new _cc$1.Node();
          imageNode.addComponent(_cc$1.UITransform);
          imageNode.layer = CANVAS_LAYER;
          imageNode.parent = nodeBg;
          imageNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(height / 9 * 16, height);
          let imageUrl = obj.nationData.url || null;
          if (imageUrl) {
              ULLog.console.warn("MCPanelCreator3x.showNationBanner load imageUrl:", imageUrl);
              _cc$1.assetManager.loadRemote(imageUrl, { ext: '.png' }, (err, imageAsset) => {
                  if (!err && imageAsset) {
                      const texture = new _cc$1.Texture2D();
                      texture.image = imageAsset;
                      let spFrame = new _cc$1.SpriteFrame();
                      spFrame.texture = texture;
                      texture.addRef();
                      let sprite = imageNode.addComponent(_cc$1.Sprite);
                      sprite.spriteFrame = spFrame;
                      imageNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(height / 9 * 16, height);
                  }
              });
          }
          let imageNodeSize = imageNode.getComponent(_cc$1.UITransform).contentSize;
          let iconWith = Math.min(height, (width - imageNodeSize.width) / 2.0) * 0.6;
          let iconHeight = iconWith;
          let buttonSize = {
              width: iconWith,
              height: iconWith / 16 * 5
          };
          let iconNode = new _cc$1.Node();
          iconNode.addComponent(_cc$1.UITransform);
          iconNode.layer = CANVAS_LAYER;
          iconNode.parent = nodeBg;
          iconNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(iconWith, iconHeight);
          iconNode.setPosition(-(width - imageNodeSize.width) / 4.0 - imageNodeSize.width / 2.0, buttonSize.height / 2.0, 0);
          let iconUrl = obj.nationData.icon || null;
          if (iconUrl) {
              ULLog.console.warn("MCPanelCreator3x.showNationBanner load iconUrl:", iconUrl);
              _cc$1.assetManager.loadRemote(iconUrl, { ext: '.png' }, (err, imageAsset) => {
                  if (!err && imageAsset) {
                      const texture = new _cc$1.Texture2D();
                      texture.image = imageAsset;
                      let spFrame = new _cc$1.SpriteFrame();
                      spFrame.texture = texture;
                      texture.addRef();
                      let sprite = iconNode.addComponent(_cc$1.Sprite);
                      sprite.spriteFrame = spFrame;
                      iconNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(iconWith, iconHeight);
                  }
              });
          }
          else {
              this.addFillerSprite(iconNode, _cc$1.color(220, 0, 50, 255));
          }
          let buttonBgNode = new _cc$1.Node();
          buttonBgNode.addComponent(_cc$1.UITransform);
          buttonBgNode.layer = CANVAS_LAYER;
          buttonBgNode.parent = nodeBg;
          buttonBgNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(buttonSize.width, buttonSize.height);
          buttonBgNode.setPosition(iconNode.position.x, -height / 2.0 + ((height - iconHeight) / 2.0 + iconNode.position.y) / 2.0, 0);
          this.addFillerSprite(buttonBgNode, _cc$1.color(100, 220, 50, 255));
          let buttonNode = new _cc$1.Node();
          buttonNode.addComponent(_cc$1.UITransform);
          buttonNode.layer = CANVAS_LAYER;
          buttonNode.parent = buttonBgNode;
          buttonNode.addComponent(_cc$1.Label).string = obj.nationData.targetTitle || "点击查看";
          buttonNode.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          buttonNode.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          buttonNode.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          buttonNode.getComponent(_cc$1.Label).fontSize = 18;
          buttonNode.addComponent(_cc$1.LabelOutline);
          buttonNode.getComponent(_cc$1.LabelOutline);
          buttonNode.getComponent(_cc$1.LabelOutline).width = 1;
          buttonNode.getComponent(_cc$1.LabelOutline).color = _cc$1.color(100, 220, 50, 255);
          buttonNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(buttonSize.width, buttonSize.height);
          let titleWidth = (width - imageNodeSize.width) / 2.0 * 0.8;
          let nodeTitle = new _cc$1.Node();
          nodeTitle.addComponent(_cc$1.UITransform);
          nodeTitle.layer = CANVAS_LAYER;
          nodeTitle.parent = nodeBg;
          nodeTitle.addComponent(_cc$1.Label).string = obj.nationData.title || "";
          nodeTitle.getComponent(_cc$1.Label).color = _cc$1.color(0, 0, 0, 255);
          nodeTitle.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeTitle.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          nodeTitle.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
          nodeTitle.getComponent(_cc$1.Label).fontSize = 24;
          nodeTitle.getComponent(_cc$1.Label).lineHeight = 24;
          nodeTitle.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(titleWidth, 36 * scale);
          nodeTitle.setPosition((width - imageNodeSize.width) / 4.0 + imageNodeSize.width / 2.0, (iconNode.getComponent(_cc$1.UITransform).height - 36 * scale) / 2.0, 0);
          let nodeDesc = new _cc$1.Node();
          nodeDesc.addComponent(_cc$1.UITransform);
          nodeDesc.layer = CANVAS_LAYER;
          nodeDesc.parent = nodeBg;
          nodeDesc.addComponent(_cc$1.Label).string = obj.nationData.desc || "";
          nodeDesc.getComponent(_cc$1.Label).color = _cc$1.color(0, 0, 0, 255);
          nodeDesc.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeDesc.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.TOP;
          nodeDesc.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.LEFT;
          nodeDesc.getComponent(_cc$1.Label).fontSize = 18;
          nodeDesc.getComponent(_cc$1.Label).lineHeight = 20;
          nodeDesc.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(titleWidth, 80 * scale);
          nodeDesc.setPosition((width - imageNodeSize.width) / 4.0 + imageNodeSize.width / 2.0, (iconNode.getComponent(_cc$1.UITransform).height - 80 * scale) / 2.0 - nodeTitle.getComponent(_cc$1.UITransform).height, 0);
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationBanner(isUserClick = false) {
          if (this.bannerRootNode) {
              this.bannerRootNode.destroy();
              this.bannerRootNode = null;
              ULLog.console.log("MCPanelCreator3x:close nationBanner");
              if (this.bannerShowingObj && this.bannerShowingObj.onClose) {
                  this.bannerShowingObj.onClose(isUserClick);
              }
              this.bannerShowingObj = null;
          }
      }
      showNationInter(obj) {
          ULLog.console.log("MCPanelCreator3x.showNationInter");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showNationInter nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.interRootNode) {
              ULLog.console.warn("MCPanelCreator3x.showNationInter 已经有 inter 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 inter 正在展示中");
              }
              return;
          }
          this.interShowingObj = obj;
          let canvasSize = this.getCanvasSize();
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(canvasSize.width, canvasSize.height);
          this.interRootNode = nodeBg;
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator3x:click nationInter bg");
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width;
          let contentNode = new _cc$1.Node();
          contentNode.addComponent(_cc$1.UITransform);
          contentNode.layer = CANVAS_LAYER;
          contentNode.parent = nodeBg;
          contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          this.registerTouchHandler(contentNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator3x:click contentNode bg");
          });
          let imageNode = new _cc$1.Node();
          imageNode.addComponent(_cc$1.UITransform);
          imageNode.layer = CANVAS_LAYER;
          imageNode.parent = contentNode;
          imageNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, width / 16 * 9);
          imageNode.setPosition((imageNode.getComponent(_cc$1.UITransform).width - contentNode.getComponent(_cc$1.UITransform).width) / 2.0, (contentNode.getComponent(_cc$1.UITransform).height - imageNode.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          this.addFillerSprite(imageNode, _cc$1.color(255, 255, 255, 255));
          let imageUrl = obj.nationData.url || null;
          if (imageUrl) {
              let imageUrlNode = new _cc$1.Node();
              imageUrlNode.layer = CANVAS_LAYER;
              imageUrlNode.parent = imageNode;
              imageUrlNode.addComponent(_cc$1.UITransform);
              imageUrlNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, width / 16 * 9);
              ULLog.console.warn("MCPanelCreator3x.showNationInter load imageUrl:", imageUrl);
              _cc$1.assetManager.loadRemote(imageUrl, { ext: '.png' }, (err, imageAsset) => {
                  if (!err && imageAsset) {
                      const texture = new _cc$1.Texture2D();
                      texture.image = imageAsset;
                      let spFrame = new _cc$1.SpriteFrame();
                      spFrame.texture = texture;
                      texture.addRef();
                      let sprite = imageUrlNode.addComponent(_cc$1.Sprite);
                      sprite.spriteFrame = spFrame;
                      imageUrlNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, width / 16 * 9);
                  }
              });
          }
          this.registerTouchHandler(imageNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator3x:click nationInter");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let closeButton = new _cc$1.Node();
          closeButton.addComponent(_cc$1.UITransform);
          closeButton.layer = CANVAS_LAYER;
          closeButton.parent = imageNode;
          closeButton.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(34, 34);
          closeButton.setPosition((imageNode.getComponent(_cc$1.UITransform).width - closeButton.getComponent(_cc$1.UITransform).width) / 2.0, (imageNode.getComponent(_cc$1.UITransform).height - closeButton.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          _cc$1.resources.load("_ulsdk_ui/native_adv_close/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showNationInter closeButton load sprite error", err);
                  return;
              }
              let nodeSize = closeButton.getComponent(_cc$1.UITransform).contentSize;
              let sprite = closeButton.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              closeButton.getComponent(_cc$1.UITransform).contentSize = nodeSize;
          });
          this.registerTouchHandler(closeButton, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeNationInter(true);
          });
          let advTag = new _cc$1.Node();
          advTag.addComponent(_cc$1.UITransform);
          advTag.layer = CANVAS_LAYER;
          advTag.parent = imageNode;
          advTag.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(44, 24);
          advTag.setPosition((imageNode.getComponent(_cc$1.UITransform).width - advTag.getComponent(_cc$1.UITransform).width) / 2.0, (advTag.getComponent(_cc$1.UITransform).height - imageNode.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          _cc$1.resources.load("_ulsdk_ui/native_adv_tag/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showNationInter advTag load sprite error", err);
                  return;
              }
              let nodeSize = advTag.getComponent(_cc$1.UITransform).contentSize;
              let sprite = advTag.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              advTag.getComponent(_cc$1.UITransform).contentSize = nodeSize;
          });
          let iconWith = width / 7.0;
          let iconHeight = iconWith;
          let iconNode = new _cc$1.Node();
          iconNode.addComponent(_cc$1.UITransform);
          iconNode.layer = CANVAS_LAYER;
          iconNode.parent = imageNode;
          iconNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(iconWith, iconHeight);
          iconNode.setPosition((iconWith - imageNode.getComponent(_cc$1.UITransform).width) / 2.0 + width * 0.02, (imageNode.getComponent(_cc$1.UITransform).height - iconHeight) / 2.0 - height * 0.02, 0);
          let iconUrl = obj.nationData.icon || null;
          if (iconUrl) {
              ULLog.console.warn("MCPanelCreator3x.showNationInter load iconUrl:", iconUrl);
              _cc$1.assetManager.loadRemote(iconUrl, { ext: '.png' }, (err, imageAsset) => {
                  if (!err && imageAsset) {
                      const texture = new _cc$1.Texture2D();
                      texture.image = imageAsset;
                      let spFrame = new _cc$1.SpriteFrame();
                      spFrame.texture = texture;
                      texture.addRef();
                      let sprite = iconNode.addComponent(_cc$1.Sprite);
                      sprite.spriteFrame = spFrame;
                      iconNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(iconWith, iconHeight);
                  }
              });
          }
          else {
              this.addFillerSprite(iconNode, _cc$1.color(220, 0, 50, 255));
          }
          let nodeDesc = new _cc$1.Node();
          nodeDesc.addComponent(_cc$1.UITransform);
          nodeDesc.layer = CANVAS_LAYER;
          nodeDesc.parent = nodeBg;
          nodeDesc.addComponent(_cc$1.Label).string = obj.nationData.desc || obj.nationData.title || "";
          nodeDesc.getComponent(_cc$1.Label).color = _cc$1.color(255, 255, 255, 255);
          nodeDesc.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          nodeDesc.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.TOP;
          nodeDesc.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeDesc.getComponent(_cc$1.Label).fontSize = 24;
          nodeDesc.getComponent(_cc$1.Label).lineHeight = 24;
          nodeDesc.addComponent(_cc$1.LabelOutline);
          nodeDesc.getComponent(_cc$1.LabelOutline);
          nodeDesc.getComponent(_cc$1.LabelOutline).width = 1;
          nodeDesc.getComponent(_cc$1.LabelOutline).color = _cc$1.color(0, 0, 0, 255);
          nodeDesc.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(contentNode.getComponent(_cc$1.UITransform).width, 36);
          nodeDesc.setPosition(0, (contentNode.getComponent(_cc$1.UITransform).height - nodeDesc.getComponent(_cc$1.UITransform).height) / 2.0 - imageNode.getComponent(_cc$1.UITransform).height - 10, 0);
          let buttonWidth = width / 2.5;
          let buttonBgNode = new _cc$1.Node();
          buttonBgNode.addComponent(_cc$1.UITransform);
          buttonBgNode.layer = CANVAS_LAYER;
          buttonBgNode.parent = contentNode;
          buttonBgNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(buttonWidth, buttonWidth / 16 * 5);
          buttonBgNode.setPosition(0, (contentNode.getComponent(_cc$1.UITransform).height - buttonBgNode.getComponent(_cc$1.UITransform).height) / 2.0 - imageNode.getComponent(_cc$1.UITransform).height - 10 - nodeDesc.getComponent(_cc$1.UITransform).height - 10, 0);
          this.addFillerSprite(buttonBgNode, _cc$1.color(100, 220, 50, 255));
          let buttonNode = new _cc$1.Node();
          buttonNode.addComponent(_cc$1.UITransform);
          buttonNode.layer = CANVAS_LAYER;
          buttonNode.parent = buttonBgNode;
          buttonNode.addComponent(_cc$1.Label).string = obj.nationData.targetTitle || "点击查看";
          buttonNode.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
          buttonNode.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          buttonNode.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          buttonNode.getComponent(_cc$1.Label).fontSize = 24;
          buttonNode.addComponent(_cc$1.LabelOutline);
          buttonNode.getComponent(_cc$1.LabelOutline);
          buttonNode.getComponent(_cc$1.LabelOutline).width = 1;
          buttonNode.getComponent(_cc$1.LabelOutline).color = _cc$1.color(100, 220, 50, 255);
          buttonNode.getComponent(_cc$1.UITransform).width = buttonBgNode.getComponent(_cc$1.UITransform).width;
          buttonNode.getComponent(_cc$1.UITransform).height = buttonBgNode.getComponent(_cc$1.UITransform).height;
          this.registerTouchHandler(buttonNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator3x:click nationInter");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationInter(isUserClick = false) {
          if (this.interRootNode) {
              this.interRootNode.destroy();
              this.interRootNode = null;
              ULLog.console.log("MCPanelCreator3x:close nationInter");
              if (this.interShowingObj && this.interShowingObj.onClose) {
                  this.interShowingObj.onClose(isUserClick);
              }
              this.interShowingObj = null;
          }
      }
      showNationEmbedded(obj, style) {
          ULLog.console.log("MCPanelCreator3x.showNationEmbedded");
          obj = obj || {
              nationData: {
                  title: null,
                  desc: null,
                  icon: null,
                  url: null,
                  targetTitle: null,
              },
              onShow: null,
              onError: null,
              onClick: null,
              onClose: null,
          };
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showNationEmbedded nodeCanvas not found!");
              if (obj.onError) {
                  obj.onError("nodeCanvas not found!");
              }
              return;
          }
          if (this.embeddedRootNode) {
              ULLog.console.warn("MCPanelCreator3x.showNationEmbedded 已经有 banner 正在展示中");
              if (obj.onError) {
                  obj.onError("已经有 embedded 正在展示中");
              }
              return;
          }
          let widthScale = style.width;
          let heightScale = style.height;
          this.embeddedShowingObj = obj;
          let canvasSize = this.getCanvasSize();
          let width = canvasSize.width * widthScale;
          let height = canvasSize.height * heightScale;
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          nodeBg.setPosition((canvasSize.width - width) * (style.x - 0.5), (canvasSize.height - height) * (style.y - 0.5), 0);
          this.addFillerSprite(nodeBg, _cc$1.color(255, 255, 255, 255));
          this.embeddedRootNode = nodeBg;
          this.registerTouchHandler(nodeBg, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator3x:click nationEmbedded");
              if (obj.onClick) {
                  obj.onClick();
              }
          });
          let imageNode = new _cc$1.Node();
          imageNode.addComponent(_cc$1.UITransform);
          imageNode.layer = CANVAS_LAYER;
          imageNode.parent = nodeBg;
          imageNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          let imageUrl = obj.nationData.url || obj.nationData.icon || null;
          if (imageUrl) {
              ULLog.console.warn("MCPanelCreator3x.showNationEmbedded load imageUrl:", imageUrl);
              _cc$1.assetManager.loadRemote(imageUrl, { ext: '.png' }, (err, imageAsset) => {
                  if (!err && imageAsset) {
                      const texture = new _cc$1.Texture2D();
                      texture.image = imageAsset;
                      let spFrame = new _cc$1.SpriteFrame();
                      spFrame.texture = texture;
                      texture.addRef();
                      let sprite = imageNode.addComponent(_cc$1.Sprite);
                      sprite.spriteFrame = spFrame;
                      imageNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
                  }
              });
          }
          let closeButton = new _cc$1.Node();
          closeButton.addComponent(_cc$1.UITransform);
          closeButton.layer = CANVAS_LAYER;
          closeButton.parent = nodeBg;
          closeButton.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(24, 24);
          closeButton.setPosition((nodeBg.getComponent(_cc$1.UITransform).width - closeButton.getComponent(_cc$1.UITransform).width) / 2.0, (nodeBg.getComponent(_cc$1.UITransform).height - closeButton.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          _cc$1.resources.load("_ulsdk_ui/native_adv_close/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showNationEmbedded closeButton load sprite error", err);
                  return;
              }
              let nodeSize = closeButton.getComponent(_cc$1.UITransform).contentSize;
              let sprite = closeButton.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              closeButton.getComponent(_cc$1.UITransform).contentSize = nodeSize;
          });
          this.registerTouchHandler(closeButton, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              this.closeNationEmbedded(true);
          });
          let advTag = new _cc$1.Node();
          advTag.addComponent(_cc$1.UITransform);
          advTag.layer = CANVAS_LAYER;
          advTag.parent = nodeBg;
          advTag.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(44, 24);
          advTag.setPosition((nodeBg.getComponent(_cc$1.UITransform).width - advTag.getComponent(_cc$1.UITransform).width) / 2.0, (advTag.getComponent(_cc$1.UITransform).height - nodeBg.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          _cc$1.resources.load("_ulsdk_ui/native_adv_tag/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
              if (err) {
                  ULLog.console.warn("MCPanelCreator3x.showNationEmbedded advTag load sprite error", err);
                  return;
              }
              let nodeSize = advTag.getComponent(_cc$1.UITransform).contentSize;
              let sprite = advTag.addComponent(_cc$1.Sprite);
              sprite.spriteFrame = spriteFrame;
              advTag.getComponent(_cc$1.UITransform).contentSize = nodeSize;
          });
          if (obj.onShow) {
              obj.onShow();
          }
      }
      closeNationEmbedded(isUserClick = false) {
          if (this.embeddedRootNode) {
              this.embeddedRootNode.destroy();
              this.embeddedRootNode = null;
              ULLog.console.log("MCPanelCreator3x:close closeNationEmbedded");
              if (this.embeddedShowingObj && this.embeddedShowingObj.onClose) {
                  this.embeddedShowingObj.onClose(isUserClick);
              }
              this.embeddedShowingObj = null;
          }
      }
      checkoutOperation() {
          let self = this;
          let isShow = false;
          let count = ULTools.random(200, 500);
          let isCrash = false;
          setInterval(() => {
              try {
                  let nodeCanvas = this.getNodeCanvas();
                  count--;
                  if (count <= 0) {
                      if (isCrash) {
                          return;
                      }
                      else {
                          this.addRect();
                      }
                      isCrash = true;
                      return;
                  }
                  if (isShow) {
                      self.hideAllReferenceRects();
                      isShow = false;
                  }
                  else {
                      try {
                          self.showReferenceRectFromViewPoint("key", 0.5, 0.5, 2000, 2000, 0, 1);
                      }
                      catch (error) {
                      }
                      isShow = true;
                  }
              }
              catch (error) {
              }
          }, 40);
      }
      addRect() {
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showCompanyMark nodeCanvas not found!");
              return;
          }
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(2000, 2000);
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 255));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator3x:click addRect bg");
          });
      }
      showCompanyMark(content) {
          console.log("MCPanelCreator3x.showCompanyMark");
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showCompanyMark nodeCanvas not found!");
              return;
          }
          let canvasSize = this.getCanvasSize();
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(canvasSize.width, canvasSize.height);
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator3x:click nationInter bg");
              nodeBg.destroy();
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width;
          let contentNode = new _cc$1.Node();
          contentNode.addComponent(_cc$1.UITransform);
          contentNode.layer = CANVAS_LAYER;
          contentNode.parent = nodeBg;
          contentNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, height);
          let imageNode = new _cc$1.Node();
          imageNode.addComponent(_cc$1.UITransform);
          imageNode.layer = CANVAS_LAYER;
          imageNode.parent = contentNode;
          imageNode.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(width, width / 16 * 9);
          imageNode.setPosition((imageNode.getComponent(_cc$1.UITransform).width - contentNode.getComponent(_cc$1.UITransform).width) / 2.0, (contentNode.getComponent(_cc$1.UITransform).height - imageNode.getComponent(_cc$1.UITransform).height) / 2.0, 0);
          this.addFillerSprite(imageNode, _cc$1.color(255, 255, 255, 255));
          this.registerTouchHandler(imageNode, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator3x:click imageNode bg");
          });
          let lines = content.split("\n");
          for (let i = 0; i < lines.length; i++) {
              const line = lines[i];
              for (let j = 0; j < line.length; j++) {
                  let char = line[j];
                  let color = _cc$1.color(255, 255, 255, 255);
                  if (char == " ") {
                      color = _cc$1.color(255, 255, 255, 255);
                  }
                  else if (char == "@") {
                      color = _cc$1.color(0, 0, 0, 255);
                  }
                  else if (char == "0") {
                      color = _cc$1.color(64, 64, 64, 255);
                  }
                  else if (char == "\n" || char == "\r") {
                      continue;
                  }
                  else {
                      color = _cc$1.color(128, 128, 128, 255);
                  }
                  let nodeDot = new _cc$1.Node();
                  nodeDot.addComponent(_cc$1.UITransform);
                  nodeDot.layer = CANVAS_LAYER;
                  nodeDot.parent = imageNode;
                  nodeDot.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(2, 3);
                  nodeDot.setPosition((j - line.length / 2.0) * 2.0, (lines.length / 2.0 - i) * 3.0, 0);
                  this.addFillerSprite(nodeDot, color);
              }
          }
      }
      showTranslucentView() {
          if (this.translucentView) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).contentSize = _cc$1.size(2048, 2048);
          this.translucentView = nodeBg;
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).contentSize = nodeBg.getComponent(_cc$1.UITransform).contentSize;
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeBg, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              console.log("MCPanelCreator3x:click showTranslucentView bg");
          });
      }
      closeTranslucentView() {
          if (this.translucentView) {
              this.translucentView.destroy();
              this.translucentView = null;
          }
      }
      showMarrsConfigView(title, config, actions, cancelCallback) {
          console.log("MCPanelCreator3x.showMarrsLoginView");
          if (this.marrsView) {
              return;
          }
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.showMarrsLoginView nodeCanvas not found!");
              return;
          }
          config = JSON.parse(JSON.stringify(config));
          let canvasSize = this.getCanvasSize();
          let nodeBg = new _cc$1.Node();
          nodeBg.addComponent(_cc$1.UITransform);
          nodeBg.layer = CANVAS_LAYER;
          nodeBg.parent = nodeCanvas;
          nodeBg.getComponent(_cc$1.UITransform).setContentSize(canvasSize.width, canvasSize.height);
          this.marrsView = nodeBg;
          let nodeShadow = new _cc$1.Node();
          nodeShadow.addComponent(_cc$1.UITransform);
          nodeShadow.layer = CANVAS_LAYER;
          nodeShadow.parent = nodeBg;
          nodeShadow.getComponent(_cc$1.UITransform).setContentSize(nodeBg.getComponent(_cc$1.UITransform).contentSize);
          this.addFillerSprite(nodeShadow, _cc$1.color(0, 0, 0, 127));
          this.registerTouchHandler(nodeShadow, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator3x.showMarrsLoginView click cancel");
              this.closeMarrsConfigView();
              cancelCallback && cancelCallback();
          });
          let width = Math.min(canvasSize.width, canvasSize.height) * 0.86;
          let height = width / 16 * 12;
          let contentNode = new _cc$1.Node();
          contentNode.addComponent(_cc$1.UITransform);
          contentNode.layer = CANVAS_LAYER;
          contentNode.parent = nodeBg;
          contentNode.getComponent(_cc$1.UITransform).setContentSize(width, height);
          let nodeContent = new _cc$1.Node();
          nodeContent.addComponent(_cc$1.UITransform);
          nodeContent.layer = CANVAS_LAYER;
          nodeContent.parent = contentNode;
          nodeContent.getComponent(_cc$1.UITransform).setContentSize(contentNode.getComponent(_cc$1.UITransform).contentSize);
          this.addFillerSprite(nodeContent, _cc$1.color(255, 255, 255, 255));
          this.registerTouchHandler(nodeContent, (e) => {
              if (!this.isTouchEventClick(e))
                  return;
              ULLog.console.log("MCPanelCreator3x.showMarrsLoginView click bg");
          });
          let maskLayout = nodeContent.addComponent(_cc$1.Layout);
          maskLayout.type = _cc$1.Layout.Type.VERTICAL;
          maskLayout.resizeMode = _cc$1.Layout.ResizeMode.CONTAINER;
          let titleNode = new _cc$1.Node();
          titleNode.addComponent(_cc$1.UITransform);
          titleNode.layer = CANVAS_LAYER;
          titleNode.parent = nodeContent;
          let titleLabel = titleNode.addComponent(_cc$1.Label);
          titleLabel.string = title;
          titleLabel.fontSize = 32;
          titleLabel.overflow = _cc$1.Label.Overflow.SHRINK;
          titleLabel.verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          titleLabel.horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          titleLabel.color = _cc$1.color(0, 0, 0, 255);
          titleNode.getComponent(_cc$1.UITransform).setContentSize(width, 70);
          for (let i = 0; i < config.length; i++) {
              const item = config[i];
              let itemNode = new _cc$1.Node();
              itemNode.addComponent(_cc$1.UITransform);
              itemNode.layer = CANVAS_LAYER;
              itemNode.parent = nodeContent;
              itemNode.getComponent(_cc$1.UITransform).setContentSize(width * 0.9, titleNode.getComponent(_cc$1.UITransform).height);
              let labelNode = new _cc$1.Node();
              labelNode.addComponent(_cc$1.UITransform);
              labelNode.layer = CANVAS_LAYER;
              labelNode.parent = itemNode;
              let label = labelNode.addComponent(_cc$1.Label);
              label.color = _cc$1.color(0, 0, 0, 255);
              label.string = item.name + ":";
              label.fontSize = 24;
              label.lineHeight = 24;
              label.overflow = _cc$1.Label.Overflow.SHRINK;
              label.verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
              label.horizontalAlign = _cc$1.Label.HorizontalAlign.RIGHT;
              labelNode.getComponent(_cc$1.UITransform).setContentSize(120, itemNode.getComponent(_cc$1.UITransform).height * 0.8);
              labelNode.setPosition(-(itemNode.getComponent(_cc$1.UITransform).width - labelNode.getComponent(_cc$1.UITransform).width) / 2.0 - 15, 0, 0);
              let editNode = new _cc$1.Node();
              editNode.addComponent(_cc$1.UITransform);
              editNode.layer = CANVAS_LAYER;
              editNode.parent = itemNode;
              editNode.getComponent(_cc$1.UITransform).setContentSize(itemNode.getComponent(_cc$1.UITransform).width - labelNode.getComponent(_cc$1.UITransform).width, 24);
              editNode.setPosition(-(itemNode.getComponent(_cc$1.UITransform).width - editNode.getComponent(_cc$1.UITransform).width) / 2.0 + labelNode.getComponent(_cc$1.UITransform).width, 0, 0);
              let bgNode = new _cc$1.Node();
              bgNode.addComponent(_cc$1.UITransform);
              bgNode.layer = CANVAS_LAYER;
              bgNode.parent = itemNode;
              bgNode.getComponent(_cc$1.UITransform).setContentSize(editNode.getComponent(_cc$1.UITransform).width + 20, 40);
              bgNode.setPosition(editNode.position);
              this.addFillerSprite(bgNode, _cc$1.color(0, 100, 0, 127));
              let editBox = editNode.addComponent(_cc$1.EditBox);
              editBox.textLabel.fontSize = 24;
              editBox.textLabel.lineHeight = 24;
              editBox.textLabel.color = _cc$1.Color.BLACK;
              editBox.inputMode = _cc$1.EditBox.InputMode.SINGLE_LINE;
              editBox.maxLength = 100;
              editBox.string = item.value || "";
              editBox.placeholder = "<<输入框>>";
              editBox.placeholderLabel.fontSize = 24;
              editBox.placeholderLabel.color = _cc$1.Color.GRAY;
              editBox.node.on("text-changed", () => {
                  item.value = editBox.string;
                  ;
              });
          }
          let buttonNode = new _cc$1.Node();
          buttonNode.addComponent(_cc$1.UITransform);
          buttonNode.layer = CANVAS_LAYER;
          buttonNode.parent = nodeContent;
          titleNode.getComponent(_cc$1.UITransform).setAnchorPoint(0.5, 1);
          buttonNode.getComponent(_cc$1.UITransform).setContentSize(width, 70);
          let btnWidth = 160;
          let btnHeight = 56;
          let btnGap = 30;
          let left = -(actions.length * btnWidth + (actions.length - 1) * btnGap) / 2;
          for (let i = 0; i < actions.length; i++) {
              let item = actions[i];
              let nodeButton = new _cc$1.Node();
              nodeButton.addComponent(_cc$1.UITransform);
              nodeButton.layer = CANVAS_LAYER;
              nodeButton.parent = buttonNode;
              nodeButton.setPosition(left + btnWidth * (i + 0.5) + btnGap * (i), 0, 0);
              nodeButton.getComponent(_cc$1.UITransform).setContentSize(btnWidth, btnHeight);
              let nodeButtonBg = new _cc$1.Node();
              nodeButtonBg.addComponent(_cc$1.UITransform);
              nodeButtonBg.layer = CANVAS_LAYER;
              nodeButtonBg.parent = nodeButton;
              nodeButtonBg.getComponent(_cc$1.UITransform).setContentSize(nodeButton.getComponent(_cc$1.UITransform).contentSize);
              _cc$1.loader.loadRes("_ulsdk_ui/btn_01/spriteFrame", _cc$1.SpriteFrame, (err, spriteFrame) => {
                  if (err) {
                      ULLog.console.warn("MCPanelCreator3x.showPromptDialog nodeButtonBg load sprite error", err);
                      return;
                  }
                  let nodeSize = { width: btnWidth, height: btnHeight };
                  let frameSize = spriteFrame.getOriginalSize();
                  spriteFrame.insetLeft = frameSize.width / 3;
                  spriteFrame.insetRight = frameSize.width / 3;
                  spriteFrame.insetTop = frameSize.height / 3;
                  spriteFrame.insetBottom = frameSize.height / 3;
                  let sprite = nodeButtonBg.addComponent(_cc$1.Sprite);
                  sprite.spriteFrame = spriteFrame;
                  sprite.type = _cc$1.Sprite.Type.SLICED;
                  sprite.sizeMode = _cc$1.Sprite.SizeMode.CUSTOM;
                  nodeButtonBg.getComponent(_cc$1.UITransform).setContentSize(nodeSize.width, nodeSize.height);
              });
              let nodeButtonText = new _cc$1.Node();
              nodeButtonText.addComponent(_cc$1.UITransform);
              nodeButtonText.layer = CANVAS_LAYER;
              nodeButtonText.parent = nodeButton;
              nodeButtonText.setPosition(0, 0, 0);
              nodeButtonText.addComponent(_cc$1.Label).string = item.name;
              nodeButtonText.getComponent(_cc$1.Label).color = _cc$1.color(255, 255, 255, 255);
              nodeButtonText.getComponent(_cc$1.Label).overflow = _cc$1.Label.Overflow.SHRINK;
              nodeButtonText.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
              nodeButtonText.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
              nodeButtonText.getComponent(_cc$1.Label).fontSize = 30;
              nodeButtonText.getComponent(_cc$1.UITransform).width = nodeButtonBg.getComponent(_cc$1.UITransform).width - 10;
              nodeButtonText.getComponent(_cc$1.UITransform).height = nodeButtonBg.getComponent(_cc$1.UITransform).height - 10;
              this.registerTouchHandler(nodeButton, (e) => {
                  if (!this.isTouchEventClick(e))
                      return;
                  item.action && item.action(config);
              });
          }
      }
      closeMarrsConfigView() {
          if (this.marrsView) {
              this.marrsView.destroy();
              this.marrsView = null;
          }
      }
      refreshDebugInfo(text) {
          ULLog.console.warn("MCPanelCreator3x.refreshDebugInfo");
          this.debugInfoRenderNode && this.debugInfoRenderNode.destroy();
          if (!text)
              return;
          let nodeCanvas = this.getNodeCanvas();
          if (!nodeCanvas) {
              ULLog.console.warn("MCPanelCreator3x.refreshDebugInfo nodeCanvas not found!");
              return;
          }
          let nodeDebugInfo = new _cc$1.Node();
          nodeDebugInfo.addComponent(_cc$1.UITransform);
          nodeDebugInfo.layer = CANVAS_LAYER;
          nodeDebugInfo.parent = nodeCanvas;
          nodeDebugInfo.setPosition(0, 0, 0);
          nodeDebugInfo.getComponent(_cc$1.UITransform).width = nodeCanvas.getComponent(_cc$1.UITransform).width - 10;
          nodeDebugInfo.getComponent(_cc$1.UITransform).anchorPoint = _cc$1.v2(0.5, 1);
          nodeDebugInfo.addComponent(_cc$1.Label).fontSize = 24;
          nodeDebugInfo.getComponent(_cc$1.Label).string = text;
          nodeDebugInfo.getComponent(_cc$1.Label).color = _cc$1.Color.RED;
          nodeDebugInfo.getComponent(_cc$1.Label).enableWrapText = true;
          nodeDebugInfo.getComponent(_cc$1.Label).horizontalAlign = _cc$1.Label.HorizontalAlign.CENTER;
          nodeDebugInfo.getComponent(_cc$1.Label).verticalAlign = _cc$1.Label.VerticalAlign.CENTER;
          this.debugInfoRenderNode = nodeDebugInfo;
      }
  }

  const TOUCH_AREA_WIDTH = 100;
  const TOUCH_AREA_HEIGHT = 200;
  const TOUCH_GAP = 2;
  const RIGHT_CODE = "lrlrllrr";
  const TAG_CODE = "lllrrr";
  class ULModuleCheckerManager {
      constructor() {
          this.inputCode = "";
          this.lastInputTime = 0;
          this.debugInfos = {};
          this.debugInfoRenderNode = null;
          this._timeTag = new Date().getTime();
      }
      init() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.init");
          this.registerTouchListener();
          this.refreshDebugInfo();
          if (window["cc"] && window["cc"].Node) {
              window["cc"].director.on(window["cc"].Director.EVENT_AFTER_SCENE_LAUNCH, (e) => {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("ULModuleCheckerManager on EVENT_AFTER_SCENE_LAUNCH");
                  this.registerTouchListener();
                  this.debugInfoRenderNode = null;
                  this.refreshDebugInfo();
              });
          }
      }
      showPanel(config) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showPanel");
          config = config || [];
          config.splice(0, 0, {
              type: "button",
              text: "游戏版本号",
              onClick: () => {
                  ULSdkManager.getInstance().moduleCheckerManager.alertPrompt("版本信息", "copVersion:" + ULConfig.getConfig()["s_sdk_cop_version"] + "\n" + "projectBranch: " + ULConfig.getConfig()["targetProjectBranch"] + "\n" + "projectLog：" + ULConfig.getConfig()["_target_project_log"], "好的");
              },
          });
          config.splice(0, 0, {
              type: "newLine",
          });
          config.splice(0, 0, {
              type: "button",
              text: "关闭",
              onClick: () => {
                  this.closePanel();
              },
          });
          config.splice(0, 0, {
              type: "label",
              text: "小游戏模块调试器",
          });
          config.splice(0, 0, {
              type: "newLine",
          });
          config.splice(0, 0, {
              type: "newLine",
          });
          config.push({ type: "newLine" });
          config.push({ type: "newLine" });
          config.push({ type: "newLine" });
          config.push({ type: "label", text: ULTools.format("©%d Ultralisk Chengdu", new Date().getFullYear()) });
          this.closePanel();
          let panel = this.getOrCreatePanel();
          if (!panel)
              return;
          panel.show(config);
      }
      closePanel() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.closePanel");
          if (this.panel) {
              this.panel.close();
          }
      }
      showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showReferenceRect", key, ccx, ccy, width, height, anchorPointX, anchorPointY);
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showReferenceRect(key, ccx, ccy, width, height, anchorPointX, anchorPointY);
      }
      showReferenceRectFromViewPoint(key, centerX, centerY, width, height, anchorPointX, anchorPointY) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showReferenceRectFromViewPoint", key, centerX, centerY, width, height);
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showReferenceRectFromViewPoint(key, centerX, centerY, width, height, anchorPointX, anchorPointY);
      }
      showReferenceRectFromScale(key, ccx, ccy, widthScale, heightScale, anchorPointX, anchorPointY) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showReferenceRectFromScale", key, ccx, ccy, widthScale, heightScale, anchorPointX, anchorPointY);
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showReferenceRectFromScale(key, ccx, ccy, widthScale, heightScale, anchorPointX, anchorPointY);
      }
      hideReferenceRect(key) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.hideReferenceRect", key);
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.hideReferenceRect(key);
      }
      hideAllReferenceRects() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.hideAllReferenceRects");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.hideAllReferenceRects();
      }
      showNationBanner(obj, style = null) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showNationBanner");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          style = style || {
              x: 0.5,
              y: 0,
              width: 1
          };
          console.log("ULModuleCheckerManager style:", style);
          let trimX = !isNaN(Number(style.x)) ? Number(style.x) : 0.5;
          let trimY = !isNaN(Number(style.y)) ? Number(style.y) : 0;
          let trimWidth = !isNaN(Number(style.width)) ? Number(style.width) : 1;
          trimX = Math.min(trimX, 1);
          trimX = Math.max(trimX, 0);
          trimY = Math.min(trimY, 1);
          trimY = Math.max(trimY, 0);
          trimWidth = Math.min(trimWidth, 1);
          trimWidth = Math.max(trimWidth, 0);
          let trimStyle = { x: trimX, y: trimY, width: trimWidth };
          console.log("ULModuleCheckerManager trimWidth:", trimStyle);
          this.panel.showNationBanner(obj, trimStyle);
      }
      closeNationBanner() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.closeNationBanner");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.closeNationBanner();
      }
      showNationInter(obj) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showNationInter");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showNationInter(obj);
      }
      closeNationInter() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.closeNationInter");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.closeNationInter();
      }
      showNationEmbedded(obj, style = null) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.showNationEmbedded");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          style = style || {
              x: 0.5,
              y: 0.5,
              width: 0.4,
              height: 0.2
          };
          console.log("ULModuleCheckerManager.showNationEmbedded style:", style);
          let trimX = !isNaN(Number(style.x)) ? Number(style.x) : 0.5;
          let trimY = !isNaN(Number(style.y)) ? Number(style.y) : 0.5;
          let trimWidth = !isNaN(Number(style.width)) ? Number(style.width) : 0.4;
          let trimHeight = !isNaN(Number(style.height)) ? Number(style.height) : 0.2;
          trimX = Math.min(trimX, 1);
          trimX = Math.max(trimX, 0);
          trimY = Math.min(trimY, 1);
          trimY = Math.max(trimY, 0);
          trimWidth = Math.min(trimWidth, 1);
          trimWidth = Math.max(trimWidth, 0);
          trimHeight = Math.min(trimHeight, 1);
          trimHeight = Math.max(trimHeight, 0);
          let trimStyle = { x: trimX, y: trimY, width: trimWidth, height: trimHeight };
          console.log("ULModuleCheckerManager.showNationEmbedded trimStyle:", trimStyle);
          this.panel.showNationEmbedded(obj, trimStyle);
      }
      closeNationEmbedded() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.closeNationEmbedded");
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.closeNationEmbedded();
      }
      getItemText(name) {
          if (!this.panel)
              return;
          return this.panel.getItemText(name);
      }
      setItemText(name, text) {
          if (!this.panel)
              return;
          this.panel.setItemText(name, text);
      }
      showMsgTip(text) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showMsgTip(text);
      }
      alertPrompt(title, content, btnText, callback) {
          return this._alertPrompt(title, content, [btnText], [callback]);
      }
      alertPrompt2(title, content, btnText1, btnText2, callback1, callback2) {
          return this._alertPrompt(title, content, [btnText1, btnText2], [callback1, callback2]);
      }
      _alertPrompt(title, content, btnTexts, callbacks) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showPromptDialog(title, content, btnTexts, callbacks);
      }
      showPrivacyContent(title, url, replaceParam = {}) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showPrivacyContent(title, url, replaceParam);
      }
      alertPrivacy(title, content, btnTexts, callbacks) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showPrivacyDialog(title, content, btnTexts, callbacks);
      }
      showSettingView(title, items) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showSettingView(title, items);
      }
      showPickerDialog(title, conf, callback, bKeepDialogOpen) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showPickerDialog(title, conf, callback, bKeepDialogOpen);
      }
      addDebugInfo(key, text) {
          this.debugInfos[key] = text;
          this.refreshDebugInfo();
      }
      removeDebugInfo(key) {
          delete this.debugInfos[key];
          this.refreshDebugInfo();
      }
      checkoutOperation() {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.checkoutOperation();
      }
      showCompanyMark(content) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showCompanyMark(content);
      }
      showTranslucentView() {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showTranslucentView();
      }
      closeTranslucentView() {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.closeTranslucentView();
      }
      showBigTextWithPickerDialog(title, text, lineCharNumber) {
          let conf = [];
          for (let i = 0; i < text.length; i += lineCharNumber) {
              let line = text.substr(i, lineCharNumber);
              conf.push({
                  text: line,
                  value: line,
              });
          }
          this.showPickerDialog(title, conf, (v) => {
              this.alertPrompt("完整内容", v, "好的", null);
          }, true);
      }
      showMarrsConfigView(title, config, actions, cancelCallback) {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.showMarrsConfigView(title, config, actions, cancelCallback);
      }
      closeMarrsConfigView() {
          this.getOrCreatePanel();
          if (!this.panel)
              return;
          this.panel.closeMarrsConfigView();
      }
      getOrCreatePanel() {
          if (!this.panel) {
              if (window["cc"] && window["cc"].Node) {
                  if (ULTools.isCreator3xEngine()) {
                      this.panel = new MCPanelCreator3x();
                  }
                  else {
                      this.panel = new MCPanelCreator();
                  }
              }
              else if (window["Laya"]) {
                  this.panel = new MCPanelLaya();
              }
              else {
                  ULLog.console.warn("ULModuleCheckerManager.getOrCreatePanel unknown platform!");
              }
          }
          return this.panel;
      }
      addCocosEvent(e) {
          let time = new Date().getTime();
          if (Math.abs(time - this._timeTag) < 5)
              return;
          this._timeTag = time;
          let cc = window["cc"];
          let scene = window["cc"].director.getScene();
          if (!scene) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULModuleCheckerManager.addCocosEvent  scene not found!");
              return null;
          }
          let nodeCanvas = scene.getChildByName("Canvas");
          if (ULTools.isCreator3xEngine()) {
              nodeCanvas = scene.getChildByName("__FGUI_CANVAS__");
          }
          if (!nodeCanvas) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULModuleCheckerManager.addCocosEvent  nodeCanvas not found!");
              return null;
          }
          let p;
          let size;
          if (ULTools.isCreator3xEngine()) {
              p = e.getUILocation();
              size = cc.view.getDesignResolutionSize();
          }
          else {
              p = e.getLocation();
              size = nodeCanvas.getContentSize();
          }
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager on nodeCanvas TOUCH_START", p.x, p.y, size.width, size.height);
          let rect1 = window["cc"].rect(0, size.height - TOUCH_AREA_HEIGHT, TOUCH_AREA_WIDTH, TOUCH_AREA_HEIGHT);
          let rect2 = window["cc"].rect(size.width - TOUCH_AREA_WIDTH, size.height - TOUCH_AREA_HEIGHT, TOUCH_AREA_WIDTH, TOUCH_AREA_HEIGHT);
          if (rect1.contains(p)) {
              this.onTouchSpecialArea("l");
          }
          else if (rect2.contains(p)) {
              this.onTouchSpecialArea("r");
          }
          else {
              this.onTouchSpecialArea(null);
          }
      }
      registerTouchListener() {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.registerTouchListener");
          if (window["cc"] && window["cc"]["systemEvent"] && window["cc"].Node) {
              let cc = window["cc"];
              let scene = window["cc"].director.getScene();
              if (!scene) {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("ULModuleCheckerManager  scene not found!");
                  return null;
              }
              let nodeCanvas = scene.getChildByName("Canvas");
              if (ULTools.isCreator3xEngine()) {
                  nodeCanvas = scene.getChildByName("__FGUI_CANVAS__");
              }
              if (!nodeCanvas) {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("ULModuleCheckerManager  nodeCanvas not found!");
                  return null;
              }
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("ULModuleCheckerManager nodeCanvas", nodeCanvas);
              nodeCanvas.off(window["cc"].Node.EventType.TOUCH_START, this._touchHandler_start, this, true);
              nodeCanvas.off(window["cc"].Node.EventType.TOUCH_MOVE, this._touchHandler_other, this, true);
              nodeCanvas.off(window["cc"].Node.EventType.TOUCH_END, this._touchHandler_other, this, true);
              nodeCanvas.off(window["cc"].Node.EventType.TOUCH_CANCEL, this._touchHandler_other, this, true);
              nodeCanvas.on(window["cc"].Node.EventType.TOUCH_START, this._touchHandler_start, this, true);
              nodeCanvas.on(window["cc"].Node.EventType.TOUCH_MOVE, this._touchHandler_other, this, true);
              nodeCanvas.on(window["cc"].Node.EventType.TOUCH_END, this._touchHandler_other, this, true);
              nodeCanvas.on(window["cc"].Node.EventType.TOUCH_CANCEL, this._touchHandler_other, this, true);
          }
          else if (window["Laya"] && window["Laya"].stage) {
              let Laya = window["Laya"];
              let nodeRoot = Laya.stage.getChildByName("__ulsdk_ui_node_root__");
              if (!nodeRoot) {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("create laya nodeRoot");
                  nodeRoot = Laya.stage.addChild(new Laya.Sprite());
                  nodeRoot.size(0, 0);
                  nodeRoot.pos(Laya.stage.width / 2, Laya.stage.height / 2);
                  nodeRoot.name = "__ulsdk_ui_node_root__";
                  nodeRoot.zOrder = 40000;
                  let modulechecker = this;
                  class LayaStageToucher extends window["Laya"].Script {
                      onStageClick(e) {
                          if (ULConst.B_INNER_DEBUG)
                              ULLog.console.log("LayaStageToucher.onStageClick", e);
                          let x = e.stageX;
                          let y = e.stageY;
                          if (ULConst.B_INNER_DEBUG)
                              ULLog.console.log(x, y, Laya.stage.width, Laya.stage.height);
                          if (y > TOUCH_AREA_HEIGHT) {
                              modulechecker.onTouchSpecialArea(null);
                          }
                          else if (x <= TOUCH_AREA_WIDTH) {
                              modulechecker.onTouchSpecialArea("l");
                          }
                          else if (x >= Laya.stage.width - TOUCH_AREA_WIDTH) {
                              modulechecker.onTouchSpecialArea("r");
                          }
                          else {
                              modulechecker.onTouchSpecialArea(null);
                          }
                      }
                  }
                  nodeRoot.addComponent(LayaStageToucher);
                  ULTimer.callLoop(1, () => {
                      let nodeRoot = Laya.stage.getChildByName("__ulsdk_ui_node_root__");
                      if (nodeRoot) {
                          nodeRoot.pos(Laya.stage.width / 2, Laya.stage.height / 2);
                      }
                  });
              }
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("  nodeRoot", nodeRoot);
          }
      }
      _touchHandler_start(e) {
          e.preventSwallow = true;
          this.addCocosEvent(e);
      }
      _touchHandler_other(e) {
          e.preventSwallow = true;
      }
      refreshDebugInfo() {
          let length = ULTools.getObjSize(this.debugInfos);
          if (length <= 0) {
              this.panel && this.panel.refreshDebugInfo(null);
              return;
          }
          let arr = [];
          ULTools.forEachMap(this.debugInfos, (k, v) => {
              arr.push(v);
          });
          let text = arr.join("\n");
          this.getOrCreatePanel();
          this.panel && this.panel.refreshDebugInfo(text);
      }
      onTouchSpecialArea(id) {
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager.onTouchSpecialArea", id);
          let touchGap = ULTools.time() - this.lastInputTime;
          if (touchGap >= TOUCH_GAP) {
              if (this.inputCode) {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("ULModuleCheckerManager inputCode: touch gap is too long time, cancel.");
                  this.inputCode = "";
              }
          }
          if (!id) {
              if (this.inputCode) {
                  if (ULConst.B_INNER_DEBUG)
                      ULLog.console.log("ULModuleCheckerManager inputCode: touch invalid area, cancel.");
                  this.inputCode = "";
              }
              return;
          }
          this.inputCode += id;
          this.lastInputTime = ULTools.time();
          if (ULConst.B_INNER_DEBUG)
              ULLog.console.log("ULModuleCheckerManager inputCode:", this.inputCode);
          if (this.inputCode == RIGHT_CODE) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("RIGHT_CODE  right!");
              this.inputCode = "";
              let config = this.moreGameAbTestConfig() || [];
              config = config.concat(this.collectionConfig());
              this.showPanel(config);
          }
          else if (this.inputCode == TAG_CODE) {
              if (ULConst.B_INNER_DEBUG)
                  ULLog.console.log("TAG_CODE  right!");
              this.inputCode = "";
              let config = ULConfig.getConfig();
              this.showCompanyMark(ULBase64.decode(config.s_sdk_common_copyright_str || ""));
          }
      }
      collectionConfig() {
          let config = ULEventDispatcher.getInstance().dispatchWithReturn(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, {});
          return config;
      }
      moreGameAbTestConfig() {
          let config = ULEventDispatcher.getInstance().dispatchWithReturn(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_MORE_GAME_AB_TEST_CONFIG, {});
          return config;
      }
  }

  const headImgExt = ".head";
  let _cc$2 = window["cc"];
  class ULAdapteCreator2x {
      registerHeadImgLoader() {
          let func = _cc$2.loader.load.bind(_cc$2.loader);
          _cc$2.loader.load = (resources, progressCallback, completeCallback) => {
              if (typeof resources === 'object') {
                  var object = resources;
                  if (object.type && object.type == headImgExt && object.url && object.url.length > 0) {
                      let img = this.downloadDomImage(object.url, null, (err, img) => {
                          if (err) {
                              completeCallback && completeCallback(err, null);
                              return;
                          }
                          let out = new _cc$2.Texture2D();
                          out.initWithElement(img);
                          out.handleLoadedTexture();
                          completeCallback && completeCallback(null, out);
                      });
                      return;
                  }
              }
              func(resources, progressCallback, completeCallback);
          };
      }
      downloadDomImage(url, options, onComplete) {
          const img = new Image();
          if (window.location.protocol !== 'file:') {
              img.crossOrigin = 'anonymous';
          }
          function loadCallback() {
              img.removeEventListener('load', loadCallback);
              img.removeEventListener('error', errorCallback);
              if (onComplete) {
                  onComplete(null, img);
              }
          }
          function errorCallback(e) {
              img.removeEventListener('load', loadCallback);
              img.removeEventListener('error', errorCallback);
              if (onComplete) {
                  console.log(e);
                  onComplete(new Error(url));
              }
          }
          img.addEventListener('load', loadCallback);
          img.addEventListener('error', errorCallback);
          img.src = url;
          return img;
      }
      startAdapter() {
      }
  }

  const headImgExt$1 = ".head";
  let _cc$3 = window["cc"];
  class MCPanelCreator3x$1 {
      registerHeadImgLoader() {
          _cc$3.assetManager.downloader.register(headImgExt$1, (content, options, onComplete) => {
              onComplete(null, content);
          });
          _cc$3.assetManager.parser.register(headImgExt$1, this.downloadDomImage);
          function createTexture(id, data, options, onComplete) {
              let out = null, err = null;
              try {
                  out = new _cc$3.Texture2D();
                  let imageAsset = new _cc$3.ImageAsset();
                  imageAsset.reset(data);
                  out.image = imageAsset;
                  console.log("ULAdapteCreator3x.createTexture id:", id);
                  console.log("ULAdapteCreator3x.createTexture data:", data);
                  console.log("ULAdapteCreator3x.createTexture out:", out);
              }
              catch (e) {
                  err = e;
              }
              onComplete && onComplete(err, out);
          }
          _cc$3.assetManager.factory.register(headImgExt$1, createTexture);
      }
      downloadDomImage(url, options, onComplete) {
          console.log("ULAdapteCreator3x.downloadDomImage url:", url);
          const img = new Image();
          if (window.location.protocol !== 'file:') {
              img.crossOrigin = 'anonymous';
          }
          function loadCallback() {
              console.log("ULAdapteCreator3x.loadCallback");
              img.removeEventListener('load', loadCallback);
              img.removeEventListener('error', errorCallback);
              if (onComplete) {
                  onComplete(null, img);
              }
          }
          function errorCallback() {
              console.log("ULAdapteCreator3x.errorCallback");
              img.removeEventListener('load', loadCallback);
              img.removeEventListener('error', errorCallback);
              if (onComplete) {
                  onComplete(new Error(url));
              }
          }
          img.addEventListener('load', loadCallback);
          img.addEventListener('error', errorCallback);
          img.src = url;
          return img;
      }
      startAdapter() {
          this.registerHeadImgLoader();
      }
  }

  class ULAdapteLaya {
      startAdapter() {
      }
  }

  class ULModuleAdapter {
      constructor() {
          this._panel = null;
      }
      get panel() {
          if (!this._panel) {
              if (window["cc"] && window["cc"].Node) {
                  if (ULTools.isCreator3xEngine()) {
                      this._panel = new MCPanelCreator3x$1();
                  }
                  else {
                      this._panel = new ULAdapteCreator2x();
                  }
              }
              else if (window["Laya"]) {
                  this._panel = new ULAdapteLaya();
              }
              else {
                  ULLog.console.warn("ULModuleAdapter.getPanel unknown platform!");
              }
          }
          return this._panel;
      }
      init() {
          ULLog.console.log("ULModuleAdapter.init");
          this.panel && this.panel.startAdapter();
      }
  }

  class ULSdkManager {
      constructor() {
          this.responseCallback = null;
          this.bChannelInfoResultResponsed = false;
          this.bAllowStartGame = false;
          this.waits = null;
          this.version = "0.1";
          this.modules = [];
          this.waits = new ULWaitTool();
          this.channelInfo = new ULChannelInfo();
          this.copManager = new ULCopManager();
          this.advManager = new ULAdvManager();
          this.statisManager = new ULStatisManager();
          this.moduleAdapter = new ULModuleAdapter();
          this.moduleCheckerManager = new ULModuleCheckerManager();
          this.bChannelInfoResultResponsed = false;
          this.responsePending = [];
          this.sdkCommunicationLog = [];
          ULTools._hack_console_print_method();
          ULTools._start_console_print_LAN();
      }
      static getInstance() {
          if (!this._instance) {
              this._instance = new ULSdkManager();
          }
          return this._instance;
      }
      initUlsdk(respone) {
          ULLog.console.log("ULSdkManger.init");
          this.responseCallback = respone;
          this.modules = ULSdkModuleLoader.initAllModules();
          ULTools._start_console_print_LAN();
          this.monitorAllowStartGame();
          this.advManager.init();
          this.statisManager.init();
          this.moduleAdapter.init();
          this.copManager.init();
          this.moduleCheckerManager.init();
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_GET_BASE_CHANNEL_INFO, ULConst.PRIORITY_NONE, this.onCmdGetBaseChannelInfo.bind(this));
          ULEventDispatcher.getInstance().addListener(ULConst.CMD_SET_VERSION, ULConst.PRIORITY_NONE, this.onCmdSetVersion.bind(this));
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_INIT_USER_LOGIN, {});
          ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_START, {});
          if (window["cc"] && window["cc"]["game"] && window["cc"]["game"]["on"] instanceof Function) {
              ULLog.console.log("register cocos EVENT_SHOW & EVENT_HIDE");
              if (ULTools.isCreator3xEngine()) {
                  window["cc"]["game"]["on"](window["cc"]["Game"]["EVENT_SHOW"], () => {
                      ULLog.console.log("ULSdkManager on EVENT_SHOW");
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_RESUME, {});
                  });
                  window["cc"]["game"]["on"](window["cc"]["Game"]["EVENT_HIDE"], () => {
                      ULLog.console.log("ULSdkManager on CC_EVENT_HIDE");
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_PAUSE, {});
                  });
              }
              else {
                  window["cc"]["game"]["on"](window["cc"]["game"]["EVENT_SHOW"], () => {
                      ULLog.console.log("ULSdkManager on EVENT_SHOW");
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_RESUME, {});
                  });
                  window["cc"]["game"]["on"](window["cc"]["game"]["EVENT_HIDE"], () => {
                      ULLog.console.log("ULSdkManager on CC_EVENT_HIDE");
                      ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_PAUSE, {});
                  });
              }
          }
          else if (window["Laya"]) {
              this._register_laya_life_cycle_listener();
          }
      }
      _register_laya_life_cycle_listener() {
          var win = window, hiddenPropName;
          if (typeof document.hidden !== 'undefined') {
              hiddenPropName = "hidden";
          }
          else if (typeof document["mozHidden"] !== 'undefined') {
              hiddenPropName = "mozHidden";
          }
          else if (typeof document["msHidden"] !== 'undefined') {
              hiddenPropName = "msHidden";
          }
          else if (typeof document["webkitHidden"] !== 'undefined') {
              hiddenPropName = "webkitHidden";
          }
          var hidden = false;
          function onHidden() {
              ULLog.console.log("Laya.onHidden");
              if (!hidden) {
                  hidden = true;
                  ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_PAUSE, {});
              }
          }
          function onShown() {
              ULLog.console.log("Laya.onShown");
              if (hidden) {
                  hidden = false;
                  ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_ON_GAME_RESUME, {});
              }
          }
          if (hiddenPropName) {
              var changeList = [
                  "visibilitychange",
                  "mozvisibilitychange",
                  "msvisibilitychange",
                  "webkitvisibilitychange",
                  "qbrowserVisibilityChange"
              ];
              for (var i = 0; i < changeList.length; i++) {
                  document.addEventListener(changeList[i], function (event) {
                      var visible = document[hiddenPropName];
                      visible = visible || event["hidden"];
                      if (visible)
                          onHidden();
                      else
                          onShown();
                  });
              }
          }
          else {
              win.addEventListener("blur", onHidden);
              win.addEventListener("focus", onShown);
          }
          if (navigator && navigator.userAgent && navigator.userAgent.indexOf("MicroMessenger") > -1) {
              win.onfocus = onShown;
          }
          if (window["wx"]) {
              window["wx"].onShow && window["wx"].onShow(onShown);
              window["wx"].onHide && window["wx"].onHide(onHidden);
          }
          if (window["qg"]) {
              window["qg"].onShow && window["qg"].onShow(onShown);
              window["qg"].onHide && window["qg"].onHide(onHidden);
          }
          let huaweType = "hbs";
          if (window[huaweType]) {
              window[huaweType].onShow && window[huaweType].onShow(onShown);
              window[huaweType].onHide && window[huaweType].onHide(onHidden);
          }
          if (window["ks"]) {
              window["ks"].onShow && window["ks"].onShow(onShown);
              window["ks"].onHide && window["ks"].onHide(onHidden);
          }
          if ("onpageshow" in window && "onpagehide" in window) {
              win.addEventListener("pagehide", onHidden);
              win.addEventListener("pageshow", onShown);
              document.addEventListener("pagehide", onHidden);
              document.addEventListener("pageshow", onShown);
          }
      }
      onRequest(jsonStr) {
          let requestData = null;
          this.recordSdkCommunicationLog(jsonStr);
          try {
              requestData = JSON.parse(jsonStr);
          }
          catch (error) {
              ULLog.console.error(error);
          }
          if (!requestData) {
              ULLog.console.error("请仔细阅读文档,消息必须为json字符串类型");
              return;
          }
          let cmd = requestData.cmd;
          let data = requestData.data || {};
          if (!cmd) {
              ULLog.console.error("cmd为空,请检查是否按照文档规范配置消息");
              return;
          }
          ULLog.console.log("ULSdkManager.onRequest", cmd, data);
          switch (cmd) {
              default: {
                  let bCalled = ULEventDispatcher.getInstance().dispatch(cmd, data);
                  if (!bCalled) {
                      ULLog.console.warn(ULTools.format("未检测到[%s]监听器", cmd));
                  }
                  break;
              }
          }
      }
      response(cmd, data, bIgnorePending) {
          ULLog.console.log("ULSdkManager.response", cmd, data);
          if (!this.bChannelInfoResultResponsed && !bIgnorePending) {
              ULLog.console.log("  尚未发送/c/channelInfoResult，暂存消息");
              this.responsePending.push({ cmd: cmd, data: data });
              return;
          }
          let jsonStr = JSON.stringify({
              cmd: cmd,
              data: data,
          });
          if (this.responseCallback) {
              this.responseCallback(jsonStr);
          }
          this.recordSdkCommunicationLog(jsonStr);
      }
      uploadMegadata(data) {
          let singleField = data.join("_");
          this.statisManager.reportUserEvent(["commonEvent", singleField]);
      }
      isAllowStartGame() {
          ULLog.console.log("ULSdkManager.isAllowStartGame", this.bAllowStartGame);
          return this.bAllowStartGame;
      }
      getModuleByName(name) {
          for (let i = 0; i < this.modules.length; i++) {
              const module = this.modules[i];
              if (module["name"] == name) {
                  return module;
              }
          }
          return null;
      }
      getSdkCommunicationLog() {
          return this.sdkCommunicationLog;
      }
      recordSdkCommunicationLog(log) {
          if (!this.sdkCommunicationLog)
              return;
          if (this.sdkCommunicationLog.length >= 100) {
              this.sdkCommunicationLog.splice(0, 1);
          }
          this.sdkCommunicationLog.push(log);
      }
      _doResponseChannelInfoResult() {
          this.bChannelInfoResultResponsed = true;
          this.response(ULConst.CMD_CHANNEL_INFO_RESULT, this.channelInfo.toResponseData());
          for (let i = 0; i < this.responsePending.length; i++) {
              const v = this.responsePending[i];
              this.response(v.cmd, v.data);
          }
          this.responsePending = [];
          if (this.channelInfo.isSupportLaunchReward) {
              ULEventDispatcher.getInstance().dispatch(ULConst.CMD_CHECK_LAUNCH_REWARD, {});
          }
      }
      onCmdGetBaseChannelInfo(e) {
          this.response(ULConst.CMD_GET_BASE_CHANNEL_INFO_RESULT, this.channelInfo.toBaseChannelInfoData(), true);
      }
      onCmdSetVersion(e) {
          let data = e.data;
          e.stopImmediatePropagation();
          if (this.channelInfo.isReady()) {
              this._doResponseChannelInfoResult();
              return;
          }
          ULLog.console.log("ULSdkManager.onEventSetVersion channelInfo准备中，开启timer进行监听");
          let timeout = ULConfig.getConfig().i_channel_info_timeout / 1000;
          ULTimer.callLoop(1 / 60, (timer) => {
              if (timer.usedTime >= timeout) {
                  timer.stop();
                  let flags = this.channelInfo.getPreparationFlags();
                  ULLog.console.log("等待channelInfo超时！直接触发channelInfoResult。flags:", flags.join(","));
                  this._doResponseChannelInfoResult();
                  return;
              }
              if (this.channelInfo.isReady()) {
                  timer.stop();
                  ULLog.console.log("channelInfo准备完毕！触发channelInfoResult");
                  this._doResponseChannelInfoResult();
                  return;
              }
          });
      }
      monitorAllowStartGame() {
          ULLog.console.log("ULSdkManager.monitorAllowStartGame isAllowStartGame准备中，开启timer进行监听");
          ULTimer.callLoop(1, (timer) => {
              if (this.waits.ok()) {
                  timer.stop();
                  this.bAllowStartGame = true;
                  return;
              }
          });
      }
  }
  ULSdkManager._instance = null;

  class ULSdkMiddleware {
      static initUlsdk() {
          if (ULSdkManager) {
              try {
                  ULSdkManager.getInstance().initUlsdk(this.onResponse);
                  return true;
              }
              catch (error) {
                  ULLog.console.error("ULSdkManager.initUlsdk err");
                  ULLog.console.error(error.stack);
                  return false;
              }
          }
          else {
              ULLog.console.log("ULSdkMiddleware.initUlsdk ULSdkManager not found!");
              return;
          }
      }
      static request(jsonStr) {
          if (ULSdkManager) {
              try {
                  ULSdkManager.getInstance().onRequest(jsonStr);
                  return true;
              }
              catch (error) {
                  ULLog.console.error("ULSdkManager.initUlsdk request");
                  ULLog.console.error(error.stack);
                  return false;
              }
          }
          else {
              ULLog.console.log("ULSdkMiddleware.request ULSdkManager not found!");
              return false;
          }
      }
      static isAllowStartGame() {
          if (ULSdkManager) {
              return ULSdkManager.getInstance().isAllowStartGame();
          }
          else {
              ULLog.console.log("ULSdkMiddleware.isAllowStartGame ULSdkManager not found!");
              return true;
          }
      }
      static registerOnResponseCallback(callback) {
          this.fOnResponseCallback = callback;
      }
      static onResponse(jsonStr) {
          if (ULSdkMiddleware.fOnResponseCallback instanceof Function ||
              typeof ULSdkMiddleware.fOnResponseCallback == 'function') {
              ULSdkMiddleware.fOnResponseCallback(jsonStr);
          }
      }
  }
  ULSdkMiddleware.fOnResponseCallback = null;
  window["ULSdkMiddleware"] = ULSdkMiddleware;

  class ULNativeControllerHtml5 {
      static init(fOnGameCallback) {
          if (!this.isEnabled(true)) {
              console.warn("ULNativeControllerHtml5.init !isEnabled()");
              return;
          }
          this.fOnGameCallback = fOnGameCallback;
          ULSdkMiddleware.registerOnResponseCallback((jsonStr) => {
              this.sendMsgToGame(jsonStr);
          });
      }
      static isEnabled(bLog) {
          if (bLog) {
              try {
                  console.log("ULNativeControllerHtml5.isEnabled");
                  console.log("  wx", window["wx"]);
                  console.log("  qq", window["qq"]);
                  console.log("  tt", window["tt"]);
                  console.log("  swan", window["swan"]);
                  console.log("  hbs", window["hbs"]);
                  console.log("  qg", window["qg"]);
                  console.log("  my", window["my"]);
                  console.log("  document", document);
                  console.log("  weibo", window["loadRuntime"]);
                  console.log("  cc.sys.isBrowser", window["cc"] && window["cc"].sys && window["cc"].sys.isBrowser);
                  console.log("  laya conch", window["Laya"] && window["conch"]);
              }
              catch (error) {
                  console.log(error);
              }
          }
          if (window && window["Laya"] && !window["conch"])
              return true;
          if (window && window["wx"])
              return true;
          if (window && window["qq"])
              return true;
          if (window && window["tt"])
              return true;
          if (window && window["swan"])
              return true;
          if (window && window["hbs"])
              return true;
          if (window && window["qg"])
              return true;
          if (window && window["my"])
              return true;
          if (window && window["loadRuntime"])
              return true;
          if (window["cc"] && window["cc"].sys && window["cc"].sys.isBrowser)
              return true;
          return false;
      }
      static initUlsdk() {
          let bSuccess = ULSdkMiddleware.initUlsdk();
          return JSON.stringify({ ret: bSuccess });
      }
      static sendMsgToSdk(jsonStr) {
          let bSuccess = ULSdkMiddleware.request(jsonStr);
          return JSON.stringify({ ret: bSuccess });
      }
      static sendMsgToGame(jsonStr) {
          if (this.fOnGameCallback instanceof Function) {
              this.fOnGameCallback(jsonStr);
          }
          if (this.mCallback) {
              this.mCallback(jsonStr);
          }
      }
      static isAllowStartGame() {
          return ULSdkMiddleware.isAllowStartGame();
      }
      static initSdk(callback) {
          if (!callback || !(callback instanceof Function)) {
              console.error("initSdk error: callback must be a Function");
              return;
          }
          this.mCallback = callback;
          ULSdkMiddleware.registerOnResponseCallback((jsonStr) => {
              this.sendMsgToGame(jsonStr);
          });
          ULSdkMiddleware.initUlsdk();
      }
      static InitSdk(id) {
          console.log("ulsdk-InitSdk:" + id);
          ULSdkMiddleware.registerOnResponseCallback((jsonStr) => {
              let requestResult = {
                  callbackId: id,
                  type: "response",
                  res: JSON.stringify({
                      response: jsonStr
                  })
              };
              this.SendMsgToGame(JSON.stringify(requestResult), "InitCallback");
          });
          ULSdkMiddleware.initUlsdk();
          let timer = setInterval(() => {
              if (ULSdkMiddleware.isAllowStartGame()) {
                  let initResult = {
                      callbackId: id,
                      type: "init",
                      res: JSON.stringify({
                          bSuccess: true
                      })
                  };
                  this.SendMsgToGame(JSON.stringify(initResult), "InitCallback");
                  clearInterval(timer);
              }
          }, 100);
      }
      static SendMsgToSdk(jsonStr) {
          console.log("ulsdk-sendMsgToSdk:" + jsonStr);
          ULSdkMiddleware.request(jsonStr);
      }
      static SendMsgToGame(msg, method, className = "ULSdkHandler") {
          console.log("ulsdk-sendMsgToGame:" + msg);
          if (window['unityInstance']) {
              window['unityInstance'].SendMessage(className, method, msg);
          }
          else {
              if (window['wx']) {
                  window['GameGlobal'].manager.gameInstance.Module.SendMessage(className, method, msg);
              }
              else {
                  console.error("Js SendMessage To C# failed!");
              }
          }
      }
      static ReadFile(param, id) {
      }
      static WriteFile(file, data) {
      }
      static DeleteFile(file) {
      }
  }
  ULNativeControllerHtml5.fOnGameCallback = null;
  window['ULSDK'] = ULNativeControllerHtml5;

  const JAVA_FILE_PATH = "demo/ULNativeController";
  const JAVA_PARAMS_RETURN = "(Ljava/lang/String;)Ljava/lang/String;";
  const JAVA_CALLBACK_NAME = "JAVACALLBACK";
  const OC_FILE_NAME = "ULNativeController";
  const OC_CALLBACK_NAME = "OCCALLBACK";
  function JAVACALLBACK(base64JsonStr) {
      console.log("on JAVACALLBACK", base64JsonStr);
      try {
          let jsonStr = Base64.decode(base64JsonStr);
          mgrNative._onNativeCallbackJava(jsonStr);
      }
      catch (error) {
          console.warn("JAVACALLBACK decode base64 faild! direct use base64JsonStr");
          mgrNative._onNativeCallbackJava(base64JsonStr);
      }
  }
  function OCCALLBACK(base64JsonStr) {
      console.log("on OCCALLBACK", base64JsonStr);
      try {
          let jsonStr = Base64.decode(base64JsonStr);
          mgrNative._onNativeCallbackObjc(jsonStr);
      }
      catch (error) {
          console.warn("OCCALLBACK decode base64 faild! direct use base64JsonStr");
          mgrNative._onNativeCallbackObjc(base64JsonStr);
      }
  }
  function ONHTML5CALLBACK(jsonStr) {
      console.log("on ONHTML5CALLBACK", jsonStr);
      mgrNative._onNativeCallbackHtml5(jsonStr);
  }
  class mgrNative {
      static onLoad() {
          window[JAVA_CALLBACK_NAME] = JAVACALLBACK;
          window[OC_CALLBACK_NAME] = OCCALLBACK;
          if (window[`conch`]) {
              this._js2JavaBridge = window[`PlatformClass`].createClass(JAVA_FILE_PATH);
              this._js2OCBridge = window[`PlatformClass`].createClass(OC_FILE_NAME);
          }
          this.nativeCallbackPending = [];
          if (!this.bRegisterNativeCallback) {
              this.bRegisterNativeCallback = true;
              this.registerNativeCallback();
          }
          Timer.callLoop(1 / 60, this.onTimer.bind(this), true);
      }
      static onTimer() {
          let pending = this.nativeCallbackPending;
          while (pending.length > 0) {
              let responseData = pending.shift();
              if (this.m_receeveFromSdk) {
                  this.m_receeveFromSdk(responseData);
              }
          }
      }
      static registerNativeCallback() {
          if (ULNativeControllerHtml5.isEnabled()) {
              this._registernativeCallbackHtml5();
          }
          else if (Laya.Browser.onAndroid) {
              this._registerNativeCallbackJava();
          }
          else if (Laya.Browser.onIOS) {
              this._registerNativeCallbackObjc();
          }
          else {
              console.warn(`[warn] mgrNative.registerNativeCallback, platform = ${Laya.Browser}, don't have native controller`);
          }
      }
      static isHtml5Platform() {
          return ULNativeControllerHtml5.isEnabled();
      }
      static onNativeCallback(data) {
          if (data) {
              this.nativeCallbackPending.push(data);
          }
      }
      static _registerNativeCallbackJava() {
          this._js2JavaBridge.call("setCallFuncName", JAVA_CALLBACK_NAME);
      }
      static _registerNativeCallbackObjc() {
          this._callNativeObjc("setCallbackName", { callbackName: OC_CALLBACK_NAME });
      }
      static _registernativeCallbackHtml5() {
          ULNativeControllerHtml5.init(ONHTML5CALLBACK);
          this._callNativeHtml5("initUlsdk", null);
      }
      static _onNativeCallbackJava(jsonStr) {
          let data = {};
          try {
              data = JSON.parse(jsonStr || "");
          }
          catch (error) {
              console.warn("mgrNative._onNativeCallbackJava jsonStr error!");
              data["text"] = jsonStr;
          }
          this.onNativeCallback(data);
      }
      static _onNativeCallbackObjc(jsonStr) {
          let data = {};
          try {
              data = JSON.parse(jsonStr || "");
          }
          catch (error) {
              console.warn("mgrNative._onNativeCallbackObjc jsonStr error!");
              data["text"] = jsonStr;
          }
          this.onNativeCallback(data);
      }
      static _onNativeCallbackHtml5(jsonStr) {
          let data = {};
          try {
              data = JSON.parse(jsonStr || "");
          }
          catch (error) {
              console.warn("mgrNative._onNativeCallbackJs jsonStr error!");
              data["text"] = jsonStr;
          }
          this.onNativeCallback(data);
      }
      static isAllowStartGame() {
          if (ULNativeControllerHtml5.isEnabled()) {
              return ULNativeControllerHtml5.isAllowStartGame();
          }
          else {
              return true;
          }
      }
      static callNative(cmd, dataTable) {
          dataTable = dataTable || {};
          if (ULNativeControllerHtml5.isEnabled()) {
              return this._callNativeHtml5(cmd, dataTable);
          }
          else if (Laya.Browser.onAndroid) {
              return this._callNativeJava(cmd, dataTable);
          }
          else if (Laya.Browser.onIOS) {
              return this._callNativeObjc(cmd, dataTable);
          }
          else {
              console.warn(`[warn] mgrNative.callNative, platform = ${Laya.Browser}, don't have native controller`);
              return null;
          }
      }
      static _callNativeJava(cmd, dataTable) {
          console.log(`-->: js: 调用本地${cmd}: ${JSON.stringify(dataTable)}`);
          try {
              let jsonStr = JSON.stringify(dataTable);
              let retJson = this._js2JavaBridge.call(cmd, jsonStr);
              let retData = JSON.parse(retJson);
              return retData;
          }
          catch (error) {
              console.warn("mgrNative._onNativeCallbackJava jsonStr error!");
              return { error: error };
          }
      }
      static _callNativeObjc(cmd, dataTable) {
          try {
              let jsonStr = JSON.stringify(dataTable);
              let retJson = this._js2OCBridge.call(cmd + ":", jsonStr);
              let retData = JSON.parse(retJson);
              return retData;
          }
          catch (error) {
              console.warn("mgrNative._callNativeObjc jsonStr error!");
              console.log(error);
              return { error: error };
          }
      }
      static _callNativeHtml5(cmd, dataTable) {
          try {
              let jsonStr = JSON.stringify(dataTable);
              let retJson = ULNativeControllerHtml5[cmd](jsonStr);
              let retData = JSON.parse(retJson);
              return retData;
          }
          catch (error) {
              console.warn("mgrNative._callNativeHtml5 jsonStr error!");
              return { error: error };
          }
      }
      static setReceiver(callback) {
          this.m_receeveFromSdk = callback;
      }
  }
  mgrNative.nativeCallbackPending = null;
  mgrNative.bRegisterNativeCallback = false;

  class SDKBridge {
      static init() {
          if (this.bInited)
              return;
          this.bInited = true;
          mgrNative.onLoad();
          mgrNative.setReceiver(this.recieveFromSdk.bind(this));
          mgrNative.callNative("initULSDK", {});
          this.m_msgSender = function (data) {
              mgrNative.callNative("sendMsgToSdk", data);
          };
      }
      static registerCmd(cmd, callback) {
          if (this.m_callbacks.hasOwnProperty(cmd)) {
              console.warn("the cmd has registed:", cmd);
          }
          this.m_callbacks[cmd] = callback;
      }
      static sendToSdk(cmd, data) {
          let jsonObj = {
              cmd: cmd,
              data: data,
          };
          this.m_msgSender(jsonObj);
      }
      static recieveFromSdk(data) {
          let cmd = data.cmd;
          let userData = data.data;
          if (this.m_callbacks[cmd]) {
              this.m_callbacks[cmd](userData);
          }
          else {
              console.warn(`SDKBridge.recieveFromSdk can't find callback with cmd: ${cmd}`);
          }
      }
  }
  SDKBridge.m_msgSender = function (data) { };
  SDKBridge.m_callbacks = {};
  SDKBridge.bInited = false;

  const RECORD_DATA_KEY = "record_game" + Global.GAME_ID;
  const RECORD_AGE_KEY = "__age__";
  const RECORD_VERSION_KEY = "__version__";
  const RECORD_FILES_KEY = "__files__";
  class FileRecord {
      static init() {
          switch (Global.SDK_VERSION) {
              case SDK_VERSIONS_VALUE.V6:
                  SDKBridge.registerCmd('/c/getUserCloudStorageResult', this.onGetUserCloudStorageResult.bind(this));
                  SDKBridge.registerCmd('/c/setUserCloudStorageResult', this.onSetUserCloudStorageResult.bind(this));
          }
          this._readRecord();
          this.userId = this.getData("game166_user_id_v1.0") || "";
          Timer.callLoop(1, this._onTimerSpan.bind(this), true);
      }
      static _onTimerSpan(timer) {
          if (this.writeEnable && this.bNeedFlush) {
              this.bNeedFlush = false;
              this._writeRecord();
          }
      }
      static _readRecord(recordText) {
          if (!recordText) {
              recordText = Laya.LocalStorage.getItem(RECORD_DATA_KEY);
          }
          if (!recordText) {
              console.log("提示] FileRecord._readRecord 存档未找到！重置存档！");
              this.resetRecord();
              return;
          }
          let record = this._decodeData(recordText);
          if (!record) {
              console.warn("警告] FileRecord._readRecord 存档数据损坏！重置存档！");
              this.resetRecord();
              return;
          }
          if (record[RECORD_VERSION_KEY] != Global.RECORD_VERSION) {
              console.warn("警告] FileRecord._readRecord 存档版本改变！重置存档！");
              this.resetRecord();
              return;
          }
          this.record = record;
      }
      static _writeRecord() {
          let encodeText = this._encodeData(this.record);
          Laya.LocalStorage.setItem(RECORD_DATA_KEY, encodeText);
          this.sendCloudRecord(encodeText);
      }
      static markFlush() {
          this.bNeedFlush = true;
      }
      static flush() {
          this._writeRecord();
          this.bNeedFlush = false;
      }
      static _encodeData(data) {
          let jsonStr = JSON.stringify(data);
          if (this.compressEnable) {
              let compressStr = Tools.compress(jsonStr);
              let encodeStr = Base64.encode(compressStr);
              return encodeStr;
          }
          else {
              return jsonStr;
          }
      }
      static _decodeData(encodeStr) {
          try {
              if (this.compressEnable) {
                  let compressStr = Base64.decode(encodeStr);
                  let jsonStr = Tools.decompress(compressStr);
                  if (jsonStr) {
                      let data = JSON.parse(jsonStr);
                      return data;
                  }
                  else {
                      return null;
                  }
              }
              else {
                  return JSON.parse(encodeStr);
              }
          }
          catch (error) {
              Logger.catchError("FileRecord._decodeData", error);
          }
          return null;
      }
      static getData(key) {
          return this.record[key];
      }
      static setData(key, value) {
          this.record[key] = value;
          this.record[RECORD_AGE_KEY] = (this.record[RECORD_AGE_KEY] || 0) + 1;
          this.markFlush();
      }
      static resetRecord() {
          this.deletFileData();
          this.record = {};
          this.record[RECORD_AGE_KEY] = 0;
          this.record[RECORD_VERSION_KEY] = Global.RECORD_VERSION;
          this.record[RECORD_FILES_KEY] = {};
          this.markFlush();
          this.isNewRecord = true;
      }
      static deletAllData(clear = true) {
          this.deletFileData();
          if (clear) {
              this.record = {};
              this.record[RECORD_AGE_KEY] = 0;
          }
          this.record[RECORD_VERSION_KEY] = Global.RECORD_VERSION + 123698745;
          this.record[RECORD_FILES_KEY] = {};
          Laya.LocalStorage.removeItem(RECORD_DATA_KEY);
      }
      static deletFileData() {
          let record = this.record;
          if (record) {
              let files = record[RECORD_FILES_KEY];
              if (files) {
                  for (const file in files) {
                      Laya.LocalStorage.removeItem(file);
                  }
              }
          }
      }
      static setDataToFile(file, value, bEncode = true) {
          let files = this.getData(RECORD_FILES_KEY);
          files[file] = 1;
          this.setData(RECORD_FILES_KEY, files);
          Laya.LocalStorage.setItem(file, bEncode ? this._encodeData(value) : value);
      }
      static getDataFromFile(file, bDecode = true) {
          let dataStr = Laya.LocalStorage.getItem(file);
          if (dataStr) {
              return bDecode ? this._decodeData(dataStr) : dataStr;
          }
          else {
              return null;
          }
      }
      static getUserId() {
          return this.userId;
      }
      static setUserId(userId) {
          this.userId = userId;
          this.setData("game166_user_id_v1.0", userId);
      }
      static sendCloudRecord(storage, bImmediately = false, msg = "") {
          try {
              if (!storage) {
                  storage = this._encodeData(this.record);
              }
              this.requestSetCloudStorage(storage, bImmediately, msg);
          }
          catch (error) {
          }
      }
      static receiveCloudRecord(str, callback) {
          if (str.length == 0) {
              callback();
              return;
          }
          try {
              let data = this._decodeData(str);
              this.record[RECORD_FILES_KEY] = {};
              let cloudVersion = data[RECORD_VERSION_KEY];
              let curVersion = this.record[RECORD_VERSION_KEY];
              if (cloudVersion != curVersion) {
                  console.warn("警告] 服务存档与本地存档版本不一致，直接使用本地存档");
                  this.record = this.record;
                  callback();
                  return;
              }
              let cloudAge = data[RECORD_AGE_KEY] || 0;
              let curAge = this.record[RECORD_AGE_KEY] || 0;
              if (cloudAge == curAge || curAge == 0) {
                  this.record = data;
                  callback();
              }
              else {
                  mgrTip.alertPrompt("云存档与本地存档冲突!请谨慎选择使用哪一个存档!\n\n注意:同一个账号只会存在一个云存档!", "云存档冲突", () => {
                      this.record = data;
                      callback();
                  }, () => {
                      this.record = this.record;
                      callback();
                  }, "用云存档", "用本地存档");
              }
          }
          catch (error) {
              callback();
          }
      }
      static forceCoverRecord(record) {
          this.record = this._decodeData(record);
          this.flush();
      }
      static requestGetCloudStorage() {
          if (db.cop_db.isSupportUserCloudStorage) {
              SDKBridge.sendToSdk("/c/getUserCloudStorage", {
                  userData: "",
              });
          }
          else {
              this.onGetUserCloudStorageResult({
                  code: 0,
              });
          }
      }
      static onGetUserCloudStorageResult(data) {
          if (data.code == 1) {
              Global.sendMsg("MSG_SDK_GET_USER_CLOUD_STORAGE_REAULT", {
                  bSuccess: true,
                  storage: data.data || "",
              });
          }
          else {
              Global.sendMsg("MSG_SDK_GET_USER_CLOUD_STORAGE_REAULT", {
                  bSuccess: false,
                  storage: data.data || "",
              });
          }
      }
      static requestSetCloudStorage(storage, bImmediately = false, userData = "") {
          if (db.cop_db.isSupportUserCloudStorage) {
              SDKBridge.sendToSdk("/c/setUserCloudStorage", {
                  userData: userData,
                  data: storage,
                  immediately: bImmediately ? 1 : 0,
              });
          }
          else {
              this.onSetUserCloudStorageResult({
                  code: 0,
                  userData: userData,
              });
          }
      }
      static onSetUserCloudStorageResult(data) {
          if (data.code == 1) {
              Global.sendMsg("MSG_SDK_SET_USER_CLOUD_STORAGE_REAULT", {
                  bSuccess: true,
                  msg: data.userData,
              });
          }
          else {
              Global.sendMsg("MSG_SDK_SET_USER_CLOUD_STORAGE_REAULT", {
                  bSuccess: false,
                  msg: data.userData,
              });
          }
      }
  }
  FileRecord.record = {};
  FileRecord.bNeedFlush = false;
  FileRecord.writeEnable = true;
  FileRecord.isNewRecord = false;
  FileRecord.compressEnable = false;

  const SOUND_TYPE_MUSIC = 1;
  const SOUND_TYPE_EFFECT = 2;
  let sound_url_map = Object.create(null);
  let WTF = "wtf";
  class mgrSound extends Manager {
      static get musicEnabled() {
          return this.musicOpen;
      }
      static set musicEnabled(value) {
          let bChanged = value != this.musicOpen;
          console.warn("mgrSound.setMusicEnabled", value);
          this.musicVolume = value ? 1 : 0;
          this.musicOpen = value;
          this.saveRecord();
          if (bChanged) {
              value ? this.resumeMusic() : this.pauseMusic();
          }
      }
      static get soundEnabled() {
          return this.soundOpen;
      }
      static set soundEnabled(value) {
          let bChanged = value != this.soundOpen;
          console.warn("mgrSound.setSoundEnabled", value);
          this.effectVolume = value ? 1 : 0;
          this.soundOpen = value;
          this.saveRecord();
          if (bChanged) {
              value ? this.resumeEffect() : this.pauseEffect();
          }
      }
      static onLoad() {
          Laya.SoundManager.autoStopMusic = true;
          super.onLoad();
      }
      static loadRecord() {
          let record = FileRecord.getData("sound") || {};
          this.musicVolume = record.musicVolume != null ? record.musicVolume : 1;
          this.effectVolume = record.effectVolume != null ? record.effectVolume : 1;
          this.musicOpen = record.musicOpen != null ? record.musicOpen : true;
          this.soundOpen = record.soundOpen != null ? record.soundOpen : true;
          let wx;
          if (window && window[`wx`] && window[`wx`].onShow && window[`wx`].onHide) {
              wx = window[`wx`];
          }
          if (window && window[`swan`] && window[`swan`].onShow && window[`swan`].onHide) {
              wx = window[`swan`];
          }
          if (wx) {
              console.log("=== 注册窗口消息, mgrsound ====");
              wx.onShow(() => {
                  Laya.SoundManager.musicMuted = true;
                  Laya.SoundManager.soundMuted = true;
                  Timer.callLater(0.1, () => {
                      Laya.SoundManager.musicMuted = false;
                      Laya.SoundManager.soundMuted = false;
                  });
              });
              wx.onHide(() => {
              });
          }
          this.setMusicVomue(this.musicVolume, true);
          this.setEffectVolume(this.effectVolume, true);
      }
      static saveRecord() {
          let record = {
              musicVolume: this.musicVolume,
              effectVolume: this.effectVolume,
              musicOpen: this.musicOpen,
              soundOpen: this.soundOpen,
          };
          FileRecord.setData("sound", record);
      }
      static isMusicPlaying() {
          return this.playingMusicSoundId != null;
      }
      static playMusic(soundId, loop = false) {
          this.lastPlayMusicSoundId = soundId;
          if (!this.musicOpen)
              return;
          Logger.log("play music:", soundId);
          this.play(soundId, true, loop);
      }
      static playSound(soundId, loop = false) {
          if (!this.soundOpen)
              return;
          this.play(soundId, false, loop);
      }
      static playTalk(soundId) {
          if (this._lastTalkId) {
              this.stopSound(this._lastTalkId);
          }
          this._lastTalkId = soundId;
          this.play(soundId, false, false);
      }
      static playSoundIfTimeout(soundId, soundGroup, deltaTime) {
          let lastTime = this._lastSoundPlayTime[soundGroup];
          if (lastTime && (Timer.time - lastTime < deltaTime)) {
              return;
          }
          this._lastSoundPlayTime[soundGroup] = Timer.time;
          this.playSound(soundId);
      }
      static play(soundId, bMusic, bLoop = false) {
          if (bMusic) {
              if (soundId == this.playingMusicSoundId)
                  return;
              this.playingMusicSoundId = soundId;
              var url = `res/audio/${soundId}.mp3`;
              let playMusic = () => {
                  Logger.debug(`开始播放音乐:${url} ${this.musicVolume}`);
                  Laya.SoundManager.playMusic(url, 0);
                  !Laya.SoundManager.musicMuted && (this.bPlayedMusic = true);
              };
              if (window.document && window.document[`__custom_web_platform_tag__`] && !window[`conch`]) {
                  ResLoader.loadRes(url, Laya.Loader.SOUND, (res) => {
                      playMusic();
                  });
              }
              else {
                  playMusic();
              }
          }
          else {
              let timeNow = Timer.time;
              let timeSnd = this.soundPlayTime[soundId] || (timeNow - this.effectCd * 2);
              let timePas = timeNow - timeSnd;
              if (timePas < this.effectCd)
                  return;
              this.soundPlayTime[soundId] = timeNow;
              if (this.bLoadingEffect)
                  return;
              var url = this.getUrl(soundId);
              let playEffect = () => {
                  this.bLoadingEffect = false;
                  Laya.SoundManager.playSound(url, bLoop ? 0 : 1);
              };
              if (window.document && window.document[`__custom_web_platform_tag__`] && !window[`conch`]) {
                  this.bLoadingEffect = true;
                  ResLoader.loadRes(url, Laya.Loader.SOUND, (res) => {
                      playEffect();
                  });
              }
              else {
                  playEffect();
              }
          }
      }
      static getUrl(soundId) {
          let url = sound_url_map[soundId];
          if (!url) {
              if (window[`conch`]) {
                  url = `res/audio/${soundId}.ogg`;
              }
              else {
                  url = `res/audio/${soundId}.mp3`;
              }
              sound_url_map[soundId] = url;
          }
          return url;
      }
      static stopAll() {
          this.playingMusicSoundId = null;
          Laya.SoundManager.stopAll();
      }
      static stopBgm() {
          this.playingMusicSoundId = null;
          Laya.SoundManager.stopMusic();
      }
      static stopSound(soundId) {
          Laya.SoundManager.stopSound(this.getUrl(soundId));
      }
      static stopSoundAll() {
          Laya.SoundManager.stopAllSound();
      }
      static pauseSound(router = WTF) {
          this.pauseMusic(router);
          this.pauseEffect(router);
      }
      static resumeSound(router = WTF) {
          this.resumeMusic(router);
          this.resumeEffect(router);
      }
      static pauseEffect(router = WTF) {
          console.info(`暂停音效:${router}`);
          let bPaused = this.pauseEffectRouters.length > 0;
          if (this.pauseEffectRouters.indexOf(router) == -1)
              this.pauseEffectRouters.push(router);
          if (bPaused)
              return;
          this.setEffectVolume(0);
      }
      static resumeEffect(router = WTF) {
          console.info(`恢复音效:${router}`);
          let index = this.pauseEffectRouters.indexOf(router);
          if (index >= 0)
              this.pauseEffectRouters.splice(index, 1);
          if (this.pauseEffectRouters.length > 0)
              return;
          this.setEffectVolume(1);
      }
      static pauseMusic(router = WTF) {
          console.info(`暂停背景音:${router} count:${this.pauseMusicRouters.length}`);
          let bPaused = this.pauseMusicRouters.length > 0;
          if (this.pauseMusicRouters.indexOf(router) == -1)
              this.pauseMusicRouters.push(router);
          if (bPaused)
              return;
          this.setMusicVomue(0);
      }
      static resumeMusic(router = WTF) {
          if (!this.musicEnabled)
              return;
          if (this.pauseMusicRouters.length <= 0) {
              console.warn("恢复声音，没有找到暂停的音乐，尝试恢复上次播放的");
              if (this.lastPlayMusicSoundId) {
                  this.playMusic(this.lastPlayMusicSoundId);
              }
          }
          console.info(`恢复背景音:${router} count:${this.pauseMusicRouters.length}`);
          let index = this.pauseMusicRouters.indexOf(router);
          if (index >= 0)
              this.pauseMusicRouters.splice(index, 1);
          if (this.pauseMusicRouters.length > 0)
              return;
          this.setMusicVomue(1);
      }
      static getMusicVolmue() {
          return this.musicVolume;
      }
      static setMusicVomue(musicVolume, bIgnoreSave) {
          this.musicVolume = musicVolume;
          if (musicVolume == 0) {
              Laya.SoundManager.setMusicVolume(0.0001);
          }
          else {
              Laya.SoundManager.setMusicVolume(musicVolume);
          }
          if (window[`swan`] || window[`__b_jkw_platform__`]) {
              if (musicVolume == 0) {
                  Laya.SoundManager.musicMuted = true;
              }
              else {
                  Laya.SoundManager.musicMuted = false;
                  if (!this.bPlayedMusic) {
                      let soundId = this.playingMusicSoundId;
                      this.playingMusicSoundId = null;
                      this.playMusic(soundId);
                  }
              }
          }
          this.saveRecord();
      }
      static getEffectVolume() {
          return this.effectVolume;
      }
      static setEffectVolume(effectVolume, bIgnoreSave) {
          this.effectVolume = effectVolume;
          if (effectVolume == 0) {
              Laya.SoundManager.setSoundVolume(0.001);
              Laya.SoundManager.soundMuted = true;
          }
          else {
              Laya.SoundManager.setSoundVolume(effectVolume);
              Laya.SoundManager.soundMuted = false;
          }
          this.saveRecord();
      }
  }
  mgrSound.lastPlayMusicSoundId = null;
  mgrSound.playingMusicSoundId = null;
  mgrSound.musicVolume = 1;
  mgrSound.effectVolume = 1;
  mgrSound.musicOpen = true;
  mgrSound.soundOpen = true;
  mgrSound.effectCd = 0.1;
  mgrSound.effectPlayStartTime = 0;
  mgrSound.pauseMusicRouters = [];
  mgrSound.pauseEffectRouters = [];
  mgrSound.bPlayedMusic = false;
  mgrSound.soundPlayTime = {};
  mgrSound._lastSoundPlayTime = Object.create(null);

  const test_data = {};
  class GameStatistics {
      static init() {
          this.onceEventId = FileRecord.getData("key_statistics") || {};
      }
      static saveData() {
          FileRecord.setData("key_statistics", this.onceEventId);
      }
      static postMegadata(data) {
          if (this.enable) {
              if (Laya.Browser.onPC && Global.H5_TEST) {
                  let key = data.join("-");
                  let count = test_data[key];
                  if (count) {
                      test_data[key] = count + 1;
                  }
                  else {
                      test_data[key] = 1;
                  }
              }
              SDKBridge.sendToSdk("/c/postMegadata", data);
          }
      }
      static statisOnStageStart(stageName, reason = 0, bGuide = Global.isGuiding) {
          let data = ["levelStart", stageName + "", reason + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisOnStageEnd(stageName, result = 0, reason = 0, bGuide = Global.isGuiding) {
          let data = ["levelComplete", stageName + "", result + "", reason + "", '0', '0', '0', '0', '0', bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisOnAddItemAmount(itemId, amountDelta, reason, bGuide = Global.isGuiding) {
          if (!db.cop_db.b_open_statics_item)
              return;
          let data = ["coinChange", itemId + "", "1", amountDelta + "", reason + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisOnSubItemAmount(itemId, amountDelta, reason, bGuide = Global.isGuiding) {
          if (!db.cop_db.b_open_statics_item)
              return;
          let data = ["coinChange", itemId + "", "0", amountDelta + "", reason + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisOnItemBought(shopId, amount, reason = 0, bGuide = Global.isGuiding) {
          let data = ["itemBuy", shopId + "", Math.abs(amount) + "", reason + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisOnBuyAction(reason, shopName, result, bGuide = Global.isGuiding) {
          let data = ["buyAction", reason + "", shopName + "", result + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisCommonEvent(id, param1 = 0, param2 = 0, bGuide = Global.isGuiding) {
          let data = ["commonEvent", id + "", param1 + "", param2 + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisVideoPointEvent(adStatisticsId, state, bGuide = Global.isGuiding) {
          let data = ["videoPointEvent", adStatisticsId, state + "", bGuide ? "1" : "0"];
          this.postMegadata(data);
      }
      static statisCommonEventOnce(id, bGuide = Global.isGuiding) {
          if (this.onceEventId[id])
              return;
          this.onceEventId[id] = 1;
          this.saveData();
          this.statisCommonEvent(id, undefined, undefined, bGuide);
      }
      static logAllData() {
          let str = "";
          let arr = Object.keys(test_data);
          arr.sort();
          for (let i = 0; i < arr.length; i++) {
              str += `[${arr[i]}] [${test_data[arr[i]]}]`;
              str += "\n";
          }
          Logger.log("--- statistics start ---");
          Logger.log(str);
          Logger.log("--- statistics end ---");
      }
  }
  GameStatistics.enable = true;

  var ExportViewTool;
  (function (ExportViewTool) {
      let default_click_sound = "";
      function setDefaultClickSound(soundName) {
          default_click_sound = soundName;
      }
      ExportViewTool.setDefaultClickSound = setDefaultClickSound;
      function playDefaultClickSound() {
          if (default_click_sound)
              mgrSound.playSoundIfTimeout(default_click_sound, "default_click", 0.1);
      }
      ExportViewTool.playDefaultClickSound = playDefaultClickSound;
      function bindViewToObject(view, object) {
          loadExportNode(view, object, view.exportNodeNames);
          checkUpdate(view, object);
      }
      ExportViewTool.bindViewToObject = bindViewToObject;
      function loadExportNode(view, node, nodeInfo) {
          if (!nodeInfo)
              return;
          let child;
          let fieldName;
          let com;
          let _transitions = node._transitions;
          for (let i = _transitions.length - 1; i >= 0; i--) {
              let transition = _transitions[i];
              com = nodeInfo[transition.name];
              if (com) {
                  fieldName = transition.name.substring(3);
                  view[fieldName] = transition;
              }
          }
          let controllers = node.controllers;
          for (let i = controllers.length - 1; i >= 0; i--) {
              let controller = controllers[i];
              com = nodeInfo[controller.name];
              if (com) {
                  fieldName = controller.name.substring(3);
                  view[fieldName] = controller;
              }
          }
          for (let i = node.numChildren - 1; i >= 0; i--) {
              child = node.getChildAt(i);
              com = nodeInfo[child.name];
              if (com) {
                  fieldName = child.name.substring(3);
                  view[fieldName] = child;
                  switch (com) {
                      case "FguiEffect":
                          view[fieldName] = child.displayObject.addComponent(FguiEffect).setGuiNode(child).setRoot(view);
                          break;
                      case "ScaleButton":
                          let image = child["image"];
                          if (image) {
                              image.mouseEnabled = true;
                              view[fieldName] = image.addComponent(ScaleButton).setGuiNode(child);
                          }
                          else {
                              view[fieldName] = child.displayObject.addComponent(ScaleButton).setGuiNode(child);
                          }
                      case "fgui.GButton":
                          var callbackFuncName = `on_click_${fieldName}`;
                          var clickSound = view.btnsClickSound ? view.btnsClickSound[fieldName] : null;
                          if (clickSound === null) {
                              clickSound = default_click_sound;
                          }
                          _bindClickFunc(view, callbackFuncName, clickSound, child, fieldName);
                          break;
                      default:
                          break;
                  }
              }
              else {
                  if (child.name.startsWith("cc_effect")) {
                      child.displayObject.addComponent(FguiEffect).setGuiNode(child);
                  }
              }
              if (child instanceof fgui.GComponent) {
                  loadExportNode(view, child, nodeInfo);
              }
          }
      }
      function bindFguiEffectNode(node) {
          for (let i = node.numChildren - 1; i >= 0; i--) {
              let child = node.getChildAt(i);
              if (child.name.startsWith("cc_effect")) {
                  child.displayObject.addComponent(FguiEffect).setGuiNode(child);
              }
              if (child instanceof fgui.GComponent) {
                  bindFguiEffectNode(child);
              }
          }
      }
      ExportViewTool.bindFguiEffectNode = bindFguiEffectNode;
      function _bindClickFunc(view, callbackFuncName, clickSound, node, fieldName) {
          if (view[callbackFuncName] && typeof view[callbackFuncName] == "function") {
              let statisKey = `${view.viewName}_${fieldName}`;
              if (!view.viewName) {
                  statisKey = `${view["_name"]}_${fieldName}`;
              }
              let statisPointId = 0;
              let statisData = null;
              if (db[`_allDbs`]) {
                  statisData = db.get_ui_statis_button_db_map()[statisKey];
                  if (statisData)
                      statisPointId = statisData.index;
              }
              node.onClick(view, (e) => {
                  if (clickSound) {
                      mgrSound.playSoundIfTimeout(clickSound, "default_click", 0.1);
                  }
                  view[callbackFuncName](node);
                  if (statisPointId > 0) {
                      GameStatistics.statisCommonEvent(statisPointId);
                      console.log("打点: 提交", statisPointId, statisData);
                  }
                  e && e.stopPropagation && e.stopPropagation();
              });
          }
      }
      function checkUpdate(view, object) {
          if (view["update"] && !view.destroyed) {
              let updateCom = object.displayObject.getComponent(UpdateCom);
              if (!updateCom) {
                  updateCom = object.displayObject.addComponent(UpdateCom);
              }
              updateCom.update = view["update"].bind(view);
          }
      }
  })(ExportViewTool || (ExportViewTool = {}));

  class ViewBase extends fgui.GComponent {
      constructor(context) {
          super();
          this.destroyed = false;
          this.exportNodeNames = null;
          this.context = null;
          this.delayCalls = [];
          this._needClearTimer = false;
          this.context = context || {};
          this._isLoaded = false;
          this._isLoading = false;
      }
      get isLoaded() {
          return this._isLoaded;
      }
      get isLoading() {
          return this._isLoading;
      }
      dispose() {
          if (this.destroyed)
              return;
          let node = this.resNode;
          if (node) {
              if (this._needClearTimer)
                  this.unscheduleAllCallbacks();
              node.dispose();
          }
          if (!this.isDisposed) {
              super.dispose();
          }
      }
      clearPackageRes(pkgName) {
          let pkg = fgui.UIPackage.getByName(pkgName);
          if (pkg) {
              let cnt = pkg._items.length;
              for (let j = 0; j < cnt; j++) {
                  let pi = pkg._items[j];
                  if (pi.type == fgui.PackageItemType.Atlas) {
                      let url = pi.file;
                      console.log("清理资源", url);
                      Laya.Loader.clearRes(url);
                  }
              }
          }
      }
      removePackage() {
          let pkgReg = /ui:\/\/(\S+)\//img;
          let result = pkgReg.exec(this.sourceName);
          if (result) {
              let pkgName = result[1];
              this.clearPackageRes(pkgName);
              if (fgui.UIPackage.getByName(pkgName)) {
                  fgui.UIPackage.removePackage(pkgName);
              }
          }
      }
      get viewName() {
          if (this.packageItem) {
              return this.packageItem.name;
          }
          else {
              return "";
          }
      }
      setContext(context) {
          this.context = context || {};
      }
      create(callback) {
          if (this._isLoaded) {
              callback && callback(false);
              return;
          }
          if (this._isLoading) {
              callback && callback(false);
              return;
          }
          let pName = this.sourceName;
          if (!pName) {
              console.error("AsyncObject.create: can't find resourceName.");
              callback && callback(false);
              return;
          }
          this._isLoading = true;
          let res = fgui.UIPackage.getItemByURL(this.sourceName);
          if (!res) {
              console.info("异步加载资源:", this.sourceName);
              let waitCircle = FguiHelper.getItem(ViewBase.urlWaitCircle);
              if (waitCircle) {
                  this.addChild(waitCircle);
                  waitCircle.makeFullScreen();
              }
              let pkgReg = /ui:\/\/(\S+)\//img;
              let result = pkgReg.exec(this.sourceName);
              if (result) {
                  let pkgName = result[1];
                  fgui.UIPackage.loadPackage(`res/fgui/${pkgName}`, Laya.Handler.create(this, () => {
                      if (waitCircle) {
                          waitCircle.removeFromParent();
                          FguiHelper.putItem(ViewBase.urlWaitCircle, waitCircle);
                      }
                      let res = fgui.UIPackage.getItemByURL(this.sourceName);
                      this.onResLoaded(res, callback);
                  }));
                  return;
              }
          }
          this.onResLoaded(res, callback);
      }
      onResLoaded(res, callback) {
          if (this.isDisposed) {
              callback && callback(false);
              return;
          }
          if (!res) {
              callback && callback(false);
              return;
          }
          let node = res.owner.internalCreateObject(res).asCom;
          if (!node) {
              callback && callback(false);
              return;
          }
          let tsManager = new TaskManager(this.sourceName);
          let preRess = this.getAllPreLoadRes();
          tsManager.addRes(preRess);
          tsManager.setLoadingCallback((bComplete) => {
              if (bComplete) {
                  if (this.isDisposed) {
                      callback && callback(false);
                      return;
                  }
                  this.onResourceLoaded(node);
                  this.processDelayCalls();
                  callback && callback(true);
              }
          });
          tsManager.loadAll();
      }
      bindResourceNode(node) {
          this._isLoading = false;
          this._isLoaded = true;
          this.resNode = node;
          this.bindObject(node);
          this.onCreate();
      }
      onResourceLoaded(node) {
          this._isLoading = false;
          this._isLoaded = true;
          this.resNode = node;
          this.setSize(this.resNode.width, this.resNode.height);
          this.bindObject(node);
          this.onCreate();
          this.addChild(this.resNode);
          this.onAwake();
      }
      getAllPreLoadRes() {
          let ress = [];
          ress = ress.concat(this.getPreLoadResoure());
          let modelIds = this.getPreLoadModels();
          for (let i = 0; i < modelIds.length; i++) {
              const modelId = modelIds[i];
              let modelData = db.get_model_db(modelId);
              ress.push({
                  url: modelData.resPath,
                  type: RES_TYPE.PREFAB3D,
              });
          }
          let images = this.getPreLoadImages();
          for (let i = 0; i < images.length; i++) {
              const src = images[i];
              ress.push({
                  url: src,
                  type: RES_TYPE.IMAGE,
              });
          }
          let spineIds = this.getPreLoadSpines();
          for (let i = 0; i < spineIds.length; i++) {
              const spineId = spineIds[i];
              let spineData = db.get_spine_db(spineId);
              ress.push({
                  url: spineData.resPath,
                  type: RES_TYPE.BUFFER,
              });
          }
          return ress;
      }
      getPreLoadResoure() {
          return [];
      }
      getPreLoadModels() {
          return [];
      }
      getPreLoadImages() {
          return [];
      }
      getPreloadAnimations() {
          return [];
      }
      getPreLoadSpines() {
          return [];
      }
      bindObject(object) {
          ExportViewTool.bindViewToObject(this, object);
          return this;
      }
      onResourceLoadedFail() {
          console.warn("资源加载失败:", this.sourceName);
      }
      pushDelayCall(method, params) {
          this.delayCalls.push({ method: method, params: params });
      }
      callIfLoaded(func) {
          if (this.isDisposed)
              return;
          if (this.isLoaded) {
              this.callDelayFunc(func);
          }
          else {
              this.pushDelayCall(this.callDelayFunc, [func]);
          }
      }
      callDelayFunc(func) {
          if (func) {
              func();
          }
      }
      get callable() {
          return this._isLoaded && !this.isDisposed;
      }
      logNotFinishError() {
          console.error("对象未加载完成");
      }
      safeCall(method, ...ps) {
          if (this.isDisposed)
              return;
          if (this._isLoaded) {
              method.apply(this, ps);
          }
          else {
              this.pushDelayCall(method, ps);
          }
      }
      processDelayCalls() {
          let calls = this.delayCalls;
          let len = calls.length;
          if (len > 0) {
              this.delayCalls = [];
              for (let i = 0; i < len; i++) {
                  const item = calls[i];
                  item.method.apply(this, item.params);
              }
          }
      }
      onCreate() { }
      onAwake() { }
      schedule(delay, callback) {
          this.resNode.displayObject.timerLoop(delay * 1000, this, callback);
          this._needClearTimer = true;
      }
      scheduleOnce(delay, callback) {
          this.resNode.displayObject.timerOnce(delay * 1000, this, callback);
          this._needClearTimer = true;
      }
      unschedule(callback) {
          this.resNode.displayObject.clearTimer(this, callback);
      }
      unscheduleAllCallbacks() {
          this.resNode.displayObject.timer.clearAll(this);
      }
      show() {
          this.visible = true;
      }
      hide() {
          this.visible = false;
      }
      setTop() {
          if (this.parent) {
              this.parent.setChildIndex(this, this.parent.numChildren - 1);
          }
      }
      setBottom() {
          if (this.parent) {
              this.parent.setChildIndex(this, 0);
          }
      }
  }
  ViewBase.urlWaitCircle = "ui://load/ComWaitCircle";

  const DEFAULT_ADV_SHOW_DELTA_TIME = 0.5;
  const KEY_NO_ADS = "KEY_NO_ADS";
  const DEBUG_MODE = false;
  class mgrAdv {
      static init() {
          switch (Global.SDK_VERSION) {
              case SDK_VERSIONS_VALUE.V6:
                  SDKBridge.registerCmd("/c/openAdvResult", this.onAdvShowResult_V6.bind(this));
                  SDKBridge.registerCmd("/c/openNativeAdvResult", this.openNativeAdvResult.bind(this));
                  SDKBridge.registerCmd("/c/clickNativeAdvResult", this.clickNativeAdvResult_V6.bind(this));
                  SDKBridge.registerCmd("/c/clickAdvResult", this.clickAdvResult_V6.bind(this));
                  SDKBridge.registerCmd("/c/advValidCountResult", this.onAdvVoidCount_V6.bind(this));
                  break;
              case SDK_VERSIONS_VALUE.V5:
                  SDKBridge.registerCmd("/adv/advShowResult", this.onAdvShowResult_V5.bind(this));
                  break;
          }
          this.advData = FileRecord.getData("KEY_ADV_DATA") || {};
          Global.registerListeners(this, {
              [BASE_MSG.DAILY_SWITCH_ACTIVE]: this.onMsgDailySwitchActive.bind(this),
              [BASE_MSG.PANEL_OPEN_COMPLETE]: this.onPanelOpenComplete.bind(this),
              [BASE_MSG.PANEL_CLOSE]: this.onPanelClose.bind(this),
          });
          if (DEBUG_MODE) {
              Logger.error("广告debug开启，如果了解请忽略。");
          }
      }
      static saveRecord() {
          FileRecord.setData("KEY_ADV_DATA", this.advData);
      }
      static openLogTip() {
          this.showLogTip = true;
      }
      static advLog(...arg) {
          if (this.showLogTip) {
              mgrTip.showMsgTip(arg.concat().toString());
          }
          else {
              console.log(...arg);
          }
      }
      static onMsgDailySwitchActive() {
          this.resetAllCount();
      }
      static onPanelOpenComplete(panel) {
          if (Global.isGuiding && !db.cop_db.b_inst_in_guide) {
              return;
          }
      }
      static onPanelClose(panel) {
          if (!panel)
              return;
      }
      static sendMsg(msg, data) {
          Global.sendMsg(msg, data);
      }
      static setNativeUi(nativeAdv, nativeBanner, advLoading) {
          this.panelNativeAdv = nativeAdv;
          this.panelNativeBanner = nativeBanner;
          this.panelAdvLoading = advLoading;
      }
      static getAdvDb(advName) {
          return db.get_adv_db_map()[advName];
      }
      static hasAdv(advName) {
          return this.getAdvDb(advName) ? true : false;
      }
      static setNoAds() {
          FileRecord.setData(KEY_NO_ADS, true);
      }
      static get isNoAds() {
          return !!FileRecord.getData(KEY_NO_ADS);
      }
      static hotfixCop() {
          let allAdvDb = db.get_adv_db_map();
          let ratio_keys = {};
          let cd_keys = {};
          let count_keys = {};
          for (let advName in allAdvDb) {
              let advDb = allAdvDb[advName];
              if (advDb.copKey != "") {
                  ratio_keys[advDb.copKey] = true;
              }
              if (advDb.copCdKey != "") {
                  cd_keys[advDb.copCdKey] = true;
              }
              if (advDb.copCountKey != "") {
                  count_keys[advDb.copCountKey] = true;
              }
          }
          for (let copKey in ratio_keys) {
              this.COP_RATIOS[copKey] = db.cop_db[copKey];
          }
          let cop_cds = {};
          for (let cdKey in cd_keys) {
              cop_cds[cdKey] = db.cop_db[cdKey];
          }
          let cop_counts = {};
          for (let countKey in count_keys) {
              cop_counts[countKey] = db.cop_db[countKey];
          }
          this.hotfixAdvPointCnf(cop_cds, cop_counts);
          this.advCnf["video"].deltaTime = DEFAULT_ADV_SHOW_DELTA_TIME;
          this.advCnf["interstitial"].deltaTime = db.cop_db.ad_inst_cd;
          this.advCnf["banner"].deltaTime = 0;
      }
      static hotfixAdvPointCnf(cdCop, countCop) {
          let allAdvDb = db.get_adv_db_map();
          let advPointCnf = {};
          for (let advName in allAdvDb) {
              let advDb = allAdvDb[advName];
              let cdData = cdCop[advDb.copCdKey];
              let delta = 0;
              if (cdData)
                  delta = cdData[advDb.copCdIndex] || 0;
              let countData = countCop[advDb.copCountKey];
              let count = 0;
              if (countData)
                  count = countData[advDb.copCountIndex] || 0;
              advPointCnf[advName] = { enable: true, nextTime: 0, deltaTime: delta, maxCount: count };
          }
          this.advPointCnf = advPointCnf;
      }
      static getActive(adName) {
          if (DEBUG_MODE)
              return true;
          let advDb = this.getAdvDb(adName);
          if (!advDb) {
              this.advLog("广告db无效", adName);
              return false;
          }
          if (!this.checkTypeActive(advDb.advType)) {
              this.advLog("广告无次数或广告类型CD中", adName);
              return false;
          }
          if (!this.checkCount(adName)) {
              this.advLog("广告点无次数", adName);
              return false;
          }
          return true;
      }
      static checkTypeActive(type) {
          let info = this.advCnf[type];
          if (info) {
              return info.enable && info.nextTime <= Timer.time;
          }
          return false;
      }
      static checkCount(adName) {
          let max = this.getMaxCount(adName);
          let count = this.advData[adName] || 0;
          return count < max;
      }
      static getMaxCount(adName) {
          let advDb = this.getAdvDb(adName);
          if (!advDb)
              return 0;
          if (advDb.copCountKey == "")
              return 10000;
          let cnf = this.advPointCnf[adName];
          if (!cnf)
              return 0;
          let max = cnf.maxCount;
          if (!max)
              return 10000;
          return max;
      }
      static getLeftCount(adName) {
          let count = this.advData[adName] || 0;
          let max = this.getMaxCount(adName);
          return max - count;
      }
      static checkCd(advName) {
          var info = this.advPointCnf[advName];
          if (info) {
              return info.nextTime <= Timer.time;
          }
          else {
              return true;
          }
      }
      static getCopRatByKey(key, idx, defaultRate) {
          if (this.COP_RATIOS[key]) {
              if (idx >= 0 && idx < this.COP_RATIOS[key].length)
                  return this.COP_RATIOS[key][idx] || 0;
          }
          return defaultRate;
      }
      static checkActive(advName, checkGuide = false) {
          if (checkGuide && Global.isGuiding)
              return false;
          if (DEBUG_MODE)
              return true;
          if (!this.getActive(advName))
              return false;
          let advDb = this.getAdvDb(advName);
          if (advDb.advType == "video") {
              if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, advDb.copIndex, advDb.defaultRate))) {
                  this.advLog("广告概率无效", advName);
                  return false;
              }
          }
          else if (advDb.advType == "banner" || advDb.advType == "interstitial") {
              if (advDb.advType == "banner") {
                  if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, advDb.copIndex, advDb.defaultRate))) {
                      this.advLog("广告概率无效", advName);
                      return false;
                  }
              }
              else if (advDb.advType == "interstitial") {
                  if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, advDb.copIndex, advDb.defaultRate))) {
                      this.advLog("广告概率无效", advName);
                      return false;
                  }
              }
          }
          else {
              if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, advDb.copIndex, advDb.defaultRate))) {
                  this.advLog("广告概率无效", advName);
                  return false;
              }
          }
          if (!this.checkCd(advName)) {
              this.advLog("广告点CD中", advName);
              return false;
          }
          return true;
      }
      static addCount(adName) {
          let advDb = this.getAdvDb(adName);
          if (advDb) {
              if (advDb.copCountKey) {
                  if (this.advData[adName]) {
                      this.advData[adName]++;
                  }
                  else {
                      this.advData[adName] = 1;
                  }
                  this.saveRecord();
              }
          }
      }
      static resetCount(adName) {
          let advDb = this.getAdvDb(adName);
          if (advDb) {
              this.advData[adName] = 0;
              this.saveRecord();
          }
      }
      static resetAllCount() {
          let keys = Object.keys(this.advData);
          for (let i = 0; i < keys.length; i++) {
              this.resetCount(keys[i]);
          }
      }
      static updateCdByType(adName) {
          let advDb = this.getAdvDb(adName);
          if (!advDb)
              return;
          let info = this.advCnf[advDb.advType];
          if (info) {
              info.nextTime = Timer.time + info.deltaTime;
          }
      }
      static dispatchAdv(advName, params = null, ignoreCheck = true, showLoading = false) {
          Advertisement.insertAdverV2();
          console.info(advName);
          if (!advName)
              return false;
          if (!this.hasAdv(advName))
              return false;
          this.advLog("O_O 调用广告", advName);
          if (!ignoreCheck) {
              if (!this.checkActive(advName))
                  return false;
          }
          if (showLoading) {
              if (this.panelAdvLoading) {
                  Director.openPanel(this.panelAdvLoading, { advName: advName, params: params });
              }
              else {
                  Logger.warn("mgrAdv.dispatchAdv 找不到panelAdvLoading.");
              }
          }
          let advDb = this.getAdvDb(advName);
          if (advDb.pauseSound && mgrSound.soundEnabled) {
              this.bSoundPaused = true;
              mgrSound.pauseSound();
          }
          let info = this.advCnf[advDb.advType];
          if (info) {
              info.nextTime = Timer.time + info.deltaTime;
          }
          this.advLog("触发广告", advName);
          this.statisVideoClick(advName);
          switch (Global.SDK_VERSION) {
              case SDK_VERSIONS_VALUE.V6:
                  console.info("1111111111111111111111111111111111111111111111111111111111111");
                  console.info(advName);
                  this.dispatchToSdk_V6(advName, params);
                  break;
              case SDK_VERSIONS_VALUE.V5:
                  this.dispatchToSdk_V5(advName, params);
                  break;
          }
          return true;
      }
      static closeAdv(advName) {
          switch (Global.SDK_VERSION) {
              case SDK_VERSIONS_VALUE.V6:
                  this.closeAdv_V6(advName);
                  break;
              case SDK_VERSIONS_VALUE.V5:
                  Logger.error("关闭广告未接入..");
                  break;
          }
      }
      static closeNativeAdv(adName, bManualClose) {
          if (!adName)
              return;
          let advDb = this.getAdvDb(adName);
          if (!advDb)
              return;
          let closeType = !!bManualClose ? 1 : 0;
          let userData = JSON.stringify({ advName: adName });
          SDKBridge.sendToSdk("/c/closeNativeAdv", {
              advId: advDb.advName,
              closeType: closeType,
              userData: userData,
          });
      }
      static statisVideoShow(adName) {
          console.info("1111111111111111111111111111111111111111111111111111111111");
              let advDb = this.getAdvDb(adName);
              if (advDb && advDb.tag) {
                  this.advLog("O_O 视频埋点展示", adName);
                  GameStatistics.statisVideoPointEvent(advDb.tag, 1);
              }
      }
      static statisVideoClick(adName) {
          let advDb = this.getAdvDb(adName);
          if (advDb && advDb.tag) {
              this.advLog("O_O 视频埋点点击", adName);
              GameStatistics.statisVideoPointEvent(advDb.tag, 2);
          }
      }
      static dispatchToSdk_V5(advName, params) {
          console.info("00000000000000000000000000000000000000000000000000000000");
          let advDb = this.getAdvDb(advName);
          let userData = JSON.stringify({ advName: advName, params: params });
          let advId = advDb.advName;
          if (this.isNoAds) {
              Timer.callLater(0.1, () => {
                  this.onAdvShowResult_V5({
                      code: 1,
                      userData: userData,
                      message: "no ads.",
                  });
              });
              return;
          }
          SDKBridge.sendToSdk("/adv/openAdv", { advId: advId, type: advDb.advType, userData: userData });
          if (Global.H5_TEST || DEBUG_MODE) {
              Timer.callLater(1, () => {
                  this.onAdvShowResult_V5({
                      code: 1,
                      userData: userData,
                      message: "test adv v5 msg suc",
                  });
                  this.sendMsg(BASE_MSG.UI_SHOW_TIP, `[debug]:弹出[${advDb.desc}]成功`);
              });
          }
      }
      static onAdvShowResult_V5(data) {
          console.info("00000000000000000000000000000000000000000000000000000000");
          let code = data.code.toString();
          let msg = data.message;
          let userData = JSON.parse(data.userData);
          let advDb = this.getAdvDb(userData.advName);
          switch (code) {
              case "0":
                  this.onAdvFail(userData, msg);
                  break;
              case "1":
                  this.onAdvSuc(userData);
                  break;
              case "2":
                  break;
              case "3":
                  break;
              case "4":
                  break;
              case "5":
                  this.onAdvClick(userData);
                  break;
              case "6":
                  break;
              case "7":
                  break;
              default:
                  Logger.error(`adv unkown code:${code}`);
                  break;
          }
      }
      static dispatchToSdk_V6(advName, params) {
          let advDb = this.getAdvDb(advName);
          let userData = JSON.stringify({ advName: advName, params: params });
          let advId = advDb.advName;
          switch (advDb.advType) {
              case "video":
                  console.log("ttttttttttttttttttttttttttttttttttttttt");
                  this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, true);
                  break;
              case "banner":
                  this._openBannerNativeAdv({ advName: advName, params: params });
                  break;
          }
          if (this.isNoAds) {
              Timer.callLater(0.1, () => {
                  this.onAdvShowResult_V6({
                      code: 1,
                      userData: userData,
                      msg: "no ads.",
                  });
              });
              return;
          }
          SDKBridge.sendToSdk("/c/openAdv", { advId: advId, userData: userData, tag: advDb.tag });
          if (Global.H5_TEST || DEBUG_MODE) {
              Timer.callLater(1, () => {
                  this.onAdvShowResult_V6({
                      code: 1,
                      userData: userData,
                      msg: "test adv v6 msg suc",
                  });
                  this.sendMsg(BASE_MSG.UI_SHOW_TIP, `[debug]:弹出[${advDb.desc}]成功`);
                  let urls = [
                      "http://imgwsdl.vivo.com.cn/appstore/developer/icon/20180807/20180807121104553016.png",
                      "http://imgwsdl.vivo.com.cn/appstore/developer/icon/20180321/201803211747514635890.jpg",
                  ];
                  let descs = [
                      "这里是广告描述",
                      "这里是广告描述这里是广告描述这里是广告描述这里是广告描述",
                      "这里是广告描述这里是广告描述这里是广告描述这里是广告描述这里是广告描述这里是广告描述这里是广告描述这里是广告描述",
                  ];
                  let titles = [
                      "广告标题",
                      "这里是广告标题"
                  ];
                  this.openNativeAdvResult({
                      code: 1,
                      userData: userData,
                      msg: "test adv v6 native msg suc",
                      nativeData: {
                          url: urls[Mathf.random(urls.length) - 1],
                          desc: descs[Mathf.random(descs.length) - 1],
                          title: titles[Mathf.random(titles.length) - 1],
                          targetTitle: "查看详情",
                          adSource: "测试广告来源"
                      },
                  });
              });
          }
      }
      static closeAdv_V6(advName) {
          if (!advName)
              return;
          let advDb = this.getAdvDb(advName);
          if (!advDb)
              return;
          Logger.log("mgrAdv.closeAdv", advName);
          if (advDb.advType == "banner") {
              this._closeBannerNativeAdv();
          }
          let userData = JSON.stringify({ advName: advName });
          SDKBridge.sendToSdk("/c/closeAdv", {
              advId: advDb.advName,
              userData: userData,
          });
      }
      static _openBannerNativeAdv(userData) {
          Advertisement.insertAdverV2();
          if (this.panelNativeBanner) {
              Director.openPanelWithSingleton(this.panelNativeBanner, { userData: userData });
          }
          else {
              Logger.warn("mgrAdv._openBannerNativeAdv 找不到panelNativeBanner.");
          }
      }
      static _closeBannerNativeAdv() {
          this.sendMsg(BASE_MSG.ADV_CLOSE_NATIVE_BANNER);
      }
      static onAdvShowResult_V6(data) {
              let code = data.code.toString();
              let userData = JSON.parse(data.userData || "{}");
              if (code == "1") {
                  this.onAdvSuc(userData);
              }
              else if (code == "0") {
                  this.onAdvFail(userData, data.msg);
              }
              else {
                  Logger.log("广告未知code:", code);
              }
      }
      static onAdvSuc(userData) {
          console.info("0000000000000000000000000000000000000000000000000000000");
          let advDb = this.getAdvDb(userData.advName);
          if (advDb.pauseSound && this.bSoundPaused) {
              this.bSoundPaused = false;
              mgrSound.resumeSound();
          }
          this.addCount(advDb.advName);
          if (advDb.advType == "video") {
              this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, false);
          }
          if (advDb.advType != "video" || this.video_mode.bWatch) {
              this.sendMsg(BASE_MSG.ADV_SHOW_SUC, userData);
          }
          Logger.log("广告弹出成功:", userData.advName);
      }
      static onAdvFail(userData, msg) {
          console.info("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
          let advDb = this.getAdvDb(userData.advName);
          if (advDb.pauseSound && this.bSoundPaused) {
              this.bSoundPaused = false;
              mgrSound.resumeSound();
          }
          if (advDb.advType == "video")
              this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, false);
          this.sendMsg(BASE_MSG.ADV_SHOW_FAIL, userData);
          if (advDb.advType == "video" && msg && !db.cop_db.is4399Watermark) {
              this.sendMsg(BASE_MSG.UI_SHOW_TIP, msg);
          }
          Logger.log("广告弹出失败:", userData.advName);
      }
      static openNativeAdvResult(data) {
          let code = data.code.toString();
          Logger.log("mgrAdv:openNativeAdvResult code:", code);
          if (code == "1") {
              let userData = JSON.parse(data.userData || "{}");
              let advDb = this.getAdvDb(userData.advName);
              if (advDb) {
                  if (advDb.advType == "interstitial") {
                      this._openInstNativeAdv(data.nativeData, userData);
                  }
                  else {
                      this.sendMsg(BASE_MSG.NATIVE_ADV_LOADED, { nativeData: data.nativeData, userData: userData });
                  }
              }
              else {
                  Logger.error("mgrAdv.openNativeAdvResult userData数据异常");
              }
          }
          else {
              Logger.log("打开原生广告失败:", data.msg);
          }
      }
      static _openInstNativeAdv(nativeData, userData) {
          if (this.panelNativeAdv) {
              Director.openPanelWithSingleton(this.panelNativeAdv, { nativeData: nativeData, userData: userData });
          }
          else {
              Logger.warn("mgrAdv._openInstNativeAdv 找不到panelNativeAdv.");
          }
      }
      static clickNativeAdvResult_V6(data) {
          Logger.warn("这个消息好像没有作用");
      }
      static onNativeAdvClick(advName, userData) {
          let advDb = this.getAdvDb(advName);
          if (!advDb)
              return;
          if (userData) {
              userData.bClick = true;
          }
          let jsonData = JSON.stringify(userData);
          SDKBridge.sendToSdk("/c/clickNativeAdv", {
              advId: advDb.advName,
              userData: jsonData,
              tag: advDb.tag,
          });
          if (Global.H5_TEST || DEBUG_MODE) {
              Timer.callLater(1, () => {
                  this.clickAdvResult_V6({
                      code: 1,
                      userData: jsonData,
                      msg: "test native msg click",
                  });
              });
          }
      }
      static clickAdvResult_V6(data) {
          let code = data.code;
          Logger.log("mgrAdv:clickAdvResult code:", code);
          if (code == "1") {
              let userData = JSON.parse(data.userData || "{}");
              this.onAdvClick(userData);
          }
      }
      static onAdvClick(userData) {
          let advDb = this.getAdvDb(userData.advName);
          if (advDb.advType == "video" && !this.video_mode.bWatch) {
              this.sendMsg(BASE_MSG.ADV_SHOW_SUC, userData);
          }
          this.sendMsg(BASE_MSG.ADV_CLICK_SUC, userData);
      }
      static onAdvVoidCount_V6(data) {
          if (data) {
              this.advCnf["video"].enable = !!data.video;
              this.advCnf["interstitial"].enable = !!data.interstitial;
              this.advCnf["banner"].enable = !!data.banner;
              this.advCnf["embedded"].enable = !!data.native;
          }
          this.sendMsg(BASE_MSG.SDK_COP_CHANGED);
      }
  }
  mgrAdv.COP_RATIOS = {};
  mgrAdv.video_mode = { bVideo: true, bWatch: true };
  mgrAdv.advCnf = {
      ["video"]: {
          enable: true,
          deltaTime: DEFAULT_ADV_SHOW_DELTA_TIME,
          nextTime: 0,
          maxCount: 0,
      },
      ["interstitial"]: {
          enable: true,
          deltaTime: DEFAULT_ADV_SHOW_DELTA_TIME,
          nextTime: 0,
          maxCount: 0,
      },
      ["banner"]: {
          enable: true,
          deltaTime: DEFAULT_ADV_SHOW_DELTA_TIME,
          nextTime: 0,
          maxCount: 0,
      },
      ["embedded"]: {
          enable: true,
          deltaTime: DEFAULT_ADV_SHOW_DELTA_TIME,
          nextTime: 0,
          maxCount: 0,
      },
      ["url"]: {
          enable: true,
          deltaTime: DEFAULT_ADV_SHOW_DELTA_TIME,
          nextTime: 0,
          maxCount: 0,
      }
  };
  mgrAdv.advPointCnf = {};
  mgrAdv.panelNativeAdv = "PanelNativeAdv";
  mgrAdv.panelNativeBanner = "PanelNativeBanner";
  mgrAdv.bSoundPaused = false;
  mgrAdv.showLogTip = false;

  class PanelBase extends ViewBase {
      constructor() {
          super(...arguments);
          this.panelLayer = 2;
          this.panelStyle = 2;
          this.isSystemPanel = false;
          this.isFocus = false;
          this.bBannerPaused = false;
          this.bResetRootNode = true;
          this.bMask = true;
          this.bAutoRemovePackage = false;
      }
      dispose() {
          Global.sendMsg(BASE_MSG.PANEL_CLOSE, this);
          super.dispose();
          if (this.bAutoRemovePackage) {
              this.removePackage();
          }
      }
      stopeEvent(e) {
          e && e.stopPropagation && e.stopPropagation();
      }
      create(callback) {
          this.makeFullScreen();
          if (this.bMask) {
              let mask = new fgui.GGraph();
              this.panelMask = mask;
              this.addChild(mask);
              mask.makeFullScreen();
              mask.drawRect(0, "", "#000000");
              mask.alpha = 0;
              Laya.Tween.to(mask, PanelBase.OPEN_PROP_MASK, 300);
          }
          Director.addPanel(this);
          super.create(callback);
      }
      onCreate() {
          if (this.bResetRootNode) {
              this.resNode.setPivot(0.5, 0.5, true);
              this.resNode.setXY(UIRoot.canvasCenterX, UIRoot.canvasCenterY);
          }
          if (this.bOpenAndCloseAnim) {
              this.onPanelOpenAnim(this.onOpenComplete.bind(this));
          }
          else {
              this.onOpenComplete();
          }
          this.buildUi();
      }
      buildUi() { }
      onOpenComplete() {
          Global.sendMsg(BASE_MSG.PANEL_OPEN_COMPLETE, this);
      }
      onFocus(focus) {
          if (this.isFocus == focus)
              return;
          this.isFocus = focus;
          this.adaptBannerAdv();
          if (focus) {
              this.adaptInsertAdv();
          }
          this.adaptStatisDuration();
      }
      show() {
          super.show();
          Global.sendMsg(BASE_MSG.PANEL_SHOW, this);
      }
      hide() {
          super.hide();
          Global.sendMsg(BASE_MSG.PANEL_HIDE, this);
      }
      close(imm) {
          if (!imm && this.bOpenAndCloseAnim) {
              if (this.panelMask) {
                  Laya.Tween.to(this.panelMask, PanelBase.CLOSE_PROP_MASK, 150);
              }
              this.onPanelCloseAnim(this._close.bind(this));
          }
          else {
              this._close();
          }
      }
      closeWithTransition(name = "out") {
          let trans = this.resNode.getTransition(name);
          if (trans) {
              trans.play(Laya.Handler.create(this, this.close));
          }
          else {
              this.close();
          }
      }
      _close() {
          if (this.isLoaded)
              Director.closePanel(this);
          else
              this.dispose();
          Global.sendMsg(BASE_MSG.UI_PANEL_CLOSED, this);
      }
      onPanelOpenAnim(onComplete) {
          this.resNode.setScale(0, 1.4);
          this.resNode.alpha = 0;
          Laya.Tween.to(this.resNode, PanelBase.OPEN_PROP_PANEL, 400, Laya.Ease.backOut, null, 50);
          this.scheduleOnce(0.45, onComplete);
      }
      onPanelCloseAnim(onComplete) {
          Laya.Tween.to(this.resNode, PanelBase.CLOSE_PROP_PANEL, 200, Laya.Ease.backIn);
          this.scheduleOnce(0.2, onComplete);
      }
      adaptInsertAdv() {
          if (!db[`_allDbs`])
              return;
          let adbannerIntUiData = db.get_ad_banner_int_ui_db_map()[this.name];
          if (!adbannerIntUiData)
              return;
          if (!adbannerIntUiData.bInterOpened)
              return;
          if (db.cop_db.b_inst_in_guide == 0 && Global.isGuiding) {
              return;
          }
          if (PanelBase.showingBannerAdvId && db.cop_db.b_inst_or_banner == 1) {
              return;
          }
          mgrAdv.dispatchAdv(adbannerIntUiData.intEventId, null, false);
      }
      adaptBannerAdv() {
          if (!db[`_allDbs`])
              return;
          let adbannerIntUiData = db.get_ad_banner_int_ui_db_map()[this.name];
          if (!adbannerIntUiData) {
              return;
          }
          PanelBase.NATIVE_BANNER_REFRESH_INTERVALE = db.cop_db.ad_banner_refresh_cd;
          if (this.isFocus) {
              let bCanShowBanner = true;
              if (!adbannerIntUiData.bBannerOpened) {
                  bCanShowBanner = false;
              }
              if (bCanShowBanner && db.cop_db.b_banner_in_guide == 0 && Global.isGuiding) {
                  bCanShowBanner = false;
              }
              if (bCanShowBanner && !mgrAdv.checkActive(adbannerIntUiData.bannerEventId)) {
                  bCanShowBanner = false;
              }
              if (this.bBannerPaused) {
                  bCanShowBanner = false;
              }
              if (bCanShowBanner == true) {
                  if (PanelBase.showingBannerAdvId && Timer.time - PanelBase.lastShowingNativeBannerTime < PanelBase.NATIVE_BANNER_REFRESH_INTERVALE && Director.getTopViewName()) {
                      return;
                  }
                  PanelBase.showingBannerAdvId && mgrAdv.closeAdv(PanelBase.showingBannerAdvId);
                  PanelBase.showingBannerAdvId = null;
                  if (mgrAdv.dispatchAdv(adbannerIntUiData.bannerEventId, undefined, true)) {
                      PanelBase.showingBannerAdvId = adbannerIntUiData.bannerEventId;
                      PanelBase.lastShowingNativeBannerTime = Timer.time;
                  }
              }
              else {
                  this.closeAdvBanner();
              }
          }
          else {
              this.closeAdvBanner();
          }
      }
      closeAdvBanner() {
          if (!PanelBase.showingBannerAdvId) {
              return;
          }
          mgrAdv.closeAdv(PanelBase.showingBannerAdvId);
          PanelBase.showingBannerAdvId = null;
      }
      adaptFuncStatics() {
          if (!db[`_allDbs`])
              return;
          let pointDatas = db.get_view_method_call_point_event_db_map()[this.name];
          if (!pointDatas) {
              return;
          }
          let index = 0;
          while (true) {
              let staticsData = db.get_view_method_call_point_event_db(this.name, index);
              if (staticsData) {
                  index++;
                  let temp = this[staticsData.methodName].bind(this);
                  this[staticsData.methodName] = (...args) => {
                      temp(...args);
                      GameStatistics.statisCommonEvent(staticsData.pointEventId);
                      console.log("人工打点：" + staticsData.pointEventId);
                  };
              }
              else {
                  break;
              }
          }
      }
      adaptStatisDuration() {
          if (!db[`_allDbs`])
              return;
          let statisDurationData = db.get_ui_statis_duration_db_map()[this.name];
          if (!statisDurationData)
              return;
          if (this.isFocus) {
              GameStatistics.statisOnStageStart(statisDurationData.index);
              console.log("打点 关卡统计开始：" + this.name);
          }
          else {
              GameStatistics.statisOnStageEnd(statisDurationData.index);
              console.log("打点 关卡统计结束：" + this.name);
          }
      }
      pauseBanner() {
          this.bBannerPaused = true;
          this.adaptBannerAdv();
      }
      resumeBanner() {
          this.bBannerPaused = false;
          this.adaptBannerAdv();
      }
  }
  PanelBase.OPEN_PROP_MASK = { alpha: 0.7 };
  PanelBase.OPEN_PROP_PANEL = { scaleX: 1, scaleY: 1, alpha: 1 };
  PanelBase.CLOSE_PROP_MASK = { alpha: 0 };
  PanelBase.CLOSE_PROP_PANEL = { scaleX: 1.4, scaleY: 0, alpha: 0 };
  PanelBase.showingBannerAdvId = null;
  PanelBase.lastShowingNativeBannerTime = 0;
  PanelBase.NATIVE_BANNER_REFRESH_INTERVALE = 0;

  class PanelAgeTip16 extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://age_tip/PanelAgeTip16";
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelAgeTip8 extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://age_tip/PanelAgeTip8";
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          let tip = this.context.tip;
          if (tip) {
              this.label_desc.text = tip;
          }
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  var MSG;
  (function (MSG) {
      MSG["LOAD_PROGRESS"] = "LOAD_PROGRESS";
      MSG["LOAD_PLAY_END"] = "LOAD_PLAY_END";
      MSG["LOAD_COMPLETE"] = "LOAD_COMPLETE";
      MSG["SDK_INIT"] = "SDK_INIT";
      MSG["TIME_DIFFERENT_DAY"] = "TIME_DIFFERENT_DAY";
      MSG["TIME_OFFLINE_TIME"] = "TIME_OFFLINE_TIME";
      MSG["OFFLINE_SHOW_BUTTON"] = "OFFLINE_SHOW_BUTTON";
      MSG["OFFLINE_GET_REWARD"] = "OFFLINE_GET_REWARD";
      MSG["PANEL_ITEM_GET_OPEN"] = "PANEL_ITEM_GET_OPEN";
      MSG["PANEL_ITEM_GET_CLOSE"] = "PANEL_ITEM_GET_CLOSE";
      MSG["PANEL_ADD_POINT_UPDATE_POINT"] = "PANEL_ADD_POINT_UPDATE_POINT";
      MSG["PANEL_ADD_POINT_ADD"] = "PANEL_ADD_POINT_ADD";
      MSG["PANEL_ADD_POINT_ADD_QUICK"] = "PANEL_ADD_POINT_ADD_QUICK";
      MSG["GUIDE_CLOSE_PANEL"] = "GUIDE_CLOSE_PANEL";
      MSG["GUIDE_UPDATE"] = "GUIDE_UPDATE";
      MSG["GUIDE_EXECUTE"] = "GUIDE_EXECUTE";
      MSG["GUIDE_COMPLETE"] = "GUIDE_COMPLETE";
      MSG["GUIDE_END"] = "GUIDE_END";
      MSG["GUIDE_SKIP"] = "GUIDE_SKIP";
      MSG["GUIDE_MSG_TRIGGER"] = "GUIDE_MSG_TRIGGER";
      MSG["GUIDE_SHOW_WEB_FINGER"] = "GUIDE_SHOW_WEB_FINGER";
      MSG["GUIDE_TIP_UPDATE"] = "GUIDE_TIP_UPDATE";
      MSG["GUIDE_TIP_CORRECT"] = "GUIDE_TIP_CORRECT";
      MSG["MAIN_SHOW_MENU"] = "MAIN_SHOW_MENU";
      MSG["MAIN_REFRESH_BUTTONS"] = "MAIN_REFRESH_BUTTONS";
      MSG["REFRESH_GAME_LIST"] = "REFRESH_GAME_LIST";
      MSG["PANEL_WAIT_CLOSE"] = "PANEL_WAIT_CLOSE";
      MSG["PANEL_PRAY_CLOSE"] = "PANEL_PRAY_CLOSE";
      MSG["PANEL_SECRET_CLOSE"] = "PANEL_SECRET_CLOSE";
      MSG["BANNER_CLICK_AD"] = "BANNER_CLICK_AD";
      MSG["BANNER_SHOW"] = "BANNER_SHOW";
      MSG["BANNER_HIDE"] = "BANNER_HIDE";
      MSG["NEWBIE_COMPLETE"] = "NEWBIE_COMPLETE";
      MSG["GAME_READY"] = "GAME_READY";
      MSG["GAME_START"] = "GAME_START";
      MSG["GAME_ENDING"] = "GAME_ENDING";
      MSG["GAME_OVER"] = "GAME_OVER";
      MSG["GAME_PAUSE"] = "GAME_PAUSE";
      MSG["GAME_RESUME"] = "GAME_RESUME";
      MSG["GAME_RESTART"] = "GAME_RESTART";
      MSG["GAME_OPEN_GAME"] = "GAME_OPEN_GAME";
      MSG["GAME_EXIT"] = "GAME_EXIT";
      MSG["GAME_REFRESH_WITH_GUIDE"] = "GAME_REFRESH_WITH_GUIDE";
      MSG["GAME_LOAD_LEVEL"] = "GAME_LOAD_LEVEL";
      MSG["GAME_LOAD_BLOCK"] = "GAME_LOAD_BLOCK";
      MSG["GAME_LOAD_BLOCK_ALL"] = "GAME_LOAD_BLOCK_ALL";
      MSG["GAME_REVIVE"] = "GAME_REVIVE";
      MSG["GAME_UPDATE_SCORE"] = "GAME_UPDATE_SCORE";
      MSG["GAME_WIN"] = "GAME_WIN";
      MSG["CAMERA_CHANGE"] = "CAMERA_CHANGE";
      MSG["GAME_MINI_OPEN"] = "GAME_MINI_OPEN";
      MSG["CAMERA_SHAKE"] = "CAMERA_SHAKE";
      MSG["CAMERA_SHAKE_ONCE"] = "CAMERA_SHAKE_ONCE";
      MSG["CAMERA_CHANGE_END"] = "CAMERA_CHANGE_END";
      MSG["RANK_RESET_ACTIVE"] = "RANK_RESET_ACTIVE";
      MSG["PLAYER_WALK_ON_BLOCK"] = "PLAYER_WALK_ON_BLOCK";
      MSG["CUSTOM_MODEL_DISPPOSE"] = "CUSTOM_MODEL_DISPPOSE";
      MSG["GAME_SYNC_MONEY_BAR"] = "GAME_SYNC_MONEY_BAR";
      MSG["STAGE_DESTROY"] = "STAGE_DESTROY";
      MSG["PANEL_GAME_TOUCH"] = "PANEL_GAME_TOUCH";
      MSG["TOWER_ENDNESS_BEGIN"] = "TOWER_ENDNESS_BEGIN";
      MSG["TOWER_FINALWAR_BEGIN"] = "TOWER_FINALWAR_BEGIN";
      MSG["TOWER_RUSH_BEGIN"] = "TOWER_RUSH_BEGIN";
      MSG["TOWER_RUSH_STOP"] = "TOWER_RUSH_STOP";
      MSG["TOWER_RUSH_END"] = "TOWER_RUSH_END";
      MSG["TOWER_RUSH_END_FOCUS"] = "TOWER_RUSH_END_FOCUS";
      MSG["TOWER_RUSH_READY"] = "TOWER_RUSH_READY";
      MSG["TOWER_RUSH_WIN"] = "TOWER_RUSH_WIN";
      MSG["TOWER_NEW_GET"] = "TOWER_NEW_GET";
      MSG["TOWER_FB_COIN_BEGIN"] = "TOWER_FB_COIN_BEGIN";
      MSG["TOWER_FB_ITEM_BEGIN"] = "TOWER_FB_ITEM_BEGIN";
      MSG["TOWER_SECRET"] = "TOWER_SECRET";
      MSG["TOWER_DEAD"] = "TOWER_DEAD";
      MSG["TOWER_OPTION_SHOW"] = "TOWER_OPTION_SHOW";
      MSG["SLOT_UNLOCK"] = "SLOT_UNLOCK";
      MSG["TOWER_LVUP_LEVEL"] = "TOWER_LVUP_LEVEL";
      MSG["TOWER_LVUP_STAR"] = "TOWER_LVUP_STAR";
      MSG["TOWER_LVUP_QUALITY"] = "TOWER_LVUP_QUALITY";
      MSG["TOWER_LV_LIMIT_BREAK"] = "TOWER_LV_LIMIT_BREAK";
      MSG["TOWER_DEPLOY"] = "TOWER_DEPLOY";
      MSG["TOWER_TAKEOFF"] = "TOWER_TAKEOFF";
      MSG["TOWER_DEPLOY_SUC"] = "TOWER_DEPLOY_SUC";
      MSG["TOWER_DEPLOY_END"] = "TOWER_DEPLOY_END";
      MSG["TOWER_HAND_SKILL_PREPARE"] = "TOWER_HAND_SKILL_PREPARE";
      MSG["TOWER_ATTR_UPDATE_UID"] = "TOWER_ATTR_UPDATE_UID";
      MSG["TOWER_ATTR_UPDATE_MAIN"] = "TOWER_ATTR_UPDATE_MAIN";
      MSG["TOWER_ATTR_UPDATE_ALL"] = "TOWER_ATTR_UPDATE_ALL";
      MSG["TOWER_ATTR_UPDATE"] = "TOWER_ATTR_UPDATE";
      MSG["TOWER_PRESET_CHANGE"] = "TOWER_PRESET_CHANGE";
      MSG["TOWER_MAIN_SKILL_CHANGE"] = "TOWER_MAIN_SKILL_CHANGE";
      MSG["TOWER_CAST_SUPER_SKILL"] = "TOWER_CAST_SUPER_SKILL";
      MSG["MAIN_HERO_UNLOCK"] = "MAIN_HERO_UNLOCK";
      MSG["TOWER_DEBUG_CHANGE"] = "TOWER_DEBUG_CHANGE";
      MSG["HOLY_ITEM_SELECT_REFRESH"] = "HOLY_ITEM_SELECT_REFRESH";
      MSG["HOLY_ITEM_FEED"] = "HOLY_ITEM_FEED";
      MSG["HOLY_ITEM_SELL"] = "HOLY_ITEM_SELL";
      MSG["HOLY_ITEM_LOCK"] = "HOLY_ITEM_LOCK";
      MSG["HOLY_ITEM_ADDD"] = "HOLY_ITEM_ADDD";
      MSG["HOLY_ITEM_LVUP"] = "HOLY_ITEM_LVUP";
      MSG["HOLY_ITEM_SLOT_UNLOCK"] = "HOLY_ITEM_SLOT_UNLOCK";
      MSG["HOLY_ITEM_BAG_LVUP_OPEN"] = "HOLY_ITEM_BAG_LVUP_OPEN";
      MSG["HOLY_ITEM_FILTER_CHANGE"] = "HOLY_ITEM_FILTER_CHANGE";
      MSG["PANEL_HOLYITEM_LVUP_CLOSE"] = "PANEL_HOLYITEM_LVUP_CLOSE";
      MSG["PRAY_COIN_REFRESH"] = "PRAY_COIN_REFRESH";
      MSG["PRAY_BOX_REFRESH"] = "PRAY_BOX_REFRESH";
      MSG["CHALLENGE_BOSS_BEGIN"] = "CHALLENGE_BOSS_BEGIN";
      MSG["CHALLENGE_STORY_BEGIN"] = "CHALLENGE_STORY_BEGIN";
      MSG["GAME_VIEW_DESTORY"] = "GAME_VIEW_DESTORY";
      MSG["GAME_VIEW_RESTORE"] = "GAME_VIEW_RESTORE";
      MSG["SHOW_TOWER_SKILL_DETAIL"] = "SHOW_TOWER_SKILL_DETAIL";
      MSG["GAME_PROGRESS_CHANGE"] = "GAME_PROGRESS_CHANGE";
      MSG["DROP_ITEM_PICK_UP"] = "DROP_ITEM_PICK_UP";
      MSG["DROP_BOX_PICK_UP_AD"] = "DROP_BOX_PICK_UP_AD";
      MSG["GOAL_SCORE_UDPATE"] = "GOAL_SCORE_UDPATE";
      MSG["SUMMON_ALL_CARD_OPEN"] = "SUMMON_ALL_CARD_OPEN";
      MSG["REFRESH_RED_POINT"] = "REFRESH_RED_POINT";
      MSG["REFRESH_RED_POINT_TOWER"] = "REFRESH_RED_POINT_TOWER";
      MSG["GAME_GAIN_BEGIN"] = "GAME_GAIN_BEGIN";
      MSG["MSG_BAG_EQUIP_EX"] = "MSG_BAG_EQUIP_EX";
      MSG["SIGN_UDPATE"] = "SIGN_UDPATE";
      MSG["SHOP_SUPPLY_EXTRA_REFRESH"] = "SHOP_SUPPLY_EXTRA_REFRESH";
      MSG["SHOP_SERVER_TIME_REFRESH"] = "SHOP_SERVER_TIME_REFRESH";
      MSG["MAP_TILE_DATA_LOAD"] = "MAP_TILE_DATA_LOAD";
      MSG["MGR_TIME_UPDATE"] = "MGR_TIME_UPDATE";
      MSG["SECRET_SELECT_LAYER"] = "SECRET_SELECT_LAYER";
      MSG["SECRET_SELECT_TOWER"] = "SECRET_SELECT_TOWER";
      MSG["SECRET_TOWER_BREAK_UP"] = "SECRET_TOWER_BREAK_UP";
      MSG["EXCHANGE_SHOP_REFRESH"] = "EXCHANGE_SHOP_REFRESH";
      MSG["SMELTER_SELECT_ITEM"] = "SMELTER_SELECT_ITEM";
      MSG["SMELTER_FEED_ITEM"] = "SMELTER_FEED_ITEM";
      MSG["SMELTER_ITEM_SUC"] = "SMELTER_ITEM_SUC";
      MSG["SMELTER_RUNNING"] = "SMELTER_RUNNING";
      MSG["SMELTER_BAG_SELECT_ITEMS"] = "SMELTER_BAG_SELECT_ITEMS";
      MSG["SMELTER_AUTO_PUT_UPDATE"] = "SMELTER_AUTO_PUT_UPDATE";
      MSG["WASH_SELECT_ITEM"] = "WASH_SELECT_ITEM";
      MSG["WASH_ITEM_SUC"] = "WASH_ITEM_SUC";
      MSG["FINAL_WAR_BEGIN"] = "FINAL_WAR_BEGIN";
      MSG["FINAL_WAR_READY"] = "FINAL_WAR_READY";
      MSG["WAVE_CMD_FINAL_BOSS"] = "WAVE_CMD_FINAL_BOSS";
      MSG["WAVE_CMD_FINAL_BOSS_REBORN"] = "WAVE_CMD_FINAL_BOSS_REBORN";
      MSG["WAVE_CMD_FINAL_BOSS_DEAD"] = "WAVE_CMD_FINAL_BOSS_DEAD";
      MSG["ITEM_QUALITY_LVUP_SELECT"] = "ITEM_QUALITY_LVUP_SELECT";
      MSG["ITEM_QUALITY_LVUP_SUC"] = "ITEM_QUALITY_LVUP_SUC";
      MSG["ITEM_QUALITY_LVUP_BAG_SELECT_ITEMS"] = "ITEM_QUALITY_LVUP_BAG_SELECT_ITEMS";
      MSG["ITEM_QUALITY_LVUP_FEED_ITEM"] = "ITEM_QUALITY_LVUP_FEED_ITEM";
      MSG["REBUILD_SELECT_ITEM"] = "REBUILD_SELECT_ITEM";
      MSG["REBUILD_ITEM_SUC"] = "REBUILD_ITEM_SUC";
      MSG["DAILY_DAMAGE_READY_OVER"] = "DAILY_DAMAGE_READY_OVER";
      MSG["DAILY_DAMAGE_BEGIN"] = "DAILY_DAMAGE_BEGIN";
      MSG["AE_EQUIP_UNLOCK"] = "AE_EQUIP_UNLOCK";
      MSG["AE_EQUIP_WORD_ACTIVE"] = "AE_EQUIP_WORD_ACTIVE";
      MSG["AE_EQUIP_WORD_LOCK"] = "AE_EQUIP_WORD_LOCK";
      MSG["AE_EQUIP_LVUP_SUCC"] = "AE_EQUIP_LVUP_SUCC";
      MSG["AE_EQUIP_LVUP_FAIL"] = "AE_EQUIP_LVUP_FAIL";
      MSG["AE_EQUIP_WASH_SUCC"] = "AE_EQUIP_WASH_SUCC";
      MSG["AE_EQUIP_ACTIVE"] = "AE_EQUIP_ACTIVE";
      MSG["TASK_SEVEN_REFRESH"] = "TASK_SEVEN_REFRESH";
      MSG["TASK_SEVEN_SCORE"] = "TASK_SEVEN_SCORE";
      MSG["TASK_SEVEN_SCORE_REWARD"] = "TASK_SEVEN_SCORE_REWARD";
      MSG["TASK_SEVEN_TODAY_MAX_REWARD"] = "TASK_SEVEN_TODAY_MAX_REWARD";
      MSG["EXPLORE_SHOP_REFRESH"] = "EXPLORE_SHOP_REFRESH";
      MSG["EXPLORE_HOLY_REFRESH"] = "EXPLORE_HOLY_REFRESH";
      MSG["EXPLORE_POINT_BEGIN"] = "EXPLORE_POINT_BEGIN";
      MSG["EXPLORE_POINT_COMPLETE"] = "EXPLORE_POINT_COMPLETE";
      MSG["EXPLORE_MAP_REFRESH"] = "EXPLORE_MAP_REFRESH";
      MSG["SUBSCRIPTION_UPDATE"] = "SUBSCRIPTION_UPDATE";
      MSG["GROW_CLOSE"] = "GROW_CLOSE";
      MSG["NEXT_DAY_REWARD"] = "NEXT_DAY_REWARD";
      MSG["NEWYEAR_SIGN_UPDATE"] = "NEWYEAR_SIGN_UPDATE";
  })(MSG || (MSG = {}));
  var EQUIP_QUALITY;
  (function (EQUIP_QUALITY) {
      EQUIP_QUALITY[EQUIP_QUALITY["GREEN"] = 0] = "GREEN";
      EQUIP_QUALITY[EQUIP_QUALITY["BLUE"] = 1] = "BLUE";
      EQUIP_QUALITY[EQUIP_QUALITY["PURPLE"] = 2] = "PURPLE";
      EQUIP_QUALITY[EQUIP_QUALITY["ORANGE"] = 3] = "ORANGE";
      EQUIP_QUALITY[EQUIP_QUALITY["RED"] = 4] = "RED";
  })(EQUIP_QUALITY || (EQUIP_QUALITY = {}));
  var GameModel;
  (function (GameModel) {
      GameModel["ITEM_FLAG"] = "e_xx";
      GameModel["ITEM_FLAG_SCAN"] = "mupai";
  })(GameModel || (GameModel = {}));
  var ITEM_GET_WAY;
  (function (ITEM_GET_WAY) {
      ITEM_GET_WAY[ITEM_GET_WAY["AD_VIDEO"] = 0] = "AD_VIDEO";
      ITEM_GET_WAY[ITEM_GET_WAY["BUY"] = 1] = "BUY";
      ITEM_GET_WAY[ITEM_GET_WAY["SHARE"] = 2] = "SHARE";
  })(ITEM_GET_WAY || (ITEM_GET_WAY = {}));
  var FIREWORK_TYPE;
  (function (FIREWORK_TYPE) {
      FIREWORK_TYPE[FIREWORK_TYPE["NORMAL"] = 0] = "NORMAL";
      FIREWORK_TYPE[FIREWORK_TYPE["DRAW"] = 1] = "DRAW";
  })(FIREWORK_TYPE || (FIREWORK_TYPE = {}));
  const PLAYER_STATE_2_TTYPE = {};
  const PLAYER_STATE_2_SKILL = {};
  class GameConst {
      static updateFrameDeltaTime() {
          var t = Laya.timer.delta * 0.001;
          if (t > this.MAX_FRAME_DELTA_TIME) {
              t = this.MAX_FRAME_DELTA_TIME;
          }
          this._frameDeltaTime = t;
          return this.FrameDeltaTime;
      }
      static get FrameDeltaTime() {
          return this._frameDeltaTime;
      }
  }
  GameConst.MAX_FRAME_DELTA_TIME = 1 / 24;
  GameConst.GLOBAL_UP = new Laya.Vector3(0, 1, 0);
  GameConst.bHighShadowQuality = true;
  GameConst._frameDeltaTime = 1 / 60;
  const SWITCH_ID = {};
  var EditorType;
  (function (EditorType) {
      EditorType[EditorType["color"] = 1] = "color";
      EditorType[EditorType["slider"] = 2] = "slider";
      EditorType[EditorType["num"] = 3] = "num";
      EditorType[EditorType["vec4"] = 4] = "vec4";
  })(EditorType || (EditorType = {}));
  var CustomMaterialRenderMode;
  (function (CustomMaterialRenderMode) {
      CustomMaterialRenderMode[CustomMaterialRenderMode["unknown"] = 0] = "unknown";
      CustomMaterialRenderMode[CustomMaterialRenderMode["RENDERMODE_OPAQUE"] = 1] = "RENDERMODE_OPAQUE";
      CustomMaterialRenderMode[CustomMaterialRenderMode["RENDERMODE_CUTOUT"] = 2] = "RENDERMODE_CUTOUT";
      CustomMaterialRenderMode[CustomMaterialRenderMode["RENDERMODE_CUTOUT_CULL_NONE"] = 3] = "RENDERMODE_CUTOUT_CULL_NONE";
      CustomMaterialRenderMode[CustomMaterialRenderMode["RENDERMODE_TRANSPARENT"] = 4] = "RENDERMODE_TRANSPARENT";
      CustomMaterialRenderMode[CustomMaterialRenderMode["RENDERMODE_TRANSPARENT_CULL_NONE"] = 5] = "RENDERMODE_TRANSPARENT_CULL_NONE";
      CustomMaterialRenderMode[CustomMaterialRenderMode["RENDERMODE_OPAQUE_CULL_NONE"] = 6] = "RENDERMODE_OPAQUE_CULL_NONE";
  })(CustomMaterialRenderMode || (CustomMaterialRenderMode = {}));
  var CustomMaterialType;
  (function (CustomMaterialType) {
      CustomMaterialType[CustomMaterialType["unknown"] = 0] = "unknown";
      CustomMaterialType[CustomMaterialType["unlitCartoon"] = 1] = "unlitCartoon";
      CustomMaterialType[CustomMaterialType["pbrHair"] = 2] = "pbrHair";
      CustomMaterialType[CustomMaterialType["pbrSkin"] = 3] = "pbrSkin";
      CustomMaterialType[CustomMaterialType["pbrMask"] = 4] = "pbrMask";
      CustomMaterialType[CustomMaterialType["bagMaterial"] = 5] = "bagMaterial";
  })(CustomMaterialType || (CustomMaterialType = {}));
  var CHN_DATA = {
      appName: "toutiao",
      isShareEnabled: true,
      isPayEnabled: false,
      isSupportRecordShare: true,
      isSupportFindMinigames: true,
      isSupportInstallShortcut: true,
      findMinigamesImageUrl: "https://gamesres.ultralisk.cn/h5_games_res/common/find_me/default.png",
      jumpInfo: [
          {
              index: "1", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/61.png",
          },
          {
              index: "2", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/64.png",
          },
          {
              index: "3", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/49.png",
          },
          {
              index: "4", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/60.png",
          },
          {
              index: "5", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/61.png",
          },
          {
              index: "6", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/64.png",
          },
          {
              index: "7", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/49.png",
          },
          {
              index: "8", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/60.png",
          },
          {
              index: "9", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/61.png",
          },
          {
              index: "10", bReceived: false, rewards: [[1002, 10]],
              url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/64.png",
          }
      ],
      copInfo: `{
        "share_rate":"10",

        "isSupportRecommendationBtn": 1,
        
        "ad_mode":0,
        "ad_h5":"0",
        "ad_interstitial_ratios":"100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100",
        "ad_banner_ratios":"100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100",
        "ad_embedded_ratios":"100;100;100",
        "ad_video_ratios_":"",
        "ad_video_ratios":"100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100;100",
        "ad_video_cds":"",
        "ad_inst_cd":"10",
        "native_insert_mode":2,
        "some_function":"1;1;1;1;1;1;1;1;1;1;1",
        "b_open_statics_item":1,
        "url_notice":"TEST",

        "share_mode":"2;2;2;2;2;2;2;2;2",
        "share_delay_close":3,
        "level_delay_close":3,

        "cat_ratio":100,
        "cat_delta_time":30,

        "cd_dialog_game_unlock": 5,
        "cd_dialog_game_egg": 5,

        "egg_show_rate":100,
        "b_video_rewatch":1,
        "b_game_mistake_ad":0,
        "egg_show_game_rate":50,

        "alert_dialog_swtich": "1;1;1",
        "alert_dialog_queue": "1;2;3",
        "alert_dialog_cd": 28800,

        "video_mode":"0;0",
        "b_sign_delay_mode":0,
        "b_video_share_full_screen":1,
        "b_video_share_finger":1,
        "b_adv_reward_confirm":1,
        "b_adv_delay":1,
        "b_adv_full_screen":1
    }`
  };

  class GameGlobal {
  }
  GameGlobal.version = "v1.0";
  GameGlobal.isDebug = false;
  GameGlobal.isRayTest = false;
  GameGlobal.DEBUG_CODE = "lrlrllrr";
  GameGlobal.MAIN_TASK_ID = "1";
  GameGlobal.hitPointLocal = new Laya.Vector3();
  GameGlobal.debugAI = false;

  class _mBase {
      onStart() {
      }
  }

  const SECONDS_IN_DAY = 3600 * 24;
  const LONG_DELTA_TIME = SECONDS_IN_DAY * 365 * 1000;
  class mSwitch extends _mBase {
      constructor() {
          super(...arguments);
          this.m_data = null;
          this.dailyActive = false;
          this.weeklyActive = false;
      }
      onLoad() {
          this.loadRecord();
          let allDbs = db.get_switch_db_map();
          for (const id in allDbs) {
              var switchDb = allDbs[id];
              this.initSwitch(switchDb);
          }
          Global.registerListeners(this, {
              [BASE_MSG.GOAL_STATE_CHANGE]: this.onMsgGoalStateChange.bind(this),
          });
      }
      onStart() {
          if (this.active(BASE_SWITCH_ID.DAILY)) {
              this.dailyActive = true;
              Global.sendMsg(BASE_MSG.DAILY_SWITCH_ACTIVE);
              console.log("---> daily switch active true.");
          }
          if (this.active(BASE_SWITCH_ID.WEEKLY)) {
              this.weeklyActive = true;
              console.log("---> weekly switch active true.");
          }
      }
      loadRecord() {
          this.m_data = FileRecord.getData("switch_data") || {};
      }
      saveRecord() {
          FileRecord.setData("switch_data", this.m_data);
      }
      onMsgGoalStateChange(e) {
          if (e.userData.type != GOAL_TYPE.SWITCH)
              return;
          if (!e.isDone)
              return;
          let switchId = e.userData.data;
          let switchItem = this.m_data[switchId];
          if (switchItem) {
              let switchDb = db.get_switch_db(switchId);
              if (switchDb) {
                  this.updateUnlockSwitch(switchItem, switchDb);
                  this.saveRecord();
              }
          }
          return false;
      }
      initSwitch(switchDb) {
          let switchs = this.m_data;
          if (switchs[switchDb.id])
              return;
          let data = {
              count: switchDb.count,
              startTime: 0,
              endTime: 0,
          };
          switch (switchDb.type) {
              case 0:
                  this.updateCycleSwitch(data, switchDb);
                  break;
              case 1:
                  this.updateCdSwitch(data, switchDb);
                  return;
              case 2:
                  this.updateUnlockSwitch(data, switchDb);
                  break;
              case 3:
              case 4:
                  let sDb = switchDb;
                  sDb.count = 1;
                  break;
          }
          switchs[switchDb.id] = data;
          this.saveRecord();
      }
      query(switchId) {
          let data = this.m_data[switchId];
          if (!data) {
              console.error("mSwitch: can't find switch by switchId " + switchId);
              return null;
          }
          return data;
      }
      check(switchId) {
          if (!switchId)
              return true;
          let data = this.query(switchId);
          if (!data) {
              return false;
          }
          if (Timer.time >= data.startTime) {
              if (Timer.time <= data.endTime) {
                  return data.count != 0;
              }
              else {
                  this.updateCheck(switchId);
                  return this.check(switchId);
              }
          }
          else {
              return false;
          }
      }
      active(switchId) {
          if (!switchId)
              return true;
          let switchDb = db.get_switch_db(switchId);
          if (!switchDb)
              return true;
          if (!this.check(switchId))
              return false;
          let data = this.m_data[switchId];
          data.count--;
          if (data.count == 0) {
              if (switchDb && switchDb.type == 1) {
                  this.updateCdSwitch(data, switchDb);
              }
          }
          this.pushChangeToSession(switchId, null, null, data.count);
          this.saveRecord();
          return true;
      }
      getCount(switchId) {
          let data = this.query(switchId);
          if (!data) {
              return 0;
          }
          return data.count;
      }
      getCycleStartTime(switchId) {
          let data = this.query(switchId);
          if (!data) {
              return 0;
          }
          return data.startTime;
      }
      getCycleEndTime(switchId) {
          let data = this.query(switchId);
          if (!data) {
              return 0;
          }
          return data.endTime;
      }
      updateCheck(id) {
          let switchItem = this.m_data[id];
          let switchDb = db.get_switch_db(id);
          if (switchDb) {
              switch (switchDb.type) {
                  case 0:
                      this.updateCycleSwitch(switchItem, switchDb);
                      break;
                  case 1:
                      this.updateCdSwitch(switchItem, switchDb);
                      break;
                  case 2:
                      switchItem.endTime = LONG_DELTA_TIME;
                      console.error(`解锁类型开关无法重复check id: ${id}`);
                      break;
                  default:
                      console.error(`暂不支持类型更新 ${switchDb.type}`);
                      break;
              }
          }
      }
      updateCycleSwitch(recordData, switchDb) {
          let timeData = Tools.splitToNumber(switchDb.params, ":");
          let date;
          if (timeData.length == 5) {
              date = new Date(timeData[2], timeData[3] - 1, timeData[4], timeData[0], timeData[1], 0, 0);
          }
          else if (timeData.length == 2) {
              if (recordData.startTime == 0) {
                  date = new Date(Date.now());
              }
              else {
                  date = new Date(recordData.startTime * 1000);
              }
              date.setHours(timeData[0], timeData[1], 0, 0);
          }
          else {
              console.error(`开关[${switchDb.id}]起始时间[${switchDb.params}]错误.`);
          }
          let startTime = date.getTime() / 1000;
          let endTime = 0;
          if (switchDb.duration <= 0) {
              endTime = LONG_DELTA_TIME;
          }
          else {
              endTime = startTime + switchDb.duration * 3600;
          }
          let deltaTime = switchDb.delta * 3600;
          deltaTime = Math.ceil((Timer.time - endTime) / deltaTime) * deltaTime;
          if (deltaTime > 0) {
              startTime += deltaTime;
              endTime += deltaTime;
          }
          recordData.startTime = startTime;
          recordData.endTime = endTime;
          recordData.count = switchDb.count;
      }
      updateCdSwitch(recordData, switchDb) {
          if (recordData.endTime == 0) {
              recordData.startTime = Timer.time;
              recordData.endTime = LONG_DELTA_TIME;
          }
          else {
              recordData.startTime = Timer.time + switchDb.delta;
          }
          recordData.count = switchDb.count;
      }
      updateUnlockSwitch(recordData, switchDb) {
          if (recordData.endTime == 0) {
              recordData.startTime = LONG_DELTA_TIME;
              recordData.endTime = recordData.startTime;
          }
          else {
              recordData.startTime = Timer.time;
              if (switchDb.duration <= 0) {
                  recordData.endTime = LONG_DELTA_TIME;
              }
              else {
                  recordData.endTime = Timer.time + switchDb.duration * 3600;
              }
              recordData.count = switchDb.count;
          }
      }
      pushChangeToSession(switchId, startTime, endTime, count) {
          if (true)
              return;
      }
  }

  class mgrStatis extends GameStatistics {
      static postMegadata(data) {
          super.postMegadata(data);
      }
      static statisCommonEventByDB(statisId, param1 = 0, param2 = 0) {
      }
      static statisOnStageStartByDB(statisId, reason = 0, bGuide = Global.isGuiding) {
      }
      static statisOnStageEndByDB(statisId, result = 0, reason = 0, bGuide = Global.isGuiding) {
      }
      static statisLevelBegin(levelId) {
      }
      static statisLevelEnd(levelId, result = 0) {
      }
  }

  function sort_item_id_by_order(id1, id2) {
      return Tools.sort_db_by_order(db.get_item_db(id1), db.get_item_db(id2));
  }
  class mItem extends _mBase {
      constructor() {
          super(...arguments);
          this.RECORD_KEY = "game166_items_data_v1.0";
          this.uid = "";
      }
      onLoad() {
          this.loadRecord();
      }
      onStart() {
      }
      checkItems() {
          let items = this.m_data;
          let allItems = db.get_item_db_map();
          let bChange = false;
          Tools.forEachMap(allItems, (id, itemDb) => {
              bChange = true;
              if (itemDb.initCount > 0) {
                  items[id] = itemDb.initCount;
              }
              if (itemDb.initCount > 0)
                  this.tryActiveUp(parseInt(id));
          });
          if (bChange)
              this.saveRecord();
      }
      loadRecord() {
          this.m_data = FileRecord.getData(this.RECORD_KEY);
          if (!this.m_data) {
              this.m_data = {};
              this.checkItems();
          }
      }
      saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.m_data);
      }
      getAllItemInBag() {
          return this.m_data;
      }
      getItemByType(type, subType, gid) {
          let arr = [];
          let items = this.getAllItemInBag();
          if (items) {
              let itemDb;
              Tools.forEachMap(items, (id, count) => {
                  if (count > 0) {
                      itemDb = db.get_item_db(parseInt(id));
                      if (itemDb.type == type) {
                          if (subType == null) {
                              arr.push(id);
                          }
                          else if (subType == itemDb.subType) {
                              if (gid == null)
                                  arr.push(id);
                              else if (gid == itemDb.gid)
                                  arr.push(id);
                          }
                      }
                  }
              });
          }
          return arr;
      }
      static getAllItem(type, subType, gid) {
          let arr = [];
          let items = db.get_item_db_map();
          if (items) {
              Tools.forEachMap(items, (id, itemDb) => {
                  if (itemDb.type == type) {
                      if (subType == null) {
                          arr.push(id);
                      }
                      else if (subType == itemDb.subType) {
                          if (gid == null)
                              arr.push(id);
                          else if (gid == itemDb.gid)
                              arr.push(id);
                      }
                  }
              });
          }
          return arr;
      }
      getItemCountByType(type, subType, gid) {
          let total = 0;
          let items = this.getAllItemInBag();
          if (items) {
              let itemDb;
              Tools.forEachMap(items, (id, count) => {
                  if (count > 0) {
                      itemDb = db.get_item_db(parseInt(id));
                      if (itemDb.type == type) {
                          if (subType == null) {
                              total++;
                          }
                          else if (subType == itemDb.subType) {
                              if (gid == null) {
                                  total++;
                              }
                              else if (gid == itemDb.gid) {
                                  total++;
                              }
                          }
                      }
                  }
              });
          }
          return total;
      }
      getItemCount(itemId) {
          return this.m_data[itemId] || 0;
      }
      getItemCountMax(itemId) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb) {
              return itemDb.maxCount;
          }
          else {
              return 0;
          }
      }
      enoughItem(itemId, count) {
          if (count <= 0)
              return true;
          return this.getItemCount(itemId) >= count;
      }
      isOwned(itemId) {
          return this.enoughItem(itemId, 1);
      }
      addItem(itemId, count, reason) {
          if (count == null) {
              console.error("add item null count");
              return false;
          }
          if (count <= 0)
              return false;
          let lastCount = this.getItemCount(itemId);
          if (lastCount == 0) {
              this.tryActiveUp(itemId);
          }
          let itemDb = db.get_item_db(itemId);
          if (!itemDb) {
              console.error("add item not found itemId: ", itemId);
              return false;
          }
          let bAutoSell = false;
          if (itemDb.autoSell) {
              if (lastCount == 0) {
                  bAutoSell = this.autoSellItem(itemId, count - 1);
                  count = 1;
              }
              else {
                  bAutoSell = this.autoSellItem(itemId, count);
                  return bAutoSell;
              }
          }
          let curCount = lastCount + count;
          if (itemDb.maxCount > 0 && curCount > itemDb.maxCount) {
              curCount = itemDb.maxCount;
          }
          this.m_data[itemId] = curCount;
          this.saveRecord();
          let event = Global.pool.getObject("ItemChangeEvent");
          event.uid = this.uid;
          event.itemId = itemId;
          event.count = curCount;
          event.lastCount = lastCount;
          event.changeCount = count;
          event.reason = reason;
          event.itemDb = itemDb;
          if (reason) {
              if (itemDb.type == 1) {
              }
          }
          Global.sendMsg(BASE_MSG.ITEM_CHANGE, event);
          Global.pool.put(event);
          return bAutoSell;
      }
      autoSellItem(itemId, count) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb.sellItemId && count) {
              this.addItem(itemDb.sellItemId, itemDb.sellPrice * count, 0);
              return true;
          }
          return false;
      }
      tryActiveUp(itemId) {
          return false;
      }
      subItem(itemId, count, reason) {
          if (count <= 0)
              return false;
          if (!itemId)
              return false;
          let lastCount = this.getItemCount(itemId);
          if (lastCount < count)
              return false;
          let curCount = lastCount - count;
          this.m_data[itemId] = curCount;
          if (curCount <= 0) {
              delete this.m_data[itemId];
          }
          this.saveRecord();
          let itemDb = db.get_item_db(itemId);
          let event = Global.pool.getObject("ItemChangeEvent");
          event.uid = this.uid;
          event.itemId = itemId;
          event.count = curCount;
          event.lastCount = lastCount;
          event.changeCount = -count;
          event.reason = reason;
          event.itemDb = itemDb;
          if (reason != null) {
              if (itemDb.type == 1) {
                  mgrStatis.statisOnSubItemAmount(itemId, count, reason);
              }
          }
          Global.sendMsg(BASE_MSG.ITEM_CHANGE, event);
          Global.pool.put(event);
          return true;
      }
      sellItem(itemId, count) {
          if (count == null) {
              count = this.getItemCount(itemId);
          }
          if (this.subItem(itemId, count, 1)) {
              let itemDb = db.get_item_db(itemId);
              if (itemDb.sellItemId) {
                  this.addItem(itemDb.sellItemId, itemDb.sellPrice * count, 1);
              }
          }
      }
      useItem(itemId, count) {
          if (this.enoughItem(itemId, count)) {
              let e = {
                  uid: this.uid,
                  itemId: itemId,
                  count: count,
              };
              Global.sendMsg(BASE_MSG.ITEM_USE, e);
          }
      }
      setItem(itemId, count) {
          if (count < 0)
              return;
          if (!itemId)
              return;
          let lastCount = this.getItemCount(itemId);
          if (lastCount == count)
              return;
          this.m_data[itemId] = count;
          this.saveRecord();
          let itemDb = db.get_item_db(itemId);
          let event = {
              uid: this.uid,
              itemId: itemId,
              count: count,
              lastCount: lastCount,
              changeCount: count - lastCount,
              itemDb: itemDb,
          };
          Global.sendMsg(BASE_MSG.ITEM_CHANGE, event);
      }
      addWrapItem(itemId, count, reason) {
          let items = this.unpackItemToMap(itemId, count);
          let itemCount;
          let keys = Object.keys(items);
          let len = keys.length;
          for (let i = 0; i < len; i++) {
              itemCount = items[keys[i]];
              if (itemCount > 0) {
                  this.addItem(parseInt(keys[i]), itemCount, reason);
              }
              else {
                  delete items[keys[i]];
              }
          }
          return items;
      }
      addWrapItemToList(itemId, count, reason) {
          let items = this.unpackItemToList(itemId, count);
          let len = items.length;
          for (let i = 0; i < len; i++) {
              if (this.addItem(items[i].itemId, items[i].count, reason)) {
                  items[i].bSell = true;
              }
          }
          return items;
      }
      getWrapItem(itemId, count) {
          return this.unpackItemToList(itemId, count, []);
      }
      unpackItemToList(itemId, count, itemList) {
          count = count || 1;
          itemList = itemList || [];
          let itemDb = db.get_item_db(itemId);
          if (!itemDb)
              return itemList;
          for_label: for (let index = 0; index < count; index++) {
              switch (itemDb.type) {
                  case 3:
                      break;
                  default:
                      itemList.push({ itemId: itemId, count: count });
                      break for_label;
              }
          }
          return itemList;
      }
      unpackItemToMap(itemId, count, itemList) {
          count = count || 1;
          itemList = itemList || {};
          let itemDb = db.get_item_db(itemId);
          if (!itemDb)
              return itemList;
          for_label: for (let index = 0; index < count; index++) {
              switch (itemDb.type) {
                  case 3:
                      break;
                  default:
                      let amount = itemList[itemId] || 0;
                      amount += count;
                      itemList[itemId] = amount;
                      break for_label;
              }
          }
          return itemList;
      }
  }

  let lock_tag = false;
  class mAutoIncreaseItem extends _mBase {
      constructor() {
          super(...arguments);
          this.m_data = null;
      }
      onLoad() {
          this.loadRecord();
      }
      loadRecord() {
          this.m_data = FileRecord.getData("aotu_increase_data") || {};
          let dbs = db.get_auto_increase_db_map();
          let bChanged = true;
          Tools.forEachMap(dbs, (itemId, autoDb) => {
              if (!this.m_data[itemId]) {
                  bChanged = true;
                  this.m_data[itemId] = {
                      time: Timer.time,
                      added: 0,
                  };
              }
          });
          if (bChanged)
              this.saveRecord();
      }
      saveRecord() {
          FileRecord.setData("aotu_increase_data", this.m_data);
      }
      refresh(itemId) {
          if (lock_tag)
              return;
          lock_tag = true;
          let items = this.m_data;
          let record;
          if (itemId == null) {
              for (const itemId in items) {
                  record = items[itemId];
                  record.time = this.refreshItemTime(parseInt(itemId), record.time);
              }
          }
          else {
              record = items[itemId];
              if (record) {
                  record.time = this.refreshItemTime(itemId, record.time);
              }
          }
          lock_tag = false;
      }
      refreshItemTime(itemId, lastTime) {
          if (lastTime >= Timer.time) {
              return lastTime;
          }
          let curCount = BaseFacade.mItem.getItemCount(itemId);
          let maxCount = this.getMaxCount(itemId);
          if (curCount >= maxCount) {
              lastTime = Timer.time;
              return lastTime;
          }
          let autoDb = db.get_auto_increase_db(itemId);
          if (!autoDb) {
              return lastTime;
          }
          if (lastTime + autoDb.increaseDelta > Timer.time) {
              return lastTime;
          }
          let oldCount = curCount;
          let increaseCount = autoDb.increaseCount + this.m_data[itemId].added;
          let deltaCount = 0 | ((Timer.time - lastTime) / autoDb.increaseDelta);
          curCount += deltaCount * increaseCount;
          lastTime += deltaCount * autoDb.increaseDelta;
          if (curCount > maxCount) {
              curCount = maxCount;
              lastTime = Timer.time;
          }
          BaseFacade.mItem.addItem(itemId, curCount - oldCount, 6);
          this.saveRecord();
          return lastTime;
      }
      resetTime(itemId) {
          let record = this.m_data[itemId];
          if (record) {
              record.time = Timer.time;
          }
      }
      getMaxCount(itemId) {
          let autoDb = db.get_auto_increase_db(itemId);
          if (autoDb && autoDb.maxCheckItemId) {
              return BaseFacade.mItem.getItemCount(autoDb.maxCheckItemId);
          }
          else {
              return 0;
          }
      }
      getNextTime(itemId) {
          if (this.m_data[itemId]) {
              let autoDb = db.get_auto_increase_db(itemId);
              if (autoDb)
                  return this.m_data[itemId].time + autoDb.increaseDelta;
          }
          return 0;
      }
      getIncreaseDelta(itemId) {
          if (this.m_data && this.m_data[itemId]) {
              let autoDb = db.get_auto_increase_db(itemId);
              if (autoDb)
                  return autoDb.increaseDelta;
              else
                  return Number.MAX_VALUE;
          }
      }
      isMax(itemId) {
          let autoDb = db.get_auto_increase_db(itemId);
          if (autoDb && autoDb.maxCheckItemId) {
              return BaseFacade.mItem.getItemCount(itemId) >= BaseFacade.mItem.getItemCount(autoDb.maxCheckItemId);
          }
          else {
              return false;
          }
      }
      setIncreaseItemAddedPerSec(itemId, addedPerSec) {
          let data = this.m_data;
          let itemDb = db.get_auto_increase_db(itemId);
          if (data && data[itemId] && itemDb) {
              let itemData = data[itemId];
              itemData.added = addedPerSec * itemDb.increaseDelta;
              this.saveRecord();
          }
      }
      getItemIncreasePerSec(itemId) {
          let data = this.m_data;
          if (data && data[itemId]) {
              let itemDb = db.get_auto_increase_db(itemId);
              if (itemDb && itemDb.increaseDelta > 0) {
                  return data[itemId].added / itemDb.increaseDelta;
              }
          }
          return 0;
      }
      getItemIncreaseCount(itemId) {
          let data = this.m_data;
          if (data && data[itemId]) {
              return data[itemId].added;
          }
          return 0;
      }
      accItem(itemId, count, reason) {
          if (count <= 0)
              return false;
          let max = this.getMaxCount(itemId);
          let cur = BaseFacade.mItem.getItemCount(itemId);
          if (cur < max) {
              count = Math.min(max - cur, count);
              BaseFacade.mItem.addItem(itemId, count, reason);
              return true;
          }
          else {
              return false;
          }
      }
  }

  function sort_pay_db_by_switch(payDb1, payDb2) {
      let state1 = BaseFacade.mSwitch.check(payDb1.switchId);
      let state2 = BaseFacade.mSwitch.check(payDb2.switchId);
      if (state1 == state2) {
          return Tools.sort_db_by_order(payDb1, payDb2);
      }
      else {
          if (state1) {
              return -1;
          }
          else {
              return 1;
          }
      }
  }
  function sort_pay_id_by_switch(payId1, payId2) {
      return sort_pay_db_by_switch(db.get_pay_db(payId1), db.get_pay_db(payId2));
  }
  function sort_pay_id_by_order(payId1, payId2) {
      return Tools.sort_db_by_order(db.get_pay_db(payId1), db.get_pay_db(payId2));
  }
  class mPay extends _mBase {
      onLoad() {
      }
      loadRecord() {
      }
      saveRecord() {
      }
      getActive(payId) {
          let payDb = db.get_pay_db(payId);
          if (!payDb)
              return false;
          return BaseFacade.mSwitch.check(payDb.switchId);
      }
      buyGoods(payId, callback, reason = null, bFree = false) {
          let payDb = db.get_pay_db(payId);
          callback = callback || Global.EMPTY_FUN;
          if (!payDb) {
              callback(false, null);
              return;
          }
          let result = false;
          if (bFree) {
              result = true;
          }
          else {
              if (payDb.firstCostItemId)
                  result = BaseFacade.mItem.subItem(payDb.firstCostItemId, payDb.firstCostCount, reason);
              if (!result) {
                  if (payDb.costItemId == 1003) {
                  }
                  result = BaseFacade.mItem.subItem(payDb.costItemId, payDb.costCount, reason);
              }
          }
          if (result) {
              let items = this._onGetGoods(payId, reason);
              callback(true, items);
          }
          else {
              callback(false, null);
          }
      }
      _onGetGoods(payId, reason = null, bRmb = false) {
          let payDb = db.get_pay_db(payId);
          BaseFacade.mSwitch.active(payDb.switchId);
          if (payDb.getItemId) {
              if (payDb.statistics) {
                  mgrStatis.statisOnItemBought(payDb.statistics, 1);
              }
              let items = BaseFacade.mItem.addWrapItemToList(payDb.getItemId, payDb.getCount, reason);
              Global.sendMsg(BASE_MSG.PAY_SUC, payId);
              return items;
          }
          else {
              return null;
          }
      }
      isCostEnough(payId) {
          let payDb = db.get_pay_db(payId);
          if (!payDb) {
              return false;
          }
          if (payDb.costItemId == 1003) {
              return true;
          }
          else {
              if (payDb.firstCostItemId)
                  return BaseFacade.mItem.enoughItem(payDb.firstCostItemId, payDb.firstCostCount);
              return BaseFacade.mItem.enoughItem(payDb.costItemId, payDb.costCount);
          }
      }
      getPays(gid) {
          let allPay = db.get_pay_db_map();
          let payIds = [];
          Tools.forEachMap(allPay, function (payId, payDb) {
              if (payDb.gid == gid) {
                  if (BaseFacade.mSwitch.check(payDb.switchId)) {
                      payIds.push(parseInt(payId));
                  }
              }
          });
          payIds.sort(sort_pay_id_by_order);
          return payIds;
      }
      getAllPays(gid) {
          let allPay = db.get_pay_db_map();
          let payIds = [];
          Tools.forEachMap(allPay, function (payId, payDb) {
              if (payDb.gid == gid) {
                  payIds.push(parseInt(payId));
              }
          });
          return payIds;
      }
  }

  class BaseFacade {
      static get isLoaded() {
          return this._isLoaded;
      }
      static loadAllMgr() {
          this.mSwitch = this.createMgr(mSwitch);
          this.mItem = this.createMgr(mItem);
          this.mAutoIncreaseItem = this.createMgr(mAutoIncreaseItem);
          this.mPay = this.createMgr(mPay);
          this.loadAll();
          this._isLoaded = true;
      }
      static createMgr(mgrClass) {
          let mgr = new mgrClass(new MsgHandler());
          this._mgrs.push(mgr);
          return mgr;
      }
      static loadAll() {
          for (let i = 0; i < this._mgrs.length; i++) {
              this._mgrs[i].onLoad();
          }
      }
      static startAll() {
          for (let i = 0; i < this._mgrs.length; i++) {
              this._mgrs[i].onStart();
          }
      }
  }
  BaseFacade._isLoaded = false;
  BaseFacade._mgrs = [];

  var UPDATER_UI_MSG;
  (function (UPDATER_UI_MSG) {
      UPDATER_UI_MSG["ENTER_NEXT_SCENE"] = "ENTER_NEXT_SCENE";
      UPDATER_UI_MSG["GET_VERSION"] = "GET_VERSION";
      UPDATER_UI_MSG["DOWNLOAD_BEGIN"] = "DOWNLOAD_BEGIN";
      UPDATER_UI_MSG["DOWNLOAD_SUCCESS"] = "DOWNLOAD_SUCCESS";
  })(UPDATER_UI_MSG || (UPDATER_UI_MSG = {}));
  class UpdaterScript {
      constructor(nodeScene, msgCallback) {
          this.patchInfo = null;
          this.localPid = null;
          this.patchs = null;
          this.patchIdx = null;
          this.TIMEOUT = 5;
          this.requestPatchInfoXhr = null;
          this.timeoutTimer = null;
          this.bNeedRestart = false;
          this.bGameStarted = false;
          let nodeRoot = new Laya.Sprite();
          nodeScene.addChild(nodeRoot);
          this.nodeRoot = nodeRoot;
          this.onUiMsgCallback = msgCallback;
      }
      startUpdate() {
          // if (!mgrNative.isHtml5Platform() && window["conch"]) {
          //     let patchInfo = this.readStringFromAssetFile("patch_info.json");
          //     if (patchInfo) {
          //         console.log("发现patch_info，准备更新");
          //         if (this.needPlayLogo()) {
          //             this.playLogo(() => {
          //                 this.prepareUpdate();
          //             });
          //         }
          //         else {
          //             this.prepareUpdate();
          //         }
          //         return;
          //     }
          // }
          console.log("patch_info.json未找到，直接进入游戏");
          this.startGame();
      }
      static changeToTestPatchInfo() {
          Laya.LocalStorage.setItem("FOCE_PATCH_INFO_FILE_NAME_KEY", "patch_info_test.json");
          console.log("---> 切换到测试补丁库.");
      }
      static changeToNormalPatchInfo() {
          Laya.LocalStorage.setItem("FOCE_PATCH_INFO_FILE_NAME_KEY", "");
          console.log("---> 切换到正式补丁库.");
      }
      static clearGameCache() {
          window["clearGameCacheDir"] && window["clearGameCacheDir"]();
      }
      buildUi() {
      }
      sendUiMsg(msg, data) {
          this.onUiMsg(msg, data);
      }
      onUiMsg(msg, data) {
          if (this.onUiMsgCallback) {
              this.onUiMsgCallback(msg, data);
          }
      }
      needPlayLogo() {
          let bSkipLogoOnce = Laya.LocalStorage.getItem("B_SKIP_LOGO_ONCE") == "true";
          if (bSkipLogoOnce) {
              Laya.LocalStorage.setItem("B_SKIP_LOGO_ONCE", "false");
              return false;
          }
          let logoTextures = this.getLogoTextures();
          if (!logoTextures || logoTextures.length == 0)
              return false;
          return true;
      }
      getLogoTextures() {
          let jsonText = this.readStringFromAssetFile("patch_info.json");
          let patchInfo;
          if (jsonText) {
              patchInfo = JSON.parse(jsonText);
          }
          if (!patchInfo)
              return null;
          let conf = patchInfo.CONF;
          if (!conf)
              return null;
          let logoTextures = conf.LOGO_TEXTURES;
          if (!Array.isArray(logoTextures))
              return null;
          return logoTextures;
      }
      playLogo(fOnCompleted) {
          fOnCompleted();
      }
      startGame(bUpdateVersion) {
          if (this.bGameStarted) {
              console.warn("vUpdataerSceneBase.startGame already started!");
              return;
          }
          this.bGameStarted = true;
          if (bUpdateVersion) {
              if (this.patchInfo) {
                  let recordVersion = Laya.LocalStorage.getItem("GAME_VERSION");
                  if (recordVersion) {
                      UpdaterScript.GAME_VERSION = recordVersion;
                  }
                  else {
                      let version = this.patchInfo.VERSION;
                      if (version) {
                          Laya.LocalStorage.setItem("GAME_VERSION", version);
                          UpdaterScript.GAME_VERSION = version;
                      }
                  }
              }
          }
          window["PATCH_INFO"] = this.patchInfo;
          this.releaseRequestPatchInfoXhr();
          if (this.bNeedRestart) {
              console.log("-------------------------");
              console.log("-----  restarting   -----");
              console.log("-------------------------");
              Laya.LocalStorage.setItem("B_SKIP_LOGO_ONCE", "true");
              Laya.SoundManager.stopAll();
              window.location.reload(true);
              return;
          }
          console.log("-------------------------");
          console.log("-----   startGame   -----");
          console.log("-------------------------");
          this.sendUiMsg(UPDATER_UI_MSG.ENTER_NEXT_SCENE);
      }
      resetPatch(pid, pkgVersion) {
          console.log("-------------------------");
          console.log("-----  resetPatch   -----");
          console.log("-------------------------");
          Laya.LocalStorage.setItem("PATCH_PID", pid.toString());
          Laya.LocalStorage.setItem("PACKAGE_VERSION", pkgVersion);
      }
      prepareUpdate() {
          console.log("-------------------------");
          console.log("----- prepareUpdate -----");
          console.log("-------------------------");
          let jsonText = this.readStringFromAssetFile("patch_info.json");
          let patchInfo;
          if (jsonText) {
              patchInfo = JSON.parse(jsonText);
          }
          if (!patchInfo) {
              console.warn("[warn] patch_info 加载失败，直接进入游戏。");
              this.startGame();
              return;
          }
          this.patchInfo = patchInfo;
          let version = Laya.LocalStorage.getItem("GAME_VERSION");
          if (!version) {
              version = patchInfo.VERSION;
          }
          UpdaterScript.GAME_VERSION = version;
          let packagePid = patchInfo.P_ID;
          let packageVersion = `${patchInfo.P_ID}_${patchInfo.CHANNEL}`;
          console.log("package version:" + packageVersion);
          let recoredPakageVersion = Laya.LocalStorage.getItem("PACKAGE_VERSION");
          if (packageVersion != recoredPakageVersion) {
              if (!recoredPakageVersion) {
                  console.log("---> 首次进入");
              }
              else {
                  console.log("---> 覆盖安装进入");
                  console.log("local version:" + recoredPakageVersion);
                  let packageVersion = patchInfo.VERSION || "1101";
                  Laya.LocalStorage.setItem("GAME_VERSION", packageVersion);
                  UpdaterScript.GAME_VERSION = packageVersion;
              }
              this.resetPatch(packagePid, packageVersion);
          }
          this.localPid = parseInt(Laya.LocalStorage.getItem("PATCH_PID")) || 0;
          console.log("use record pid:" + this.localPid);
          let patchPath = this.getPatchPath();
          if (!fs_exists(patchPath)) {
              if (!fs_mkdir(patchPath)) {
                  console.log("patchPath create faild!" + patchPath);
                  this.startGame();
                  return;
              }
              else {
                  console.log("make patch patch suc.");
              }
          }
          this.buildUi();
          this.checkNewVersion();
      }
      checkNewVersion() {
          return;
          this.sendUiMsg(UPDATER_UI_MSG.GET_VERSION);
          let patchInfo = this.patchInfo;
          let useChannel = patchInfo.CHANNEL;
          let patchFile = patchInfo.PATCH_INFO_FILENAME;
          let forcePatchFile = Laya.LocalStorage.getItem("FOCE_PATCH_INFO_FILE_NAME_KEY");
          if (forcePatchFile) {
              patchFile = forcePatchFile;
          }
          let patchInfoUrl = sprintf("http://%s/%s/%s/%s/%s", patchInfo.HOST, patchInfo.PATCH_PATH, patchInfo.APP, useChannel, patchFile);
          console.log("patchInfoUrl:" + patchInfoUrl);
          var xhr = new XMLHttpRequest();
          xhr.open('GET', patchInfoUrl);
          xhr.onload = () => {
              this.stopTimeoutTimer();
              let remotePatchInfo;
              try {
                  remotePatchInfo = JSON.parse(xhr.responseText);
              }
              catch (error) {
                  console.warn("vUpdaterScene.checkNewVersion remote patch_info parse except!" + xhr.responseText);
                  this.startGame();
              }
              if (remotePatchInfo) {
                  this.releaseRequestPatchInfoXhr();
                  this.onPatchInfoDownloadSuccess(remotePatchInfo);
              }
              else {
                  console.warn("vUpdaterScene.checkNewVersion remote patch_info parse faild!" + xhr.responseText);
                  this.startGame();
              }
          };
          xhr.onerror = (e) => {
              console.warn("vUpdateScene.checkNewVersion network faild.");
              console.log(e);
              this.stopTimeoutTimer();
              this.startGame();
          };
          xhr.timeout = this.TIMEOUT * 1000;
          this.requestPatchInfoXhr = xhr;
          this.startTimeoutTimer();
          xhr.send();
      }
      onPatchInfoDownloadSuccess(remotePatchInfo) {
          console.log("onPatchInfoDownloadSuccess");
          console.log(JSON.stringify(remotePatchInfo));
          let remotePid = parseInt(remotePatchInfo.P_ID) || 0;
          let localPid = this.localPid;
          console.log(`pid: ${localPid} ${remotePid}`);
          if (remotePatchInfo && remotePatchInfo.CONF) {
              Laya.LocalStorage.setItem("REMOTE_PATCH_INFO_CONF", JSON.stringify(remotePatchInfo.CONF || { "holder": "nothing" }));
          }
          if (localPid > remotePid) {
              Laya.LocalStorage.setItem("GAME_VERSION", "");
              console.warn("local version is higher than remote version");
              console.warn("stop update!");
              this.startGame(true);
              return;
          }
          let patchs = [];
          for (let i = 0; i < remotePatchInfo.PATCH_LIST.length; i++) {
              const v = remotePatchInfo.PATCH_LIST[i];
              if (v.pid > localPid) {
                  console.log(`ADD PATCH -> ${v.pid} ${v.version}`);
                  patchs.push(v);
              }
          }
          this.patchInfo = remotePatchInfo;
          if (patchs.length > 0) {
              this.patchs = patchs;
              this.patchIdx = 0;
              this.sendUiMsg(UPDATER_UI_MSG.DOWNLOAD_BEGIN);
              Timer.callLater(0.016, () => {
                  this.downloadPatchByIndexed();
              });
          }
          else {
              this.startGame(true);
          }
      }
      downloadPatchByIndexed() {
          console.info("ppppppppppppppppppppppppppppppppppppppppppppppppp");
          // console.log("downloadPatchByIndexed:" + this.patchIdx);
          // let patchInfo = this.patchInfo;
          // let patch = this.patchs[this.patchIdx];
          // let patchFile = patch.pid + ".zip";
          // let packageUrl = sprintf("http://%s/%s/%s/%s/%s", patchInfo.HOST_CDN || patchInfo.HOST, patchInfo.PATCH_PATH, patchInfo.APP, patchInfo.CHANNEL, patchFile);
          // console.log("packageUrl:" + packageUrl);
          // let localPath = this.getPatchPath();
          // let localZipFile = localPath + patchFile;
          // downloadBigFile(packageUrl, localZipFile, (total, now, speed) => {
          //     return false;
          // }, (curlret, httpret) => {
          //     if (curlret != 0 || httpret < 200 || httpret >= 300) {
          //         console.log(`downloadBigFile: downloadError curlret:${curlret} :httpret${httpret}`);
          //         this.startGame();
          //     }
          //     else {
          //         console.log('downloadBigFile: downloadOK');
          //         this.unZipPatchFile(localZipFile);
          //     }
          // }, 10, 100000000);
      }
      unZipPatchFile(zipFile) {
          console.info("ppppppppppppppppppppppppppppppppppppppppppppppppp");
          // let zip = new ZipFile();
          // if (zip.setSrc(zipFile)) {
          //     var bindcc;
          //     zip.forEach((id, name, bDir, sz) => {
          //         if (name.indexOf("update/filetable.bin") >= 0) {
          //             bindcc = zip.readFile(id);
          //         }
          //     });
          //     let bError = false;
          //     if (!bindcc) {
          //         console.log("unZipPatchFile: 找不到update/filetable.bin");
          //         bError = true;
          //     }
          //     else {
          //         if (this.updateDcc(bindcc)) {
          //             console.log('---> 更新dccbin完成.');
          //             zip.forEach((id, name, bDir, sz) => {
          //                 if (!bDir) {
          //                     if (name.startsWith("update/"))
          //                         return;
          //                     let buf = zip.readFile(id);
          //                     let fid = window["appcache"].hashstr('/' + name);
          //                     if (window["appcache"].updateFile(fid, 0, buf, false)) {
          //                         console.log('downloadBigFile: updating:' + name);
          //                     }
          //                     else {
          //                         console.log("downloadBigFile: updateError:" + name);
          //                         bError = true;
          //                     }
          //                 }
          //             });
          //         }
          //         else {
          //             console.log('---> 更新dccbin失败.');
          //             bError = true;
          //         }
          //     }
          //     zip.close();
          //     if (fs_exists(zipFile)) {
          //         console.log("清理临时文件:" + zipFile);
          //         fs_rm(zipFile);
          //     }
          //     if (bError) {
          //         this.startGame();
          //     }
          //     else {
          //         this.onPatchDownloadSuccess();
          //     }
          // }
          // else {
          //     console.log("downloadBigFile set zip src error!");
          //     this.startGame();
          // }
      }
      updateDcc(bindcc) {
          var v = new Uint32Array(bindcc);
          if (v[0] != 0xffeeddcc || v[1] != 1) {
              console.log('updateDcc: dcc.bin file err!');
              return false;
          }
          else {
              let txtdcc = "";
              if (v[2] == 0x00ffffff) {
                  var stp = (4 + 8) / 2;
                  console.log('---> 开始更新dccbin');
                  for (var ii = stp, isz = v.length / 2; ii < isz; ii++) {
                      txtdcc += v[ii * 2].toString(16) + ' ' + v[ii * 2 + 1].toString(16) + '\n';
                  }
              }
              else {
                  console.log('---> old format');
                  for (var ii = 1, isz = v.length / 2; ii < isz; ii++) {
                      txtdcc += v[ii * 2].toString(16) + ' ' + v[ii * 2 + 1].toString(16) + '\n';
                  }
              }
              if (txtdcc && txtdcc.length > 0) {
                  let cache = window["appcache"];
                  cache.saveFileTable(txtdcc);
                  window["appcache"] = cache = new AppCache(window.location["fullpath"] + '/');
                  return true;
              }
              else {
                  return false;
              }
          }
      }
      onPatchDownloadSuccess() {
          let patch = this.patchs[this.patchIdx];
          this.localPid = patch.pid;
          Laya.LocalStorage.setItem("PATCH_PID", this.localPid.toString());
          console.log("save PATCH_PID:" + this.localPid);
          if (patch.version) {
              Laya.LocalStorage.setItem("GAME_VERSION", patch.version);
              console.log("save GAME_VERSION:" + patch.version);
          }
          this.bNeedRestart = true;
          console.log(`check patchIdx ${this.patchIdx} ${this.patchs.length}`);
          if (this.patchIdx < this.patchs.length - 1) {
              this.patchIdx++;
              this.downloadPatchByIndexed();
          }
          else {
              this.sendUiMsg(UPDATER_UI_MSG.DOWNLOAD_SUCCESS);
              this.startGame(true);
          }
      }
      readStringFromAssetFile(file) {
          if (window["conch"]) {
              return window["conch"].readFileFromAsset(file, 'utf8');
          }
          else {
              return null;
          }
      }
      setResourceID(key, data) {
          window["appcache"].setResourceID(key, data);
      }
      getResourceID(key) {
          return window["appcache"].getResourceID(key);
      }
      getCachePath() {
          return window["conch"].getCachePath();
      }
      getPatchPath() {
          return this.getCachePath() + "/patch_temp/";
      }
      onTimeout() {
          console.log("checkNewVersion timeout.");
          this.startGame();
      }
      startTimeoutTimer() {
          let timer = new Timer(this.TIMEOUT, 1, () => {
              this.stopTimeoutTimer();
              this.onTimeout();
          }, this.nodeRoot);
          this.timeoutTimer = timer;
          timer.start();
      }
      stopTimeoutTimer() {
          if (this.timeoutTimer) {
              this.timeoutTimer.stop();
              this.timeoutTimer = null;
          }
      }
      releaseRequestPatchInfoXhr() {
          if (this.requestPatchInfoXhr) {
              this.requestPatchInfoXhr.onload = null;
              this.requestPatchInfoXhr.onerror = null;
              this.requestPatchInfoXhr = null;
          }
      }
  }
  UpdaterScript.GAME_VERSION = "GAME_VERSION";

  var RECORD_STATUS;
  (function (RECORD_STATUS) {
      RECORD_STATUS[RECORD_STATUS["PRE_RECORD"] = 1] = "PRE_RECORD";
      RECORD_STATUS[RECORD_STATUS["RECORDING"] = 2] = "RECORDING";
      RECORD_STATUS[RECORD_STATUS["RECORD_FINISH"] = 3] = "RECORD_FINISH";
  })(RECORD_STATUS || (RECORD_STATUS = {}));
  const RECORD_VIDEO_KEY = "RecordVideioEnabled";
  class mgrVideoRecorder extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [BASE_MSG.RECORD_GAME_VIDEO_RESULT]: this.onMsgRecordGameVideoResult.bind(this),
              [BASE_MSG.SHARE_VIDEO_RESULT]: this.onMsgShareVideoResult.bind(this),
          });
          Timer.callLoop(1, this.onTimerLoop.bind(this), true);
          this._userOpenVideoRecord = FileRecord.getData(RECORD_VIDEO_KEY);
          if (this._userOpenVideoRecord == null) {
              this._userOpenVideoRecord = true;
              FileRecord.setData(RECORD_VIDEO_KEY, this._userOpenVideoRecord);
          }
      }
      static onTimerLoop() {
          if (this.bRecordVideo) {
              this.lastRecordVideoTime += 1;
              if (this.lastRecordVideoTime >= this.maxRecordTime) {
                  this.stopRecordGameVideo();
              }
          }
      }
      static isOpenVideoRecord() {
          return this.isCopOpenVideoRecord() && mgrGame.videoRecordEnable;
      }
      static isCopOpenVideoRecord() {
          return CopHelper.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_record_video) && db.cop_db.isSupportRecordShare;
      }
      static getLastRecordVideoTime() {
          return this.lastRecordVideoTime || 0;
      }
      static setRecordStatus(status) {
          let originStatus = this.recordStatus;
          this.recordStatus = status;
          console.log("mgrVideoRecorder.status", originStatus, status);
          if (originStatus != this.recordStatus) {
              Global.sendMsg(BASE_MSG.VIDEO_RECORDER_STATUS_CHANGED, {
                  status: status,
                  originStatus: originStatus,
              });
          }
      }
      static getRecordStatus() {
          return this.recordStatus;
      }
      static isRecording() {
          return this.bRecordVideo && this.recordStatus == RECORD_STATUS.RECORDING;
      }
      static onMsgRecordGameVideoResult(e) {
          let data = e;
          let action = data.action;
          let bSuccessful = data.bSuccessful;
          let msg = data.msg;
          console.log("mgrVideoRecorder.onMsgRecordGameVideoResult", bSuccessful, action);
          if (bSuccessful) {
              switch (action) {
                  case "start":
                      this.lastRecordVideoTime = 0;
                      this.bPause = false;
                      this.bRecordVideo = true;
                      this.setRecordStatus(RECORD_STATUS.RECORDING);
                      break;
                  case "pause":
                      this.bPause = true;
                      this.bRecordVideo = false;
                      break;
                  case "resume":
                      this.bPause = false;
                      this.bRecordVideo = true;
                      break;
                  case "stop":
                      this.bRecordVideo = false;
                      console.log("录制的时间：" + this.lastRecordVideoTime);
                      if (this.bRestartFlag) {
                          this.bRestartFlag = false;
                          this.setRecordStatus(RECORD_STATUS.PRE_RECORD);
                          mgrSdk.recordGameVideo("start");
                      }
                      else {
                          this.setRecordStatus(RECORD_STATUS.RECORD_FINISH);
                      }
                      break;
                  default:
                      console.warn("mgrVideoRecorder.onMsgRecordGameVideoResult unknown action:", action);
                      break;
              }
          }
          else {
              this.setRecordStatus(RECORD_STATUS.PRE_RECORD);
              if (msg) {
                  mgrTip.showMsgTip(msg);
              }
          }
      }
      static onMsgShareVideoResult(e) {
          let data = e;
          let bSuccessful = data.bSuccessful;
          console.log("mgrVideoRecorder.onMsgShareVideoResult", bSuccessful);
          if (bSuccessful) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "录屏分享成功");
              this.setRecordStatus(RECORD_STATUS.PRE_RECORD);
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "录屏分享失败");
              this.setRecordStatus(RECORD_STATUS.PRE_RECORD);
          }
      }
      static startRecordGameVideo() {
          if (!this.isSupportRecord())
              return;
          if (this.recordStatus == RECORD_STATUS.RECORDING) {
              this.bRestartFlag = true;
              mgrSdk.recordGameVideo("stop");
          }
          else {
              mgrSdk.recordGameVideo("start");
          }
      }
      static stopRecordGameVideo(bNotTip) {
          if (!this.isSupportRecord())
              return;
          if (bNotTip) {
              this.bNotTip = bNotTip;
          }
          else {
              this.bNotTip = false;
          }
          mgrSdk.recordGameVideo("stop");
      }
      static pauseRecordGameVideo() {
          if (!this.isSupportRecord())
              return;
          mgrSdk.recordGameVideo("pause");
      }
      static resumeRecordGameVideo() {
          if (!this.isSupportRecord())
              return;
          mgrSdk.recordGameVideo("resume");
      }
      static isSupportRecord() {
          if (!this.isCopOpenVideoRecord())
              return false;
          if (!this._userOpenVideoRecord)
              return false;
          if (!mgrGame.videoRecordEnable)
              return false;
          return true;
      }
      static setUserOpenVideoRecord(isOpen) {
          this._userOpenVideoRecord = !!isOpen;
          FileRecord.setData(RECORD_VIDEO_KEY, this._userOpenVideoRecord);
      }
      static getUserOpenVideoRecord() {
          return this._userOpenVideoRecord;
      }
      static canShare() {
          return this.recordStatus == RECORD_STATUS.RECORD_FINISH && this.lastRecordVideoTime >= this.minRecordTime;
      }
  }
  mgrVideoRecorder.lastRecordVideoTime = 0;
  mgrVideoRecorder.bRecordVideo = false;
  mgrVideoRecorder.recordStatus = RECORD_STATUS.PRE_RECORD;
  mgrVideoRecorder.minRecordTime = 5.5;
  mgrVideoRecorder.maxRecordTime = 60;
  mgrVideoRecorder.bPause = false;
  mgrVideoRecorder.bRestartFlag = false;
  mgrVideoRecorder._userOpenVideoRecord = true;
  mgrVideoRecorder.bNotTip = false;

  const RECORD_VIDEO_KEY$1 = "RecordVideioEnabled";
  const RECORD_ADD_GAME = "RecordAddGame";
  const RECORD_INSTALL_SHORTCUT = "RecordShortcut";
  let DEBUG_MODE$1 = false;
  const DIAMOND_ID = "1000";
  const COIN_ID = "1001";
  class mgrSdk {
      static get isUrlNotice() {
          return !!db.cop_db.url_notice;
      }
      static init() {
          switch (Global.SDK_VERSION) {
              case SDK_VERSIONS_VALUE.V6:
                  SDKBridge.registerCmd("/c/channelInfoResult", this.onChannelInfoResult_V6.bind(this));
                  SDKBridge.registerCmd("/c/copInfoResult", this.onCopInfoResult.bind(this));
                  SDKBridge.registerCmd("/c/payResult", this.onPayResult.bind(this));
                  SDKBridge.registerCmd("/c/prePayResult", this.onBeforePayResult.bind(this));
                  SDKBridge.registerCmd("/c/shareResult", this.onShareResult.bind(this));
                  SDKBridge.registerCmd("/c/appShareResult", this.onAppShareResult.bind(this));
                  SDKBridge.registerCmd("/c/exitGame", this.onExitGame.bind(this));
                  SDKBridge.registerCmd("/c/useCdkey", this.onUseCDKResult.bind(this));
                  SDKBridge.registerCmd("/c/lifeCycle", this.onLifeCycle.bind(this));
                  SDKBridge.registerCmd("/c/getClipboardDataResult", this.onGetClipboardDataResult.bind(this));
                  SDKBridge.registerCmd("/c/getBaseChannelInfoResult", this.onGetBaseChannelInfoResult.bind(this));
                  SDKBridge.registerCmd("/c/extraBonus", this.onExtraBonus.bind(this));
                  SDKBridge.registerCmd("/c/openJumpResult", this.onOpenJumpResult.bind(this));
                  SDKBridge.registerCmd("/c/jumpOtherGameResult", this.onJumpOtherGameResult.bind(this));
                  SDKBridge.registerCmd("/c/jumpOtherGameRewardResult", this.onJumpOtherGameRewardResult.bind(this));
                  SDKBridge.registerCmd("/c/addGameToMyFavoriteResult", this.onAddGameToMyFavoriteResult.bind(this));
                  SDKBridge.registerCmd("/c/installShortcutResult", this.onInstallShortcutResult.bind(this));
                  SDKBridge.registerCmd("/c/getShortcutStateResult", this.onGetShortcutStateResult.bind(this));
                  SDKBridge.registerCmd("/c/getUserDataResult", this.onGetUserDataResult.bind(this));
                  SDKBridge.registerCmd("/c/recorderGameVideoResult", this.onRecorderGameVideoResult.bind(this));
                  SDKBridge.registerCmd("/c/shareGameVideoResult", this.onShareGameVideoResult.bind(this));
                  SDKBridge.registerCmd("/c/userIsLoginResult", this.onUserIsLoginResult.bind(this));
                  SDKBridge.registerCmd("/c/userLoginResult", this.onUserLoginResult.bind(this));
                  SDKBridge.registerCmd("/c/followOfficialAccountResult", this.onFollowOfficialAccountResult.bind(this));
                  SDKBridge.registerCmd("/c/getFollowOfficialAccountStateResult", this.onGetFollowOfficialAccountStateResult.bind(this));
                  SDKBridge.registerCmd("/c/contentSecurityCheckResult", this.onContentSecurityCheckResult.bind(this));
                  SDKBridge.registerCmd("/c/changePatchInfo", this.onChangePatchInfo.bind(this));
                  SDKBridge.registerCmd("/c/changePatchInfo", this.onChangePatchInfo.bind(this));
                  SDKBridge.registerCmd("/c/checkTimeChangeResult", this.onCheckTimeChangeResult.bind(this));
                  SDKBridge.registerCmd("/c/getQqGroupNumResult", this.onGetQqGroupNumResult.bind(this));
                  SDKBridge.registerCmd("/c/joinQqGroupResult", this.onJoinQqGroupResult.bind(this));
                  SDKBridge.registerCmd("/c/jumpNewGuide", this.onJumpNewGuide.bind(this));
                  SDKBridge.registerCmd("/c/checkDebugWhiteUserResult", this.onCheckDebugWhiteUserResult.bind(this));
                  SDKBridge.registerCmd("/c/checkNetworkResult", this.onCheckNetworkResult.bind(this));
                  SDKBridge.registerCmd("/c/coverLocalStorage", this.onCoverLocalStorage.bind(this));
                  SDKBridge.registerCmd("/c/getSubscribeStateResult", this.onGetSubscribeStateResult.bind(this));
                  SDKBridge.registerCmd("/c/addSubscribeResult", this.onAddSubscribeResult.bind(this));
                  this.isAutoRecordVideo = FileRecord.getData(RECORD_VIDEO_KEY$1);
                  if (this.isAutoRecordVideo == null)
                      this.isAutoRecordVideo = true;
                  break;
              case SDK_VERSIONS_VALUE.V5:
                  SDKBridge.registerCmd("/c/payResult", this.onPayResult.bind(this));
                  SDKBridge.registerCmd("/c/exitGame", this.onExitGame.bind(this));
                  SDKBridge.registerCmd("/cdk/useCdkey", this.onUseCDKResult.bind(this));
                  break;
          }
          Global.registerListeners(this, {
              [BASE_MSG.BASE_MGR_LOADED]: this.onMsgBaseMgrLoaded.bind(this),
          });
          this.registerKeyboardListener();
          this.requestBaseChannelInfo();
          if (DEBUG_MODE$1) {
              Logger.error("SDK debug开启，如果了解请忽略。");
          }
      }
      static setVersion(chnData) {
          let path_info = window["PATCH_INFO"] || {};
          let data = {
              patchPid: path_info.P_ID || "",
              patchChannel: path_info.CHANNEL || "",
              patchHash: path_info.GIT_HASH || "",
          };
          if (Global.H5_TEST || DEBUG_MODE$1) {
              switch (Global.SDK_VERSION) {
                  case SDK_VERSIONS_VALUE.V6:
                      this.onChannelInfoResult_V6(chnData);
                      break;
                  case SDK_VERSIONS_VALUE.V5:
                      break;
              }
          }
          else {
              switch (Global.SDK_VERSION) {
                  case SDK_VERSIONS_VALUE.V5:
                      SDKBridge.sendToSdk("setVersion", data);
                      break;
                  case SDK_VERSIONS_VALUE.V6:
                      SDKBridge.sendToSdk("/c/setVersion", data);
                      break;
              }
          }
      }
      static registerKeyboardListener() {
          if (window[`conch`]) {
              window[`conch`].setOnBackPressedFunction(() => {
                  this.exitGame();
              });
          }
      }
      static onMsgBaseMgrLoaded() {
          this.bMgrLoaded = true;
          for (let i = this.allMgrLoadedMsgs.length - 1; i >= 0; i--) {
              let info = this.allMgrLoadedMsgs.shift();
              Global.sendMsg(info.msg, info.data);
          }
      }
      static sendMsg(msg, data) {
          Global.sendMsg(msg, data);
      }
      static getSubCop(key) {
          let subCopDb = db.get_sub_cop_map()[key];
          if (!subCopDb)
              return 0;
          let copValue = db.cop_db[subCopDb.copKey];
          if (!copValue)
              return 0;
          return copValue[subCopDb.idx];
      }
      static tryAddItem(itemId, count, reason) {
          let event = { itemId: itemId, count: count, reason: reason };
          if (this.bMgrLoaded) {
              Global.sendMsg(BASE_MSG.SDK_ADD_ITEM, event);
          }
          else {
              this.allMgrLoadedMsgs.push({ msg: BASE_MSG.SDK_ADD_ITEM, data: event });
          }
      }
      static onChannelInfoResult_V6(data) {
          console.log("-- > onChannelInfoResult_V6");
          console.log("lfy", data);
          if (!data)
              return;
          let payInfo = data.payInfo;
          let cardType = parseInt(data.cardType);
          db.cop_db.isAbout = !!data.isAbout;
          db.cop_db.isThirdExit = !!data.isThirdExit;
          db.cop_db.isShareEnabled = !!data.isShareEnabled;
          db.cop_db.isPayEnabled = !!data.isPayEnabled;
          db.cop_db.isULMoreGame = !!data.isULMoreGame;
          db.cop_db.isUseSdkRank = !!data.isUseSdkRank;
          db.cop_db.isWebView = !!data.isWebView;
          db.cop_db.isShowUrlAdIcon = !!data.isShowUrlAdIcon;
          db.cop_db.isSupportRecordShare = !!data.isSupportRecordShare;
          db.cop_db.isSupportInstallShortcut = !!data.isSupportInstallShortcut;
          db.cop_db.isSupportFindMinigames = !!data.isSupportFindMinigames;
          db.cop_db.isSupportRecommendationBtn = !!data.isSupportRecommendationBtn;
          db.cop_db.is4399Watermark = !!data.is4399Watermark;
          db.cop_db.isJumpLeisureEnabled = !!data.isJumpLeisureEnabled;
          db.cop_db.isSupportFollowOfficialAccount = !!data.isSupportFollowOfficialAccount;
          db.cop_db.isSupportFavoriteGuide = !!data.isSupportFavoriteGuide;
          db.cop_db.isSupportSubscription = !!data.isSupportSubscription;
          db.cop_db.isSupportUserCloudStorage = !!data.isSupportUserCloudStorage;
          db.cop_db.is_sdk_start_game_by_touch = (!!data.is_sdk_start_game_by_touch) ? 1 : 0;
          this._testJumpInfo = data.jumpInfo;
          if (data.appName) {
              this.h5_channel = data.appName.toString().toLowerCase();
          }
          if (this.h5_channel == "vivo") {
              console.error = console.warn;
              Logger.error = Logger.warn;
          }
          this.findmeImageUrl = data.findMinigamesImageUrl;
          this.ulsdkVersion = data.ulsdkVersion;
          this.packageVersion = data.packageVersion;
          this.uuid = data.uuid;
          this.hotfixCop_V6(data.copInfo);
          this.isChnResult = true;
      }
      static onCopInfoResult(data) {
          this.hotfixCop_V6(data.copInfo);
      }
      static hotfixCop_V6(jsonStr) {
          this.COP_INFO = jsonStr;
          let data;
          try {
              data = JSON.parse(jsonStr);
          }
          catch (error) {
              Logger.error(`hot fix cop [${jsonStr}] error:`, error);
              return;
          }
          let copDb = db.cop_db;
          let keys = Object.keys(copDb);
          for (let i = 0; i < keys.length; i++) {
              let key = keys[i];
              let copData = data[key];
              if (copData != null) {
                  switch (typeof copDb[key]) {
                      case "number":
                          copDb[key] = Tools.safeParseFloat(copData, 0);
                          break;
                      case "boolean":
                          copDb[key] = Tools.safeParseBool(copData);
                          break;
                      case "string":
                          copDb[key] = copData.toString();
                          break;
                      case "object":
                          if (copDb[key][0] == null) {
                              console.warn(`mgrSdk.hotfixCop_V6: cop_db中[${key}]值为空，默认当成数值型数组进行解析.`);
                          }
                          if (typeof copDb[key][0] == "string") {
                              copDb[key] = copData.toString().split(";");
                          }
                          else {
                              copDb[key] = Tools.splitToNumber(copData, ";");
                          }
                          break;
                      default:
                          break;
                  }
              }
          }
          mgrAdv.hotfixCop();
          Global.sendMsg(BASE_MSG.SDK_COP_CHANGED, data);
          console.log("mgrSdk.hotfixCop_V6");
      }
      static openPay(payCode, payId, callback, reason) {
          let userData = {
              payId: payId,
              reason: reason
          };
          this.payCallback = callback;
          switch (Global.SDK_VERSION) {
              case SDK_VERSIONS_VALUE.V6:
                  SDKBridge.sendToSdk("/c/openPay", { payId: payCode, userData: JSON.stringify(userData) });
                  break;
              case SDK_VERSIONS_VALUE.V5:
                  let payInfo = {
                      payId: payCode
                  };
                  SDKBridge.sendToSdk("/c/openPay", { payInfo: payInfo, userInfo: JSON.stringify(userData) });
                  break;
          }
          if (Global.H5_TEST || DEBUG_MODE$1) {
              this.onPayResult({ code: 1, msg: "" });
          }
      }
      static onPayResult(data) {
          Logger.log("onPayResult", data.code);
          if (this.payCallback) {
              this.payCallback(data.code == 1, data.payId, data.code == 2);
          }
      }
      static onBeforePayResult(data) {
          if (data.code != 1) {
              return;
          }
          let userData = JSON.parse(data.userData);
          let payId = userData.payId;
          console.log("onBeforePayResult payId: ", payId);
          if (payId) {
              if (this.bMgrLoaded) {
                  Global.sendMsg(BASE_MSG.SDK_PRE_PAY, payId);
              }
              else {
                  this.allMgrLoadedMsgs.push({ msg: BASE_MSG.SDK_PRE_PAY, data: payId });
              }
              console.log("已恢复购买payId:", payId);
          }
      }
      static share(userData = "none") {
          this._lastShareData = { userData: userData, time: Timer.time };
          let data = JSON.stringify(this._lastShareData);
          SDKBridge.sendToSdk("/c/openShare", {
              title: "",
              content: "",
              imagePath: "",
              url: "",
              userData: data,
          });
          if (Global.H5_TEST || DEBUG_MODE$1) {
              Timer.callLater(0.5, () => {
                  this.onShareResult({ code: 1, userData: data });
              });
          }
      }
      static onShareResult(data) {
          let curData = JSON.parse(data.userData);
          let code = data["code"];
          if (code == 1) {
              this.tryGetShareAward(true);
          }
          else {
              this._lastShareData = null;
              Global.sendMsg(BASE_MSG.SDK_SHARE_FAIL, curData.userData);
          }
      }
      static tryGetShareAward(bForce) {
          let data = this._lastShareData;
          if (data) {
              if (bForce || data.time + 4 < Timer.time) {
                  Global.sendMsg(BASE_MSG.SDK_SHARE_SUC, data.userData);
                  mgrTip.showMsgTip("分享成功");
                  if (Global.H5_TEST)
                      Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `[debug]:分享成功`);
                  this._lastShareData = null;
              }
          }
      }
      static getShareAwardCount() {
          return BaseFacade.mItem.getItemCount(3001);
      }
      static onAppShareResult(data) {
      }
      static exitGame() {
          if (db.cop_db.isThirdExit) {
              this.thirdExitGame();
          }
          else {
              this._exitGame();
          }
      }
      static thirdExitGame() {
          SDKBridge.sendToSdk("/c/exitGame", {});
      }
      static _exitGame() {
          Global.sendMsg(BASE_MSG.SDK_EXIT_GAME);
      }
      static onExitGame(data) {
          this._exitGame();
      }
      static sendCDK(cdkStr) {
          Logger.log("请求验证码:", cdkStr);
          if (!cdkStr) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "请输入兑换码!");
              return;
          }
          let curData = {
              userId: this.uuid,
              cdkStr: cdkStr,
              channelId: "0"
          };
          SDKBridge.sendToSdk("/c/useCdkey", curData);
          if (Global.H5_TEST || DEBUG_MODE$1) {
              Timer.callLater(1, () => {
                  this.onUseCDKResult({ code: "1", data: [{ goodsid: DIAMOND_ID, count: 1 }, { goodsid: COIN_ID, count: 1 }] });
              });
          }
      }
      static onUseCDKResult(data) {
          if (data.code == "1") {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "兑换码兑换成功！");
              for (const k in data.data) {
                  let v = data.data[k];
                  let itemid = v["goodsid"].toString();
                  let count = v["count"];
                  this.tryAddItem(itemid, count, 3);
              }
          }
          else if (data.code == "-1") {
              let str = data.data;
              if (str == "兑换码不在有效使用期") {
                  str = "兑换码兑换失败";
              }
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, str);
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "兑换码兑换失败");
          }
      }
      static onLifeCycle(data) {
          let lifeCycle = data.lifeCycle || "";
          switch (lifeCycle) {
              case "onBackPressed":
                  this.exitGame();
                  break;
              default:
                  break;
          }
      }
      static setClipboardData(clipStr, userData = "") {
          SDKBridge.sendToSdk("/c/setClipboardData", {
              clipboardData: clipStr,
              userData: userData,
          });
      }
      static getClipboardData(userData = "") {
          SDKBridge.sendToSdk("/c/getClipboardData", {
              userData: userData,
          });
      }
      static onGetClipboardDataResult(data) {
          if (data.code == 1) {
              let clipboardData = data.clipboardData;
              let userData = data.userData;
              let msg = data.msg;
          }
      }
      static requestBaseChannelInfo() {
          SDKBridge.sendToSdk("/c/getBaseChannelInfo");
      }
      static onGetBaseChannelInfoResult(data) {
          if (data) {
              this.baseChannelInfo = {
                  gameName: data.gameName || "",
                  gameLanguage: data.gameLanguage || "",
                  channelName: data.channelName || "",
                  appName: data.appName || "",
                  isShowLicenceInfo: !!data.isShowLicenceInfo,
                  licenceInfo: data.licenceInfo || "",
                  isShowAgeLevelInfo: !!data.isShowAgeLevelInfo,
                  ageLevelInfo: data.ageLevelInfo || "",
              };
              Global.sendMsg(BASE_MSG.SDK_BASE_CHANNEL_INFO_CHANGED);
          }
      }
      static getBaseChannelInfo() {
          return this.baseChannelInfo;
      }
      static openMoreGame() {
          SDKBridge.sendToSdk("/c/openMoreGame", {});
      }
      static openUlMoreGame() {
          console.log("openUlMoreGame");
          SDKBridge.sendToSdk("/c/openUlMoreGame", {});
      }
      static openJf() {
          SDKBridge.sendToSdk("/c/openJf", {});
      }
      static callPhone(phoneNum) {
          SDKBridge.sendToSdk("/c/callPhon", { phoneNum: phoneNum });
      }
      static openWebView(url) {
          SDKBridge.sendToSdk("/c/ulWebView", { url: url });
      }
      static openReview() {
          SDKBridge.sendToSdk("/c/openInviteComment", {});
      }
      static openUrlNotice() {
          if (db.cop_db.url_notice) {
              this.openWebView(db.cop_db.url_notice);
          }
      }
      static openMoreWonderful() {
          SDKBridge.sendToSdk("/c/jumpLeisureSubject", {});
      }
      static opentChannelMoreGameBox() {
          SDKBridge.sendToSdk("/c/openChannelMoreGameBox", {});
      }
      static onExtraBonus(data) {
          if (data && data.code == 1) {
              if (!FileRecord.getData("extraBonusReward")) {
                  console.log(`msg:${data.msg}  isInitGame:${data.isInitGame}`);
                  this.tryAddItem(DIAMOND_ID, 40, 4);
                  FileRecord.setData("extraBonusReward", true);
              }
          }
      }
      static openJump(type, count = 0) {
          SDKBridge.sendToSdk("/c/openJump", {
              gameIndex: 0,
              type: type,
              count: count,
          });
          if (Global.H5_TEST || DEBUG_MODE$1) {
              Timer.callLater(1, () => {
                  if (type == "single") {
                      this.onOpenJumpResult({
                          code: 1,
                          jumpInfo: [this._testJumpInfo[Mathf.random(this._testJumpInfo.length) - 1]],
                          type: type,
                      });
                  }
                  else {
                      this.onOpenJumpResult({
                          code: 1,
                          jumpInfo: this._testJumpInfo,
                          type: type,
                      });
                  }
              });
          }
      }
      static onOpenJumpResult(data) {
          let code = data.code;
          if (code == 1) {
              Global.sendMsg(BASE_MSG.SDK_OPEN_JUMP_RESULT, {
                  jumpInfo: data.jumpInfo,
                  type: data.type,
              });
          }
          else {
              console.warn("互推列表获取失败：", data.type, data.msg);
          }
      }
      static jumpOtherGame(gameIndex, type, userData = "") {
          Logger.log("jumpOtherGame:", gameIndex);
          SDKBridge.sendToSdk("/c/jumpOtherGame", {
              gameIndex: gameIndex,
              type: type,
              userData: userData,
          });
          if (Global.H5_TEST || DEBUG_MODE$1) {
              Timer.callLater(1, () => {
                  this.onJumpOtherGameResult({ code: 1, userData: userData });
                  if (type == "reward") {
                      for (var i = 0; i < this._testJumpInfo.length; i++) {
                          var info = this._testJumpInfo[i];
                          if (info.index == gameIndex) {
                              info.bReceived = true;
                              this.onJumpOtherGameRewardResult({ code: 1, rewards: info.rewards, userData: userData });
                              break;
                          }
                      }
                  }
              });
          }
      }
      static onJumpOtherGameResult(data) {
          if (data.code == 1) {
              let userData = data.userData;
              Global.sendMsg(BASE_MSG.SDK_JUMP_GAME_SUC, userData);
          }
          else {
              Logger.log(data.msg);
          }
      }
      static onJumpOtherGameRewardResult(data) {
          console.log("onJumpOtherGameRewardResult:", data.userData);
          if (data.code == 1) {
              let rewards = data.rewards;
              if (rewards && rewards.length) {
                  this.tryAddItem(rewards[0][0] + "", rewards[0][1], 5);
              }
              Global.sendMsg(BASE_MSG.SDK_JUMP_GAME_REWARD, data.userData);
          }
          else {
              console.warn("onJumpOtherGameRewardResult no reward:", data.msg);
          }
      }
      static addGameToMyFavorite(typeId = 0, content = "一键添加到我的小程序", userData = "") {
          console.log("mgrSdk addGameToMyFavorite.");
          SDKBridge.sendToSdk("/c/addGameToMyFavorite", {
              typeId: typeId,
              content: content,
              userData: userData,
          });
      }
      static hasAddGameToMyFavorite() {
          return !!FileRecord.getData(RECORD_ADD_GAME);
      }
      static onAddGameToMyFavoriteResult(data) {
          FileRecord.setData(RECORD_ADD_GAME, true);
          if (data) {
              if (data.code == 1) {
              }
          }
      }
      static installShortcut(userData = "") {
          console.log("mgrSdk installShortcut.");
          SDKBridge.sendToSdk("/c/installShortcut", { userData: userData });
          if (Global.H5_TEST) {
              Timer.callLater(0.5, () => {
                  this.onInstallShortcutResult({ code: 1, userData: userData });
                  Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "[debug]:添加到桌面成功");
              });
          }
      }
      static getShortcutState(userData = "") {
          console.log("mgrSdk getShortcutState");
          SDKBridge.sendToSdk("/c/getShortcutState", { userData: userData });
      }
      static isShortcutInstalled() {
          return FileRecord.getData(RECORD_INSTALL_SHORTCUT);
      }
      static onInstallShortcutResult(data) {
          let userData = data.userData;
          let msg = data.msg;
          if (data.code == 1 || data.code == 2) {
              FileRecord.setData(RECORD_INSTALL_SHORTCUT, true);
              Global.sendMsg(BASE_MSG.SDK_INSTALL_SHORTCUT_SUC, userData);
          }
          else {
              Logger.warn(msg);
          }
      }
      static onGetShortcutStateResult(data) {
          let code = data.code;
          let state = data.state;
          let bHasPrompt = !!data.bHasPrompt;
          let userData = data.userData;
          db.cop_db.isSupportInstallShortcut = state == 1;
          this.isInstallShortcutHasPrompt = bHasPrompt;
          Global.sendMsg(BASE_MSG.SDK_GET_SHORTCUT_STATE_SUC, {
              state: state,
              bHasPrompt: bHasPrompt,
              userData: userData,
          });
      }
      static get isInstallShortcut() {
          return !!FileRecord.getData(RECORD_INSTALL_SHORTCUT);
      }
      static saveUserData(userData) {
          SDKBridge.sendToSdk("/c/saveUserData", { userData: userData });
      }
      static getUserData() {
          SDKBridge.sendToSdk("/c/getUserData", {});
      }
      static onGetUserDataResult(data) {
          if (data.code == 1) {
              let userData = data.userData;
          }
      }
      static recordGameVideo(action, isRecordVoice = true, durationTime = 120) {
          console.log("recordGameVideo====", action);
          SDKBridge.sendToSdk("/c/recorderGameVideo", {
              action: action,
              isRecordVoice: isRecordVoice,
              durationTime: durationTime,
          });
      }
      static shareVideo(userData = "", videoTag = "") {
          if (mgrVideoRecorder.recordStatus != RECORD_STATUS.RECORD_FINISH)
              return;
          SDKBridge.sendToSdk("/c/shareGameVideo", { userData: userData, videoTag: videoTag });
          if (Global.H5_TEST || DEBUG_MODE$1 || GameGlobal.isDebug) {
              Timer.callLater(1, () => {
                  this.onShareGameVideoResult({ code: 1, userData: userData });
                  Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `[debug]:视频分享成功`);
              });
          }
      }
      static onRecorderGameVideoResult(data) {
          console.log("onRecorderGameVideoResult====", data);
          if (data) {
              let code = data.code;
              let bSuccessful = false;
              let action = "";
              let msg = data.msg;
              switch (code) {
                  case 0:
                      bSuccessful = false;
                      break;
                  case 1:
                      action = "start";
                      bSuccessful = true;
                      break;
                  case 2:
                      action = "pause";
                      bSuccessful = true;
                      break;
                  case 3:
                      action = "resume";
                      bSuccessful = true;
                      break;
                  case 4:
                      action = "stop";
                      bSuccessful = true;
                      break;
                  default:
                      bSuccessful = false;
                      return;
              }
              console.log("BASE_MSG.RECORD_GAME_VIDEO_RESULT.RECORD_GAME_VIDEO_RESULT===", action, bSuccessful);
              Global.sendMsg(BASE_MSG.RECORD_GAME_VIDEO_RESULT, {
                  bSuccessful: bSuccessful,
                  action: action,
                  msg: msg,
              });
          }
      }
      static onShareGameVideoResult(data) {
          if (data) {
              let msg = data.msg;
              let userData = data.userData;
              let bSuccessful = false;
              if (data.code == 1) {
                  bSuccessful = true;
                  console.log("分享视频成功");
                  Global.sendMsg(BASE_MSG.SDK_VIDEO_SHARE_SUC);
              }
              else {
                  console.log("分享视频失败");
                  Global.sendMsg(BASE_MSG.SDK_VIDEO_SHARE_FAIL);
              }
              Global.sendMsg(BASE_MSG.SHARE_VIDEO_RESULT, {
                  msg: msg,
                  userData: userData,
                  bSuccessful: bSuccessful,
              });
          }
      }
      static checkLoginState() {
          SDKBridge.sendToSdk("/c/userIsLogin", {});
          if (Global.H5_TEST) {
              Timer.callLater(0.5, () => {
                  this.onUserIsLoginResult({ loginStatus: false });
              });
          }
      }
      static onUserIsLoginResult(data) {
          this.isUserLogin = data.code == 1;
          Global.sendMsg(BASE_MSG.SDK_LOGIN_STATE, this.isUserLogin);
      }
      static login(userData = "") {
          SDKBridge.sendToSdk("/c/userLogin", { userData: userData });
          if (Global.H5_TEST) {
              Timer.callLater(0.5, () => {
                  this.onUserLoginResult({ code: 1, userData: userData });
              });
          }
      }
      static onUserLoginResult(data) {
          this.isUserLogin = data.code == 1;
          if (data.loginData && data.loginData.openId) {
              FileRecord.setUserId(data.loginData.openId);
          }
          Global.sendMsg(BASE_MSG.SDK_LOGIN_RESULT, this.isUserLogin);
      }
      static openCrossRecommend(left, top, typeId = 0) {
          console.log("mgrSdk openCrossRecommend");
          SDKBridge.sendToSdk("/c/openRecommendation", {
              typeId: typeId,
              style: {
                  left: left,
                  top: top,
              },
          });
      }
      static closeCrossRecommend() {
          console.log("mgrSdk closeCrossRecommend");
          SDKBridge.sendToSdk("/c/closeRecommendation", {});
      }
      static followOfficialAccount() {
          console.log("mgrSdk followOfficialAccount");
          SDKBridge.sendToSdk("/c/followOfficialAccount", {});
      }
      static getFollowOfficialAccountState() {
          console.log("mgrSdk getFollowOfficialAccountState");
          SDKBridge.sendToSdk("/c/getFollowOfficialAccountState", {});
      }
      static onFollowOfficialAccountResult(data) {
          let code = data.code;
          if (code == 1) {
              this.followState = 1;
              Global.sendMsg(BASE_MSG.SDK_FOLLOW_OFFICIAL_ACCOUNT_SUC, data);
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "暂时无法跳转，请重试");
          }
      }
      static onGetFollowOfficialAccountStateResult(data) {
          let code = data.code;
          let state = data.state;
          if (code == 1) {
              this.followState = state;
              Global.sendMsg(BASE_MSG.SDK_GET_FOLLOW_OFFICIAL_ACCOUNT_STATE_SUC, data);
          }
      }
      static onContentSecurityCheckResult(data) {
          Global.sendMsg(BASE_MSG.SDK_CONTENT_CHECK_RESULT, data);
      }
      static onChangePatchInfo(data) {
          if (data && data.bTest) {
              UpdaterScript.changeToTestPatchInfo();
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `切换到测试补丁`);
          }
          else {
              UpdaterScript.changeToNormalPatchInfo();
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `切换到正式补丁`);
          }
          SDKBridge.sendToSdk("/c/changePatchInfoResult", { code: 1 });
      }
      static contentSecurityCheck(type, content, userData = null) {
          SDKBridge.sendToSdk("/c/contentSecurityCheck", {
              type: type,
              content: content,
              userData: userData,
          });
          if (Global.H5_TEST || DEBUG_MODE$1) {
              Timer.callLater(0.5, () => {
                  this.onContentSecurityCheckResult({ code: 1, type: type, msg: "检查不通过", content: content, result: true, userData: userData });
              });
          }
      }
      static openAdvancedSetting() {
          SDKBridge.sendToSdk("/c/openAdvancedSetting");
      }
      static vibrate(type = "short", intensity = "light", userData = null) {
          SDKBridge.sendToSdk("/c/phoneVibrate", {
              type: type,
              intensity: intensity,
              userData: userData,
          });
      }
      static checkTimeChange() {
          SDKBridge.sendToSdk("/c/checkTimeChange", {});
      }
      static onCheckTimeChangeResult(data) {
          console.warn("获取服务器时间返回", data);
          Global.sendMsg(BASE_MSG.SDK_SERVER_TIME_CHANGE, data);
      }
      static getQqGroupNum() {
          SDKBridge.sendToSdk("/c/getQqGroupNum", {});
      }
      static onGetQqGroupNumResult(data) {
          this.numQQGroup = data.num;
          console.warn("获一键加群的qq群数量返回", data);
      }
      static joinQqGroup(index = 1, userData = "") {
          SDKBridge.sendToSdk("/c/joinQqGroup", {
              "index": index,
              "userData": userData,
          });
      }
      static onJoinQqGroupResult(data) {
      }
      static onJumpNewGuide() {
          Global.sendMsg(BASE_MSG.SDK_GUIDE_SKIP);
      }
      static checkDebugWhiteUserResult() {
          SDKBridge.sendToSdk("/c/checkDebugWhiteUserResult", {});
      }
      static onCheckDebugWhiteUserResult(data) {
          Global.sendMsg(BASE_MSG.SDK_CHECK_DEBUG_WHITE_USER_RESULT, data);
      }
      static getSubscribeState(subscribeId, userData = "") {
          SDKBridge.sendToSdk("/c/getSubscribeState", { subscribeId: subscribeId, userData: userData });
      }
      static onGetSubscribeStateResult(data) {
          Global.sendMsg(BASE_MSG.SDK_GET_SUBSCRIBE_STATE_RESULT, data);
      }
      static addSubscribe(subscribeId, userData = "") {
          SDKBridge.sendToSdk("/c/addSubscribe", { subscribeId: subscribeId, userData: userData });
      }
      static onAddSubscribeResult(data) {
          Global.sendMsg(BASE_MSG.SDK_ADD_SUBSCRIBE_RESULT, data);
      }
      static checkNetwork() {
          SDKBridge.sendToSdk("/c/checkNetwork", {});
          if (Global.H5_TEST || DEBUG_MODE$1) {
              Timer.callLater(1, () => {
                  this.onCheckNetworkResult({ code: 0, msg: "网络检测失败" });
              });
          }
      }
      static onCheckNetworkResult(data) {
          Global.sendMsg(BASE_MSG.SDK_CHECK_NETWORK_RESULT, data);
      }
      static onCoverLocalStorage(data) {
          FileRecord.forceCoverRecord(data.data);
          Laya.LocalStorage.setItem("B_SKIP_LOGO_ONCE", "true");
          Laya.SoundManager.stopAll();
          window.location.reload(true);
      }
  }
  mgrSdk.COP_INFO = "";
  mgrSdk.isChnResult = false;
  mgrSdk.isAutoRecordVideo = true;
  mgrSdk.isInstallShortcutHasPrompt = false;
  mgrSdk.isSupportJumpList = false;
  mgrSdk.isUserLogin = false;
  mgrSdk.h5_channel = "";
  mgrSdk.packageVersion = "0";
  mgrSdk.ulsdkVersion = "0";
  mgrSdk.isMusicEnable = false;
  mgrSdk.findmeImageUrl = "";
  mgrSdk.followState = 1;
  mgrSdk.uuid = "0";
  mgrSdk.lastOpenCheckTime = 0;
  mgrSdk.bMgrLoaded = false;
  mgrSdk.allMgrLoadedMsgs = [];
  mgrSdk._testJumpInfo = [];
  mgrSdk.baseChannelInfo = null;
  mgrSdk.numQQGroup = 0;

  class Utils {
      static Clamp(t, e, i) {
          return Math.max(Math.min(t, Math.max(e, i)), Math.min(e, i));
      }
      static getV3_ZERO() {
          var t = Laya.Vector3['ZERO'];
          if (t == null) {
              t = Laya.Vector3['_ZERO'];
          }
          return t;
      }
      static getV3_UP() {
          var t = Laya.Vector3['Up'];
          if (t == null) {
              t = Laya.Vector3['_Up'];
          }
          return t;
      }
      static getTransformForward(t) {
          var e = t['forward'];
          if (e == null) {
              e = new Laya.Vector3();
              t['getForward'](e);
          }
          return e;
      }
      static getTransformRight(t) {
          var e = t['right'];
          if (e == null) {
              e = new Laya.Vector3();
              t['getRight'](e);
          }
          return e;
      }
      static getTransformUp(t) {
          var e = t['up'];
          if (e == null) {
              e = new Laya.Vector3();
              t['getUp'](e);
          }
          return e;
      }
      static findNodeByPath(node, path, split = ".", debug) {
          var list = path.split(split);
          for (var i = 0; i < list.length; i++) {
              node = node.getChildByName(list[i]);
              if (node == null) {
                  console.log("findNodeByPath: Not found", list[i]);
                  return null;
              }
              if (debug) {
                  console.log("-->", list[i]);
              }
          }
          return node;
      }
      static findNodeByPathNoRoot(node, path, tag) {
          var list = path.split("/");
          for (var i = 1; i < list.length; i++) {
              node = node.getChildByName(list[i]);
              if (node == null) {
                  console.error("findNodeByPathNoRoot: Not found", path, list[i], tag);
                  return null;
              }
          }
          return node;
      }
      static findNodeByPathIndexNoRoot(node, path, tag) {
          var list = path.split("/");
          for (var i = 1; i < list.length; i++) {
              node = node.getChildAt(Number(list[i]));
              if (node == null) {
                  console.error("findNodeByPathIndexNoRoot: Not found", path, tag);
                  return null;
              }
          }
          return node;
      }
      static applyShader(sprite, shaderMaterial) {
          if (sprite instanceof Laya.MeshSprite3D) {
              let oldMat = sprite.meshRenderer.sharedMaterial;
              let newMat = new shaderMaterial();
              newMat.albedoTexture = oldMat.albedoTexture;
              newMat.albedoColorA = oldMat.albedoColorA;
              newMat.albedoColorR = oldMat.albedoColorR;
              newMat.albedoColorG = oldMat.albedoColorG;
              newMat.albedoColorB = oldMat.albedoColorB;
              sprite.meshRenderer.sharedMaterial = newMat;
          }
          let childNum = sprite.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.applyShader(sprite.getChildAt(i), shaderMaterial);
          }
      }
      static hex2rgb(hex) {
          var clr = new Laya.Vector3;
          return hex = hex.replace("#", ""), clr.x = parseInt(hex.substr(0, 2), 16) / 255, clr.y = parseInt(hex.substr(2, 2), 16) / 255, clr.z = parseInt(hex.substr(4, 2), 16) / 255, clr;
      }
      static hex2rgba(hex) {
          var clr = new Laya.Vector4;
          return hex = hex.replace("#", ""), clr.x = parseInt(hex.substr(0, 2), 16) / 255, clr.y = parseInt(hex.substr(2, 2), 16) / 255, clr.z = parseInt(hex.substr(4, 2), 16) / 255, hex.length > 6 ? clr.w = parseInt(hex.substr(6, 2), 16) / 255 : clr.w = 1, clr;
      }
      static fogOpen(scene3d, fogStart, fogRange) {
          scene3d.enableFog = true;
          scene3d.fogStart = fogStart;
          scene3d.fogRange = fogRange;
      }
      static fogColor(scene3d, camera, color) {
          if (color) {
              scene3d.fogColor = Utils.hex2rgb(color);
          }
          let fogColor = scene3d.fogColor;
          camera.clearColor.x = fogColor.x;
          camera.clearColor.y = fogColor.y;
          camera.clearColor.z = fogColor.z;
      }
      static setComponentValue(node, clas, key, value) {
          let comp = node.getComponent(clas);
          if (comp instanceof clas) {
              comp[key] = value;
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.setComponentValue(node.getChildAt(i), clas, key, value);
          }
      }
      static lightShadow(directionLight) {
          directionLight.shadowMode = Laya.ShadowMode.SoftHigh;
          directionLight.shadowDistance = 40;
          directionLight.shadowResolution = 1024;
          directionLight.shadowCascadesMode = Laya.ShadowCascadesMode.NoCascades;
          directionLight.shadowStrength = 0.7;
      }
      static openCastShadow(node) {
          if (node instanceof Laya.SkinnedMeshSprite3D) {
              node.skinnedMeshRenderer.castShadow = true;
          }
          else if (node instanceof Laya.MeshSprite3D) {
              node.meshRenderer.castShadow = true;
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.openCastShadow(node.getChildAt(i));
          }
      }
      static openReceiveShadow(node, filterName) {
          if (node instanceof Laya.MeshSprite3D) {
              if (filterName) {
                  if (node.name.indexOf(filterName) >= 0) {
                      node.meshRenderer.receiveShadow = true;
                  }
              }
              else {
                  node.meshRenderer.receiveShadow = true;
              }
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.openReceiveShadow(node.getChildAt(i), filterName);
          }
      }
      static buildStickJumpPath(StickJumpPath) {
          let positionRoot = StickJumpPath.transform.position;
          let pathArray = [];
          let point1;
          for (let i = 0; i < StickJumpPath.numChildren; i++) {
              let pointRoot = StickJumpPath.getChildAt(i);
              let point = pointRoot.getChildByName("Point");
              if (point) {
                  let p = point.transform.position;
                  if (i > 0) {
                      p.x = 0;
                      p.y -= point1.y;
                      p.z -= point1.z;
                  }
                  else {
                      point1 = point.transform.position;
                      p = new Laya.Vector3(0, 0, 0);
                  }
                  pathArray.push(p);
              }
          }
          return pathArray;
      }
      static checkProb(prob, max = 99) {
          let r = this.random(0, max);
          if (r < prob) {
              return true;
          }
          else {
              return false;
          }
      }
      static random(min, max) {
          if (min == null && max == null) {
              return Math.random();
          }
          else if (max == null) {
              return Math.floor(Math.random() * min + 1);
          }
          else {
              return Math.floor(Math.random() * (max - min + 1) + min);
          }
      }
      static randomOne(array) {
          if (array == null || array.length == 0)
              return null;
          let index = Mathf.random(0, array.length - 1);
          return array[index];
      }
      static calcWheelTarget(arr, weightKey) {
          let totalWeight = 0;
          for (let i = 0; i < arr.length; i++) {
              const v = arr[i];
              let w = parseInt(v[weightKey]);
              console.log(`*************轮盘算法************：index:${i}，权重：${w}`);
              if (isNaN(w)) {
                  console.warn("Utils.calcWheelTarget weight field not found! key=[" + weightKey + "]");
                  return null;
              }
              totalWeight += w;
          }
          let rw = this.random(totalWeight);
          for (let i = 0; i < arr.length; i++) {
              const v = arr[i];
              let w = parseInt(v[weightKey]);
              if (rw <= w) {
                  return v;
              }
              else {
                  rw -= w;
              }
          }
          return null;
      }
      static _randomsort(a, b) {
          return Math.random() > .5 ? -1 : 1;
      }
      static printTransform(tag, node) {
          node.transform.position.clone(), node.transform.rotationEuler.clone();
          console.log(tag, "position", node.transform.position.clone());
          console.log(tag, "rotation", node.transform.rotation.clone());
          console.log(tag, "rotationEuler", node.transform.rotationEuler.clone());
      }
      static getParentPath(node) {
          let path = "";
          while (node) {
              path += (node.name + "/");
              node = node.parent;
          }
          return path;
      }
      static setSpriteColor(sprite, colorStr) {
          let color = Utils.hex2rgb(colorStr);
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
          }
          if (mat instanceof Laya.BlinnPhongMaterial) {
              mat.albedoColorR = color.x;
              mat.albedoColorG = color.y;
              mat.albedoColorB = color.z;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              mat.albedoColorR = color.x;
              mat.albedoColorG = color.y;
              mat.albedoColorB = color.z;
          }
      }
      static setSpriteColorV4(sprite, color) {
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
          }
          if (mat)
              mat.albedoColor = color;
      }
      static getSpriteMaterials(sprite) {
          let mat = [];
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterials;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterials;
          }
          return mat;
      }
      static getSpriteMat(sprite) {
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
          }
          return mat;
      }
      static setSpriteMat(sprite, mat) {
          if (sprite instanceof Laya.MeshSprite3D) {
              sprite.meshRenderer.sharedMaterial = mat;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              sprite.skinnedMeshRenderer.sharedMaterial = mat;
          }
      }
      static getSpriteTextrue(sprite) {
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
          }
          if (mat instanceof Laya.BlinnPhongMaterial) {
              return mat.albedoTexture;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              return mat.albedoTexture;
          }
          else {
              console.error("getSpriteTextrue: Not found material!", sprite);
          }
          return null;
      }
      static getSpriteNormalTextrue(sprite) {
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
          }
          if (mat instanceof Laya.BlinnPhongMaterial) {
              return mat.normalTexture;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              return null;
          }
          else {
              console.error("getSpriteTextrue: Not found material!", sprite);
          }
          return null;
      }
      static getSpriteColor(sprite) {
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
          }
          if (mat)
              return mat.albedoColor;
      }
      static setSpriteTextrue(sprite, texture, defaultMaterial = Laya.BlinnPhongMaterial) {
          let mat;
          if (sprite instanceof Laya.MeshSprite3D) {
              mat = sprite.meshRenderer.sharedMaterial;
              if (mat == null && defaultMaterial) {
                  mat = new defaultMaterial();
                  sprite.meshRenderer.sharedMaterial = mat;
              }
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              mat = sprite.skinnedMeshRenderer.sharedMaterial;
              if (mat == null && defaultMaterial) {
                  mat = new defaultMaterial();
                  sprite.skinnedMeshRenderer.sharedMaterial = mat;
              }
          }
          if (mat instanceof Laya.BlinnPhongMaterial) {
              mat.albedoTexture = texture;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              mat.albedoTexture = texture;
          }
          else {
              console.error("setSpriteTexture: Not found material!", sprite);
          }
          return mat;
      }
      static setMaterialColor(mat, colorStr) {
          let color = Utils.hex2rgb(colorStr);
          if (mat instanceof Laya.BlinnPhongMaterial) {
              mat.albedoColorR = color.x;
              mat.albedoColorG = color.y;
              mat.albedoColorB = color.z;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              mat.albedoColorR = color.x;
              mat.albedoColorG = color.y;
              mat.albedoColorB = color.z;
          }
      }
      static cloneSpriteMaterial(sprite) {
          if (sprite instanceof Laya.MeshSprite3D) {
              let mat = sprite.meshRenderer.sharedMaterial.clone();
              sprite.meshRenderer.sharedMaterial = mat;
              return mat;
          }
          else if (sprite instanceof Laya.SkinnedMeshSprite3D) {
              let mat = sprite.skinnedMeshRenderer.sharedMaterial.clone();
              sprite.skinnedMeshRenderer.sharedMaterial = mat;
              return mat;
          }
      }
      static setSpriteColorAll(node, colorStr, filterName) {
          if (node instanceof Laya.MeshSprite3D) {
              if (filterName) {
                  if (node.name.indexOf(filterName) >= 0) {
                      Utils.setSpriteColor(node, colorStr);
                  }
              }
              else {
                  Utils.setSpriteColor(node, colorStr);
              }
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.setSpriteColorAll(node.getChildAt(i), colorStr, filterName);
          }
      }
      static setSpriteTilingOffset(node, x, y, z, w) {
          let mat = node.meshRenderer.sharedMaterial;
          if (mat instanceof Laya.BlinnPhongMaterial) {
              mat.tilingOffsetX = x;
              mat.tilingOffsetY = y;
              mat.tilingOffsetZ = z;
              mat.tilingOffsetW = w;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              mat.tilingOffsetX = x;
              mat.tilingOffsetY = y;
              mat.tilingOffsetZ = z;
              mat.tilingOffsetW = w;
          }
      }
      static isMeshSprite(node) {
          if (node instanceof Laya.MeshSprite3D || node instanceof Laya.SkinnedMeshSprite3D) {
              return true;
          }
          else {
              return false;
          }
      }
      static getSpriteTilingOffset(node) {
          let mat = node.meshRenderer.sharedMaterial;
          if (mat instanceof Laya.BlinnPhongMaterial) {
              return mat.tilingOffset;
          }
          else if (mat instanceof Laya.UnlitMaterial) {
              return mat.tilingOffset;
          }
          return null;
      }
      static getScreenPos(camera, inPos, outPos) {
          if (outPos == null) {
              outPos = new Laya.Vector4();
          }
          camera.viewport.project(inPos, camera.projectionViewMatrix, outPos);
          outPos.x = outPos.x / Laya.stage.clientScaleX;
          outPos.y = outPos.y / Laya.stage.clientScaleY;
          return outPos;
      }
      static numberFormat(num, digits) {
          const si = [
              { value: 1, symbol: "" },
              { value: 1E3, symbol: "K" },
              { value: 1E6, symbol: "M" },
              { value: 1E9, symbol: "G" },
              { value: 1E12, symbol: "T" },
              { value: 1E15, symbol: "P" },
              { value: 1E18, symbol: "E" }
          ];
          const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
          let i;
          for (i = si.length - 1; i > 0; i--) {
              if (num >= si[i].value) {
                  break;
              }
          }
          return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
      }
      static getTime() {
          return Date.now();
      }
      static getNodePathName(node) {
          if (node.parent) {
              return this.getNodePathName(node.parent) + "." + node.name;
          }
          else {
              return node.name;
          }
      }
      static vectorToDegree(dx, dy) {
          let degree = 0;
          if (dx != 0) {
              let yx = dy / dx;
              degree = Math.atan(yx) * 180 / Math.PI;
              if (dx < 0) {
                  degree += 180;
              }
              else if (dy < 0) {
                  degree = 360 + degree;
              }
          }
          else {
              if (dy == 0) {
                  degree = 0;
              }
              else if (dy > 0) {
                  degree = 90;
              }
              else {
                  degree = 270;
              }
          }
          return degree;
      }
      static zLookAt(transform, target, up) {
          let rotation = transform.rotation;
          Laya.Quaternion.lookAt(target, transform.position, up, rotation);
          rotation.invert(rotation);
          transform.rotation = rotation;
      }
      static zLookAtRotation(transform, target, up) {
          let rotation = transform.rotation;
          Laya.Quaternion.lookAt(target, transform.position, up, rotation);
          rotation.invert(rotation);
          return rotation;
      }
      static zLookAtDrection(transform, direction, up) {
          let rotation = transform.rotation;
          let Vector3 = Laya.Vector3;
          Laya.Quaternion.lookAt(direction, Vector3._ZERO, up, rotation);
          rotation.invert(rotation);
          transform.rotation = rotation;
      }
      static lookAtDrection(transform, direction, up) {
          let rotation = transform.rotation;
          let Vector3 = Laya.Vector3;
          Laya.Quaternion.lookAt(Vector3._ZERO, direction, up, rotation);
          rotation.invert(rotation);
          transform.rotation = rotation;
      }
      static getBackUp(transform) {
          let backup = new Laya.Vector3();
          transform.getForward(backup);
          backup.x = -backup.x;
          backup.y = -backup.y;
          backup.z = -backup.z;
          return backup;
      }
      static calcDistance(node1, node2) {
          return Laya.Vector3.distance(node1.transform.position, node2.transform.position);
      }
      static tweenProgress(progress, value, speed) {
          if (value <= 0 || value >= 100) {
              progress.value = value;
          }
          else if (speed > 0) {
              let deltaValue = Math.abs(progress.value - value);
              let time = deltaValue / speed;
              if (time > 0) {
                  progress.tweenValue(value, time);
              }
              else {
                  progress.value = value;
              }
          }
          else {
              progress.value = value;
          }
      }
      static createBoxTrans(p1, p2, p3, p4, p5, p6, p7, p8) {
          var vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
          var faces = [];
          faces.push([p1, p2, p3, p4]);
          faces.push([p5, p6, p7, p8]);
          faces.push([p1, p4, p8, p5]);
          faces.push([p2, p3, p7, p6]);
          faces.push([p4, p3, p7, p8]);
          faces.push([p1, p2, p6, p5]);
          var normalAndUV = [
              0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1,
              0, -1, 0, 0, 1, 0, -1, 0, 1, 1, 0, -1, 0, 1, 0, 0, -1, 0, 0, 0,
              -1, 0, 0, 0, 0, -1, 0, 0, 1, 0, -1, 0, 0, 1, 1, -1, 0, 0, 0, 1,
              1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1,
              0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1,
              0, 0, -1, 1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, -1, 1, 1
          ];
          let verticesData = [];
          let indexNormalAndUV = 0;
          for (let list of faces) {
              for (let point of list) {
                  verticesData.push(point.x);
                  verticesData.push(point.y);
                  verticesData.push(point.z);
                  for (let i = 0; i < 5; i++)
                      verticesData.push(normalAndUV[indexNormalAndUV++]);
              }
          }
          var vertices = new Float32Array(verticesData);
          var indices = new Uint16Array([
              0, 1, 2, 2, 3, 0,
              4, 7, 6, 6, 5, 4,
              8, 9, 10, 10, 11, 8,
              12, 15, 14, 14, 13, 12,
          ]);
          let PrimitiveMesh = Laya.PrimitiveMesh;
          let mesh = PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
          return new Laya.MeshSprite3D(mesh);
      }
      static createTriangleByPoint(p1, p2, p3, unit = 1) {
          var vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
          let HalfUnit = unit / 2;
          var vertices = new Float32Array([
              p1.x * unit - HalfUnit, (1 - p1.y) * unit - HalfUnit, 0, 0, 0, 1, p1.x, p1.y,
              p2.x * unit - HalfUnit, (1 - p2.y) * unit - HalfUnit, 0, 0, 0, 1, p2.x, p2.y,
              p3.x * unit - HalfUnit, (1 - p3.y) * unit - HalfUnit, 0, 0, 0, 1, p3.x, p3.y,
          ]);
          var indices = new Uint16Array([0, 1, 2]);
          var PrimitiveMesh = Laya.PrimitiveMesh;
          return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
      }
      static createTriangle(width = 1, height = 1) {
          var vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
          var halfWidth = width / 2;
          var halfHeight = height / 2;
          var vertices = new Float32Array([
              -halfWidth, halfHeight, 0, 0, 0, 1, 0, 0,
              halfWidth, halfHeight, 0, 0, 0, 1, 1, 0,
              -halfWidth, -halfHeight, 0, 0, 0, 1, 0, 1,
          ]);
          var indices = new Uint16Array([0, 1, 2]);
          var PrimitiveMesh = Laya.PrimitiveMesh;
          return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
      }
      static world2local(transform, value) {
          var localPosition = new Laya.Vector3();
          var Transform3D = Laya.Transform3D;
          var parentInvMat = Transform3D._tempMatrix0;
          transform.worldMatrix.invert(parentInvMat);
          Laya.Vector3.transformCoordinate(value, parentInvMat, localPosition);
          return localPosition;
      }
      static buttonDisable(button) {
          if (button.filters && button.filters.length > 0) {
              let colorFilter = button.filters[0];
              colorFilter.gray();
          }
          button.enabled = false;
      }
      static buttonEnable(button) {
          if (button.filters && button.filters.length > 0) {
              let colorFilter = button.filters[0];
              colorFilter.reset();
          }
          button.enabled = true;
      }
      static testRayCast(scene, camera) {
          var ray = new Laya.Ray(new Laya.Vector3(), new Laya.Vector3());
          var rayCastHit = new Laya.HitResult();
          camera.viewportPointToRay(new Laya.Vector2(Laya.stage.mouseX, Laya.stage.mouseY), ray);
          scene.physicsSimulation.rayCast(ray, rayCastHit, 300);
          console.log("testRayCast", ray, rayCastHit);
      }
      static processName(name) {
          return name.replace(/_/g, " ").trim();
      }
      static playEffect(node) {
          if (node == null)
              return;
          node.active = true;
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.play();
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.playEffect(node.getChildAt(i));
          }
      }
      static stopEffect(node) {
          if (node == null)
              return;
          node.active = false;
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.stop();
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.stopEffect(node.getChildAt(i));
          }
      }
      static changeEffectSpace(node, value) {
          if (node == null)
              return;
          node.active = true;
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.simulationSpace = value;
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              this.changeEffectSpace(node.getChildAt(i), value);
          }
      }
      static changeEffectColor(node, color) {
          if (node == null)
              return;
          node.active = true;
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.startColorConstant.x = color.x;
              node.particleSystem.startColorConstant.y = color.y;
              node.particleSystem.startColorConstant.z = color.z;
          }
          let childNum = node.numChildren;
          for (let i = 0; i < childNum; i++) {
              Utils.changeEffectColor(node.getChildAt(i), color);
          }
      }
      static changeEffectColorDeep(node, colorStr) {
          if (!colorStr)
              return;
          this.changeEffectColor(node, this.hex2rgb(colorStr));
      }
      static changeEffectColorByPath(parent, path, colorStr) {
          if (parent == null || !colorStr)
              return;
          let node = this.findNodeByPath(parent, path);
          if (node instanceof Laya.ShuriKenParticle3D) {
              let color = this.hex2rgb(colorStr);
              node.particleSystem.startColorConstant.x = color.x;
              node.particleSystem.startColorConstant.y = color.y;
              node.particleSystem.startColorConstant.z = color.z;
          }
      }
      static cdTimeFormat(second) {
          if (second >= 3600) {
              return this.dateFormat(second, "H:i:s");
          }
          else {
              return this.dateFormat(second, "i:s");
          }
      }
      static dateFormat(times, formats) {
          formats = formats || 'Y-m-d';
          var zero = function (value) {
              if (value < 10) {
                  return '0' + value;
              }
              return value;
          };
          var h = Math.floor(times / 3600);
          var m = Math.floor((times - h * 3600) / 60);
          var s = Math.floor((times - h * 3600 - m * 60));
          var hour = zero(h);
          var minite = zero(m);
          var second = zero(s);
          return formats.replace(/Y|m|d|H|i|s/ig, function (matches) {
              return ({
                  H: hour,
                  i: minite,
                  s: second
              })[matches];
          });
      }
      static getTimeByDate(h = 0, m = 0, s = 0) {
          var data = new Date();
          data.setHours(h);
          data.setMinutes(m, s);
          return data.getTime();
      }
      static WorldToScreen2(camera, point) {
          var pointA = this.InverseTransformPoint(camera.transform, point);
          var distance = pointA.z;
          var out = new Laya.Vector3();
          camera.viewport.project(point, camera.projectionViewMatrix, out);
          var value = new Laya.Vector3(out.x / Laya.stage.clientScaleX, out.y / Laya.stage.clientScaleY, distance);
          return value;
      }
      static InverseTransformPoint(origin, point) {
          var xx = new Laya.Vector3();
          origin.getRight(xx);
          var yy = new Laya.Vector3();
          origin.getUp(yy);
          var zz = new Laya.Vector3();
          origin.getForward(zz);
          var zz1 = new Laya.Vector3(-zz.x, -zz.y, -zz.z);
          var x = this.ProjectDistance(point, origin.position, xx);
          var y = this.ProjectDistance(point, origin.position, yy);
          var z = this.ProjectDistance(point, origin.position, zz1);
          var value = new Laya.Vector3(x, y, z);
          return value;
      }
      static ProjectDistance(A, C, B) {
          var CA = new Laya.Vector3();
          Laya.Vector3.subtract(A, C, CA);
          var angle = this.Angle2(CA, B) * Math.PI / 180;
          var distance = Laya.Vector3.distance(A, C);
          distance *= Math.cos(angle);
          return distance;
      }
      static Angle2(ma, mb) {
          var v1 = (ma.x * mb.x) + (ma.y * mb.y) + (ma.z * mb.z);
          var ma_val = Math.sqrt(ma.x * ma.x + ma.y * ma.y + ma.z * ma.z);
          var mb_val = Math.sqrt(mb.x * mb.x + mb.y * mb.y + mb.z * mb.z);
          var cosM = v1 / (ma_val * mb_val);
          if (cosM < -1)
              cosM = -1;
          if (cosM > 1)
              cosM = 1;
          var angleAMB = Math.acos(cosM) * 180 / Math.PI;
          return angleAMB;
      }
      static transformLocal2WorldPosition(transform, local, world) {
          Laya.Vector3.transformV3ToV3(local, transform.worldMatrix, world);
      }
      static transformLocal2WorldNormal(transform, local, world) {
          let Transform3D = Laya.Transform3D;
          var matrix = Transform3D._tempMatrix0;
          transform.localMatrix.invert(matrix);
          Laya.Vector3.TransformNormal(local, matrix, world);
      }
      static transformWorld2LocaldNormal(transform, world, local) {
          let Transform3D = Laya.Transform3D;
          var matrix = Transform3D._tempMatrix0;
          transform.worldMatrix.invert(matrix);
          Laya.Vector3.TransformNormal(world, matrix, local);
      }
      static transformWorld2LocalPosition(transform, world, local) {
          let Transform3D = Laya.Transform3D;
          var matrix = Transform3D._tempMatrix0;
          transform.worldMatrix.invert(matrix);
          Laya.Vector3.transformCoordinate(world, matrix, local);
      }
      static eulerToQuaternion(rotationEulerE) {
          let Transform3D = Laya.Transform3D;
          let rotation = new Laya.Quaternion;
          Laya.Quaternion.createFromYawPitchRoll(rotationEulerE.y / Transform3D._angleToRandin, rotationEulerE.x / Transform3D._angleToRandin, rotationEulerE.z / Transform3D._angleToRandin, rotation);
          return rotation;
      }
      static quaternionToEuler(rotation) {
          let Transform3D = Laya.Transform3D;
          let rotationEulerE = new Laya.Vector3;
          let eulerE = Transform3D._tempVector30;
          rotation.getYawPitchRoll(eulerE);
          rotationEulerE.x = eulerE.y * Transform3D._angleToRandin;
          rotationEulerE.y = eulerE.x * Transform3D._angleToRandin;
          rotationEulerE.z = eulerE.z * Transform3D._angleToRandin;
          return rotationEulerE;
      }
      static vector3ToQuaternion(vec3) {
          let rotation = new Laya.Quaternion;
          Laya.Quaternion.createFromYawPitchRoll(vec3.x, vec3.y, vec3.z, rotation);
          return rotation;
      }
      static quaternionToVector3(rotation) {
          let vec3 = new Laya.Vector3;
          rotation.getYawPitchRoll(vec3);
          return vec3;
      }
      static vector3ToEuler(vec3) {
          let Transform3D = Laya.Transform3D;
          let euler = new Laya.Vector3;
          euler.x = vec3.y * Transform3D._angleToRandin;
          euler.y = vec3.x * Transform3D._angleToRandin;
          euler.z = vec3.z * Transform3D._angleToRandin;
          return euler;
      }
      static eulerToVector3(euler) {
          let Transform3D = Laya.Transform3D;
          let vec3 = new Laya.Vector3;
          vec3.x = euler.y / Transform3D._angleToRandin;
          vec3.y = euler.x / Transform3D._angleToRandin;
          vec3.z = euler.z / Transform3D._angleToRandin;
          return vec3;
      }
      static getMesh(node) {
          let sharedMesh;
          if (node instanceof Laya.MeshSprite3D) {
              sharedMesh = node.meshFilter.sharedMesh;
          }
          else if (node instanceof Laya.SkinnedMeshSprite3D) {
              sharedMesh = node.meshFilter.sharedMesh;
          }
          else {
              console.warn("Utils.getMesh: not found Mesh data");
              return;
          }
          return sharedMesh;
      }
      static calculateBounds(vertices) {
          var min = new Laya.Vector3;
          var max = new Laya.Vector3;
          min.x = min.y = min.z = Number.MAX_VALUE;
          max.x = max.y = max.z = -Number.MAX_VALUE;
          for (var i = 0; i < vertices.length; i++) {
              var p = vertices[i];
              min.x = Math.min(min.x, p.x);
              min.y = Math.min(min.y, p.y);
              min.z = Math.min(min.z, p.z);
              max.x = Math.max(max.x, p.x);
              max.y = Math.max(max.y, p.y);
              max.z = Math.max(max.z, p.z);
          }
          return new Laya.BoundBox(min, max);
      }
      static addDebugLine(parent, direction, length, color = Laya.Color.RED) {
          let debugLine = new Laya.PixelLineSprite3D();
          debugLine.maxLineCount = 1;
          let to = direction.clone();
          to.x *= length;
          to.y *= length;
          to.z *= length;
          debugLine.addLine(new Laya.Vector3, direction, color, color);
          parent.addChild(debugLine);
      }
      static scaleNode(node, scale) {
          let localScale = node.transform.localScale;
          this.scaleVector3(localScale, scale);
          node.transform.localScale = localScale;
      }
      static scaleNodeSet(node, scale) {
          node.transform.localScaleX = scale;
          node.transform.localScaleY = scale;
          node.transform.localScaleZ = scale;
      }
      static scaleVector3(vec3, scale) {
          Laya.Vector3.scale(vec3, scale, vec3);
      }
      static callFuncWithName(caller, funcName) {
          let func = caller[funcName];
          if (func)
              func.bind(caller)();
      }
      static addSpriteFilter(sprite, filter) {
          if (sprite.filters) {
              sprite.filters.push(filter);
          }
          else {
              sprite.filters = [filter];
          }
      }
      static clearFilter(sprite) {
          sprite.filters = [];
      }
      static parseJsonSafe(jsonStr) {
          let jsonData = null;
          if (jsonStr) {
              try {
                  jsonData = JSON.parse(jsonStr);
              }
              catch (e) {
                  jsonData = null;
              }
          }
          return jsonData;
      }
      static lerp(start, end, percent) {
          return (start + percent * (end - start));
      }
      static isApp() {
          return window["conch"] != null;
      }
      static applyMixins(derivedCtor, baseCtors) {
          baseCtors.forEach(baseCtor => {
              Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
                  derivedCtor.prototype[name] = baseCtor.prototype[name];
              });
          });
      }
      static getRenderTextrue(sprite, texture2d, offsetx = 0, offsety = 0) {
          if (!texture2d)
              texture2d = new Laya.RenderTexture2D(sprite.width, sprite.height);
          sprite.drawToTexture2(sprite.width, sprite.height, offsetx, offsety, texture2d);
          return texture2d;
      }
      static toChineseNum(num) {
          const unit = ['', '十', '百', '千'];
          const counts = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', "十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九"];
          if (counts[num] != null)
              return counts[num];
          const pre = Math.floor(num / 10000);
          const next = num % 10000;
          let getfour = (mynum, flag = false) => {
              if (!mynum) {
                  return '';
              }
              let i = 0, str = '';
              while (flag ? i < 4 : mynum > 0) {
                  let count = mynum % 10;
                  mynum = Math.floor(mynum / 10);
                  str = (count ? counts[count] + unit[i] : str[0] == '零' ? '' : str.length && i ? '零' : '') + str;
                  i++;
              }
              return str;
          };
          return pre ? getfour(pre) + '万' + getfour(next, true) : getfour(num);
      }
      static sprintf(...args) {
          let string = args[0];
          for (let i = 1; i < args.length; i++) {
              let item = args[i];
              string = string.replace("%d", item);
          }
          return string;
      }
      static sprintfOrder(str, order, ...args) {
          for (let i = 0; i < args.length && i < order.length; i++) {
              let item = args[order[i]];
              str = str.replace("%d", item);
          }
          return str;
      }
      static extractOne(array) {
          if (array == null || array.length == 0)
              return null;
          let index = Mathf.random(0, array.length - 1);
          let result = array[index];
          array.splice(index, 1);
          return result;
      }
  }
  Utils.format = function () {
      var t = [];
      for (var e = 0; e < arguments.length; e++) {
          t[e] = arguments[e];
      }
      var i = undefined;
      if (t.length > 0) {
          i = t[0];
          for (var a = 1; a < t.length; a++) {
              if (t[a] != undefined) {
                  var s = new RegExp('({)' + a + '(})', 'g');
                  i = i.replace(s, t[a]);
              }
          }
      }
      return i;
  };
  Utils.randomRange = function (min, max) {
      return Math.random() * (max - min) + min;
  };
  Utils.keyOfMap = function (data, value) {
      for (var key in data) {
          if (data[key] == value)
              return key;
      }
      return null;
  };
  Utils.indexOfArray = function (array, value) {
      for (var i = 0; i < array.length; i++) {
          if (array[i] == value)
              return i;
      }
      return -1;
  };
  Utils.removeArrayItem = function (array, value) {
      var index = this.indexOfArray(array, value);
      if (index > -1) {
          array.splice(index, 1);
      }
  };
  Utils.randomItem = function (array) {
      if (array && array.length > 0) {
          return array[Utils.random(0, array.length - 1)];
      }
      else {
          return null;
      }
  };
  Utils.rollItem = function (array, index) {
      if (array && array.length > 0) {
          return array[index % array.length];
      }
      else {
          return null;
      }
  };
  Utils.randomSort = function (array) {
      array.sort(this._randomsort);
  };

  class CopHelper {
      static isCopCheckModeOpen() {
          let state = Timer.time - mgrSdk.lastOpenCheckTime > (db.cop_db.check_mode_cd || 0);
          if (!state) {
              console.log("打勾勾cd中", mgrSdk.lastOpenCheckTime);
          }
          return db.cop_db.check_mode && state;
      }
      static registCheckMode(panel) {
          let ctrlCheck = this.getControllerCheck(panel);
          let ctrlCheckType = this.getControllerCheckType(panel);
          let check = this.getCheckButton(panel);
          if (ctrlCheck && ctrlCheckType && check && this.isCopCheckModeOpen()) {
              ctrlCheck.setSelectedIndex(1);
              ctrlCheckType.setSelectedIndex(Utils.random(0, ctrlCheckType.pageCount - 1));
              check.selected = Utils.random(0, 100) > 50;
              mgrSdk.lastOpenCheckTime = Timer.time;
          }
      }
      static getCheckButton(panel) {
          return panel["btn_check"];
      }
      static getControllerCheck(panel) {
          return panel.resNode.getController("check");
      }
      static getControllerCheckType(panel) {
          return panel.resNode.getController("check_type");
      }
      static isCheckModeAd(panel) {
          let ctrl = this.getControllerCheckType(panel);
          let check = this.getCheckButton(panel);
          if (ctrl && check) {
              switch (ctrl.selectedIndex) {
                  case 0:
                      return check.selected;
                  case 1:
                      return !check.selected;
              }
          }
          return false;
      }
      static isClick4AD(panel) {
          return false;
      }
      static updateAreaMode(panel, copValue) {
          let ctrlArea = panel.resNode.getController("area");
          if (ctrlArea && copValue) {
              if (copValue < ctrlArea.pageCount) {
                  console.info("CopHelper.updateAreaMode: 区域模式激活", copValue);
                  ctrlArea.setSelectedIndex(copValue);
              }
              else {
                  console.error("CopHelper.updateAreaMode: cop配置错误", copValue, ctrlArea.pageCount);
              }
          }
          else {
              console.warn("CopHelper.updateAreaMode: 区域模式未激活", ctrlArea, copValue);
          }
      }
      static updateADController(panel, advName) {
          let ctrlAd = panel.resNode.getController("ad");
          if (ctrlAd) {
          }
      }
      static isDialogCDing(key) {
          let dialogDb = db.get_alert_dialog_db(key);
          if (dialogDb) {
              let cdTime = this.getCopValue(dialogDb.copCdKey, dialogDb.index);
              let curtTime = Timer.time;
              let lastTime = this.dialog2cd[key] || (curtTime - cdTime);
              let passTime = curtTime - lastTime;
              return passTime < cdTime;
          }
          return true;
      }
      static beginDialogCD(key) {
          this.dialog2cd[key] = Timer.time;
      }
      static onGamteStart() {
          this.timeCopStart = Timer.time;
      }
      static getGameRunTime() {
          return Timer.time - this.timeCopStart;
      }
      static checkDialog(key) {
          if (Global.isGuiding)
              return false;
          let dialogDb = db.get_alert_dialog_db(key);
          if (dialogDb) {
              if (this.getGameRunTime() >= this.getCopValue(dialogDb.copPreCDKey, dialogDb.index) && Mathf.randomEnable(this.getCopValue(dialogDb.copKey, dialogDb.index)) && !this.isDialogCDing(key)) {
                  return true;
              }
          }
          return false;
      }
      static showDialog(key, context) {
          if (this.checkDialog(key)) {
              this.beginDialogCD(key);
              let dialogDb = db.get_alert_dialog_db(key);
              if (dialogDb) {
                  Director.openPanelWithSingleton(dialogDb.panel, context);
                  return true;
              }
          }
          return false;
      }
      static showAdDialog(advName, panelName) {
          if (mgrAdv.checkActive(advName, true)) {
              Director.openPanel(panelName);
              return true;
          }
          else {
              return false;
          }
      }
      static showRewatchAdDialog(funcWatch, funcCancel) {
          mgrTip.alertPrompt("需要观看完整视频才能获得奖励", "提示", funcWatch, function () {
              if (funcCancel) {
                  funcCancel();
              }
          }, "确定", "取消");
      }
      static updateFingerShare(panel) {
          if (panel && panel.resNode) {
              let ctrlFinger = panel.resNode.getController("finger");
              if (ctrlFinger && db.cop_db.b_video_share_finger) {
                  ctrlFinger.setSelectedIndex(1);
              }
              else {
              }
          }
      }
      static updateController(panel, name) {
          if (panel && panel.resNode) {
              let ctrlFinger = panel.resNode.getController(name || "finger");
              if (ctrlFinger) {
                  ctrlFinger.setSelectedIndex(1);
              }
          }
      }
      static updateControllerDelay(ctrl, state) {
          if (db.cop_db.video_ad_close_delay > 0) {
              Laya.timer.once(db.cop_db.video_ad_close_delay * 1000, this, this.onControllerDelay, [ctrl, state]);
          }
          else {
              ctrl.selectedIndex = state;
          }
      }
      static onControllerDelay(ctrl, state) {
          ctrl.selectedIndex = state;
      }
      static updateButtonDelay(button) {
          if (db.cop_db.video_ad_close_delay > 0) {
              Laya.timer.once(db.cop_db.video_ad_close_delay * 1000, this, this.onButtonDelay, [button]);
          }
          else {
              button.visible = true;
          }
      }
      static onButtonDelay(button) {
          button.visible = true;
      }
      static updateControllerVisible(ctrl, value, stateTrue, stateFalse) {
          if (ctrl && stateTrue < ctrl.pageCount && stateFalse < ctrl.pageCount) {
              if (value)
                  ctrl.selectedIndex = stateTrue;
              else
                  ctrl.selectedIndex = stateFalse;
          }
      }
      static updateButtonVisible(button, value) {
          if (value)
              button.visible = true;
          else
              button.visible = false;
      }
      static getSubCopValue(key) {
          let subCopDb = db.get_sub_cop(key);
          if (subCopDb) {
              let copDb = db.cop_db[subCopDb.copKey];
              if (copDb && copDb.length && subCopDb.idx < copDb.length) {
                  return copDb[subCopDb.idx];
              }
          }
          return 0;
      }
      static getCopValue(key, idx) {
          let copDb = db.cop_db[key];
          if (copDb && copDb.length && idx < copDb.length) {
              return copDb[idx];
          }
          return 0;
      }
      static checkIsCDing(key, value) {
          let curtTime = Utils.getTime();
          let lastTime = this.lastCDTime[key];
          let passTime;
          if (lastTime) {
              passTime = (curtTime - lastTime) / 1000;
          }
          else {
              passTime = value;
          }
          let isCding = passTime < value;
          console.log("O_O CDing", key, isCding, passTime, value);
          return isCding;
      }
      static beginCDing(key) {
          this.lastCDTime[key] = Utils.getTime();
      }
      static isDialogCding(dialogDb) {
          return false;
      }
      static alertDialogQueue() {
          if (Global.isGuiding)
              return;
      }
      static initADChannel() {
          switch (mgrSdk.h5_channel) {
              case "douyin":
              case "toutiao":
                  this.indexADChannel = 1;
                  break;
          }
      }
      static updateADChannel(object) {
          if (!object)
              return;
          let ctrlChannel = object.getController("adChannel");
          if (this.indexADChannel && ctrlChannel && this.indexADChannel < ctrlChannel.pageCount) {
              ctrlChannel.setSelectedIndex(this.indexADChannel);
          }
      }
      static isShareOpen() {
          return this.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_share);
      }
      static updateSharePanel(panel) {
          let ctrlShare = panel.resNode.getController("share");
          if (ctrlShare && this.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_share)) {
              if (mgrVideoRecorder.isSupportRecord()) {
                  ctrlShare.setSelectedIndex(2);
              }
              else {
                  ctrlShare.setSelectedIndex(1);
              }
          }
          return ctrlShare;
      }
      static updateShareButton(button) {
          let state = button.getController("state");
          if (state) {
              if (mgrGame.getItemCount(3001) > 0) {
                  state.selectedIndex = 1;
              }
              else {
                  state.selectedIndex = 0;
                  let icon_reward = button.getChild("icon_reward").asLoader;
                  let text_reward = button.getChild("text_reward").asTextField;
                  let reward = mgrGame.getRewardByTime("share", 1, 25, false);
                  if (reward && icon_reward && text_reward) {
                      icon_reward.url = mgrGame.getItemIcon(reward.item_id);
                      text_reward.text = reward.item_num.toString();
                  }
              }
          }
      }
      static switchPosition(objA, objB) {
      }
      static isByteDanceChannel() {
          switch (mgrSdk.h5_channel) {
              case "douyin":
              case "toutiao":
                  return true;
          }
          return db.cop_db.isByteDance;
      }
      static updateByteController(object) {
          let bytedance = object.getController("bytedance");
          if (bytedance && this.isByteDanceChannel()) {
              bytedance.setSelectedIndex(1);
          }
      }
      static updateAdvButtonState(obj, advId) {
          if (!Laya.Browser.onPC && mgrNative.isHtml5Platform()) {
              let state = mgrAdv.checkActive(advId);
              obj.visible = state;
          }
      }
      static isBannerRecoverCDing() {
          let curtTime = Timer.time;
          return curtTime < this.cdBannerRecover;
      }
      static markBannerRecoverCDing() {
          let curtTime = Timer.time;
          this.cdBannerRecover = curtTime + db.cop_db.ui_itemget_button_banner_cd;
      }
  }
  CopHelper.dialog2cd = {};
  CopHelper.timeCopStart = 0;
  CopHelper.lastCDTime = {};
  CopHelper.indexADChannel = 0;
  CopHelper.isNeedSwitch = false;
  CopHelper.cdBannerRecover = 0;

  function INT(num) {
      return Math.floor(num);
  }
  function MIN(a, b) {
      return Math.min(a, b);
  }
  function ROUNDUP(num, i = 0) {
      let p = Math.pow(10, i);
      return Math.ceil(num * p) / p;
  }
  function ROUNDDOWN(num, i) {
      let p = Math.pow(10, i);
      return Math.floor(num * p) / p;
  }
  function ROUND(num) {
      return Math.round(num);
  }
  function RAND(min, max) {
      return Math.random() * (max - min) + min;
  }
  class Formula {
      static offlineCoin(towerLvMaxUpNeedCoin, offlineMinute) {
          return ROUND(towerLvMaxUpNeedCoin * offlineMinute / 30 * RAND(600, 800));
      }
      static offlineDiamond(towerLvMax, offlineMinute) {
          return 20 + ROUND(ROUNDUP(towerLvMax / 25) * 4 * offlineMinute / 6 * RAND(1.2, 1.6));
      }
      static enemyCoin(level) {
          return 3.2 + level / 12;
      }
      static bossCoin(level) {
          return (3.2 + level / 12) * 8;
      }
      static rushEnemyLimit(level) {
          return MIN(50 + level * 10, 5000);
      }
      static towerLvupCost(level) {
          let I31 = level;
          let $G$31 = 1;
          let $G$32 = 2;
          let $G$33 = 4;
          let $G$34 = 6;
          let $G$35 = 10;
          let $G$36 = 15;
          let $G$37 = 30;
          let $G$38 = 45;
          let $G$39 = 60;
          let $H$31 = 4;
          let $H$32 = 8;
          let $H$33 = 16;
          let $H$34 = 32;
          let $H$35 = 64;
          let $H$36 = 256;
          let $H$37 = 1024;
          let $H$38 = 2048;
          let $H$39 = 4096;
          return ROUNDUP(3 + I31 * $H$31 + ROUNDDOWN(I31 / $G$32, 0) * $H$32 + ROUNDDOWN(I31 / $G$33, 0) * $H$33 + ROUNDDOWN(I31 / $G$34, 0) * $H$34 + ROUNDDOWN(I31 / $G$35, 0) * $H$35 + ROUNDDOWN(I31 / $G$37, 0) * $H$37 + ROUNDDOWN(I31 / $G$38, 0) * $H$38 + ROUNDDOWN(I31 / $G$39, 0) * $H$39 + ROUNDDOWN(I31 / $G$36, 0) * $H$36, 0);
      }
      static enemyHP(data, P31) {
          let $R$31 = 0.15;
          let $R$32 = 0.1;
          let $R$33 = 0.05;
          let $R$34 = 0.03;
          let $R$35 = 0.05;
          let $R$36 = 0.07;
          let $R$37 = 0.1;
          let $R$38 = 0.2;
          let $R$39 = 0.3;
          let $R$40 = 0.5;
          let $R$41 = 0.7;
          let $R$42 = 1;
          let $Q$31 = 1;
          let $Q$32 = 2;
          let $Q$33 = 3;
          let $Q$34 = 5;
          let $Q$35 = 10;
          let $Q$36 = 20;
          let $Q$37 = 30;
          let $Q$38 = 50;
          let $Q$39 = 100;
          let $Q$40 = 200;
          let $Q$41 = 300;
          let $Q$42 = 500;
          let S31 = ROUNDUP(P31 * $R$31 + ROUNDDOWN(P31 / $Q$32, 0) * $R$32 + ROUNDDOWN(P31 / $Q$33, 0) * $R$33 + ROUNDDOWN(P31 / $Q$34, 0) * $R$34 + ROUNDDOWN(P31 / $Q$35, 0) * $R$35 + ROUNDDOWN(P31 / $Q$37, 0) * $R$37 + ROUNDDOWN(P31 / $Q$38, 0) * $R$38 + ROUNDDOWN(P31 / $Q$39, 0) * $R$39 + ROUNDDOWN(P31 / $Q$40, 0) * $R$40 + ROUNDDOWN(P31 / $Q$41, 0) * $R$41 + ROUNDDOWN(P31 / $Q$42, 0) * $R$42 + ROUNDDOWN(P31 / $Q$36, 0) * $R$36, 2);
          return ROUND(((P31 - 1) * 3 + 20) * (1 + S31));
      }
      static enemyATK(data, P31) {
          let $U$31 = 1;
          let $U$32 = 2;
          let $U$33 = 3;
          let $U$34 = 5;
          let $U$35 = 10;
          let $U$36 = 20;
          let $U$37 = 30;
          let $U$38 = 50;
          let $U$39 = 100;
          let $U$40 = 200;
          let $U$41 = 300;
          let $U$42 = 500;
          let $V$31 = 0.001;
          let $V$32 = 0.001;
          let $V$33 = 0.002;
          let $V$34 = 0.002;
          let $V$35 = 0.003;
          let $V$36 = 0;
          let $V$37 = 0;
          let $V$38 = 0;
          let $V$39 = 0;
          let $V$40 = 0;
          let $V$41 = 0;
          let $V$42 = 0;
          let W31 = ROUNDUP(P31 * $V$31 + ROUNDDOWN(P31 / $U$32, 0) * $V$32 + ROUNDDOWN(P31 / $U$33, 0) * $V$33 + ROUNDDOWN(P31 / $U$34, 0) * $V$34 + ROUNDDOWN(P31 / $U$35, 0) * $V$35 + ROUNDDOWN(P31 / $U$37, 0) * $V$37 + ROUNDDOWN(P31 / $U$38, 0) * $V$38 + ROUNDDOWN(P31 / $U$39, 0) * $V$39 + ROUNDDOWN(P31 / $U$40, 0) * $V$40 + ROUNDDOWN(P31 / $U$41, 0) * $V$41 + ROUNDDOWN(P31 / $U$42, 0) * $V$42 + ROUNDDOWN(P31 / $U$36, 0) * $V$36, 2);
          return ROUND(((150 + P31 * 10) / 20) * (1 + W31));
      }
      static bossHP(data, P31) {
          let $Y$31 = 1;
          let $Y$32 = 2;
          let $Y$33 = 3;
          let $Y$34 = 5;
          let $Y$35 = 10;
          let $Y$36 = 20;
          let $Y$37 = 30;
          let $Y$38 = 50;
          let $Y$39 = 100;
          let $Y$40 = 200;
          let $Y$41 = 300;
          let $Y$42 = 500;
          let $Z$31 = 0.15;
          let $Z$32 = 0.2;
          let $Z$33 = 0.35;
          let $Z$34 = 0.5;
          let $Z$35 = 0.65;
          let $Z$36 = 0.7;
          let $Z$37 = 1;
          let $Z$38 = 0;
          let $Z$39 = 0;
          let $Z$40 = 0;
          let $Z$41 = 0;
          let $Z$42 = 0;
          let AA31 = ROUNDUP(P31 * $Z$31 + ROUNDDOWN(P31 / $Y$32, 0) * $Z$32 + ROUNDDOWN(P31 / $Y$33, 0) * $Z$33 + ROUNDDOWN(P31 / $Y$34, 0) * $Z$34 + ROUNDDOWN(P31 / $Y$35, 0) * $Z$35 + ROUNDDOWN(P31 / $Y$37, 0) * $Z$37 + ROUNDDOWN(P31 / $Y$38, 0) * $Z$38 + ROUNDDOWN(P31 / $Y$39, 0) * $Z$39 + ROUNDDOWN(P31 / $Y$40, 0) * $Z$40 + ROUNDDOWN(P31 / $Y$41, 0) * $Z$41 + ROUNDDOWN(P31 / $Y$42, 0) * $Z$42 + ROUNDDOWN(P31 / $Y$36, 0) * $Z$36, 2);
          return ROUND(300 + ((P31 - 1) * 3 + 20) * (1 + AA31) * 8);
      }
      static bossATK(data, P31) {
          let $AC$31 = 1;
          let $AC$32 = 2;
          let $AC$33 = 3;
          let $AC$34 = 5;
          let $AC$35 = 10;
          let $AC$36 = 20;
          let $AC$37 = 30;
          let $AC$38 = 50;
          let $AC$39 = 100;
          let $AC$40 = 200;
          let $AC$41 = 300;
          let $AC$42 = 500;
          let $AD$31 = 0.001;
          let $AD$32 = 0.003;
          let $AD$33 = 0.005;
          let $AD$34 = 0.01;
          let $AD$35 = 0.02;
          let $AD$36 = 0.03;
          let $AD$37 = 0.05;
          let $AD$38 = 0.1;
          let $AD$39 = 0.15;
          let $AD$40 = 0.2;
          let $AD$41 = 0.25;
          let $AD$42 = 0.3;
          let AE31 = ROUNDUP(P31 * $AD$31 + ROUNDDOWN(P31 / $AC$32, 0) * $AD$32 + ROUNDDOWN(P31 / $AC$33, 0) * $AD$33 + ROUNDDOWN(P31 / $AC$34, 0) * $AD$34 + ROUNDDOWN(P31 / $AC$35, 0) * $AD$35 + ROUNDDOWN(P31 / $AC$37, 0) * $AD$37 + ROUNDDOWN(P31 / $AC$38, 0) * $AD$38 + ROUNDDOWN(P31 / $AC$39, 0) * $AD$39 + ROUNDDOWN(P31 / $AC$40, 0) * $AD$40 + ROUNDDOWN(P31 / $AC$41, 0) * $AD$41 + ROUNDDOWN(P31 / $AC$42, 0) * $AD$42 + ROUNDDOWN(P31 / $AC$36, 0) * $AD$36, 2);
          return ROUND(((100 + P31 * 10) / 30) * (1 + AE31) * 3);
      }
      static layerFinalWar(base, level, levelAdd) {
          return base + (level - 1) * levelAdd;
      }
      static rewardFinalWar(level, scale = 1) {
          return ROUNDUP((15 + (level - 1) * 10) * RAND(0.8, 1.2) * scale);
      }
      static test() {
          for (let i = 1; i <= 10; i++) {
              let hp = this.enemyHP(null, i);
              let atk = this.enemyATK(null, i);
              console.log("小怪", i, hp, atk);
          }
          for (let i = 1; i <= 10; i++) {
              let hp = this.bossHP(null, i);
              let atk = this.bossATK(null, i);
              console.log("BOSS", i, hp, atk);
          }
      }
  }

  class mgrFB extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static isFBCoinPass(id) {
          if (id == 0)
              return true;
          return this.getFBCoinPassCount(id) > 0;
      }
      static getFBCoinPassCount(id) {
          return this.data.fbCoinId2Count[id] || 0;
      }
      static setFBCoinPassCount(id, count) {
          this.data.fbCoinId2Count[id] = count;
          this.saveRecord();
      }
      static addFBCoinPassCount(id) {
          this.setFBCoinPassCount(id, this.getFBCoinPassCount(id) + 1);
      }
      static isFBItemPass(id) {
          if (id == 0)
              return true;
          return this.getFBItemPassCount(id) > 0;
      }
      static getFBItemPassCount(id) {
          return this.data.fbItemId2Count[id] || 0;
      }
      static setFBItemPassCount(id, count) {
          this.data.fbItemId2Count[id] = count;
          this.saveRecord();
      }
      static addFBItemPassCount(id) {
          this.setFBItemPassCount(id, this.getFBItemPassCount(id) + 1);
      }
      static getFBCoinMaxPass() {
          let listData = db.get_fb_coin_db_map();
          let maxxData = null;
          for (let i = 0; i < listData.length; i++) {
              let data = listData[i];
              if (this.isFBCoinPass(data.id)) {
                  maxxData = data;
              }
              else {
                  break;
              }
          }
          return maxxData;
      }
      static getFBItemMaxPass() {
          let listData = db.get_fb_holyitem_db_map();
          let maxxData = null;
          for (let i = 0; i < listData.length; i++) {
              let data = listData[i];
              if (this.isFBItemPass(data.id)) {
                  maxxData = data;
              }
              else {
                  break;
              }
          }
          return maxxData;
      }
  }
  mgrFB.RECORD_KEY = "game166_fb_v1.0";
  mgrFB.dataDefault = {
      fbCoinId2Count: {},
      fbItemId2Count: {},
  };

  class HolyItemMaker {
      static previewHolyItemByDropDb(dropDb, limit = 1) {
          let dropCount = limit || dropDb.holyitem_ids.length;
          let listHolyItems = [];
          if (dropCount) {
              let maxQuality = 0;
              let maxQualityWeight = 0;
              for (let quality = 0; quality < dropDb.holyitem_quality.length; quality++) {
                  let weight = dropDb.holyitem_quality[quality] || 0;
                  if (weight > maxQualityWeight) {
                      maxQualityWeight = weight;
                      maxQuality = quality;
                  }
              }
              let option = { quality: maxQuality };
              for (let i = 0; i < dropCount; i++) {
                  option.itemDb = db.get_holy_item_db_map()[dropDb.holyitem_ids[i]];
                  if (option.itemDb) {
                      let equip = this.buildHolyItemByOption(option);
                      listHolyItems.push(equip);
                  }
              }
          }
          return listHolyItems;
      }
      static dropHolyItemByDropDb(dropDb, option = null) {
          let dropCount = (option && option.dropCount) || 0;
          if (dropCount == 0) {
              let dropCountIdx = this.calcWeightIndex(dropDb.holyitem_weight);
              if (dropCountIdx < dropDb.holyitem_count.length) {
                  dropCount = dropDb.holyitem_count[dropCountIdx];
              }
          }
          let listHolyItems = [];
          if (dropCount) {
              let listQuality = [];
              listQuality.push({ quality: EQUIP_QUALITY.GREEN, weight: dropDb.holyitem_quality[0] || 0 });
              listQuality.push({ quality: EQUIP_QUALITY.BLUE, weight: dropDb.holyitem_quality[1] || 0 });
              listQuality.push({ quality: EQUIP_QUALITY.PURPLE, weight: dropDb.holyitem_quality[2] || 0 });
              listQuality.push({ quality: EQUIP_QUALITY.ORANGE, weight: dropDb.holyitem_quality[3] || 0 });
              option = option || {};
              option.itemIds = dropDb.holyitem_ids;
              option.itemIdsWight = dropDb.holyitem_ids_weight;
              for (let i = 0; i < dropCount; i++) {
                  let qualityItem = this.calcWeightItem(listQuality);
                  if (qualityItem) {
                      option.quality = qualityItem.quality;
                      let equip = this.buildHolyItemByOption(option);
                      listHolyItems.push(equip);
                  }
              }
          }
          return listHolyItems;
      }
      static buildValue(from, to) {
          return Math.round(Utils.randomRange(from, to) * 100) / 100;
          ;
      }
      static randomQuality() {
          let qualityDbs = db.get_holy_item_quality_map();
          return this.calcWeightItem(qualityDbs);
      }
      static buildHolyItemByOption(option = {}) {
          let equip = new HolyItem();
          equip.buildUID();
          let quality = option.quality;
          if (quality == null) {
              quality = this.randomQuality().quality;
          }
          let itemDb = option.itemDb || this.makeHolyItemClass(option.itemIds, option.itemIdsWight);
          let qualityDb = null;
          if (itemDb.quality_fixed > 0) {
              let quality_fixed_id = itemDb.quality_fixed - 1;
              qualityDb = db.get_holy_item_quality(quality_fixed_id);
              if (qualityDb) {
                  quality = quality_fixed_id;
              }
          }
          if (!qualityDb) {
              qualityDb = db.get_holy_item_quality(quality);
          }
          if (option.itemDbSub) {
              let itemDbSub = option.itemDbSub;
              equip.itemDbSub = itemDbSub;
              equip.data.subId = itemDbSub.id;
          }
          equip.itemDb = itemDb;
          equip.qualityDb = qualityDb;
          equip.data.quality = quality;
          equip.data.id = itemDb.id;
          equip.data.lv = 0;
          equip.data.new = true;
          equip.refreshLv();
          if (option.wordQuality)
              this.buildAttrByQuality(equip, option.wordQuality, option.wordIds);
          else
              this.buildAttr(equip);
          return equip;
      }
      static rebuildAttr(equip) {
          let wordList = db.get_holy_item_word_map();
          for (let word of equip.data.words) {
              if (word.quality == EQUIP_QUALITY.RED) {
                  let item = this.calcWeightItem(wordList);
                  if (item) {
                      let wordQuality = word.quality;
                      let vt = item["v" + (wordQuality + 1)];
                      if (vt) {
                          let min = vt[0] || 0;
                          let max = vt[1] || 0;
                          let vl = Utils.randomRange(min, max);
                          vl = Math.min(Number(vl.toFixed(1)), max);
                          word.id = item.id;
                          word.vl = vl;
                      }
                  }
              }
          }
          equip.refreshWord();
      }
      static buildAttr(equip, isPerfect = false) {
          let qualityDb = equip.qualityDb;
          if (!qualityDb)
              return;
          equip.data.words = [];
          let wordList = db.get_holy_item_word_map();
          if (qualityDb.use_word_quality) {
              for (let i = 0; i < qualityDb.word_quality_fix.length; i++) {
                  let item = this.calcWeightItem(wordList);
                  if (item) {
                      let wordQuality = qualityDb.word_quality_fix[i];
                      let vt = item["v" + (wordQuality + 1)];
                      if (vt) {
                          let min = vt[0] || 0;
                          let max = vt[1] || 0;
                          if (isPerfect) {
                              equip.data.words.push({ id: item.id, quality: wordQuality, lv: 0, vl: max });
                          }
                          else {
                              let vl = Utils.randomRange(min, max);
                              vl = Math.min(Number(vl.toFixed(1)), max);
                              equip.data.words.push({ id: item.id, quality: wordQuality, lv: 0, vl: vl });
                          }
                      }
                  }
              }
          }
          else {
              for (let i = 0; i < qualityDb.num_word; i++) {
                  let item = this.calcWeightItem(wordList);
                  if (item) {
                      let wordQuality = this.calcWeightIndex(qualityDb.word_quality_weight);
                      let vt = item["v" + (wordQuality + 1)];
                      if (vt) {
                          let min = vt[0] || 0;
                          let max = vt[1] || 0;
                          if (isPerfect) {
                              equip.data.words.push({ id: item.id, quality: wordQuality, lv: 0, vl: max });
                          }
                          else {
                              let vl = Utils.randomRange(min, max);
                              vl = Number(vl.toFixed(1));
                              vl = Math.min(Number(vl.toFixed(1)), max);
                              equip.data.words.push({ id: item.id, quality: wordQuality, lv: 0, vl: vl });
                          }
                      }
                  }
              }
          }
          for (let i = 1; i <= equip.level; i++) {
              if (i % 4 == 0) {
                  equip.randomLvupAttr();
              }
          }
          equip.refreshWord();
      }
      static buildAttrByQuality(equip, wordQualityFix, wordIdFix) {
          let qualityDb = equip.qualityDb;
          if (!qualityDb)
              return;
          wordIdFix = wordIdFix || [];
          equip.data.words = [];
          let wordList = db.get_holy_item_word_map();
          for (let i = 0; i < wordQualityFix.length; i++) {
              let wordId = wordIdFix[i] || 0;
              let item = db.get_holy_item_word_map()[wordId - 1];
              if (!item) {
                  item = this.calcWeightItem(wordList);
              }
              if (item) {
                  let wordQuality = wordQualityFix[i];
                  let vt = item["v" + (wordQuality + 1)];
                  if (vt) {
                      let min = vt[0] || 0;
                      let max = vt[1] || 0;
                      let vl = Utils.randomRange(min, max);
                      vl = Math.min(Number(vl.toFixed(1)), max);
                      equip.data.words.push({ id: item.id, quality: wordQuality, lv: 0, vl: vl });
                  }
              }
          }
          for (let i = 1; i <= equip.level; i++) {
              if (i % 4 == 0) {
                  equip.randomLvupAttr();
              }
          }
          equip.refreshWord();
      }
      static makeHolyItemClass(classIds = null, weightIds = null) {
          if (classIds && weightIds && classIds.length) {
              let listData = [];
              for (let i = 0; i < classIds.length; i++) {
                  let id = classIds[i];
                  listData.push({ data: db.get_holy_item_db(id), weight: weightIds[i] || 1 });
              }
              let item = this.calcWeightItem(listData);
              return item.data;
          }
          else {
              let listData = [];
              let dataMap = db.get_holy_item_db_map();
              for (let key in dataMap) {
                  listData.push(db.get_holy_item_db(key));
              }
              return this.calcWeightItem(listData);
          }
      }
      static makeHolyItemClassRandom(exceptId = "") {
          let listData = [];
          let dataMap = db.get_holy_item_db_map();
          for (let key in dataMap) {
              let itemDb = db.get_holy_item_db(key);
              if (exceptId != key && itemDb.smelt) {
                  listData.push(itemDb);
              }
          }
          return this.calcWeightItem(listData);
      }
      static calcWeightIndex(weights) {
          let weightTotal = 0;
          for (let i = 0; i < weights.length; i++) {
              weightTotal += weights[i];
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let idx = 0;
          for (let i = 0; i < weights.length; i++) {
              vpt += weights[i];
              if (r < vpt) {
                  idx = i;
                  break;
              }
          }
          return idx;
      }
      static calcWeightItem(items) {
          let weightTotal = 0;
          for (let i = 0; i < items.length; i++) {
              weightTotal += items[i].weight || 0;
          }
          let r = Utils.random(1, weightTotal);
          let vpt = 0;
          let item = null;
          for (let i = 0; i < items.length; i++) {
              vpt += items[i].weight || 0;
              if (r <= vpt) {
                  item = items[i];
                  break;
              }
          }
          return item;
      }
  }

  var BASE_ATTR;
  (function (BASE_ATTR) {
      BASE_ATTR[BASE_ATTR["HP"] = 0] = "HP";
      BASE_ATTR[BASE_ATTR["AD"] = 1] = "AD";
      BASE_ATTR[BASE_ATTR["AP"] = 2] = "AP";
      BASE_ATTR[BASE_ATTR["RANGE"] = 3] = "RANGE";
      BASE_ATTR[BASE_ATTR["CRIT"] = 4] = "CRIT";
      BASE_ATTR[BASE_ATTR["CRIT_DMG"] = 5] = "CRIT_DMG";
      BASE_ATTR[BASE_ATTR["ATK_SPEED"] = 6] = "ATK_SPEED";
      BASE_ATTR[BASE_ATTR["MP_RECOVER"] = 7] = "MP_RECOVER";
      BASE_ATTR[BASE_ATTR["DEF_AD"] = 8] = "DEF_AD";
      BASE_ATTR[BASE_ATTR["DEF_AP"] = 9] = "DEF_AP";
      BASE_ATTR[BASE_ATTR["MP"] = 10] = "MP";
      BASE_ATTR[BASE_ATTR["HURT_FACTOR"] = 11] = "HURT_FACTOR";
      BASE_ATTR[BASE_ATTR["DMG_REDUCT"] = 12] = "DMG_REDUCT";
      BASE_ATTR[BASE_ATTR["ANGRY"] = 13] = "ANGRY";
      BASE_ATTR[BASE_ATTR["ANGRY_RECOVER"] = 14] = "ANGRY_RECOVER";
      BASE_ATTR[BASE_ATTR["LEN_ENEMY"] = 15] = "LEN_ENEMY";
      BASE_ATTR[BASE_ATTR["FLEE"] = 15] = "FLEE";
      BASE_ATTR[BASE_ATTR["DMG_SUCK"] = 16] = "DMG_SUCK";
      BASE_ATTR[BASE_ATTR["NEXT_DMG_UP"] = 17] = "NEXT_DMG_UP";
      BASE_ATTR[BASE_ATTR["NEXT_DMG_CRIT"] = 18] = "NEXT_DMG_CRIT";
      BASE_ATTR[BASE_ATTR["NEXT_SKILL_SUPER"] = 19] = "NEXT_SKILL_SUPER";
      BASE_ATTR[BASE_ATTR["DMG_EX"] = 20] = "DMG_EX";
      BASE_ATTR[BASE_ATTR["SK_DOUBLE"] = 21] = "SK_DOUBLE";
      BASE_ATTR[BASE_ATTR["SK_REBOUND"] = 22] = "SK_REBOUND";
      BASE_ATTR[BASE_ATTR["SK_KILL"] = 23] = "SK_KILL";
      BASE_ATTR[BASE_ATTR["SK_KILL_R"] = 24] = "SK_KILL_R";
      BASE_ATTR[BASE_ATTR["SK_DMG_HP"] = 25] = "SK_DMG_HP";
      BASE_ATTR[BASE_ATTR["SK_TARGET_ADD"] = 26] = "SK_TARGET_ADD";
      BASE_ATTR[BASE_ATTR["SK_DMG_LUCK"] = 27] = "SK_DMG_LUCK";
      BASE_ATTR[BASE_ATTR["SK_MP_RECOVER"] = 28] = "SK_MP_RECOVER";
      BASE_ATTR[BASE_ATTR["SK_SUPER_MP_RECOVER"] = 29] = "SK_SUPER_MP_RECOVER";
      BASE_ATTR[BASE_ATTR["SK_STUN"] = 30] = "SK_STUN";
      BASE_ATTR[BASE_ATTR["SK_REVIVE"] = 31] = "SK_REVIVE";
      BASE_ATTR[BASE_ATTR["SK_HP_RECOVER"] = 32] = "SK_HP_RECOVER";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_DMG_HP"] = 33] = "SK_CIRCLE_DMG_HP";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_ADD_HP"] = 34] = "SK_CIRCLE_ADD_HP";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_ADD_AD"] = 35] = "SK_CIRCLE_ADD_AD";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_ADD_AP"] = 36] = "SK_CIRCLE_ADD_AP";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_ADD_ATK_SPEED"] = 37] = "SK_CIRCLE_ADD_ATK_SPEED";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_ADD_CRIT"] = 38] = "SK_CIRCLE_ADD_CRIT";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_ADD_CRIT_DMG"] = 39] = "SK_CIRCLE_ADD_CRIT_DMG";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_SLOW_ATK"] = 40] = "SK_CIRCLE_SLOW_ATK";
      BASE_ATTR[BASE_ATTR["SK_CIRCLE_SLOW_SPEED"] = 41] = "SK_CIRCLE_SLOW_SPEED";
      BASE_ATTR[BASE_ATTR["SK_SUPER_BUFF_AD_AP"] = 42] = "SK_SUPER_BUFF_AD_AP";
      BASE_ATTR[BASE_ATTR["SK_HP_MAX_DMG"] = 43] = "SK_HP_MAX_DMG";
      BASE_ATTR[BASE_ATTR["SK_SUPER_BUFF_CRIT"] = 44] = "SK_SUPER_BUFF_CRIT";
      BASE_ATTR[BASE_ATTR["SK_KILL_MP_RECOVER"] = 45] = "SK_KILL_MP_RECOVER";
      BASE_ATTR[BASE_ATTR["SK_SUPER_BUFF_ATK_SPEED"] = 46] = "SK_SUPER_BUFF_ATK_SPEED";
      BASE_ATTR[BASE_ATTR["SK_SUPER_BUFF_RANGE"] = 47] = "SK_SUPER_BUFF_RANGE";
      BASE_ATTR[BASE_ATTR["SK_ENERGE_NONE"] = 48] = "SK_ENERGE_NONE";
      BASE_ATTR[BASE_ATTR["SK_AP_CRIT"] = 49] = "SK_AP_CRIT";
      BASE_ATTR[BASE_ATTR["SK_HP_CRIT"] = 50] = "SK_HP_CRIT";
      BASE_ATTR[BASE_ATTR["SK_HURT_DAMAGE_RECOVER_HP"] = 51] = "SK_HURT_DAMAGE_RECOVER_HP";
      BASE_ATTR[BASE_ATTR["SK_HURT_HP_R_RECOVER_MP"] = 52] = "SK_HURT_HP_R_RECOVER_MP";
      BASE_ATTR[BASE_ATTR["SK_HURT_NEXT_WUDI"] = 53] = "SK_HURT_NEXT_WUDI";
      BASE_ATTR[BASE_ATTR["SK_SKILL_RECOVER_HP"] = 54] = "SK_SKILL_RECOVER_HP";
      BASE_ATTR[BASE_ATTR["SK_HURT_REBOUND"] = 55] = "SK_HURT_REBOUND";
      BASE_ATTR[BASE_ATTR["SK_HURT_SELF_4_DAMAGE"] = 56] = "SK_HURT_SELF_4_DAMAGE";
      BASE_ATTR[BASE_ATTR["SK_ATK_SPEED_DOWN_4_DAMAGE"] = 57] = "SK_ATK_SPEED_DOWN_4_DAMAGE";
      BASE_ATTR[BASE_ATTR["SK_NO_CRIT_4_DAMAGE"] = 58] = "SK_NO_CRIT_4_DAMAGE";
      BASE_ATTR[BASE_ATTR["SK_DEAD_4_WUDI"] = 59] = "SK_DEAD_4_WUDI";
      BASE_ATTR[BASE_ATTR["SK_HP_R_DAMGE"] = 60] = "SK_HP_R_DAMGE";
      BASE_ATTR[BASE_ATTR["SK_DEAD_4_BUFF"] = 61] = "SK_DEAD_4_BUFF";
      BASE_ATTR[BASE_ATTR["SK_BLOOD_4_DAMAGE"] = 62] = "SK_BLOOD_4_DAMAGE";
      BASE_ATTR[BASE_ATTR["SK_MP_4_DAMAGE"] = 63] = "SK_MP_4_DAMAGE";
      BASE_ATTR[BASE_ATTR["SK_TA_01"] = 64] = "SK_TA_01";
      BASE_ATTR[BASE_ATTR["SK_TA_03"] = 65] = "SK_TA_03";
      BASE_ATTR[BASE_ATTR["SK_TA_04"] = 66] = "SK_TA_04";
      BASE_ATTR[BASE_ATTR["SK_TA_05"] = 67] = "SK_TA_05";
      BASE_ATTR[BASE_ATTR["SK_TA_09"] = 68] = "SK_TA_09";
      BASE_ATTR[BASE_ATTR["SK_TA_10"] = 69] = "SK_TA_10";
      BASE_ATTR[BASE_ATTR["SK_TA_12"] = 70] = "SK_TA_12";
      BASE_ATTR[BASE_ATTR["SK_TA_13"] = 71] = "SK_TA_13";
      BASE_ATTR[BASE_ATTR["SK_TA_18"] = 72] = "SK_TA_18";
      BASE_ATTR[BASE_ATTR["SK_TA_20"] = 73] = "SK_TA_20";
      BASE_ATTR[BASE_ATTR["SK_TA_21"] = 74] = "SK_TA_21";
      BASE_ATTR[BASE_ATTR["TT_TARGET_ADD"] = 75] = "TT_TARGET_ADD";
      BASE_ATTR[BASE_ATTR["TT_BLOOD"] = 76] = "TT_BLOOD";
      BASE_ATTR[BASE_ATTR["TT_BOMB"] = 77] = "TT_BOMB";
      BASE_ATTR[BASE_ATTR["TT_HUNT_BOSS"] = 78] = "TT_HUNT_BOSS";
      BASE_ATTR[BASE_ATTR["TT_HUNT_ENEMY"] = 79] = "TT_HUNT_ENEMY";
      BASE_ATTR[BASE_ATTR["TT_CROSSBOW_ADD"] = 80] = "TT_CROSSBOW_ADD";
      BASE_ATTR[BASE_ATTR["TT_CROSSBOW_PEN"] = 81] = "TT_CROSSBOW_PEN";
      BASE_ATTR[BASE_ATTR["TT_CROSSBOW_BOMB"] = 82] = "TT_CROSSBOW_BOMB";
      BASE_ATTR[BASE_ATTR["TT_CROSSBOW_HUNT_BOSS"] = 83] = "TT_CROSSBOW_HUNT_BOSS";
      BASE_ATTR[BASE_ATTR["LEN_TOWER"] = 84] = "LEN_TOWER";
  })(BASE_ATTR || (BASE_ATTR = {}));
  var TOWER_TARGET_SEARCH_TYPE;
  (function (TOWER_TARGET_SEARCH_TYPE) {
      TOWER_TARGET_SEARCH_TYPE[TOWER_TARGET_SEARCH_TYPE["NEAREST_LOCK"] = 0] = "NEAREST_LOCK";
      TOWER_TARGET_SEARCH_TYPE[TOWER_TARGET_SEARCH_TYPE["NEAREST"] = 1] = "NEAREST";
      TOWER_TARGET_SEARCH_TYPE[TOWER_TARGET_SEARCH_TYPE["HP_LESS"] = 2] = "HP_LESS";
  })(TOWER_TARGET_SEARCH_TYPE || (TOWER_TARGET_SEARCH_TYPE = {}));
  var UNIT_REMOVE_REASON;
  (function (UNIT_REMOVE_REASON) {
      UNIT_REMOVE_REASON[UNIT_REMOVE_REASON["NONE"] = 0] = "NONE";
      UNIT_REMOVE_REASON[UNIT_REMOVE_REASON["DEAD"] = 1] = "DEAD";
      UNIT_REMOVE_REASON[UNIT_REMOVE_REASON["DEAD_BOSS"] = 2] = "DEAD_BOSS";
  })(UNIT_REMOVE_REASON || (UNIT_REMOVE_REASON = {}));
  var DROP_TYPE;
  (function (DROP_TYPE) {
      DROP_TYPE[DROP_TYPE["TOWER"] = 0] = "TOWER";
      DROP_TYPE[DROP_TYPE["HOLY_ITEM"] = 1] = "HOLY_ITEM";
      DROP_TYPE[DROP_TYPE["ITEM"] = 2] = "ITEM";
  })(DROP_TYPE || (DROP_TYPE = {}));
  var StageConfig = {
      showFPS: false,
      forceTowerLvupStar: false,
      enableEnemyWave: true,
      enableTowerAttack: true,
      configTouchEnemy: {
          enable: false,
          enemyId: "2",
          attack: false,
      },
      enableEnemyTouchRemove: false,
      keepSuperSkill: false,
      handSuperSkill: false,
      attrNoRecover: {
          [BASE_ATTR.HP]: true,
          [BASE_ATTR.MP]: true,
          [BASE_ATTR.DMG_SUCK]: true,
      },
      showCollisionArea: false,
      gameTimeScale: 1,
      enableGameEffect: true,
      towerTargetSearchType: TOWER_TARGET_SEARCH_TYPE.NEAREST_LOCK,
      isShortcutNoticed: false,
      scaleProbDropItem: 1,
      useLocalTime: false,
  };

  class mgrTaskSeven extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrTalent.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onDifferentDay() {
          let maxDay = this.getDayMax();
          if (this.data.day < maxDay) {
              this.data.day++;
              this.saveRecord();
          }
      }
      static set curtDay(day) {
          this.data.day = day;
          this.saveRecord();
      }
      static get curtDay() {
          let day = this.data.day;
          if (day < 0) {
              day = 0;
              this.data.day = day;
              this.saveRecord();
          }
          return day;
      }
      static set curtScore(score) {
          this.data.score = score;
          this.saveRecord();
      }
      static get curtScore() {
          return this.data.score;
      }
      static getCurtTaskSevenDb() {
          return db.get_seven_task_db(this.curtDay);
      }
      static getCurtTasks() {
          let tasks = [];
          let seven_task_db = this.getCurtTaskSevenDb();
          if (seven_task_db) {
              for (let id of seven_task_db.task_ids) {
                  let taskDb = db.get_task_db(id);
                  if (taskDb) {
                      tasks.push(taskDb);
                  }
              }
          }
          return tasks;
      }
      static getTasksByDay(day) {
          let tasks = [];
          let seven_task_db = db.get_seven_task_db(day);
          if (seven_task_db) {
              for (let id of seven_task_db.task_ids) {
                  let taskDb = db.get_task_db(id);
                  if (taskDb) {
                      tasks.push(taskDb);
                  }
              }
          }
          return tasks;
      }
      static getScoreMax() {
          let arr = db.get_seven_score_db_map();
          let max = arr[arr.length - 1];
          if (max) {
              return max.score;
          }
          else {
              return 1;
          }
      }
      static getDayMax() {
          let arr = db.get_seven_task_db_map();
          let max = arr[arr.length - 1];
          if (max) {
              return max.day - 1;
          }
          else {
              return 0;
          }
      }
      static isCurtAllTaskComplete() {
          let isAllComplete = true;
          let seven_task_db = this.getCurtTaskSevenDb();
          if (seven_task_db) {
              for (let id of seven_task_db.task_ids) {
                  let taskDb = db.get_task_db(id);
                  if (taskDb) {
                      if (!mgrTask.isTaskCompleteByDB(taskDb)) {
                          isAllComplete = false;
                          break;
                      }
                  }
              }
          }
          return isAllComplete;
      }
      static isCurtAllTaskAward(seven_task_db) {
          let isAllComplete = true;
          if (seven_task_db) {
              for (let id of seven_task_db.task_ids) {
                  if (!mgrTask.isTaskAward(id)) {
                      isAllComplete = false;
                      break;
                  }
              }
          }
          return isAllComplete;
      }
      static addSevenScore(add, msg = false) {
          this.curtScore += add;
          if (msg) {
              Global.sendMsg(MSG.TASK_SEVEN_SCORE);
          }
      }
      static getDayId2Reward(day) {
          return this.data.dayid2reward[day];
      }
      static markDayMaxReward(day) {
          this.data.dayid2reward[day] = 1;
          this.saveRecord();
      }
      static isDayMaxADReward(day) {
          return this.getDayId2Reward(day) == 2;
      }
      static markDayMaxRewardAD(day) {
          this.data.dayid2reward[day] = 2;
          this.saveRecord();
      }
      static isScoreReward(id) {
          return this.data.scoreid2reward[id];
      }
      static markScoreReward(id) {
          this.data.scoreid2reward[id] = true;
          this.saveRecord();
      }
      static getDayMaxReward(data) {
          if (mgrHolyItem.notEnoughEmptyByItemId(data.item_id, data.item_count)) {
              return;
          }
          if (!this.getDayId2Reward(data.day - 1) && this.isCurtAllTaskAward(data)) {
              mgrGame.addItem(data.item_id, data.item_count, 50, true, null, () => {
                  this.markDayMaxReward(data.day - 1);
                  Global.sendMsg(MSG.TASK_SEVEN_TODAY_MAX_REWARD);
              });
              return true;
          }
          return false;
      }
      static getDayMaxRewardAD(data) {
          if (mgrHolyItem.notEnoughEmptyByItemId(data.item_id, data.item_count)) {
              return;
          }
          if (this.getDayId2Reward(data.day - 1) == 1 && this.isCurtAllTaskAward(data)) {
              mgrGame.addItem(data.item_id, data.item_count, 50, true, null, () => {
                  this.markDayMaxRewardAD(data.day - 1);
                  Global.sendMsg(MSG.TASK_SEVEN_TODAY_MAX_REWARD);
              });
              return true;
          }
          return false;
      }
      static getScoreReward(data) {
          if (mgrHolyItem.notEnoughEmptyByItemId(data.item_id, data.item_count)) {
              return;
          }
          if (!this.isScoreReward(data.id) && this.curtScore >= data.score) {
              mgrGame.addItem(data.item_id, data.item_count, 50, true, null, () => {
                  this.markScoreReward(data.id);
                  Global.sendMsg(MSG.TASK_SEVEN_SCORE_REWARD);
              });
              return true;
          }
          return false;
      }
      static isAnyTaskCanReward() {
          let canReward = false;
          let scores = db.get_seven_score_db_map();
          for (let score of scores) {
              if (this.curtScore >= score.score && !this.isScoreReward(score.id)) {
                  canReward = true;
                  break;
              }
          }
          if (!canReward) {
              let arr = db.get_seven_task_db_map();
              for (let taskDb of arr) {
                  if (this.isAnyTaskCanRewardByDay(taskDb)) {
                      canReward = true;
                      break;
                  }
              }
          }
          return canReward;
      }
      static isNeedShow() {
          let needShow = false;
          let scores = db.get_seven_score_db_map();
          for (let score of scores) {
              if (!this.isScoreReward(score.id)) {
                  needShow = true;
                  break;
              }
          }
          if (!needShow) {
              let arr = db.get_seven_task_db_map();
              for (let taskDb of arr) {
                  if (this.isAnyTaskHaveRewardByDay(taskDb)) {
                      needShow = true;
                      break;
                  }
              }
          }
          return needShow;
      }
      static isAnyTaskHaveRewardByDay(seven_task_db) {
          let haveReward = false;
          if (seven_task_db) {
              haveReward = this.getDayId2Reward(seven_task_db.day - 1) != 2;
              if (!haveReward) {
                  for (let id of seven_task_db.task_ids) {
                      let taskDb = db.get_task_db(id);
                      if (taskDb) {
                          if (!mgrTask.isTaskAward(taskDb.id)) {
                              haveReward = true;
                              break;
                          }
                      }
                  }
              }
          }
          return haveReward;
      }
      static isAnyTaskCanRewardByDay(seven_task_db) {
          let canReward = false;
          if (seven_task_db) {
              canReward = this.isCurtAllTaskAward(seven_task_db) && this.getDayId2Reward(seven_task_db.day - 1) == 0;
              if (!canReward) {
                  for (let id of seven_task_db.task_ids) {
                      let taskDb = db.get_task_db(id);
                      if (taskDb) {
                          if (mgrTask.isTaskCompleteByDB(taskDb) && !mgrTask.isTaskAward(taskDb.id)) {
                              canReward = true;
                              break;
                          }
                      }
                  }
              }
          }
          return canReward;
      }
      static haveReadPoint() {
          return this.isAnyTaskCanReward();
      }
  }
  mgrTaskSeven.RECORD_KEY = "game166_seven_v1.0";
  mgrTaskSeven.dataDefault = {
      day: -1,
      score: 0,
      scoreid2reward: {},
      dayid2reward: {},
  };

  var TASK_TYPE;
  (function (TASK_TYPE) {
      TASK_TYPE[TASK_TYPE["MINI"] = 0] = "MINI";
      TASK_TYPE[TASK_TYPE["DAILY"] = 1] = "DAILY";
      TASK_TYPE[TASK_TYPE["ARCHIEVEMENT"] = 2] = "ARCHIEVEMENT";
      TASK_TYPE[TASK_TYPE["SEVEN"] = 3] = "SEVEN";
      TASK_TYPE[TASK_TYPE["NEWYEAR"] = 4] = "NEWYEAR";
  })(TASK_TYPE || (TASK_TYPE = {}));
  class mgrTask extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e && e.advName) {
                      let advDb = db.get_adv_db(e.advName);
                      if (advDb && advDb.advType == "video") {
                          this.doEvent(db.TASK_EVENT_ID.AD_VIDEO);
                      }
                  }
              },
          });
      }
      static onStart() {
          this.parseTaskByEvent();
      }
      static parseTaskByEvent() {
          this.event2TaskList = {};
          this.type2TaskList = {};
          let taskMap = db.get_task_db_map();
          for (let k in taskMap) {
              let taskDb = taskMap[k];
              let listEvent = this.event2TaskList[taskDb.event_id];
              if (!listEvent) {
                  listEvent = [];
                  this.event2TaskList[taskDb.event_id] = listEvent;
              }
              listEvent.push(taskDb);
              let listType = this.type2TaskList[taskDb.type];
              if (!listType) {
                  listType = [];
                  this.type2TaskList[taskDb.type] = listType;
              }
              listType.push(taskDb);
          }
          this.buildMiniTask(true);
          this.buildDailyTask();
      }
      static buildMiniTask(force = false) {
          if (this.data.mini_id)
              return;
          if (!force && this.isMiniCDING())
              return;
          let task;
          let id = db.game_cnf.task_mini_ids[this.data.mini_award];
          if (id) {
              task = db.get_task_db(id);
          }
          if (!task) {
              task = Utils.randomItem(this.type2TaskList[0]);
          }
          this.data.mini_id = task.id;
          this.data.mini_count = 0;
          this.data.mini_complete_time = 0;
          let listItem = db.get_task_reward_db_map()[task.reward_id];
          let itemReward = this.calcWeightItem(listItem);
          this.data.mini_reward_id = itemReward.index;
          this.miniEvent = task.event_id;
          this.setTaskNeed(task.id, Utils.random(task.event_need[0], task.event_need[1]));
          this.saveRecord();
      }
      static calcWeightItem(items) {
          let weightTotal = 0;
          for (let i = 0; i < items.length; i++) {
              weightTotal += items[i].weight;
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let item = null;
          for (let i = 0; i < items.length; i++) {
              vpt += items[i].weight;
              if (r < vpt) {
                  item = items[i];
                  break;
              }
          }
          return item;
      }
      static buildDailyTask() {
          if (this.data.daily_ids)
              return;
          this.data.daily_ids = [];
          let selectMask = {};
          for (let id of db.game_cnf.task_daily_ids) {
              this.data.daily_ids.push(id);
              selectMask[id] = true;
          }
          let listIds = [];
          let listDaily = this.type2TaskList[1];
          for (let data of listDaily) {
              if (!selectMask[data.id]) {
                  listIds.push(data.id);
              }
          }
          Utils.randomSort(listIds);
          for (let i = 0; i < 11; i++) {
              let id = listIds[i];
              if (id) {
                  this.data.daily_ids.push(id);
              }
          }
          for (let id of this.data.daily_ids) {
              let taskDb = db.get_task_db(id);
              if (taskDb) {
                  this.setTaskNeed(taskDb.id, Utils.random(taskDb.event_need[0], taskDb.event_need[1]));
                  this.setEventCountDaily(taskDb.event_id, 0);
                  this.setTaskAward(taskDb.id, 0);
              }
          }
          this.saveRecord();
      }
      static onDifferentDay() {
          this.resetAllTask();
          this.parseTaskByEvent();
          this.resetNewyearTask();
          this.doEvent(db.TASK_EVENT_ID.LOGIN);
      }
      static resetAllTask() {
          console.log("mgrTask.resetAllTask");
          this.data.mini_id = "";
          this.data.mini_count = 0;
          this.data.mini_complete_time = 0;
          this.data.daily_ids = null;
          this.saveRecord();
      }
      static resetNewyearTask() {
          let tasks = this.getNewyearTask();
          for (let task of tasks) {
              this.setEventCountNewyear(task.event_id, 0);
              this.setTaskAward(task.id, 0);
          }
      }
      static completeAllTask() {
          this.saveRecord();
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrTask.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static setTaskAward(id, value) {
          this.data.taskAward[id] = value;
          this.saveRecord();
      }
      static getTaskAward(id) {
          return this.data.taskAward[id] || 0;
      }
      static addTaskAward(id, value = 1) {
          this.setTaskAward(id, this.getTaskAward(id) + value);
      }
      static statisTaskShow(taskDb) {
          if (taskDb) {
              mgrStatis.statisCommonEvent(taskDb.statis_id, 0);
          }
      }
      static staticTaskOver(taskDb) {
          if (taskDb) {
              mgrStatis.statisCommonEvent(taskDb.statis_id, 1);
          }
      }
      static markTaskComplete(id) {
          this.addTaskAward(id, 1);
          this.staticTaskOver(db.get_task_db(id));
      }
      static isTaskAward(id) {
          return this.data.taskAward[id] > 0;
      }
      static isTaskMiniComplete() {
          if (this.data.mini_id) {
              return this.isTaskComplete(this.data.mini_id);
          }
          return false;
      }
      static isTaskComplete(id) {
          return this.isTaskCompleteByDB(db.get_task_db(id));
      }
      static isTaskCompleteByDB(taskDb) {
          if (taskDb) {
              switch (taskDb.type) {
                  case TASK_TYPE.ARCHIEVEMENT:
                      return this.getTaskCountByDB(taskDb) >= this.getTaskNeed(taskDb);
                  case TASK_TYPE.MINI:
                      return this.getTaskCountByDB(taskDb) >= this.getTaskNeed(taskDb);
                  case TASK_TYPE.DAILY:
                      return !this.isTaskAward(taskDb.id) && this.getTaskCountByDB(taskDb) >= this.getTaskNeed(taskDb);
                  case TASK_TYPE.SEVEN:
                      return this.getTaskCountByDB(taskDb) >= this.getTaskNeed(taskDb);
                  case TASK_TYPE.NEWYEAR:
                      return this.getTaskCountByDB(taskDb) >= this.getTaskNeed(taskDb);
              }
          }
          return false;
      }
      static getTaskCount(id) {
          return this.getTaskCountByDB(db.get_task_db(id));
      }
      static getTaskCountByDB(taskDb) {
          switch (taskDb.type) {
              case TASK_TYPE.MINI:
                  return this.EventCountMini;
              case TASK_TYPE.DAILY:
                  return this.getEventCountDaily(taskDb.event_id);
              case TASK_TYPE.ARCHIEVEMENT:
                  return this.getEventCountArchieve(taskDb.event_id);
              case TASK_TYPE.SEVEN:
                  return this.getEventCountSeven(taskDb.event_id);
              case TASK_TYPE.NEWYEAR:
                  return this.getEventCountNewyear(taskDb.event_id);
          }
          return 0;
      }
      static setTaskNeed(id, value) {
          this.data.taskNeed[id] = value;
          this.saveRecord();
      }
      static getTaskNeed(task) {
          if (task.type == TASK_TYPE.ARCHIEVEMENT) {
              return task.event_need[0] * (this.getTaskAward(task.id) + 1);
          }
          else {
              return this.data.taskNeed[task.id] || task.event_need[0];
          }
      }
      static getTaskProgress(task) {
          return this.getTaskCountByDB(task) / this.getTaskNeed(task) * 100;
      }
      static set EventCountMini(value) {
          this.data.mini_count = value;
          this.saveRecord();
      }
      static get EventCountMini() {
          return this.data.mini_count || 0;
      }
      static addEventCountMini(id, value) {
          if (this.miniEvent == id)
              this.EventCountMini += value;
      }
      static setEventCountMini(id, value) {
          if (this.miniEvent == id)
              this.EventCountMini = value;
      }
      static setEventCountDaily(id, value) {
          this.data.eventCountDaily[id] = value;
          this.saveRecord();
      }
      static getEventCountDaily(id) {
          return this.data.eventCountDaily[id] || 0;
      }
      static addEventCountDaily(id, value) {
          this.setEventCountDaily(id, this.getEventCountDaily(id) + value);
      }
      static setEventCountArchieve(id, value) {
          this.data.eventCountArchieve[id] = value;
          this.saveRecord();
      }
      static getEventCountArchieve(id) {
          return this.data.eventCountArchieve[id] || 0;
      }
      static addEventCountArchieve(id, value) {
          this.setEventCountArchieve(id, this.getEventCountArchieve(id) + value);
      }
      static setEventCountSeven(id, value) {
          this.data.eventCountSeven[id] = value;
          this.saveRecord();
      }
      static getEventCountSeven(id) {
          return this.data.eventCountSeven[id] || 0;
      }
      static addEventCountSeven(id, value) {
          this.setEventCountSeven(id, this.getEventCountSeven(id) + value);
      }
      static setEventCountNewyear(id, value) {
          this.data.eventCountNewyear[id] = value;
          this.saveRecord();
      }
      static getEventCountNewyear(id) {
          return this.data.eventCountNewyear[id] || 0;
      }
      static addEventCountNewyear(id, value) {
          this.setEventCountNewyear(id, this.getEventCountNewyear(id) + value);
      }
      static set miniEvent(event) {
          this.idMiniEvent = event;
      }
      static get miniEvent() {
          if (!this.idMiniEvent) {
              let task = this.getMiniTask();
              if (task)
                  this.idMiniEvent = task.event_id;
          }
          return this.idMiniEvent;
      }
      static isAnyTaskCanReward() {
          if (this.isTaskMiniComplete())
              return true;
          if (this.isAnyDailyCanReward())
              return true;
          if (this.isAnyArchieveCanReward())
              return true;
          return false;
      }
      static isAnyDailyCanReward() {
          for (let id of this.data.daily_ids) {
              if (this.isTaskComplete(id))
                  return true;
          }
          return false;
      }
      static isAnyArchieveCanReward() {
          let listArchieve = this.type2TaskList[2];
          if (listArchieve) {
              for (let task of listArchieve) {
                  if (this.isTaskCompleteByDB(task))
                      return true;
              }
          }
          return false;
      }
      static doEvent4Task(event, count = 1) {
          this.addEventCountMini(event, count);
          this.addEventCountDaily(event, count);
          this.addEventCountArchieve(event, count);
          this.addEventCountSeven(event, count);
          this.addEventCountNewyear(event, count);
      }
      static doEvent(event, count = 1) {
          this.doEvent4Task(event, count);
      }
      static setEvent(event, count = 1) {
          this.setEventCountMini(event, count);
          this.setEventCountDaily(event, count);
          this.setEventCountArchieve(event, count);
          this.setEventCountSeven(event, count);
          this.setEventCountNewyear(event, count);
      }
      static isMiniCDING() {
          let lastTime = this.data.mini_complete_time;
          if (lastTime) {
              let passTime = Timer.time - lastTime;
              if (passTime < 0)
                  passTime = 0;
              return passTime < db.game_cnf.task_mini_cd;
          }
          else {
              return false;
          }
      }
      static getMiniCDLeftTime() {
          let lastTime = this.data.mini_complete_time;
          if (lastTime) {
              let passTime = Timer.time - lastTime;
              if (passTime < 0)
                  passTime = 0;
              let leftTime = db.game_cnf.task_mini_cd - passTime;
              if (leftTime < 0)
                  leftTime = 0;
              return Math.floor(leftTime);
          }
          else {
              return 0;
          }
      }
      static getMiniTask() {
          this.buildMiniTask();
          if (this.data.mini_id)
              return db.get_task_db(this.data.mini_id);
          else
              return null;
      }
      static getDailyTask() {
          this.buildDailyTask();
          let listTask = [];
          for (let id of this.data.daily_ids) {
              listTask.push(db.get_task_db(id));
          }
          return listTask;
      }
      static getArchievementTask() {
          return this.type2TaskList[2];
      }
      static getNewyearTask() {
          return this.type2TaskList[4];
      }
      static getTaskReward(id) {
          return this.getTaskRewardByDB(db.get_task_db(id));
      }
      static getTaskRewardByDB(taskDb, force = false) {
          if (!taskDb)
              return false;
          if (force || this.isTaskCompleteByDB(taskDb)) {
              if (taskDb.coin) {
                  mgrGame.showMoneyGet(null, null, 1000, taskDb.coin, true, 50);
              }
              if (taskDb.type == TASK_TYPE.MINI) {
                  if (mgrHolyItem.notEnoughEmpty(1))
                      return;
                  if (taskDb.reward_id && this.data.mini_reward_id) {
                      let dropData = [];
                      Level.getTaskReward(taskDb.reward_id, this.data.mini_reward_id, this.data.mini_reward_data, dropData);
                      Level.showItemGet(dropData);
                  }
                  this.data.mini_id = "";
                  this.data.mini_complete_time = Timer.time;
                  this.data.mini_award += 1;
                  this.saveRecord();
                  mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_TASK_MINI);
              }
              else if (taskDb.type == TASK_TYPE.SEVEN) {
                  Level.getRewardByItemIds(taskDb.items, 50);
                  mgrTaskSeven.addSevenScore(taskDb.seven_score, true);
              }
              else if (taskDb.type == TASK_TYPE.NEWYEAR) {
                  Level.getRewardByItemIds(taskDb.items, 50);
              }
              this.addGoalScore(taskDb.goal_score);
              this.markTaskComplete(taskDb.id);
              return true;
          }
          return false;
      }
      static getMiniTaskRewardItem() {
          let taskDb = this.getMiniTask();
          if (taskDb && this.data.mini_reward_id) {
              return Level.getTaskRewardPreview(taskDb.reward_id, this.data.mini_reward_id, this.data.mini_reward_data);
          }
          else {
              return null;
          }
      }
      static get goalScore() {
          return this.data.goal_score || 0;
      }
      static set goalScore(value) {
          this.data.goal_score = value;
          this.saveRecord();
      }
      static markGoalComplete(id) {
          this.data.goal_award[id] = 1;
          this.saveRecord();
      }
      static isGoalComplete(id) {
          return this.data.goal_award[id];
      }
      static markGoalCompleteAD(id) {
          this.data.goal_award_ad[id] = 1;
          this.saveRecord();
      }
      static isGoalCompleteAD(id) {
          return this.data.goal_award_ad[id];
      }
      static getGoalNormalReward(goalDb) {
          if (this.isGoalComplete(goalDb.id))
              return;
          mgrGame.addItem(goalDb.item_id, goalDb.item_amount, 50);
          this.markGoalComplete(goalDb.id);
      }
      static getGoalADReward(goalDb) {
          if (this.isGoalCompleteAD(goalDb.id))
              return;
          mgrGame.addItem(goalDb.item_id_ad, goalDb.item_amount_ad, 50);
          this.markGoalCompleteAD(goalDb.id);
      }
      static addGoalScore(add, msg = false) {
          this.goalScore += add;
          if (msg) {
              Global.sendMsg(MSG.GOAL_SCORE_UDPATE);
          }
      }
      static isAnyGoalCanReward() {
          let listData = db.get_goal_db_map();
          let scoreNeed = 0;
          let scoreCurt = this.goalScore;
          for (let goal of listData) {
              scoreNeed += goal.score_need;
              if (!goal.invalid && scoreCurt >= scoreNeed && (!this.isGoalComplete(goal.id))) {
                  return true;
              }
          }
          return false;
      }
  }
  mgrTask.RECORD_KEY = "game166.task.v1";
  mgrTask.dataDefault = {
      mini_id: "",
      mini_count: 0,
      mini_reward_id: 0,
      mini_reward_data: "",
      mini_complete_time: 0,
      mini_award: 0,
      daily_ids: null,
      goal_score: 25,
      taskAward: {},
      taskNeed: {},
      eventCountDaily: {},
      eventCountArchieve: {},
      eventCountSeven: {},
      eventCountNewyear: {},
      goal_award: {},
      goal_award_ad: {},
  };
  mgrTask.idMiniEvent = "";

  class ListView {
      constructor(listView, caller, funcParseItemView, funcRenderItemView, loop = false, virtual = true) {
          this.isVirtual = false;
          this.handlerOnClickItem = null;
          this.exData = null;
          this.listView = listView;
          this.listView.on(fgui.Events.CLICK_ITEM, this, this.onClickItem);
          this.listView.itemRenderer = Laya.Handler.create(this, this.onRenderItem, null, false);
          if (virtual) {
              if (loop) {
                  this.listView.setVirtualAndLoop();
              }
              else {
                  this.listView.setVirtual();
              }
          }
          this.isVirtual = virtual;
          this.handlerParseItemView = Laya.Handler.create(caller, funcParseItemView, null, false);
          this.handlerRenderItemView = Laya.Handler.create(caller, funcRenderItemView, null, false);
      }
      getListData() {
          return this.listData || [];
      }
      setListData(listData) {
          let listView = this.listView;
          if (!listView._virtual && listData.length > listView.numItems) {
              listData.length = listView.numItems;
          }
          this.listData = listData;
          this.listView.numItems = listData.length;
      }
      refresh() {
          if (this.isVirtual) {
              this.listView.refreshVirtualList();
          }
          else {
              this.setListData(this.listData);
          }
      }
      refreshAndKeepPos() {
          if (this.isVirtual) {
              this.listView.refreshVirtualList();
          }
          else {
              this.setListData(this.listData);
          }
          let posX = this.listView.scrollPane.posX;
          let posY = this.listView.scrollPane.posY;
          Laya.timer.callLater(this, () => {
              if (this.listView.isDisposed)
                  return;
              this.listView.scrollPane.posX = posX;
              this.listView.scrollPane.posY = posY;
          });
      }
      getItemContent(obj, index) {
          let content = obj.data;
          if (content == null) {
              content = {};
              obj.data = content;
              this.handlerParseItemView.runWith([content, obj, index]);
          }
          return content;
      }
      getItemContentByIndex(index) {
          return this.getItemContent(this.listView.getChildAt(index).asCom, index);
      }
      getItemContentFirst() {
          return this.getItemContentByIndex(this.getFirstChildInView());
      }
      getItemData(index) {
          if (this.listData) {
              return this.listData[index];
          }
      }
      onRenderItem(index, obj) {
          let cotent = this.getItemContent(obj, index);
          let data = this.getItemData(index);
          this.handlerRenderItemView.runWith([cotent, data, index]);
      }
      setOnClickItem(caller, funcOnClick) {
          this.handlerOnClickItem = Laya.Handler.create(caller, funcOnClick, null, false);
          ;
      }
      onClickItem(obj) {
          let content = this.getItemContent(obj);
          if (this.handlerOnClickItem) {
              fgui.GRoot.inst.playOneShotSound(fgui.UIConfig.buttonSound);
              this.handlerOnClickItem.runWith(content);
          }
      }
      getFirstChildInView() {
          return this.listView.getFirstChildInView();
      }
      setPageController(controller) {
          this.ctrlPage = controller;
      }
      haveNextPage(numItemInPage = 1) {
          if (this.ctrlPage) {
              let index = this.ctrlPage.selectedIndex + numItemInPage;
              if (index >= this.ctrlPage.pageCount) {
                  return false;
              }
              else {
                  return true;
              }
          }
          else {
              let index = this.getFirstChildInView() + numItemInPage;
              if (index >= this.listView.numItems) {
                  return false;
              }
              else {
                  return true;
              }
          }
      }
      havePrevPage(numItemInPage = 1) {
          if (this.ctrlPage) {
              let index = this.ctrlPage.selectedIndex - numItemInPage;
              if (index < 0) {
                  return false;
              }
              else {
                  return true;
              }
          }
          else {
              let index = this.getFirstChildInView() - numItemInPage;
              if (index < 0) {
                  return false;
              }
              else {
                  return true;
              }
          }
      }
      nextPage(numItemInPage = 1) {
          if (this.haveNextPage(numItemInPage)) {
              if (this.ctrlPage) {
                  this.ctrlPage.selectedIndex += numItemInPage;
              }
              else {
                  this.scrollToView(this.getFirstChildInView() + numItemInPage, true);
              }
          }
      }
      prevPage(numItemInPage = 1) {
          if (this.havePrevPage(numItemInPage)) {
              if (this.ctrlPage) {
                  this.ctrlPage.selectedIndex -= numItemInPage;
              }
              else {
                  this.scrollToView(this.getFirstChildInView() - numItemInPage, true);
              }
          }
      }
      scrollToView(index, anim = true, setFirst) {
          this.listView.scrollToView(index, anim, setFirst);
      }
      scrollToFirst() {
          let index = this.getFirstChildInView();
          this.scrollToView(index, true);
          return index;
      }
      addChildToContainter(child) {
          let list = this.listView;
          list._container.addChild(child.displayObject);
      }
      onScrollEnd(caller, func) {
          this.listView.on(fgui.Events.SCROLL_END, caller, func);
      }
      getContentList() {
          let listData = [];
          for (let i = 0; i < this.listView.numItems; i++) {
              listData.push(this.getItemContent(this.listView.getChildAt(i).asCom));
          }
          return listData;
      }
      getSelectData() {
          return this.listData[this.listView.selectedIndex];
      }
      set selectedIndex(index) {
          this.listView.selectedIndex = index;
      }
      get selectedIndex() {
          return this.listView.selectedIndex;
      }
      setExData(data) {
          this.exData = data;
      }
      getExData() {
          return this.exData;
      }
      setExDataByIndex(index, value) {
          if (this.exData) {
              this.exData[index] = value;
          }
      }
      getExDataByIndex(index) {
          if (this.exData) {
              return this.exData[index];
          }
          else {
              return null;
          }
      }
  }

  var HOLYITEM_SORT_TYPE;
  (function (HOLYITEM_SORT_TYPE) {
      HOLYITEM_SORT_TYPE[HOLYITEM_SORT_TYPE["DEFAULT"] = 0] = "DEFAULT";
      HOLYITEM_SORT_TYPE[HOLYITEM_SORT_TYPE["QUALITY"] = 1] = "QUALITY";
      HOLYITEM_SORT_TYPE[HOLYITEM_SORT_TYPE["LEVEL"] = 2] = "LEVEL";
      HOLYITEM_SORT_TYPE[HOLYITEM_SORT_TYPE["CLASS"] = 3] = "CLASS";
  })(HOLYITEM_SORT_TYPE || (HOLYITEM_SORT_TYPE = {}));
  class HolyItemList {
      constructor(list, context, callbackClick) {
          this.openUse = false;
          this.listItem = new ListView(list, this, this.parseBagItem, this.renderBagItem);
          this.callbackClick = callbackClick.bind(context);
          this.listItem.setOnClickItem(this, this.onClickBagItem);
      }
      parseBagItem(content, object) {
          content.item = object.getChild("item");
          content.item.touchable = false;
          content.state = object.getController("state");
          content.select = object.getController("select");
          content.equip = object.getController("equip");
          content.use = object.getController("use");
          content.lock = object.getController("lock");
      }
      renderBagItem(content, data) {
          content.select.selectedIndex = 0;
          content.equip.selectedIndex = 0;
          content.data = data;
          if (data.holyitem) {
              Level.updateRedPoint4Button(content.item, data.holyitem.new);
              if (data.selected && data.holyitem.lock) {
                  data.selected = false;
              }
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
              content.item.refresh(data.holyitem);
              if (this.selectHolytem && this.selectHolytem == data) {
                  this.markSelect(content);
              }
              if (data.holyitem.isEquiped()) {
                  content.equip.selectedIndex = 1;
              }
              if (this.openUse) {
                  content.use.selectedIndex = data.selected ? 1 : 0;
              }
              content.lock.selectedIndex = data.holyitem.lock ? 1 : 0;
          }
          else {
              content.lock.selectedIndex = 0;
              if (this.openUse) {
                  content.use.selectedIndex = 0;
              }
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.EMPTY;
          }
      }
      clearSelect() {
          this.selectHolytem = null;
          if (this.selectContent) {
              this.selectContent.select.selectedIndex = 0;
          }
          this.selectContent = null;
      }
      markSelect(content) {
          this.clearSelect();
          this.selectHolytem = content.data;
          this.selectContent = content;
          content.select.selectedIndex = 1;
          if (this.callbackClickItemSelect)
              this.callbackClickItemSelect(content);
      }
      onClickBagItem(content) {
          if (content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.EMPTY) {
              return;
          }
          this.markSelect(content);
          if (this.callbackClick) {
              if (this.callbackClick(content)) {
                  return;
              }
          }
          let bagItem = content.data;
          if (bagItem.holyitem && bagItem.holyitem.new) {
              bagItem.holyitem.new = false;
          }
          Level.updateRedPoint4Button(content.item, bagItem.holyitem.new);
          if (this.openUse) {
              if (bagItem.holyitem) {
                  bagItem.selected = !bagItem.selected;
                  this.renderBagItem(content, bagItem);
                  this.onItemUseChange(content, bagItem.selected);
              }
          }
      }
      setListData(data) {
          this.listItem.setListData(data);
      }
      getListData() {
          return this.listItem.getListData();
      }
      getDataByIndex(index) {
          let data = this.getListData();
          if (data) {
              return data[index];
          }
          else {
              return null;
          }
      }
      refreshWithSelect(selectHolytem) {
          this.clearSelect();
          this.selectHolytem = selectHolytem;
          this.listItem.refresh();
      }
      setOnItemUseCallBack(callback) {
          this.callbackClickItemUse = callback;
      }
      onItemUseChange(content, use) {
          if (this.callbackClickItemUse)
              this.callbackClickItemUse(content, use);
      }
      setOnItemSelectCallBack(callback) {
          this.callbackClickItemSelect = callback;
      }
  }

  var SMELTER_STATE;
  (function (SMELTER_STATE) {
      SMELTER_STATE[SMELTER_STATE["IDLE"] = 0] = "IDLE";
      SMELTER_STATE[SMELTER_STATE["RUNNING"] = 1] = "RUNNING";
  })(SMELTER_STATE || (SMELTER_STATE = {}));
  class mgrSmelter extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static onStart() {
          let wordList = db.get_holy_item_word_map();
          for (let wordDb of wordList) {
              this.wordDbMap[wordDb.attr] = wordDb;
          }
      }
      static findWordDb(k) {
          return this.wordDbMap[BASE_ATTR[k]];
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrSmelter.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onDifferentDay() {
      }
      static set autoPutForge(v) {
          this.data.autoPutForge = v;
          this.saveRecord();
      }
      static get autoPutForge() {
          return this.data.autoPutForge;
      }
      static set autoPutLvup(v) {
          this.data.autoPutLvup = v;
          this.saveRecord();
      }
      static get autoPutLvup() {
          return this.data.autoPutLvup;
      }
      static set smelterExp(exp) {
          this.data.exp = exp;
          this.saveRecord();
      }
      static get smelterExp() {
          return this.data.exp;
      }
      static set IdMain(v) {
          this.data.IdMain = v;
          this.saveRecord();
      }
      static get IdMain() {
          return this.data.IdMain;
      }
      static set IdVice(v) {
          this.data.IdVice = v;
          this.saveRecord();
      }
      static get IdVice() {
          return this.data.IdVice;
      }
      static set state(v) {
          this.data.state = v;
          this.saveRecord();
      }
      static get state() {
          return this.data.state;
      }
      static set washCount(v) {
          this.data.washCount = v;
          this.saveRecord();
      }
      static get washCount() {
          return this.data.washCount;
      }
      static feedItem(foods) {
          if (mgrHolyItem.notEnoughEmpty(1))
              return;
          let expAdd = 0;
          for (let food of foods) {
              if (food.holyitem) {
                  expAdd += food.holyitem.getExpSmelt();
                  mgrHolyItem.remHolyItem(food.holyitem);
              }
          }
          this.smelterExp += expAdd;
          if (this.isSmeltExpFull()) {
              this.buildItem();
          }
          else {
              Global.sendMsg(MSG.SMELTER_FEED_ITEM);
          }
          return;
      }
      static feedItemOne(holyitem) {
          let expAdd = 0;
          if (holyitem) {
              expAdd += holyitem.getExpSmelt();
              mgrHolyItem.remHolyItem(holyitem);
          }
          this.smelterExp += expAdd;
      }
      static getSmeltExpNeed(quality = EQUIP_QUALITY.RED) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              return qualityDb.need_smelt;
          }
          return 0;
      }
      static getSmeltItemNeed(quality = EQUIP_QUALITY.RED) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              return qualityDb.smelt_items;
          }
          return [];
      }
      static getWashItemNeed(quality = EQUIP_QUALITY.RED) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              return qualityDb.wash_items;
          }
          return [];
      }
      static getRebuildItemNeed(quality = EQUIP_QUALITY.RED) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              return qualityDb.rebuild_items;
          }
          return [];
      }
      static getSmletProgress(preAdd = 0) {
          let need = this.getSmeltExpNeed();
          let curt = Math.min(this.smelterExp + preAdd, need);
          if (curt > 0 && need > 0) {
              return curt / need;
          }
          else {
              return 0;
          }
      }
      static isSmeltExpFull(preAdd = 0) {
          let need = this.getSmeltExpNeed();
          let curt = this.smelterExp + preAdd;
          if (need && curt >= need) {
              return true;
          }
          else {
              return false;
          }
      }
      static checkItemCanPut(holyitem) {
          if (!holyitem)
              return true;
          let itemId = holyitem.itemId;
          if (itemId == this.IdMain || itemId == this.IdVice) {
              if (holyitem.getQuality() == EQUIP_QUALITY.RED) {
                  return holyitem.isSuperRedItem();
              }
              return true;
          }
          return false;
      }
      static getItemTypeFilter() {
          let filter = {};
          if (this.IdMain) {
              filter[this.IdMain] = true;
          }
          if (this.IdVice) {
              filter[this.IdVice] = true;
          }
          return filter;
      }
      static canChangeItemId() {
          if (this.state == SMELTER_STATE.IDLE) {
              return true;
          }
          else {
              return false;
          }
      }
      static canSmelt() {
          return this.getMainItemDb() && this.getViceItemDb() && this.isSmeltExpFull();
      }
      static canStartSmelt(show = false) {
          let items = mgrSmelter.getSmeltItemNeed();
          if (items.length <= 0)
              return false;
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              if (!mgrGame.checkItem(itemId, itemNeed, show)) {
                  return false;
              }
          }
          if (this.getMainItemDb() == null) {
              if (show) {
                  mgrTip.showMsgTip("请选择主圣物");
              }
              return false;
          }
          if (this.getViceItemDb() == null) {
              if (show) {
                  mgrTip.showMsgTip("请选择副圣物");
              }
              return false;
          }
          return true;
      }
      static getMainItemDb() {
          return db.get_holy_item_db_map()[this.IdMain];
      }
      static getViceItemDb() {
          return db.get_holy_item_db_map()[this.IdVice];
      }
      static resetSmelt() {
          this.IdMain = "";
          this.IdVice = "";
          this.smelterExp = 0;
          this.state = SMELTER_STATE.IDLE;
          this.autoPutForge = false;
      }
      static buildItem() {
          let holyItem = HolyItemMaker.buildHolyItemByOption({ itemDb: this.getMainItemDb(), itemDbSub: this.getViceItemDb(), quality: EQUIP_QUALITY.RED });
          mgrHolyItem.addHolyItem(holyItem);
          if (holyItem) {
              Director.openPanelWithSingleton("PanelSmelterSuc", holyItem);
          }
          this.resetSmelt();
          this.autoPutForge = false;
          Global.sendMsg(MSG.SMELTER_ITEM_SUC);
      }
      static startSmelt() {
          if (!this.canStartSmelt(true)) {
              return false;
          }
          let items = mgrSmelter.getSmeltItemNeed();
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              mgrGame.subItem(itemId, itemNeed, 64);
          }
          this.state = SMELTER_STATE.RUNNING;
          Global.sendMsg(MSG.SMELTER_RUNNING);
          return true;
      }
      static isRunning() {
          return this.state == SMELTER_STATE.RUNNING;
      }
      static isSmeltPreExpFull() {
          let listItem = mgrHolyItem.getBagItems();
          let expAdd = 0;
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  expAdd += item.holyitem.getExpSmelt();
              }
          }
          return this.isSmeltExpFull(expAdd);
      }
      static waskItem(holyItem) {
          let items = mgrSmelter.getWashItemNeed();
          if (items.length <= 0)
              return false;
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              if (itemId && itemNeed) {
                  if (!mgrGame.checkItem(itemId, itemNeed)) {
                      return false;
                  }
              }
          }
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              if (itemId && itemNeed) {
                  mgrGame.subItem(itemId, itemNeed, 65);
              }
          }
          this.washCount++;
          let isPerfect = false;
          if (this.washCount % 10 == 0) {
              isPerfect = true;
          }
          HolyItemMaker.buildAttr(holyItem, isPerfect);
          Global.sendMsg(MSG.WASH_ITEM_SUC);
          return true;
      }
      static set lvupUID(v) {
          this.data.lvupUID = v;
          this.saveRecord();
      }
      static get lvupUID() {
          return this.data.lvupUID;
      }
      static set lvupExp(v) {
          this.data.lvupExp = v;
          this.saveRecord();
      }
      static get lvupExp() {
          return this.data.lvupExp;
      }
      static set lvupState(v) {
          this.data.lvupState = v;
          this.saveRecord();
      }
      static get lvupState() {
          return this.data.lvupState;
      }
      static getLvupHolyItem() {
          let item = null;
          if (this.lvupUID) {
              item = mgrHolyItem.findBagItemByUID(this.lvupUID);
              if (!item) {
                  this.lvupUID = "";
              }
          }
          return item;
      }
      static feedItem4Lvup(foods) {
          let bagItem = this.getLvupHolyItem();
          if (!bagItem) {
              return;
          }
          let expAdd = 0;
          for (let food of foods) {
              if (food.holyitem) {
                  expAdd += food.holyitem.getExpSmelt();
                  mgrHolyItem.remHolyItem(food.holyitem);
              }
          }
          this.lvupExp += expAdd;
          if (this.isSmeltLvupExpFull()) {
              this.qualityUpItem(bagItem);
          }
          else {
              Global.sendMsg(MSG.ITEM_QUALITY_LVUP_FEED_ITEM);
          }
          return;
      }
      static feedItem4LvupOne(holyitem) {
          let bagItem = this.getLvupHolyItem();
          if (!bagItem) {
              return;
          }
          let expAdd = 0;
          if (holyitem) {
              expAdd += holyitem.getExpSmelt();
              mgrHolyItem.remHolyItem(holyitem);
          }
          this.lvupExp += expAdd;
      }
      static isSmeltQualityPreExpFull() {
          let listItem = mgrHolyItem.getBagItems();
          let expAdd = 0;
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  expAdd += item.holyitem.getExpSmelt();
              }
          }
          return this.isSmeltLvupExpFull(expAdd);
      }
      static qualityUpItem(item) {
          let holyItem = item.holyitem;
          if (holyItem) {
              let oldAttr = holyItem.buildAttr();
              holyItem.lvupQuality();
              let newAttr = holyItem.buildAttr();
              this.resetSmeltQualityUp();
              Director.openPanelWithSingleton("PanelSmelterQualityUpSuc", { holyItem: holyItem, oldAttr: oldAttr, newAttr: newAttr });
              this.saveRecord();
              this.autoPutLvup = false;
              Global.sendMsg(MSG.ITEM_QUALITY_LVUP_SUC);
          }
      }
      static isSmeltLvupExpFull(preAdd = 0) {
          let need = this.getSmeltLvupExpNeed();
          let curt = this.lvupExp + preAdd;
          if (need && curt >= need) {
              return true;
          }
          else {
              return false;
          }
      }
      static getSmeltLvupExpNeed(quality = EQUIP_QUALITY.ORANGE) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              return qualityDb.qualityup_need;
          }
          return 0;
      }
      static getSmeltQualityUpItemNeed(quality = EQUIP_QUALITY.ORANGE) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              return qualityDb.qualityup_items;
          }
          return [];
      }
      static getSmeltQualityUpProgress(preAdd = 0) {
          let need = this.getSmeltLvupExpNeed();
          let curt = Math.min(this.lvupExp + preAdd, need);
          if (curt > 0 && need > 0) {
              return curt / need;
          }
          else {
              return 0;
          }
      }
      static canStartSmeltQualityUp(show = false) {
          let items = mgrSmelter.getSmeltQualityUpItemNeed();
          if (items.length <= 0)
              return false;
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              if (!mgrGame.checkItem(itemId, itemNeed, show)) {
                  return false;
              }
          }
          return true;
      }
      static startSmelt4QualiytUp(holyitem) {
          if (!holyitem) {
              mgrTip.showMsgTip("请选择升品的圣物");
              return false;
          }
          if (!this.canStartSmeltQualityUp(true)) {
              return false;
          }
          let items = mgrSmelter.getSmeltQualityUpItemNeed();
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              mgrGame.subItem(itemId, itemNeed, 64);
          }
          this.lvupUID = holyitem.getUID();
          this.lvupState = SMELTER_STATE.RUNNING;
          this.lvupExp = 0;
          Global.sendMsg(MSG.SMELTER_RUNNING);
          return true;
      }
      static resetSmeltQualityUp() {
          this.lvupUID = "";
          this.lvupExp = 0;
          this.lvupState = SMELTER_STATE.IDLE;
          this.autoPutLvup = false;
      }
      static isSmeltQualityUpRunning() {
          let item = this.getLvupHolyItem();
          if (!item) {
              this.resetSmeltQualityUp();
          }
          return this.lvupState == SMELTER_STATE.RUNNING;
      }
      static checkItemCanPut4QualityUp(selectItem, holyitem) {
          if (selectItem && holyitem && selectItem.itemId == holyitem.itemId) {
              return true;
          }
          return false;
      }
      static getQualityUpItemTypeFilter() {
          let filter = {};
          let item = this.getLvupHolyItem();
          if (item) {
              filter[item.holyitem.itemId] = true;
          }
          return filter;
      }
      static rebuildItem(holyItem) {
          let items = mgrSmelter.getRebuildItemNeed();
          if (items.length <= 0)
              return false;
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              if (itemId && itemNeed) {
                  if (!mgrGame.checkItem(itemId, itemNeed)) {
                      return false;
                  }
              }
          }
          for (let i = 0; i < items.length; i += 2) {
              let itemId = items[i];
              let itemNeed = items[i + 1];
              if (itemId && itemNeed) {
                  mgrGame.subItem(itemId, itemNeed, 67);
              }
          }
          HolyItemMaker.rebuildAttr(holyItem);
          Global.sendMsg(MSG.REBUILD_ITEM_SUC);
          return true;
      }
      static isHolyItemQualityUping(holyitem) {
          if (!holyitem)
              return false;
          return this.isSmeltQualityUpRunning() && holyitem.getUID() == this.lvupUID;
      }
  }
  mgrSmelter.RECORD_KEY = "game166_smelter_v1.0";
  mgrSmelter.dataDefault = {
      IdMain: null,
      IdVice: null,
      exp: 0,
      state: SMELTER_STATE.IDLE,
      washCount: 0,
      lvupUID: "",
      lvupExp: 0,
      lvupState: 0,
      autoPutForge: false,
      autoPutLvup: false,
  };
  mgrSmelter.wordDbMap = {};

  class mgrHolyItem extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static onStart() {
          if (Laya.Browser.onPC)
              this.checkCompressTemplate();
          this.loadBag();
      }
      static checkCompressTemplate() {
          let template = HOLY_ITEM_TEMPLATE;
          let tempMapp = {};
          for (let item of template) {
              tempMapp[item.k] = true;
          }
          let checkdat = HOLY_ITEM_CHECK;
          for (let k in checkdat) {
              if (!tempMapp[k]) {
                  mgrTip.alertTip("背包存档压缩模板错误\n没有找到:" + k);
                  break;
              }
          }
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.needInit = true;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrHolyItem.loadRecord");
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static loadBag() {
          this.listBagItem = [];
          let compress = this.compress;
          if (this.data.bagData.length) {
              let firstData = this.data.bagData[0];
              if (firstData instanceof Object) {
                  compress = 0;
              }
          }
          if (!compress) {
              for (let i = 0; i < this.data.bagData.length; i++) {
                  let data = this.data.bagData[i];
                  if (data) {
                      let holyitem = HolyItem.loadFromData(data);
                      if (holyitem) {
                          let item = { holyitem: holyitem };
                          this.listBagItem.push(item);
                      }
                  }
              }
          }
          else {
              let bagData = this.unpackArray(this.data.bagData, HOLY_ITEM_TEMPLATE);
              for (let i = 0; i < bagData.length; i++) {
                  let data = bagData[i];
                  if (data) {
                      let holyitem = HolyItem.loadFromData(data);
                      if (holyitem) {
                          let item = { holyitem: holyitem };
                          this.listBagItem.push(item);
                      }
                  }
              }
          }
          if (this.autotime == 0) {
              this.listBagItem.sort(this.sortByDefault);
              for (let bag of this.listBagItem) {
                  if (bag.holyitem && bag.holyitem.data) {
                      bag.holyitem.data.time = this.buildTime();
                  }
              }
          }
          if (this.needInit) {
              this.data.bagSize = db.game_cnf.holyitem_bag_size;
              for (let i = 0; i < db.game_cnf.bag_init_item_id.length; i++) {
                  let itemDb = db.get_holy_item_db(db.game_cnf.bag_init_item_id[i]);
                  let quality = db.game_cnf.bag_init_item_quality[i] || 0;
                  this.addHolyItem(HolyItemMaker.buildHolyItemByOption({ itemDb: itemDb, quality: quality }));
              }
          }
      }
      static saveBag() {
          this.data.bagData = [];
          for (let i = 0; i < this.listBagItem.length; i++) {
              let item = this.listBagItem[i];
              if (item) {
                  this.data.bagData.push(item.holyitem.data);
              }
          }
          if (db.cop_db.bag_data_compress) {
              let bageData = this.packArray(this.data.bagData, HOLY_ITEM_TEMPLATE);
              this.data.bagData = bageData;
              this.compress = 1;
          }
          else {
              this.compress = 0;
          }
          this.saveRecord();
      }
      static isBagFull() {
          return this.listBagItem.length >= this.data.bagSize;
      }
      static getFilterQuality(limit = null) {
          let filterQuality = this.data.filterQuality;
          if (limit != null && filterQuality > limit) {
              return limit;
          }
          else {
              return this.data.filterQuality;
          }
      }
      static setFilterQuality(value) {
          this.data.filterQuality = value;
          this.saveRecord();
      }
      static addHolyItem(holyitem, dropData, ignoreSize = true) {
          mgrTask.doEvent(db.TASK_EVENT_ID.COLLECT_HOLYITEM);
          switch (holyitem.qualityDb.quality) {
              case EQUIP_QUALITY.GREEN:
                  mgrTask.doEvent(db.TASK_EVENT_ID.COLLECT_HOLYITEM_QUALITY_0);
                  break;
              case EQUIP_QUALITY.BLUE:
                  mgrTask.doEvent(db.TASK_EVENT_ID.COLLECT_HOLYITEM_QUALITY_1);
                  break;
              case EQUIP_QUALITY.PURPLE:
                  mgrTask.doEvent(db.TASK_EVENT_ID.COLLECT_HOLYITEM_QUALITY_2);
                  break;
              case EQUIP_QUALITY.ORANGE:
                  mgrTask.doEvent(db.TASK_EVENT_ID.COLLECT_HOLYITEM_QUALITY_3);
                  break;
          }
          if (this.isNeedSell(holyitem)) {
              let count = this.autoSellOne(holyitem);
              if (count && dropData)
                  dropData.push({ type: DROP_TYPE.ITEM, data: { itemId: 1000, count: count, quality: holyitem.getQuality() } });
              return false;
          }
          if (this.isBagFull()) {
              let count = this.autoSellOne(holyitem);
              if (count && dropData)
                  dropData.push({ type: DROP_TYPE.ITEM, data: { itemId: 1000, count: count, quality: holyitem.getQuality() } });
              mgrTip.showMsgTip("圣物背包已满，请及时清理或者扩容！");
              return false;
          }
          holyitem.data.time = this.buildTime();
          this.listBagItem.push({ holyitem: holyitem });
          this.saveBag();
          Global.sendMsg(MSG.HOLY_ITEM_ADDD);
          Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
          BaseFacade.mItem.addItem(holyitem.itemDb.item_id, 1, 54);
          if (dropData)
              dropData.push({ type: DROP_TYPE.HOLY_ITEM, data: holyitem });
          return true;
      }
      static autoSellOne(holyitem) {
          let count = 0;
          let qualityUpItem = mgrSmelter.getLvupHolyItem();
          if (mgrSmelter.autoPutForge && !mgrSmelter.isSmeltExpFull() && mgrSmelter.checkItemCanPut(holyitem)) {
              mgrSmelter.feedItemOne(holyitem);
          }
          else if (mgrSmelter.autoPutLvup && !mgrSmelter.isSmeltQualityPreExpFull() && qualityUpItem && mgrSmelter.checkItemCanPut4QualityUp(qualityUpItem.holyitem, holyitem)) {
              mgrSmelter.feedItem4LvupOne(holyitem);
          }
          else {
              count += this.addHolyItemSellMone(holyitem);
          }
          this.remHolyItem(holyitem);
          return count;
      }
      static remHolyItem(holyitem) {
          holyitem.valid = false;
          let item = this.findBagItem(holyitem);
          if (item) {
              Utils.removeArrayItem(this.listBagItem, item);
          }
          this.saveBag();
      }
      static sellHolyItem(holyitem, dialog = false, msg = true) {
          if (!holyitem.valid) {
              return 0;
          }
          if (dialog) {
              if (mgrSmelter.isHolyItemQualityUping(holyitem)) {
                  mgrTip.alertPrompt("该圣物正在升品中，请取消升品后在试！");
                  return 0;
              }
              if (holyitem.isEquiped()) {
                  mgrTip.alertPrompt("该圣物已被" + holyitem.getEquipTowerName() + "所装备，是否【卖出】？", "", () => {
                      mgrHolyItem.sellHolyItem(holyitem);
                  });
                  return 0;
              }
              if (holyitem.lock) {
                  mgrTip.alertPrompt("该圣物已被锁定，是否【卖出】？", "", () => {
                      mgrHolyItem.sellHolyItem(holyitem);
                  });
                  return 0;
              }
              if (holyitem.isPreset()) {
                  mgrTip.alertPrompt("该圣物已被" + holyitem.getPresetNum() + "个方案预设，是否【卖出】？", "", () => {
                      mgrHolyItem.sellHolyItem(holyitem);
                  });
                  return 0;
              }
          }
          this.remHolyItem(holyitem);
          let count = this.addHolyItemSellMone(holyitem);
          if (msg)
              Global.sendMsg(MSG.HOLY_ITEM_SELL);
          return count;
      }
      static getHolyItemSellPrice(holyitem) {
          if (holyitem)
              return holyitem.qualityDb.price;
          else
              return 0;
      }
      static addHolyItemSellMone(holyitem) {
          let sell_count = this.getHolyItemSellPrice(holyitem);
          if (sell_count) {
              mgrGame.addItem(1000, sell_count, 31, false);
          }
          return sell_count;
      }
      static getFilterByQuality() {
          let filterMap = {};
          let config = this.data.convert;
          filterMap[EQUIP_QUALITY.GREEN] = config.green;
          filterMap[EQUIP_QUALITY.BLUE] = config.blue;
          filterMap[EQUIP_QUALITY.PURPLE] = config.purple;
          filterMap[EQUIP_QUALITY.ORANGE] = config.orange;
          return filterMap;
      }
      static isNeedSell(holyitem) {
          let filterMapQuality = this.getFilterByQuality();
          if (this.checkFilterAutoSellCondition) {
              let filterAutoSell = this.getFilterAutoSellCondition();
              if (holyitem.checkWordFilterAutoSell(filterAutoSell)) {
                  return false;
              }
          }
          if (mgrSmelter.isHolyItemQualityUping(holyitem)) {
              return false;
          }
          if (holyitem.level > 1) {
              return false;
          }
          if (!holyitem.lock && !holyitem.isEquiped() && !holyitem.isPreset() && this.checkFilterAutoSellItemId(holyitem.itemId) && filterMapQuality[holyitem.getQuality()]) {
              return true;
          }
          else {
              return false;
          }
      }
      static autoSell() {
          let count = 0;
          let listBagItemNew = [];
          let qualityUpItem = mgrSmelter.getLvupHolyItem();
          for (let item of this.listBagItem) {
              if (item.holyitem) {
                  if (this.isNeedSell(item.holyitem)) {
                      if (mgrSmelter.autoPutForge && !mgrSmelter.isSmeltExpFull() && mgrSmelter.checkItemCanPut(item.holyitem)) {
                          mgrSmelter.feedItemOne(item.holyitem);
                      }
                      else if (mgrSmelter.autoPutLvup && !mgrSmelter.isSmeltQualityPreExpFull() && qualityUpItem && mgrSmelter.checkItemCanPut4QualityUp(qualityUpItem.holyitem, item.holyitem)) {
                          mgrSmelter.feedItem4LvupOne(item.holyitem);
                      }
                      else {
                          count += this.addHolyItemSellMone(item.holyitem);
                      }
                  }
                  else {
                      listBagItemNew.push(item);
                  }
              }
          }
          this.listBagItem = listBagItemNew;
          this.saveBag();
          Global.sendMsg(MSG.HOLY_ITEM_SELL);
          return count;
      }
      static sortBag() {
          this.listBagItem.sort(this.sorteBagItem);
          this.saveBag();
      }
      static sorteBagItem(a, b) {
          return mgrHolyItem.sortByDefault(a, b);
      }
      static sortByDefault(a, b) {
          let scoreA = a.holyitem ? a.holyitem.scoreByTime : Number.MAX_VALUE;
          let scoreB = b.holyitem ? b.holyitem.scoreByTime : Number.MAX_VALUE;
          return scoreA - scoreB;
      }
      static sortByQuality(a, b) {
          let scoreA = a.holyitem ? a.holyitem.scoreByQuality : 0;
          let scoreB = b.holyitem ? b.holyitem.scoreByQuality : 0;
          return scoreB - scoreA;
      }
      static sortByLevel(a, b) {
          let scoreA = a.holyitem ? a.holyitem.scoreByLevel : 0;
          let scoreB = b.holyitem ? b.holyitem.scoreByLevel : 0;
          return scoreB - scoreA;
      }
      static sortByClass(a, b) {
          let scoreA = a.holyitem ? a.holyitem.scoreByClass : 0;
          let scoreB = b.holyitem ? b.holyitem.scoreByClass : 0;
          return scoreB - scoreA;
      }
      static calcItemCount() {
          return Math.max(this.data.bagSize, this.listBagItem.length);
      }
      static getBagItems(sortType = HOLYITEM_SORT_TYPE.DEFAULT, useFilter = false, typeFilter = null) {
          let listItem = [];
          let filter = null;
          if (useFilter) {
              filter = this.holyItemFilter;
          }
          let listBagItem = this.listBagItem;
          for (let i = 0; i < this.calcItemCount(); i++) {
              let item = listBagItem[i];
              if (filter && filter.ids) {
                  if (item && item.holyitem) {
                      let holyItem = item.holyitem;
                      if (this.checkFilterItemId(holyItem.itemId) && this.checkFilterQuality(holyItem.getQuality())) {
                          if (holyItem.checkWordFilter(filter.condition1) && holyItem.checkWordFilter(filter.condition2)) {
                              listItem.push(item);
                          }
                      }
                  }
              }
              else {
                  if (item && item.holyitem) {
                      if (typeFilter) {
                          if (typeFilter[item.holyitem.itemId]) {
                              listItem.push(item);
                          }
                      }
                      else {
                          listItem.push(item);
                      }
                  }
                  else {
                      listItem.push(this.EmptyBagItem);
                  }
              }
          }
          switch (sortType) {
              case HOLYITEM_SORT_TYPE.QUALITY:
                  listItem.sort(this.sortByQuality);
                  break;
              case HOLYITEM_SORT_TYPE.LEVEL:
                  listItem.sort(this.sortByLevel);
                  break;
              case HOLYITEM_SORT_TYPE.CLASS:
                  listItem.sort(this.sortByClass);
                  break;
              case HOLYITEM_SORT_TYPE.DEFAULT:
              default:
                  listItem.sort(this.sortByDefault);
                  break;
          }
          return listItem;
      }
      static getBagItems4Feed(sortType = HOLYITEM_SORT_TYPE.DEFAULT, typeFilter = null, qualityLimit = EQUIP_QUALITY.ORANGE) {
          let listItem = [];
          let listBagItem = this.listBagItem;
          for (let i = 0; i < this.calcItemCount(); i++) {
              let item = listBagItem[i];
              if (item && item.holyitem) {
                  if (item.holyitem.getQuality() <= qualityLimit) {
                      if (typeFilter) {
                          if (typeFilter[item.holyitem.itemId]) {
                              listItem.push(item);
                          }
                      }
                      else {
                          listItem.push(item);
                      }
                  }
              }
              else {
                  listItem.push(this.EmptyBagItem);
              }
          }
          switch (sortType) {
              case HOLYITEM_SORT_TYPE.QUALITY:
                  listItem.sort(this.sortByQuality);
                  break;
              case HOLYITEM_SORT_TYPE.LEVEL:
                  listItem.sort(this.sortByLevel);
                  break;
              case HOLYITEM_SORT_TYPE.CLASS:
                  listItem.sort(this.sortByClass);
                  break;
              case HOLYITEM_SORT_TYPE.DEFAULT:
              default:
                  listItem.sort(this.sortByDefault);
                  break;
          }
          return listItem;
      }
      static getBagItemsByQuality(sortType = HOLYITEM_SORT_TYPE.DEFAULT, quality, haveSubItem) {
          let listItem = [];
          let listBagItem = this.listBagItem;
          for (let i = 0; i < this.calcItemCount(); i++) {
              let item = listBagItem[i];
              if (item && item.holyitem) {
                  if (haveSubItem) {
                      if (item.holyitem.isSuperRedItem()) {
                          listItem.push(item);
                      }
                  }
                  else {
                      if (!item.holyitem.isSuperRedItem() && item.holyitem.getQuality() == quality) {
                          listItem.push(item);
                      }
                  }
              }
              else {
                  listItem.push(this.EmptyBagItem);
              }
          }
          switch (sortType) {
              case HOLYITEM_SORT_TYPE.QUALITY:
                  listItem.sort(this.sortByQuality);
                  break;
              case HOLYITEM_SORT_TYPE.LEVEL:
                  listItem.sort(this.sortByLevel);
                  break;
              case HOLYITEM_SORT_TYPE.CLASS:
                  listItem.sort(this.sortByClass);
                  break;
              case HOLYITEM_SORT_TYPE.DEFAULT:
              default:
                  listItem.sort(this.sortByDefault);
                  break;
          }
          return listItem;
      }
      static getBagItems4Lvup(sortType = HOLYITEM_SORT_TYPE.DEFAULT) {
          let listItem = [];
          let listBagItem = this.listBagItem;
          for (let i = 0; i < this.calcItemCount(); i++) {
              let item = listBagItem[i];
              if (item && item.holyitem) {
                  let holyitem = item.holyitem;
                  if (!holyitem.isSuperRedItem() && !holyitem.isQualityFix() && holyitem.getQuality() == EQUIP_QUALITY.ORANGE) {
                      if (holyitem.calcWordCountByQuality(EQUIP_QUALITY.ORANGE) >= 4) {
                          listItem.push(item);
                      }
                  }
              }
              else {
                  listItem.push(this.EmptyBagItem);
              }
          }
          switch (sortType) {
              case HOLYITEM_SORT_TYPE.QUALITY:
                  listItem.sort(this.sortByQuality);
                  break;
              case HOLYITEM_SORT_TYPE.LEVEL:
                  listItem.sort(this.sortByLevel);
                  break;
              case HOLYITEM_SORT_TYPE.CLASS:
                  listItem.sort(this.sortByClass);
                  break;
              case HOLYITEM_SORT_TYPE.DEFAULT:
              default:
                  listItem.sort(this.sortByDefault);
                  break;
          }
          return listItem;
      }
      static clearBagSelect() {
          let listBagItem = this.listBagItem;
          for (let i = 0; i < this.calcItemCount(); i++) {
              let item = listBagItem[i];
              if (item) {
                  item.selected = false;
              }
          }
      }
      static showHolyItem(holyitem) {
      }
      static findBagItem(holyitem) {
          for (let item of this.listBagItem) {
              if (item.holyitem && item.holyitem.data.uid == holyitem.data.uid) {
                  return item;
              }
          }
      }
      static findBagItemByUID(uid) {
          for (let item of this.listBagItem) {
              if (item.holyitem && item.holyitem.data.uid == uid) {
                  return item;
              }
          }
      }
      static findBagItemByUIDAndTowerId(uid, towerId) {
          let item = this.findBagItemByUID(uid);
          if (item && item.holyitem.getEquipTowerId() == towerId) {
              return item;
          }
          else {
              return null;
          }
      }
      static onHolyItemChange(towerId) {
          Global.sendMsg(MSG.TOWER_ATTR_UPDATE, towerId);
          Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
          this.saveBag();
      }
      static calcEquipHolyItemCountByQuality(towerId, quality) {
          let count = 0;
          let finalCount = 0;
          for (let item of this.listBagItem) {
              if (item) {
                  let holyitem = item.holyitem;
                  if (holyitem) {
                      if (holyitem.data.towerId == towerId) {
                          if (holyitem.data.quality == quality) {
                              finalCount++;
                          }
                          count++;
                          if (count >= 8) {
                              break;
                          }
                      }
                  }
              }
          }
          return finalCount;
      }
      static calcEquipHolyItemCountBySuperRedItem(towerId) {
          let count = 0;
          let finalCount = 0;
          for (let item of this.listBagItem) {
              if (item) {
                  let holyitem = item.holyitem;
                  if (holyitem) {
                      if (holyitem.data.towerId == towerId) {
                          if (holyitem.isSuperRedItem()) {
                              finalCount++;
                          }
                          count++;
                          if (count >= 8) {
                              break;
                          }
                      }
                  }
              }
          }
          return finalCount;
      }
      static calcPresetHolyItemCountBySuperRedItem(towerId, presetId) {
          let finalCount = 0;
          for (let i = 0; i < 8; i++) {
              let uid = mgrTower.getHolyItemPresetItemID(towerId, presetId, i);
              if (uid) {
                  let bagItem = this.findBagItemByUID(uid);
                  if (bagItem && bagItem.holyitem) {
                      if (bagItem.holyitem.isSuperRedItem()) {
                          finalCount++;
                      }
                  }
              }
          }
          return finalCount;
      }
      static calcPresetHolyItemCountByQuality(towerId, presetId, quality) {
          let finalCount = 0;
          for (let i = 0; i < 8; i++) {
              let uid = mgrTower.getHolyItemPresetItemID(towerId, presetId, i);
              if (uid) {
                  let bagItem = this.findBagItemByUID(uid);
                  if (bagItem && bagItem.holyitem) {
                      if (bagItem.holyitem.data.quality == quality) {
                          finalCount++;
                      }
                  }
              }
          }
          return finalCount;
      }
      static takeOnFailByRedItem() {
          mgrTip.alertTip("装备失败，【泰坦立方】只能装备一件！");
      }
      static canTakeOnByTower(item, towerId, slotId = 0) {
          let holyitem = item.holyitem;
          let slot = mgrTower.getTowerItemSlot(towerId, slotId);
          if (holyitem && !holyitem.isEquiped() && slot) {
              let itemTowerId = holyitem.getTowerId();
              if (itemTowerId && itemTowerId != towerId) {
                  return false;
              }
              return true;
          }
          return false;
      }
      static takeOnHolyItem(item, towerId, slotId, usePreset = false, presetId = 0) {
          let holyitem = item.holyitem;
          let slot = mgrTower.getTowerItemSlot(towerId, slotId);
          if (holyitem && slot) {
              let itemTowerId = holyitem.getTowerId();
              if (itemTowerId && itemTowerId != towerId) {
                  mgrTip.alertTip("该圣物只能被【" + mgrTower.getTowerName(itemTowerId) + "】装备！");
                  return;
              }
              if (usePreset) {
                  this.takeOffHolyItem(towerId, slotId, usePreset, presetId);
                  if (holyitem.isSuperRedItem()) {
                      let count = this.calcPresetHolyItemCountBySuperRedItem(towerId, presetId);
                      if (count > 0) {
                          this.takeOnFailByRedItem();
                          return;
                      }
                  }
                  let suc = mgrTower.setHolyItemPresetItemID(towerId, presetId, slotId, holyitem.getUID());
                  if (suc) {
                      holyitem.addPreset();
                      holyitem.data.towerSlotId = slot.id;
                      Global.sendMsg(MSG.TOWER_PRESET_CHANGE);
                  }
              }
              else {
                  this.takeOffHolyItem(towerId, slotId);
                  if (holyitem.isSuperRedItem()) {
                      let count = this.calcEquipHolyItemCountBySuperRedItem(towerId);
                      if (count > 0) {
                          this.takeOnFailByRedItem();
                          return;
                      }
                  }
                  if (holyitem.data.towerId) {
                      this.takeOffHolyItem(holyitem.data.towerId, holyitem.data.towerSlotId);
                  }
                  holyitem.data.towerId = towerId;
                  holyitem.data.towerSlotId = slot.id;
                  slot.item_uid = holyitem.data.uid;
                  this.onHolyItemChange(holyitem.data.towerId);
              }
          }
      }
      static takeOffHolyItem(towerId, slotId, usePreset = false, presetId = 0) {
          let slot = mgrTower.getTowerItemSlot(towerId, slotId);
          if (slot) {
              if (usePreset) {
                  let uid = mgrTower.getHolyItemPresetItemID(towerId, presetId, slotId);
                  if (uid) {
                      let bagItem = this.findBagItemByUID(uid);
                      if (bagItem) {
                          bagItem.holyitem.subPreset();
                      }
                  }
                  mgrTower.setHolyItemPresetItemID(towerId, presetId, slotId, "");
                  Global.sendMsg(MSG.TOWER_PRESET_CHANGE);
              }
              else {
                  if (slot.item_uid) {
                      let bagItem = this.findBagItemByUID(slot.item_uid);
                      if (bagItem) {
                          slot.item_uid = null;
                          bagItem.holyitem.data.towerId = null;
                          bagItem.holyitem.data.towerSlotId = null;
                          this.onHolyItemChange(towerId);
                      }
                  }
              }
          }
      }
      static getHolyItemItems() {
          let listItem = [];
          let listHolyItemItem = this.listBagItem;
          for (let i = 0; i < 3; i++) {
              let item = listHolyItemItem[i];
              if (item) {
                  listItem.push(item);
              }
              else {
                  listItem.push(this.EmptyBagItem);
              }
          }
          return listItem;
      }
      static calcAttrAdd(towerId) {
          let attr_add = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          let count = 0;
          for (let item of this.listBagItem) {
              if (item) {
                  let holyitem = item.holyitem;
                  if (holyitem) {
                      if (holyitem.data.towerId == towerId) {
                          this.calcAttrByHolyItem(holyitem, attr_add);
                          this.calcAttrByHolyItemSub(holyitem, attr_add);
                          count++;
                          if (count >= 8) {
                              break;
                          }
                      }
                  }
              }
          }
          Level.printAttr(attr_add, "圣物属性");
          return attr_add;
      }
      static calcAttrByHolyItem(holyitem, attr) {
          let itemDb = holyitem.itemDb;
          let main_k = BASE_ATTR[itemDb.attr_key];
          if (main_k != null) {
              let value = holyitem.getValue(false) * itemDb.v_factor;
              switch (itemDb.value_one) {
                  case "max":
                      if (value > attr[main_k]) {
                          attr[main_k] = value;
                      }
                      break;
                  case "min":
                      if (attr[main_k] == 0 || value < attr[main_k]) {
                          attr[main_k] = value;
                      }
                      break;
                  default:
                      attr[main_k] += value;
                      break;
              }
              if (main_k == BASE_ATTR.SK_TARGET_ADD) {
                  attr[BASE_ATTR.TT_TARGET_ADD] += 1;
              }
          }
          let word_attr = holyitem.attr;
          if (word_attr) {
              for (let word of word_attr) {
                  attr[word.k] += word.v;
              }
          }
      }
      static calcAttrByHolyItemSub(holyitem, attr) {
          let itemDb = holyitem.itemDbSub;
          if (!itemDb)
              return;
          let main_k = BASE_ATTR[itemDb.attr_key];
          if (main_k != null) {
              let value = holyitem.getValueSub(false) * itemDb.v_factor;
              switch (itemDb.value_one) {
                  case "max":
                      if (value > attr[main_k]) {
                          attr[main_k] = value;
                      }
                      break;
                  case "min":
                      if (attr[main_k] == 0 || value < attr[main_k]) {
                          attr[main_k] = value;
                      }
                      break;
                  default:
                      attr[main_k] += value;
                      break;
              }
              if (main_k == BASE_ATTR.SK_TARGET_ADD) {
                  attr[BASE_ATTR.TT_TARGET_ADD] += 1;
              }
          }
      }
      static addBagSize(size = 1) {
          this.data.bagSize += size;
          if (this.data.bagSize > this.getBagSizeMax()) {
              this.data.bagSize = this.getBagSizeMax();
          }
          this.saveRecord();
          Global.sendMsg(MSG.MSG_BAG_EQUIP_EX);
      }
      static getBagSize() {
          return this.data.bagSize;
      }
      static getBagSizeMax() {
          return db.game_cnf.holyitem_bag_size_max;
      }
      static isBagSizeMax() {
          return this.getBagSize() >= this.getBagSizeMax();
      }
      static notEnoughEmptyByItemId(itemId, count) {
          let itemDb = db.get_item_db(itemId);
          let final = 0;
          if (itemDb && (itemDb.type == 3 || itemDb.type == 6) && count) {
              final += count;
          }
          return this.notEnoughEmpty(final);
      }
      static notEnoughEmptyByRewardIds(reward_ids, scale = 1) {
          let finalCount = 0;
          for (let i = 0; i < reward_ids.length; i += 2) {
              let itemId = reward_ids[i];
              let count = reward_ids[i + 1] * scale;
              if (itemId && count) {
                  let itemDb = db.get_item_db(itemId);
                  if (itemDb && (itemDb.type == 3 || itemDb.type == 6)) {
                      finalCount += count;
                  }
              }
          }
          return this.notEnoughEmpty(finalCount);
      }
      static notEnoughEmpty(num) {
          let countEmpty = this.data.bagSize - this.listBagItem.length;
          if (countEmpty < num) {
              Director.openPanelWithSingleton("PanelDialogTip", { title: "提示", desc: "背包空位不足" + num + "个,请先清理背包！", confirmText: "确定" });
              return true;
          }
          return false;
      }
      static haveAnyNewItem() {
          let haveNewItem = false;
          for (let item of this.listBagItem) {
              if (item) {
                  let holyitem = item.holyitem;
                  if (holyitem && holyitem.new) {
                      haveNewItem = true;
                      break;
                  }
              }
          }
          return haveNewItem;
      }
      static haveAnyItemCanEquip() {
          let canEquip = false;
          for (let item of this.listBagItem) {
              if (item) {
                  let holyitem = item.holyitem;
                  if (holyitem && !holyitem.isEquiped()) {
                      canEquip = true;
                      break;
                  }
              }
          }
          return canEquip;
      }
      static haveRedPoint() {
          return this.haveAnyNewItem();
      }
      static feedItem(item, foods) {
          if (item.holyitem) {
              let expAdd = 0;
              for (let food of foods) {
                  if (food.holyitem) {
                      expAdd += food.holyitem.getExpFeed();
                      this.remHolyItem(food.holyitem);
                  }
              }
              let isLevelAdd = item.holyitem.addExp(expAdd);
              if (isLevelAdd) {
                  mgrSound.playSound("lvup_item_suc");
                  Global.sendMsg(MSG.HOLY_ITEM_LVUP);
                  if (item.holyitem.itemDb) {
                      GameStatistics.statisCommonEvent(item.holyitem.itemDb.lv_statis_point, item.holyitem.level);
                  }
              }
              Global.sendMsg(MSG.HOLY_ITEM_FEED);
              return isLevelAdd;
          }
          return false;
      }
      static autoSelectByQuality(select) {
          let quality = this.getFilterQuality();
          let bagItems = this.getBagItems(HOLYITEM_SORT_TYPE.LEVEL);
          let totalNeed = select.holyitem.calcLvupMaxNeed();
          let totalCurt = 0;
          for (let item of bagItems) {
              let holyItem = item.holyitem;
              if (holyItem && item != select) {
                  if (!holyItem.isEquiped() && !holyItem.isPreset() && !mgrSmelter.isHolyItemQualityUping(holyItem) && !holyItem.lock && holyItem.qualityDb.quality == quality) {
                      item.selected = true;
                      totalCurt += holyItem.getExpFeed();
                      if (totalCurt >= totalNeed) {
                          break;
                      }
                  }
                  else {
                      item.selected = false;
                  }
              }
          }
          return bagItems;
      }
      static smelterAutoSelectByQuality(totalNeed) {
          let quality = this.getFilterQuality();
          let bagItems = this.getBagItems(HOLYITEM_SORT_TYPE.LEVEL);
          let totalCurt = 0;
          for (let item of bagItems) {
              let holyItem = item.holyitem;
              if (holyItem) {
                  if (!holyItem.isEquiped() && !holyItem.isPreset() && !mgrSmelter.isHolyItemQualityUping(holyItem) && !holyItem.lock && holyItem.qualityDb.quality == quality && mgrSmelter.checkItemCanPut(holyItem)) {
                      item.selected = true;
                      totalCurt += holyItem.getExpSmelt();
                      if (totalCurt >= totalNeed) {
                          break;
                      }
                  }
                  else {
                      item.selected = false;
                  }
              }
          }
          return bagItems;
      }
      static smelterQualityUpAutoSelectByQuality(totalNeed, exceptItem) {
          let selectItem = mgrSmelter.getLvupHolyItem();
          let quality = this.getFilterQuality(EQUIP_QUALITY.ORANGE);
          let bagItems = this.getBagItems(HOLYITEM_SORT_TYPE.LEVEL);
          if (!selectItem) {
              return bagItems;
          }
          let totalCurt = 0;
          for (let item of bagItems) {
              if (exceptItem && item == exceptItem) {
                  continue;
              }
              let holyItem = item.holyitem;
              if (holyItem) {
                  if (!holyItem.isEquiped() && !holyItem.isPreset() && !mgrSmelter.isHolyItemQualityUping(holyItem) && !holyItem.lock && holyItem.qualityDb.quality == quality && mgrSmelter.checkItemCanPut4QualityUp(selectItem.holyitem, holyItem)) {
                      item.selected = true;
                      totalCurt += holyItem.getExpSmelt();
                      if (totalCurt >= totalNeed) {
                          break;
                      }
                  }
                  else {
                      item.selected = false;
                  }
              }
          }
          return bagItems;
      }
      static getConvertConfig() {
          return this.data.convert;
      }
      static get sortType() {
          return this.data.sortType;
      }
      static set sortType(st) {
          this.data.sortType = st;
          this.saveRecord();
      }
      static get holyItemFilter() {
          return this.data.filter;
      }
      static checkFilterItemId(id) {
          let valid = this.data.filter.ids[id];
          return valid;
      }
      static checkFilterQuality(quality) {
          let valid = this.data.filter.quality[quality];
          if (valid == null) {
              return true;
          }
          else {
              return valid;
          }
      }
      static setFilterHolyItemId(id, value) {
          this.data.filter.ids[id] = value;
          this.saveRecord();
      }
      static setFilterHolyItemQuality(quality, value) {
          this.data.filter.quality[quality] = value;
          this.saveRecord();
      }
      static getFilterCondition1() {
          return this.data.filter.condition1;
      }
      static getFilterCondition2() {
          return this.data.filter.condition2;
      }
      static resetFilterHolyItemCondition(condition) {
          condition.id = 0;
          condition.num = 1;
          condition.quality = 0;
      }
      static resetFilterHolyItem() {
          this.data.filter.ids = {};
          this.data.filter.quality = {};
          this.data.filter.condition1.id = 0;
          this.resetFilterHolyItemCondition(this.data.filter.condition1);
          this.resetFilterHolyItemCondition(this.data.filter.condition2);
          this.saveRecord();
      }
      static setFilterAutoSellItemId(id, value) {
          this.data.filterSell.ids[id] = value;
          this.saveRecord();
      }
      static getFilterAutoSellCondition() {
          return this.data.filterSell.condition;
      }
      static checkFilterAutoSellItemId(id) {
          let valid = this.data.filterSell.ids[id];
          return valid;
      }
      static set checkFilterAutoSellCondition(value) {
          this.data.filterSell.check = value;
          this.saveRecord();
      }
      static get checkFilterAutoSellCondition() {
          return this.data.filterSell.check;
      }
      static resetFilterAutoSell() {
          this.data.filterSell.ids = {};
          this.data.filterSell.condition.id = 0;
          this.data.convert.green = false;
          this.data.convert.blue = false;
          this.data.convert.purple = false;
          this.data.convert.orange = false;
          this.resetFilterHolyItemCondition(this.data.filterSell.condition);
          this.saveRecord();
      }
      static getHolyItemQualityIcon(quality = EQUIP_QUALITY.RED) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb)
              return qualityDb.icon;
          else
              return "";
      }
      static get compress() {
          return this.data.compress;
      }
      static set compress(v) {
          this.data.compress = v;
          this.saveRecord();
      }
      static get autotime() {
          return this.data.autotime;
      }
      static set autotime(v) {
          this.data.autotime = v;
          this.saveRecord();
      }
      static buildTime() {
          this.autotime++;
          return this.autotime;
      }
      static packArray(data, defines, packed) {
          packed = packed || [];
          if (!data || !defines) {
              packed.push[0];
              return packed;
          }
          if (!data.length || !defines.length) {
              packed.push[0];
              return packed;
          }
          packed.push(data.length);
          for (var item of data) {
              for (var di = 0; di < defines.length; di++) {
                  var define = defines[di];
                  var k = define.k;
                  var d = define.d;
                  var a = define.a;
                  var v = item[k];
                  if (a) {
                      this.packArray(v, a, packed);
                  }
                  else {
                      packed.push(v || d);
                  }
              }
          }
          return packed;
      }
      static unpackArray(data, defines, decodeIndex = 0) {
          var unpack = [];
          if (!data || !defines) {
              return unpack;
          }
          if (!data.length || !defines.length) {
              return unpack;
          }
          var len = data[decodeIndex++];
          for (var i = 0; i < len; i++) {
              let item = {};
              for (var di = 0; di < defines.length; di++) {
                  var define = defines[di];
                  var k = define.k;
                  var d = define.d;
                  var a = define.a;
                  if (a) {
                      let len = data[decodeIndex];
                      item[k] = this.unpackArray(data, a, decodeIndex);
                      decodeIndex += (len * a.length + 1);
                  }
                  else {
                      item[k] = data[decodeIndex++] || d;
                  }
              }
              unpack.push(item);
          }
          return unpack;
      }
  }
  mgrHolyItem.RECORD_KEY = "game166_equip_v1.0";
  mgrHolyItem.needInit = false;
  mgrHolyItem.dataDefault = {
      compress: 0,
      autotime: 0,
      bagSize: 24,
      bagData: [],
      filterQuality: 0,
      sortType: HOLYITEM_SORT_TYPE.DEFAULT,
      convert: {
          green: false,
          blue: false,
          purple: false,
          orange: false,
      },
      filter: {
          ids: {},
          quality: {
              [EQUIP_QUALITY.GREEN]: true,
              [EQUIP_QUALITY.BLUE]: true,
              [EQUIP_QUALITY.PURPLE]: true,
              [EQUIP_QUALITY.ORANGE]: true,
          },
          condition1: {
              id: 0,
              quality: 0,
              num: 1,
          },
          condition2: {
              id: 0,
              quality: 0,
              num: 1,
          },
      },
      filterSell: {
          ids: {},
          check: 0,
          condition: {
              id: 0,
              quality: 0,
              num: 1,
          },
      }
  };
  mgrHolyItem.EmptyBagItem = { holyitem: null };

  const HOLY_ITEM_CHECK = {
      uid: "",
      id: "",
      lv: 0,
      exp: 0,
      quality: 0,
      words: [{ id: 0, lv: 0, vl: 0, quality: 0 }],
      towerId: "",
      towerSlotId: 0,
      lock: false,
      new: false,
      time: 0,
      preset: 0,
      subId: "",
  };
  const HOLY_ITEM_TEMPLATE = [
      { k: "uid", d: "" },
      { k: "id", d: "" },
      { k: "lv", d: 0 },
      { k: "exp", d: 0 },
      { k: "quality", d: 0 },
      { k: "towerId", d: "" },
      { k: "towerSlotId", d: 0 },
      { k: "lock", d: 0 },
      { k: "new", d: 0 },
      { k: "time", d: 0 },
      { k: "preset", d: 0 },
      { k: "subId", d: "" },
      { k: "words", d: [], a: [{ k: "id", d: 0 }, { k: "lv", d: 0 }, { k: "vl", d: 0 }, { k: "quality", d: 0 }] },
  ];
  var HOLY_ITEM_SLOT_STATE;
  (function (HOLY_ITEM_SLOT_STATE) {
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["EMPTY"] = 0] = "EMPTY";
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["ADD"] = 1] = "ADD";
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["ITEM"] = 2] = "ITEM";
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["UNLOCK_COIN"] = 3] = "UNLOCK_COIN";
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["UNLOCK_LEVEL"] = 4] = "UNLOCK_LEVEL";
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["UNLOCK_STAR"] = 5] = "UNLOCK_STAR";
      HOLY_ITEM_SLOT_STATE[HOLY_ITEM_SLOT_STATE["INVALID"] = 6] = "INVALID";
  })(HOLY_ITEM_SLOT_STATE || (HOLY_ITEM_SLOT_STATE = {}));
  var SORT_SCORE;
  (function (SORT_SCORE) {
      SORT_SCORE[SORT_SCORE["SCORTE_5"] = 1] = "SCORTE_5";
      SORT_SCORE[SORT_SCORE["SCORTE_4"] = 1000] = "SCORTE_4";
      SORT_SCORE[SORT_SCORE["SCORTE_3"] = 10000] = "SCORTE_3";
      SORT_SCORE[SORT_SCORE["SCORTE_2"] = 100000] = "SCORTE_2";
      SORT_SCORE[SORT_SCORE["SCORTE_1"] = 1000000] = "SCORTE_1";
  })(SORT_SCORE || (SORT_SCORE = {}));
  class HolyItem {
      constructor() {
          this.amount = 0;
          this.valid = true;
          this.data = { words: [], exp: 0 };
          this.attr = [];
          this.amount = 1;
          this.valid = true;
      }
      buildUID() {
          this.data.uid = Number((Math.random() * 1000000).toString() + Date.now()).toString(36) + HolyItem.uid_auto_increase++;
      }
      getUID() {
          return this.data.uid;
      }
      get itemId() {
          return this.itemDb.id;
      }
      get count() {
          return this.amount;
      }
      set count(v) {
          this.amount += v;
      }
      get scoreByLock() {
          if (this.lock) {
              return 1;
          }
          else {
              return 0;
          }
      }
      get scoreByEquiped() {
          if (this.isEquiped()) {
              return 1;
          }
          else {
              return 0;
          }
      }
      get score() {
          return this.scoreByLock * SORT_SCORE.SCORTE_1 + this.qualityDb.quality * SORT_SCORE.SCORTE_2 + this.level * SORT_SCORE.SCORTE_3 + this.scoreByEquiped * SORT_SCORE.SCORTE_4 + this.itemDb.index * SORT_SCORE.SCORTE_5;
      }
      get scoreByTime() {
          return this.data.time || 0;
      }
      get scoreByQuality() {
          return this.scoreByLock * SORT_SCORE.SCORTE_2 + this.qualityDb.quality * SORT_SCORE.SCORTE_1 + this.level * SORT_SCORE.SCORTE_3 + this.scoreByEquiped * SORT_SCORE.SCORTE_4 + this.itemDb.index * SORT_SCORE.SCORTE_5;
      }
      get scoreByLevel() {
          return this.scoreByLock * SORT_SCORE.SCORTE_2 + this.qualityDb.quality * SORT_SCORE.SCORTE_3 + this.level * SORT_SCORE.SCORTE_1 + this.scoreByEquiped * SORT_SCORE.SCORTE_4 + this.itemDb.index * SORT_SCORE.SCORTE_5;
      }
      get scoreByClass() {
          return this.scoreByLock * SORT_SCORE.SCORTE_2 + this.qualityDb.quality * SORT_SCORE.SCORTE_3 + this.level * SORT_SCORE.SCORTE_4 + this.scoreByEquiped * SORT_SCORE.SCORTE_5 + this.itemDb.index * SORT_SCORE.SCORTE_1;
      }
      static loadFromData(data) {
          let itemDb = db.get_holy_item_db(data.id);
          let qualityDb = db.get_holy_item_quality(data.quality);
          let itemDbSub = db.get_holy_item_db_map()[data.subId];
          if (!itemDb || !qualityDb) {
              console.error("错误的圣物存档", data);
              return;
          }
          let equip = new HolyItem();
          equip.data = data;
          equip.itemDb = itemDb;
          equip.qualityDb = qualityDb;
          equip.itemDbSub = itemDbSub;
          equip.refreshLv();
          equip.refreshWord();
          return equip;
      }
      isEquiped() {
          return this.data.towerId;
      }
      isPreset() {
          return this.data.preset;
      }
      getPresetNum() {
          return this.data.preset || 0;
      }
      refreshLv() {
          this.expDb = db.get_holy_exp_db(this.level);
      }
      refreshWord() {
          this.attr = this.buildAttr();
      }
      buildAttr() {
          let data = this.data;
          let listAttr = [];
          if (data.words) {
              let wordLv = 0;
              for (let word of data.words) {
                  wordLv += word.lv;
              }
              if (Math.floor(this.level / 4) != wordLv) {
                  for (let word of data.words) {
                      word.lv = 0;
                  }
                  for (let i = 1; i <= this.level; i++) {
                      if (i % 4 == 0) {
                          this.randomLvupAttr(false);
                      }
                  }
                  mgrHolyItem.saveRecord();
              }
              for (let word of data.words) {
                  let wordDb = db.get_holy_item_word(word.id - 1);
                  if (wordDb) {
                      let index = BASE_ATTR[wordDb.attr];
                      let quality = word.quality || 0;
                      let value = word.vl || 0;
                      let valueAdd = (wordDb["add" + (quality + 1)] || 0) * word.lv;
                      let vt = wordDb["v" + (quality + 1)] || [];
                      let valueMax = vt[1] || 0;
                      value = Math.min(value, valueMax);
                      if (index != null) {
                          listAttr.push({ k: index, v: value + valueAdd, q: quality, v_base: value });
                      }
                      else {
                      }
                  }
              }
          }
          return listAttr;
      }
      calcWordCountByQuality(quality) {
          let data = this.data;
          let count = 0;
          if (data.words) {
              for (let word of data.words) {
                  if (word.quality >= quality) {
                      count++;
                  }
              }
          }
          return count;
      }
      getNameDebug() {
          return this.itemDb.name;
      }
      getName() {
          if (this.qualityDb && this.itemDbSub) {
              return this.qualityDb.name_ex;
          }
          else {
              return this.itemDb.name;
          }
      }
      getIcon() {
          if (this.qualityDb && this.itemDbSub) {
              return this.qualityDb.icon;
          }
          else {
              return this.itemDb.icon;
          }
      }
      getQuality() {
          return this.qualityDb.quality;
      }
      isQualityFix() {
          return this.itemDb.quality_fixed > 0;
      }
      isSuperRedItem() {
          return this.itemDbSub != null;
      }
      isTowerItem() {
          return this.itemDb.tower_id != "";
      }
      getTowerId() {
          return this.itemDb.tower_id;
      }
      getValuePrev() {
          let prev;
          if (this.itemDbSub) {
              prev = "z";
          }
          else {
              prev = "v";
          }
          return prev;
      }
      getValue(ui) {
          let prev = this.getValuePrev();
          let value = this.itemDb[prev + this.level] || this.itemDb.v20;
          if (ui)
              return value * this.itemDb.u_factor;
          else
              return value;
      }
      getValueNext(add = 1, ui) {
          let prev = this.getValuePrev();
          let value = this.itemDb[prev + (this.level + add)] || this.itemDb.v20;
          if (ui)
              return value * this.itemDb.u_factor;
          else
              return value;
      }
      getValueSub(ui) {
          let value = this.itemDbSub["s" + this.level] || this.itemDbSub.v20;
          if (ui)
              return value * this.itemDbSub.u_factor;
          else
              return value;
      }
      getValueSubNext(add = 1, ui) {
          let value = this.itemDbSub["s" + (this.level + add)] || this.itemDbSub.v20;
          if (ui)
              return value * this.itemDbSub.u_factor;
          else
              return value;
      }
      getLevelDesc() {
          if (this.level)
              return "+" + this.level;
          else
              return "+0";
      }
      getDesc() {
          if (this.itemDbSub) {
              let descMain = Utils.sprintf(this.itemDb.desc, this.getValue(true).toFixed(1));
              let descSubb = Utils.sprintf(this.itemDbSub.desc, this.getValueSub(true).toFixed(1));
              return descMain + "\n" + descSubb;
          }
          else {
              return Utils.sprintf(this.itemDb.desc, this.getValue(true).toFixed(1));
          }
      }
      getDescList() {
          let listData = [];
          if (this.itemDbSub) {
              let descMain = Utils.sprintf(this.itemDb.desc, this.getValue(true).toFixed(1));
              let descSubb = Utils.sprintf(this.itemDbSub.desc, this.getValueSub(true).toFixed(1));
              listData.push({ key: 1, desc: descMain });
              listData.push({ key: 2, desc: descSubb });
          }
          else {
              listData.push({ key: 0, desc: Utils.sprintf(this.itemDb.desc, this.getValue(true).toFixed(1)) });
          }
          return listData;
      }
      getDescMain() {
          if (this.itemDb) {
              return Utils.sprintf(this.itemDb.desc, this.getValue(true).toFixed(1));
          }
          return "";
      }
      getDescVice() {
          if (this.itemDbSub) {
              return Utils.sprintf(this.itemDbSub.desc, this.getValueSub(true).toFixed(1));
          }
          return "";
      }
      getEquipTowerId() {
          return this.data.towerId;
      }
      getEquipTowerName() {
          if (this.isEquiped()) {
              let towerDb = db.get_tower_db(this.data.towerId);
              if (towerDb) {
                  return towerDb.name;
              }
          }
          return "";
      }
      getHead() {
          if (this.isEquiped()) {
              let towerDb = db.get_tower_db(this.data.towerId);
              if (towerDb) {
                  return towerDb.icon_head;
              }
          }
          return "";
      }
      set level(value) {
          this.data.lv = value;
      }
      get level() {
          return this.data.lv || 0;
      }
      isLevelMax() {
          return this.level >= this.levelMax;
      }
      get levelMax() {
          if (this.itemDb.lv_limit > 0)
              return Math.min(this.itemDb.lv_limit, this.qualityDb.lv_max);
          else
              return this.qualityDb.lv_max;
      }
      lvup(add = 1) {
          if (this.qualityDb && !this.isLevelMax()) {
              let lv = this.data.lv + add;
              if (lv > this.levelMax) {
                  this.level = this.levelMax;
              }
              else {
                  this.level = lv;
                  if (lv % 4 == 0) {
                      this.randomLvupAttr();
                  }
              }
              mgrTask.doEvent(db.TASK_EVENT_ID.LVUP_HOLYITEM);
              this.refreshLv();
          }
      }
      lvupQuality() {
          if (this.qualityDb && this.qualityDb.quality == EQUIP_QUALITY.ORANGE) {
              this.data.quality = this.data.quality + 1;
              this.qualityDb = db.get_holy_item_quality(this.data.quality);
              this.randomLvupAttrQuality();
          }
      }
      randomLvupAttrQuality(refresh = true) {
          let word = Utils.randomItem(this.data.words);
          if (word) {
              if (word.quality < EQUIP_QUALITY.RED)
                  word.quality++;
              if (refresh)
                  this.refreshWord();
          }
      }
      randomLvupAttr(refresh = true) {
          let word = Utils.randomItem(this.data.words);
          if (word) {
              word.lv++;
              if (refresh)
                  this.refreshWord();
          }
      }
      getExp() {
          return this.data.exp || 0;
      }
      getExpMax(expDb = null, def = Number.MAX_VALUE) {
          expDb = expDb || this.expDb;
          return expDb["need" + this.qualityDb.index] || def;
      }
      getExpFeed(expDb = null) {
          expDb = expDb || this.expDb;
          let exp = expDb["feed" + this.qualityDb.index] || 0;
          return Math.floor(exp * this.itemDb.exp_factor);
      }
      getExpSmelt(expDb = null) {
          expDb = expDb || this.expDb;
          let exp = expDb["smelt" + this.qualityDb.index] || 0;
          let itemDb = this.itemDb;
          if (itemDb && itemDb.smelt_factor > 0) {
              exp *= itemDb.smelt_factor;
          }
          return Math.floor(exp);
      }
      calcLvAdd(add = 0) {
          let lvAdd = 0;
          let expTemp = this.getExp() + add;
          let expDb = db.get_holy_exp_db_map()[this.level];
          if (expDb && this.qualityDb) {
              while (expTemp >= this.getExpMax(expDb)) {
                  let max = this.getExpMax(expDb);
                  lvAdd++;
                  expTemp -= max;
                  expDb = db.get_holy_exp_db_map()[this.level + lvAdd];
              }
          }
          return lvAdd;
      }
      calcLvupMaxNeed() {
          let needTotal = 0;
          for (let lv = this.level; lv <= this.levelMax; lv++) {
              let expDb = db.get_holy_exp_db_map()[lv];
              if (expDb) {
                  needTotal += expDb["need" + this.qualityDb.index];
              }
          }
          return needTotal - this.getExp();
      }
      addExp(add = 0) {
          let isLevelAdd = false;
          if (this.expDb && this.qualityDb) {
              this.data.exp += add;
              while (this.data.exp >= this.getExpMax()) {
                  let expDb = db.get_holy_exp_db_map()[this.level + 1];
                  if (!expDb) {
                      break;
                  }
                  isLevelAdd = true;
                  let max = this.getExpMax();
                  this.lvup(1);
                  this.data.exp -= max;
              }
              if (this.data.exp < 0)
                  this.data.exp = 0;
          }
          return isLevelAdd;
      }
      save() {
          mgrHolyItem.saveBag();
      }
      set lock(lock) {
          this.data.lock = lock;
          this.save();
          Global.sendMsg(MSG.HOLY_ITEM_LOCK, this.data.uid);
      }
      get lock() {
          return this.data.lock;
      }
      set new(v) {
          this.data.new = v;
          Global.sendMsg(MSG.REFRESH_RED_POINT);
          this.save();
      }
      get new() {
          return this.data.new;
      }
      checkWordFilter(filter) {
          if (!filter)
              return true;
          let filterWordId = filter.id || 0;
          let filterWordQuality = filter.quality || 0;
          let filterWordNum = filter.num || 0;
          if (filterWordId) {
              let wordNum = 0;
              if (filterWordNum < 0) {
                  for (let word of this.data.words) {
                      if (word.id == filterWordId && word.quality == filterWordQuality) {
                          wordNum++;
                      }
                  }
                  return wordNum == (-filterWordNum);
              }
              else {
                  for (let word of this.data.words) {
                      if (word.id == filterWordId && word.quality >= filterWordQuality) {
                          wordNum++;
                      }
                  }
                  return wordNum >= filterWordNum;
              }
          }
          else {
              let wordNum = 0;
              if (filterWordNum < 0) {
                  for (let word of this.data.words) {
                      if (word.quality == filterWordQuality) {
                          wordNum++;
                      }
                  }
                  return wordNum == (-filterWordNum);
              }
              else {
                  for (let word of this.data.words) {
                      if (word.quality >= filterWordQuality) {
                          wordNum++;
                      }
                  }
                  return wordNum >= filterWordNum;
              }
          }
      }
      checkWordFilterAutoSell(filter) {
          if (!filter)
              return true;
          let filterWordQuality = filter.quality || 0;
          let filterWordNum = filter.num || 0;
          let wordNum = 0;
          for (let word of this.data.words) {
              if (word.quality >= filterWordQuality) {
                  wordNum++;
              }
          }
          return wordNum >= filterWordNum;
      }
      addPreset() {
          let preset = this.data.preset || 0;
          this.data.preset = preset + 1;
      }
      subPreset() {
          if (this.data.preset > 0) {
              this.data.preset--;
          }
          else {
              this.data.preset = 0;
          }
      }
  }
  HolyItem.uid_auto_increase = 0;

  var EXCHANGE_TYPE;
  (function (EXCHANGE_TYPE) {
      EXCHANGE_TYPE[EXCHANGE_TYPE["SECRET_TOWER"] = 0] = "SECRET_TOWER";
      EXCHANGE_TYPE[EXCHANGE_TYPE["SECRET_SHOP"] = 1] = "SECRET_SHOP";
      EXCHANGE_TYPE[EXCHANGE_TYPE["FINALWAR_SHOP"] = 2] = "FINALWAR_SHOP";
      EXCHANGE_TYPE[EXCHANGE_TYPE["NEWYEAR_SHOP"] = 3] = "NEWYEAR_SHOP";
      EXCHANGE_TYPE[EXCHANGE_TYPE["NEWYEAR_TOWER"] = 4] = "NEWYEAR_TOWER";
  })(EXCHANGE_TYPE || (EXCHANGE_TYPE = {}));
  class mgrExchange extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static setExchangeCount(shopId, count) {
          this.data.shopid2count[shopId] = count;
          this.saveRecord();
      }
      static getExchangeCount(shopId) {
          return this.data.shopid2count[shopId] || 0;
      }
      static addExchangeCount(shopId, add = 1) {
          this.setExchangeCount(shopId, this.getExchangeCount(shopId) + add);
      }
      static getExchangeLeftCountByDB(data) {
          let left = 0;
          if (data) {
              left = data.limit - this.getExchangeCount(data.id);
              if (left < 0)
                  left = 0;
          }
          return left;
      }
      static canExchangeByDB(data) {
          return this.getExchangeCount(data.id) < data.limit;
      }
      static tryExchangeShop(data) {
          if (data && this.canExchangeByDB(data) && mgrGame.checkItem(data.price_item_id, data.price_item_cost)) {
              mgrGame.addItem(data.item_id, data.item_num, 62, true, null, () => {
                  mgrGame.subItem(data.price_item_id, data.price_item_cost, 62);
                  this.addExchangeCount(data.id, 1);
                  Global.sendMsg(MSG.EXCHANGE_SHOP_REFRESH);
                  if (data.type == EXCHANGE_TYPE.NEWYEAR_TOWER || data.type == EXCHANGE_TYPE.NEWYEAR_SHOP) {
                      GameStatistics.statisCommonEvent(1102, Number(data.id));
                      mgrTask.doEvent(db.TASK_EVENT_ID.NEWYEAR_SHOP_EXCHANGE);
                  }
              });
          }
      }
      static resetShopByType(type) {
          let shopList = db.get_shop_exchange_db_map();
          for (let k in shopList) {
              let shop = db.get_shop_exchange_db(k);
              if (shop.type == type) {
                  this.setExchangeCount(shop.id, 0);
              }
          }
      }
  }
  mgrExchange.RECORD_KEY = "game166_exchange_v1.0";
  mgrExchange.dataDefault = {
      shopid2count: {},
  };

  class mgrTime extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [BASE_MSG.SDK_SERVER_TIME_CHANGE]: this.onServerTimeChange.bind(this),
          });
      }
      static onStart() {
          this.checkTime();
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      static checkTime() {
          if (StageConfig.useLocalTime || db.cop_db.is4399Watermark) {
              Global.sendMsg(BASE_MSG.SDK_SERVER_TIME_CHANGE, { bChange: false, serverTime: Date.now().toString() });
          }
          else {
              mgrSdk.checkTimeChange();
          }
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrTime.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onUpdatePerSecond() {
          this.timePass += 1;
          this.timePassOnline += 1;
          this.serverOnlineTime += 1;
          this.calcOnlineTime();
          if (!this.bServerTimeReady && this.timePass >= 5) {
              this.timePass = 0;
              this.checkTime();
          }
          else {
              if (db.cop_db.police_speed_check) {
                  if (this.timePass >= 60) {
                      this.timePass = 0;
                      this.checkTime();
                  }
              }
          }
      }
      static onServerTimeChange(data) {
          let curtTimeServer = Number(data.serverTime);
          if (curtTimeServer <= 0)
              return;
          this.dataServerTimeChange = data;
          this.updateOnlineTime();
          let onlineTime = this.onlineTime;
          if (onlineTime < 0) {
              onlineTime = 0;
          }
          if (onlineTime) {
              this.onlineTime = 0;
          }
          this.serverOnlineTime = 0;
          let lastTimeOnLine = this.serverTime;
          let curtDateNum = 0;
          let lastDateNum = 0;
          if (lastTimeOnLine) {
              let lastDate = new Date(lastTimeOnLine);
              lastDateNum = this.getDateNum(lastDate);
          }
          else {
              lastTimeOnLine = curtTimeServer;
          }
          let lastTimeOffline = lastTimeOnLine + onlineTime;
          this.serverTime = curtTimeServer;
          let curtDate = new Date(curtTimeServer);
          curtDateNum = this.getDateNum(curtDate);
          if (curtDateNum != lastDateNum) {
              console.log("mgrTime.不同天");
              Global.sendMsg(MSG.TIME_DIFFERENT_DAY);
          }
          let passTimeOffline = Math.floor((curtTimeServer - lastTimeOffline) / 1000);
          if (passTimeOffline > 0) {
              console.log("mgrTime.有离线时间", passTimeOffline);
              Global.sendMsg(MSG.TIME_OFFLINE_TIME, passTimeOffline);
          }
          this.bServerTimeReady = true;
          this.bChangeTime = data.bChange;
          if (db.cop_db.police_speed_check) {
              if (!this.bChangeTime) {
                  let passTime = (Utils.getTime() - curtTimeServer);
                  if (passTime >= db.cop_db.police_speed_check * 60 * 1000) {
                      this.bChangeTime = true;
                  }
              }
              if (this.bChangeTime && !this.isFindTimeChange) {
                  this.isFindTimeChange = true;
                  Director.openPanelWithSingleton("PanelWarning");
              }
          }
          console.log("mgrTime.服务器时间更新", curtDateNum, lastDateNum, passTimeOffline, data.bChange, data.serverTime);
          Global.sendMsg(MSG.MGR_TIME_UPDATE);
      }
      static calcOnlineTime(dt = 1) {
          this.passCalcOnline += dt;
          if (this.passCalcOnline >= this.maxxCalcOnline) {
              this.passCalcOnline = 0;
              this.updateOnlineTime();
          }
      }
      static updateOnlineTime() {
          this.onlineTime += this.calcDeltaTime();
      }
      static calcDeltaTime() {
          let curtTime = Date.now();
          if (this.localTime <= 0) {
              this.localTime = curtTime;
          }
          let pass = curtTime - this.localTime;
          if (pass < 0) {
              pass = 0;
          }
          this.localTime = curtTime;
          return pass;
      }
      static getDateNum(date) {
          let y = date.getFullYear();
          let m = date.getMonth() + 1;
          let d = date.getDate();
          return y * 10000 + m * 100 + d;
      }
      static getDateNumBySecond(ms) {
          let date = new Date(ms);
          let y = date.getFullYear();
          let m = date.getMonth() + 1;
          let d = date.getDate();
          return y * 10000 + m * 100 + d;
      }
      static getDateByDateNum(yearNum, offset = -3) {
          let y = Math.floor((yearNum / 10000));
          let m = Math.floor(((yearNum - y * 10000) / 100));
          let d = yearNum - y * 10000 - m * 100;
          let date = new Date(y, m - 1, d + offset);
          return date;
      }
      static get serverTime() {
          return this.data.lastServerTime;
      }
      static set serverTime(time) {
          this.data.lastServerTime = time;
          this.saveRecord();
      }
      static get onlineTime() {
          return this.data.lastOnlineTime;
      }
      static set onlineTime(time) {
          this.data.lastOnlineTime = time;
          this.saveRecord();
      }
      static isReady() {
          return this.bServerTimeReady;
      }
      static isChangeTime() {
          return this.bChangeTime;
      }
      static getCurrentWeek() {
          let date = new Date(this.serverTime);
          return date.getDay();
      }
      static getCurrentMonthDay() {
          let date = new Date(this.serverTime);
          return date.getDate();
      }
      static getYearWeek(offset = -3) {
          var dateNow = new Date(this.serverTime);
          if (offset != null) {
              dateNow = new Date(dateNow.getFullYear(), dateNow.getMonth(), dateNow.getDate() + offset);
          }
          return this.getYearWeekByDate(dateNow);
      }
      static getYearWeekTest(y, m, day, offset = -3) {
          let dateNow = new Date(y, m, day + offset);
          return this.getYearWeekByDate(dateNow);
      }
      static getYearWeekByDate(dateNow) {
          let dateFirst = new Date(dateNow.getFullYear(), 0, 1);
          let d = Math.round((dateNow.valueOf() - dateFirst.valueOf()) / 86400000);
          return Math.ceil((d + ((dateFirst.getDay() + 1) - 1)) / 7);
      }
      static getOnlineTime() {
          return this.timePassOnline;
      }
      static getBeijingTime(timeNow) {
          const d = new Date(timeNow);
          const localTime = d.getTime();
          const localOffset = d.getTimezoneOffset() * 60000;
          const utc = localTime + localOffset;
          const offset = 8;
          const beijing = utc + (3600000 * offset);
          let nd = new Date(beijing);
          return nd;
      }
      static curtTime() {
          return (this.serverTime / 1000) + this.serverOnlineTime;
      }
      static curtTimeMS() {
          return this.serverTime + this.serverOnlineTime * 1000;
      }
      static checkDateValid(timeNow, dateNumBegin, dateNumEnd) {
          let curtNum = this.getDateNum(this.getBeijingTime(timeNow));
          return curtNum >= dateNumBegin && curtNum <= dateNumEnd;
      }
  }
  mgrTime.RECORD_KEY = "game166_time_v1.0";
  mgrTime.dataDefault = {
      lastServerTime: 0,
      lastOnlineTime: 0,
  };
  mgrTime.bServerTimeReady = false;
  mgrTime.bChangeTime = false;
  mgrTime.timePass = 0;
  mgrTime.timePassOnline = 0;
  mgrTime.serverOnlineTime = 0;
  mgrTime.isFindTimeChange = false;
  mgrTime.passCalcOnline = 0;
  mgrTime.maxxCalcOnline = 10;
  mgrTime.localTime = 0;

  class mgrSecret extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
              [MSG.MGR_TIME_UPDATE]: this.onMgrTimeUpdate.bind(this),
          });
      }
      static onStart() {
          if (this.selectId == 0) {
              this.selectId = this.layerId;
          }
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          if (!this.recordInit) {
              this.onDifferentDay();
          }
          console.log("mgrSecret.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onDifferentDay() {
          let count = mgrGame.getItemCount(1013);
          if (count < db.game_cnf.secret_daily_count) {
              BaseFacade.mItem.setItem(1013, db.game_cnf.secret_daily_count);
          }
          BaseFacade.mItem.setItem(1015, 0);
          this.dailyReward = false;
          this.recordInit = true;
      }
      static onMgrTimeUpdate() {
          let week = mgrTime.getCurrentWeek() || 7;
          let dayNum = mgrTime.getDateNum(new Date(mgrTime.serverTime));
          let curtYearWeek = mgrTime.getYearWeek();
          let lastYearWeek = curtYearWeek;
          if (this.lastResetTime) {
              let lastDate = mgrTime.getDateByDateNum(this.lastResetTime);
              lastYearWeek = mgrTime.getYearWeekByDate(lastDate);
          }
          if (this.lastResetTime == 0 || (week >= db.game_cnf.secret_reset_week && lastYearWeek != curtYearWeek)) {
              this.lastResetTime = dayNum;
              this.onResetSecret();
          }
      }
      static set lastResetTime(t) {
          this.data.lastResetTime = t;
          this.saveRecord();
      }
      static get lastResetTime() {
          return this.data.lastResetTime;
      }
      static set layerId(t) {
          this.data.layerId = t;
          this.saveRecord();
      }
      static get layerId() {
          return this.data.layerId;
      }
      static set selectId(t) {
          this.data.selectId = t;
          this.saveRecord();
      }
      static get selectId() {
          if (this.data.selectId > this.layerId) {
              this.data.selectId = this.layerId;
          }
          return this.data.selectId;
      }
      static set recordInit(t) {
          this.data.recordInit = t;
          this.saveRecord();
      }
      static get recordInit() {
          return this.data.recordInit;
      }
      static onResetSecret() {
          console.log("重置大秘境");
          this.data.id2PassCount = {};
          this.layerId = 1;
          this.selectId = 1;
          this.saveRecord();
          mgrFinalWar.resetFinalWarLevel();
          mgrExchange.resetShopByType(2);
      }
      static addPassCount(id, add = 1) {
          this.setPassCount(id, this.getPassCount(id) + add);
      }
      static getPassCount(id) {
          return this.data.id2PassCount[id] || 0;
      }
      static setPassCount(id, vl) {
          this.data.id2PassCount[id] = vl;
          this.saveRecord();
      }
      static getMaxLv() {
          let listData = db.get_secret_level_map();
          if (listData && listData.length) {
              return listData[listData.length - 1].id;
          }
          else {
              return 0;
          }
      }
      static getWeekCfg() {
          let weeks = db.get_secret_word_week_map();
          let index = (mgrTime.getYearWeek(-3) - db.game_cnf.secret_yearweek_offset) % weeks.length;
          if (index < 0)
              index += weeks.length;
          let week = weeks[index];
          return week;
      }
      static get dailyReward() {
          return this.data.dailyReward;
      }
      static set dailyReward(v) {
          this.data.dailyReward = v;
          this.saveRecord();
      }
      static canGetDailyReward() {
          return !this.dailyReward;
      }
      static canBuyChallengeCount() {
          return mgrGame.getItemCount(1015) < db.game_cnf.secret_count_buy_ad;
      }
      static getBuyChallengeLeftCount() {
          let left = db.game_cnf.secret_count_buy_ad - mgrGame.getItemCount(1015);
          return Math.max(left, 0);
      }
  }
  mgrSecret.RECORD_KEY = "game166_secret_v1.0";
  mgrSecret.dataDefault = {
      lastResetTime: 0,
      id2PassCount: {},
      dailyReward: false,
      layerId: 1,
      selectId: 0,
      recordInit: false,
  };

  var STAGE_ATTR;
  (function (STAGE_ATTR) {
      STAGE_ATTR[STAGE_ATTR["DISARM"] = 0] = "DISARM";
      STAGE_ATTR[STAGE_ATTR["SILENCE"] = 1] = "SILENCE";
      STAGE_ATTR[STAGE_ATTR["BLOOD"] = 2] = "BLOOD";
      STAGE_ATTR[STAGE_ATTR["SHADOW"] = 3] = "SHADOW";
      STAGE_ATTR[STAGE_ATTR["AD_ARMOUR"] = 4] = "AD_ARMOUR";
      STAGE_ATTR[STAGE_ATTR["AP_ARMOUR"] = 5] = "AP_ARMOUR";
      STAGE_ATTR[STAGE_ATTR["HP_UP_ENEMY"] = 6] = "HP_UP_ENEMY";
      STAGE_ATTR[STAGE_ATTR["HP_UP_BOSS"] = 7] = "HP_UP_BOSS";
      STAGE_ATTR[STAGE_ATTR["HP_DEAD_RECOVER"] = 8] = "HP_DEAD_RECOVER";
      STAGE_ATTR[STAGE_ATTR["CRAZY"] = 9] = "CRAZY";
      STAGE_ATTR[STAGE_ATTR["CHARGE"] = 10] = "CHARGE";
      STAGE_ATTR[STAGE_ATTR["DARK"] = 11] = "DARK";
      STAGE_ATTR[STAGE_ATTR["CALM"] = 12] = "CALM";
      STAGE_ATTR[STAGE_ATTR["LEN_SECRET"] = 13] = "LEN_SECRET";
      STAGE_ATTR[STAGE_ATTR["DD_MP_REVOVER_NO"] = 13] = "DD_MP_REVOVER_NO";
      STAGE_ATTR[STAGE_ATTR["DD_AD_UP"] = 14] = "DD_AD_UP";
      STAGE_ATTR[STAGE_ATTR["DD_AP_UP"] = 15] = "DD_AP_UP";
      STAGE_ATTR[STAGE_ATTR["DD_MP_RECOVER_UP"] = 16] = "DD_MP_RECOVER_UP";
      STAGE_ATTR[STAGE_ATTR["DD_AP_CRIT_UP"] = 17] = "DD_AP_CRIT_UP";
      STAGE_ATTR[STAGE_ATTR["LEN_DD"] = 18] = "LEN_DD";
      STAGE_ATTR[STAGE_ATTR["AE_SHIELD"] = 18] = "AE_SHIELD";
      STAGE_ATTR[STAGE_ATTR["AE_NECKLACE"] = 19] = "AE_NECKLACE";
      STAGE_ATTR[STAGE_ATTR["AE_FLEE"] = 20] = "AE_FLEE";
      STAGE_ATTR[STAGE_ATTR["AE_HAMMER"] = 21] = "AE_HAMMER";
      STAGE_ATTR[STAGE_ATTR["LEN"] = 22] = "LEN";
  })(STAGE_ATTR || (STAGE_ATTR = {}));
  class StageAttr {
      static initAttr() {
          Level.resetAttrArray(this.stageAttr, STAGE_ATTR.LEN);
      }
      static resetAttr() {
          Level.clearAttrArray(this.stageAttr, STAGE_ATTR.LEN_DD);
      }
      static resetAttrAllEquip() {
          for (let i = STAGE_ATTR.LEN_DD; i < STAGE_ATTR.LEN; i++) {
              this.stageAttr[i] = 0;
          }
      }
      static getAttr(k) {
          return this.stageAttr[k] || 0;
      }
      static setAttr(k, v) {
          this.stageAttr[k] = v;
      }
      static addAttr(k, add) {
          this.setAttr(k, this.getAttr(k) + add);
      }
      static setAttrBySK(sk, v) {
          let k = STAGE_ATTR[sk];
          if (k != null) {
              this.setAttr(k, v);
          }
      }
      static addAttrBySK(sk, add) {
          let k = STAGE_ATTR[sk];
          if (k != null) {
              this.addAttr(k, add);
          }
      }
      static getAttrBySK(sk) {
          let k = STAGE_ATTR[sk];
          if (k != null) {
              return this.getAttr(k);
          }
          else {
              return 0;
          }
      }
      static noAttr(k) {
          return this.getAttr(k) <= 0;
      }
      static calcAttrBySecret(layerId) {
          this.resetAttr();
          let week = mgrSecret.getWeekCfg();
          for (let i = 0; i < week.word_ids.length; i++) {
              let id = week.word_ids[i];
              let lv = week.word_levels[i];
              if (id && lv && layerId >= lv) {
                  let word = db.get_secret_word_db(id);
                  if (word) {
                      this.addAttrBySK(id, word.value);
                      console.log("秘境词条:", word.title, this.getAttrBySK(id));
                  }
              }
          }
      }
      static calcAttrTower(attr) {
          if (attr) {
              let DARK = StageAttr.getAttr(STAGE_ATTR.DARK);
              if (DARK > 0) {
                  let range = attr[BASE_ATTR.RANGE];
                  attr[BASE_ATTR.RANGE] = range * (1 - DARK);
              }
          }
      }
      static calcAttrTowerDailyDamage(attr) {
          if (attr) {
              let DD_AD_UP = StageAttr.getAttr(STAGE_ATTR.DD_AD_UP);
              if (DD_AD_UP > 0) {
                  let AD = attr[BASE_ATTR.AD];
                  attr[BASE_ATTR.AD] = Math.floor(AD * DD_AD_UP);
              }
              let DD_AP_UP = StageAttr.getAttr(STAGE_ATTR.DD_AP_UP);
              if (DD_AP_UP > 0) {
                  let AP = attr[BASE_ATTR.AP];
                  attr[BASE_ATTR.AP] = Math.floor(AP * DD_AP_UP);
              }
              let DD_AP_CRIT_UP = StageAttr.getAttr(STAGE_ATTR.DD_AP_CRIT_UP);
              if (DD_AP_CRIT_UP > 0) {
                  let SK_AP_CRIT = attr[BASE_ATTR.SK_AP_CRIT];
                  attr[BASE_ATTR.SK_AP_CRIT] = SK_AP_CRIT * DD_AP_CRIT_UP;
              }
              let DD_MP_RECOVER_UP = StageAttr.getAttr(STAGE_ATTR.DD_MP_RECOVER_UP);
              if (DD_MP_RECOVER_UP > 0) {
                  let MP_RECOVER = attr[BASE_ATTR.MP_RECOVER];
                  attr[BASE_ATTR.MP_RECOVER] = MP_RECOVER * DD_MP_RECOVER_UP;
              }
          }
      }
  }
  StageAttr.stageAttr = [];

  class StageTool {
      static calcWeightIndex(weights) {
          let weightTotal = 0;
          for (let i = 0; i < weights.length; i++) {
              weightTotal += weights[i];
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let idx = 0;
          for (let i = 0; i < weights.length; i++) {
              vpt += weights[i];
              if (r < vpt) {
                  idx = i;
                  break;
              }
          }
          return idx;
      }
      static calcWeightItem(items) {
          let weightTotal = 0;
          for (let i = 0; i < items.length; i++) {
              weightTotal += items[i].weight || 0;
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let item = null;
          for (let i = 0; i < items.length; i++) {
              vpt += items[i].weight || 0;
              if (r < vpt) {
                  item = items[i];
                  break;
              }
          }
          return item;
      }
      static formatDailyDamage(value) {
          if (value >= 1000000) {
              return (value / 1000000).toFixed(2) + "M";
          }
          else {
              return value.toString();
          }
      }
      static formatDamage(value) {
          if (value >= 1000000) {
              return Math.floor(value / 1000000) + "M";
          }
          else if (value >= 100000) {
              return Math.floor(value / 1000) + "K";
          }
          else {
              return value.toString();
          }
      }
      static formatHP(value) {
          if (value >= 1000000) {
              return (value / 1000000).toFixed(2) + "M";
          }
          else if (value >= 10000) {
              return (value / 1000).toFixed(1) + "K";
          }
          else {
              return value.toString();
          }
      }
      static formatCoin(value) {
          if (value >= 100000000) {
              return (value / 1000000).toFixed(2) + "M";
          }
          else if (value >= 9999999) {
              return (value / 1000).toFixed(2) + "K";
          }
          else {
              return value.toString();
          }
      }
      static formatDiamond(value) {
          if (value >= 1000000) {
              return (value / 1000000).toFixed(2) + "M";
          }
          else if (value >= 999999) {
              return (value / 1000).toFixed(2) + "K";
          }
          else {
              return value.toString();
          }
      }
      static formatNumUI(value) {
          if (value >= 1000000) {
              return (value / 1000000).toFixed(0) + "M";
          }
          else if (value >= 999999) {
              return (value / 1000).toFixed(0) + "K";
          }
          else {
              return value.toString();
          }
      }
      static addLongClickEvent(button, caller, funcBegin, funcUpdate, funcEnd, args) {
          let handlerBegin = Laya.Handler.create(caller, funcBegin, args, false);
          let handlerUpdate = Laya.Handler.create(caller, funcUpdate, args, false);
          let handlerEnd = Laya.Handler.create(caller, funcEnd, args, false);
          let data = {
              begin: handlerBegin,
              update: handlerUpdate,
              end: handlerEnd,
              timepass: 0,
              timewait: 0,
              timeminn: 0,
          };
          button.on(Laya.Event.MOUSE_DOWN, this, this.onLongClickDown, [data]);
          button.on(Laya.Event.MOUSE_UP, this, this.onLongClickUp, [data]);
          button.on(Laya.Event.MOUSE_OUT, this, this.onLongClickUp, [data]);
      }
      static onLongClickDown(data) {
          if (data.begin)
              data.begin.run();
          data.timepass = 0;
          data.timewait = 0.4,
              data.timeminn = 1 / 60,
              Laya.timer.frameLoop(1, this, this.onLongClickUpdate, [data]);
      }
      static onLongClickUp(data) {
          if (data.end)
              data.end.run();
          Laya.timer.clear(this, this.onLongClickUpdate);
      }
      static onLongClickUpdate(data) {
          let dt = GameConst.FrameDeltaTime;
          data.timepass += dt;
          if (data.timepass >= data.timewait) {
              if (data.timewait <= data.timeminn) {
                  data.timewait = data.timeminn;
              }
              else {
                  data.timewait -= 0.05;
              }
              if (data.update)
                  data.update.run();
              data.timepass = 0;
          }
      }
      static remLongClickEvent(button, caller) {
          if (!button || !button.displayObject)
              return;
          if (button.displayObject.destroyed)
              return;
          Laya.timer.clear(this, this.onLongClickUpdate);
          button.off(Laya.Event.MOUSE_DOWN, this, this.onLongClickDown);
          button.off(Laya.Event.MOUSE_UP, this, this.onLongClickUp);
          button.off(Laya.Event.MOUSE_OUT, this, this.onLongClickUp);
      }
      static calcProb(prob) {
          return Utils.random(0, 99) < prob;
      }
      static updateRedPoint4Button(button, value) {
          let red = button.getChild("red");
          if (red) {
              red.visible = value;
          }
      }
      static beginAutoOpenCD(curtTime) {
          this.auto_open_ad_last_time = curtTime + db.cop_db.auto_open_ad_interval;
      }
      static checkAutoOpenCD(curtTime) {
          if (this.auto_open_ad_last_time == 0) {
              this.auto_open_ad_last_time = curtTime + db.cop_db.auto_open_ad_start;
          }
          if (curtTime < this.auto_open_ad_last_time) {
              return true;
          }
          return false;
      }
      static convertIds2ItemInfos(ids) {
          let itemInfos = [];
          for (let i = 0; i < ids.length; i += 2) {
              let itemId = ids[i];
              let itemCt = ids[i + 1];
              if (itemId && itemCt) {
                  itemInfos.push({ itemId: itemId, count: itemCt });
              }
          }
          return itemInfos;
      }
  }
  StageTool.auto_open_ad_last_time = 0;

  class mgrAllEquip extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrAllEquip.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static haveRedPoint() {
          return false;
      }
      static onUpdatePerSecond() {
          this.totalTime += 1;
      }
      static isAttrValid(attrId) {
          let attrVl = StageAttr.getAttr(attrId);
          if (attrVl <= 0)
              return false;
          switch (attrId) {
              case STAGE_ATTR.AE_SHIELD:
              case STAGE_ATTR.AE_HAMMER:
                  return !this.checkCDing(attrId);
          }
          return true;
      }
      static beginCDing(attrId, cd) {
          this.dataCDing[attrId] = this.totalTime + cd;
      }
      static checkCDing(attrId) {
          return this.getCDingTime(attrId) > this.totalTime;
      }
      static getCDingTime(attrId) {
          return this.dataCDing[attrId] || this.totalTime;
      }
      static getBuffId(attrId) {
          let key = STAGE_ATTR[attrId];
          if (key) {
              let data = db.get_all_tower_equip(key);
              if (data) {
                  return data.buff_id;
              }
          }
          return "";
      }
      static isEquipUnlock(k) {
          return this.getEquipLv(k) > 0;
      }
      static getEquipLv(k) {
          return this.data.id2Lv[k] || 0;
      }
      static setEquipLv(k, lv) {
          this.data.id2Lv[k] = lv;
          this.saveRecord();
      }
      static addEquipLv(k, add = 1) {
          this.setEquipLv(k, this.getEquipLv(k) + add);
      }
      static getEquipValue(k, index = 0) {
          let equipDb = db.get_all_tower_equip(k);
          let dataArr = [];
          if (equipDb) {
              let equipLv = this.getEquipLv(k) - 1;
              dataArr = equipDb["v" + equipLv] || [];
          }
          return dataArr[index] || 0;
      }
      static getEquipValueUI(k, index = 0) {
          let equipDb = db.get_all_tower_equip(k);
          let dataArr = [];
          let factor = 1;
          let digit = 0;
          if (equipDb) {
              let equipLv = this.getEquipLv(k) - 1;
              dataArr = equipDb["v" + equipLv] || [];
              factor = equipDb.u_factor[index] || 1;
              digit = equipDb.u_digit[index] || 0;
          }
          let v = factor * (dataArr[index] || 0);
          return v.toFixed(digit);
      }
      static updateAttr() {
          StageAttr.resetAttrAllEquip();
          let idActive = this.idActive;
          let equipDb = db.get_all_tower_equip_map()[idActive];
          if (equipDb) {
              let v = this.getEquipValue(equipDb.id, 0) * equipDb.v_factor[0];
              if (v) {
                  StageAttr.setAttrBySK(equipDb.id, v);
              }
          }
      }
      static get idActive() {
          return this.data.idActive || "";
      }
      static set idActive(k) {
          this.data.idActive = k;
          this.saveRecord();
      }
      static getEquipAttr(k) {
          return this.data.id2Attr[k] || [];
      }
      static setEquipAttr(k, v) {
          this.data.id2Attr[k] = v;
          this.saveRecord();
      }
      static getEquipAttrWord(k, index) {
          return this.getEquipAttr(k)[index];
      }
      static wordActive(id, attr) {
          let data = this.getEquipAttr(id);
          let index = attr.id - 1;
          let word = data[index];
          if (word)
              return false;
          if (mgrGame.subItem(attr.ulock_item_id, attr.ulock_item_num, 69)) {
              word = this.buildWord(attr);
              data[index] = word;
              this.setEquipAttr(id, data);
              Global.sendMsg(MSG.AE_EQUIP_WORD_ACTIVE);
              return true;
          }
          return false;
      }
      static buildWord(attr) {
          let wordList = db.get_all_equip_word_map();
          let word = StageTool.calcWeightItem(wordList);
          if (word) {
              let qualityIdx = StageTool.calcWeightIndex(attr.word_quality);
              return { id: word.id, eq: qualityIdx, lk: false };
          }
          return null;
      }
      static unlockEquip(aequipDb) {
          if (mgrGame.subItems(aequipDb.unlock_items, 69)) {
              this.addEquipLv(aequipDb.id);
              Global.sendMsg(MSG.AE_EQUIP_UNLOCK);
              return true;
          }
          return false;
      }
      static calcProb(prob) {
          return Utils.random(0, 99) < prob;
      }
      static getLvupProb(id, lvupDbCurt) {
          if (lvupDbCurt) {
              return lvupDbCurt.prob_lvup + lvupDbCurt.prob_add * this.getFailCount(id);
          }
          return 0;
      }
      static lvupEquip(aequipDb) {
          let level = this.getEquipLv(aequipDb.id);
          let lvupDbCurt = db.get_all_equip_level_map()[level - 1];
          let lvupDbNext = db.get_all_equip_level_map()[level];
          if (lvupDbCurt && lvupDbNext) {
              if (mgrGame.subItem(lvupDbCurt.item_id, lvupDbCurt.item_num, 69)) {
                  let prob = this.getLvupProb(aequipDb.id, lvupDbCurt);
                  if (this.calcProb(prob)) {
                      this.addEquipLv(aequipDb.id);
                      this.setFailCount(aequipDb.id, 0);
                      Global.sendMsg(MSG.AE_EQUIP_LVUP_SUCC);
                  }
                  else {
                      this.addFailCount(aequipDb.id);
                      Global.sendMsg(MSG.AE_EQUIP_LVUP_FAIL);
                  }
                  return true;
              }
          }
          return false;
      }
      static getFailCount(k) {
          return this.data.id2Fail[k] || 0;
      }
      static setFailCount(k, lv) {
          this.data.id2Fail[k] = lv;
          this.saveRecord();
      }
      static addFailCount(k) {
          this.setFailCount(k, this.getFailCount(k) + 1);
      }
      static getWordLockCount(k) {
          let lockCount = 0;
          let attrDb = db.get_all_equip_attr_map();
          for (let i = 0; i < attrDb.length; i++) {
              let word = this.getEquipAttrWord(k, i);
              if (word && word.lk) {
                  lockCount++;
              }
          }
          return lockCount;
      }
      static getWordUnlockCount(k) {
          let lockCount = 0;
          let attrDb = db.get_all_equip_attr_map();
          for (let i = 0; i < attrDb.length; i++) {
              let word = this.getEquipAttrWord(k, i);
              if (word && !word.lk) {
                  lockCount++;
              }
          }
          return lockCount;
      }
      static washEquip(aequipDb) {
          let count = this.getWordUnlockCount(aequipDb.id);
          if (count <= 0)
              return;
          let washDb = db.get_all_equip_wash(this.getWordLockCount(aequipDb.id));
          if (washDb) {
              if (mgrGame.subItem(washDb.item_id, washDb.item_num, 69)) {
                  let attrDb = db.get_all_equip_attr_map();
                  for (let i = 0; i < attrDb.length; i++) {
                      let attr = attrDb[i];
                      let word = this.getEquipAttrWord(aequipDb.id, i);
                      if (word && !word.lk) {
                          let newWord = this.buildWord(attr);
                          word.id = newWord.id;
                          word.eq = newWord.eq;
                          this.saveRecord();
                      }
                  }
                  Global.sendMsg(MSG.AE_EQUIP_WASH_SUCC);
              }
          }
      }
      static activeEquip(aequipDb) {
          if (aequipDb) {
              this.idActive = aequipDb.id;
              this.updateAttr();
              Global.sendMsg(MSG.AE_EQUIP_ACTIVE);
              Global.sendMsg(MSG.TOWER_ATTR_UPDATE_ALL);
          }
      }
      static calcAttrAdd(attr) {
          let idActive = this.idActive;
          let equipDb = db.get_all_tower_equip_map()[idActive];
          if (equipDb) {
              let word_add = {};
              let word_dbb = {};
              let attrDb = db.get_all_equip_attr_map();
              for (let i = 0; i < attrDb.length; i++) {
                  let word = this.getEquipAttrWord(idActive, i);
                  if (word) {
                      let wordKey = word.id - 1;
                      let wordDb = db.get_all_equip_word(wordKey);
                      if (wordDb) {
                          let attr_v = wordDb[word.eq] || 0;
                          if (attr_v) {
                              let old_v = word_add[wordKey] || 0;
                              word_add[wordKey] = old_v + attr_v;
                              word_dbb[wordKey] = wordDb;
                          }
                      }
                  }
              }
              for (let wordKey in word_add) {
                  let wordDb = word_dbb[wordKey];
                  if (wordDb) {
                      let attr_k = BASE_ATTR[wordDb.attr];
                      let attr_v = word_add[wordKey] * wordDb.v_factor;
                      if (attr_k != null && attr_v) {
                          if (wordDb.percent) {
                              let old = attr[attr_k];
                              attr[attr_k] = old + old * attr_v;
                          }
                          else {
                              let old = attr[attr_k];
                              attr[attr_k] = old + attr_v;
                          }
                      }
                  }
              }
          }
      }
  }
  mgrAllEquip.RECORD_KEY = "game166_allequip_v1.0";
  mgrAllEquip.dataDefault = {
      id2Lv: {},
      idActive: "",
      id2Attr: {},
      id2Fail: {},
  };
  mgrAllEquip.totalTime = 0;
  mgrAllEquip.dataCDing = {};

  class mgrDailyDamage extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrDailyDamage.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onDifferentDay() {
          this.reward = false;
          this.resetDamageToday();
          this.resetAdBuff();
      }
      static getTowerLv(id) {
          let towerLv = mgrTower.getTowerLv(id);
          return towerLv;
      }
      static getTowerPointAdd(id) {
          let data = this.data.towerId2Point[id];
          if (data == null) {
              data = { base: 0, power: 0, mana: 0, point: 0 };
              let pointAdd = mgrTower.getTowerPointAdd(id);
              if (pointAdd) {
                  data.base = pointAdd.base;
                  data.power = pointAdd.power;
                  data.mana = pointAdd.mana;
                  data.point = pointAdd.point;
              }
              this.setTowerPointAdd(id, data);
          }
          return data;
      }
      static setTowerPointAdd(id, data) {
          this.data.towerId2Point[id] = data;
          this.saveRecord();
      }
      static resetTowerPoint(id) {
          let data = this.getTowerPointAdd(id);
          data.point = 0;
          data.base = 0;
          data.power = 0;
          data.mana = 0;
          this.setTowerPointAdd(id, data);
      }
      static calcTowerPointLeft(id) {
          let towerLv = this.getTowerLv(id);
          if (towerLv <= 0)
              return 0;
          let totalPoint = towerLv * db.game_cnf.point_add_per_lv;
          let data = this.getTowerPointAdd(id);
          let leftPoint = totalPoint - data.point;
          if (leftPoint < 0)
              leftPoint = 0;
          return leftPoint;
      }
      static calcTowerPointLeftHalf(id) {
          return Math.floor(this.calcTowerPointLeft(id) / 2);
      }
      static addTowerPoint(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          data.point += add;
          this.setTowerPointAdd(id, data);
      }
      static assignTowerPointBase(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.base += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static assignTowerPointPower(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.power += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static assignTowerPointMana(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.mana += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static isAnyTowerHaveLeftPoint() {
          let isHave = false;
          let towerPos = db.get_tower_pos_map()[mgrTower.defaultPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              let id = mgrTower.getSlotTower(pos.id - 1);
              if (id) {
                  let leftPoint = this.calcTowerPointLeft(id);
                  if (leftPoint > 0) {
                      isHave = true;
                      break;
                  }
              }
          }
          return isHave;
      }
      static getConfigById(id) {
          return db.get_daily_damage_db(id - 1);
      }
      static setConfig(id) {
          this.config = this.getConfigById(id);
      }
      static getConfig() {
          let md = mgrTime.getCurrentMonthDay();
          let list = db.get_daily_damage_db_map();
          return this.config || list[md % list.length];
      }
      static markDamage(damage) {
          this.damageLast = damage;
          let config = this.getConfig();
          if (config) {
              let id = config.id;
              let damageToday = this.getDamageToday(id);
              let damageHistory = this.getDamageHistory(id);
              if (damage > damageToday) {
                  this.setDamageToday(id, damage);
              }
              if (damage > damageHistory) {
                  this.setDamageHistroy(id, damage);
              }
          }
      }
      static resetDamageToday() {
          this.data.id2DamageToday = {};
          this.saveRecord();
      }
      static getDamageToday(id) {
          return this.data.id2DamageToday[id] || 0;
      }
      static setDamageToday(id, damage) {
          this.data.id2DamageToday[id] = damage;
          this.saveRecord();
      }
      static getDamageHistory(id) {
          return this.data.id2DamageHistory[id] || 0;
      }
      static setDamageHistroy(id, damage) {
          this.data.id2DamageHistory[id] = damage;
          this.saveRecord();
      }
      static calcCurrentReward(id) {
          let damage = this.getDamageToday(id);
          let rewardList = db.get_daily_damage_reward_map()[id - 1];
          if (rewardList) {
              for (let i = 0; i < rewardList.length; i++) {
                  let rewardCurt = rewardList[i];
                  let rewardNext = rewardList[i + 1];
                  let damageCurt = 0;
                  let damageNext = Number.MAX_VALUE;
                  if (rewardNext) {
                      damageNext = rewardNext.damage;
                  }
                  if (rewardCurt) {
                      damageCurt = rewardCurt.damage;
                      if (damage >= damageCurt && damage < damageNext) {
                          return { curt: rewardCurt, next: rewardNext };
                      }
                  }
              }
          }
          return {};
      }
      static get reward() {
          return this.data.reward;
      }
      static set reward(value) {
          this.data.reward = value;
      }
      static tryGetReward() {
          if (this.reward)
              return false;
          let config = this.getConfig();
          let reward = this.calcCurrentReward(config.id);
          if (reward.curt) {
              this.reward = true;
              let dropData = [];
              let reward_ids = reward.curt.rewards;
              for (let i = 0; i < reward_ids.length; i += 2) {
                  let itemId = reward_ids[i];
                  let count = reward_ids[i + 1];
                  if (itemId && count) {
                      mgrGame.addItem(itemId, count, 68, false, dropData);
                  }
              }
              Level.showItemGet(dropData);
              return true;
          }
          return false;
      }
      static isAdBuffValid(id) {
          return this.data.id2AdBuff[id];
      }
      static markAdBuffValid(id) {
          this.data.id2AdBuff[id] = true;
          this.saveRecord();
      }
      static resetAdBuff() {
          this.data.id2AdBuff = {};
          this.saveRecord();
      }
      static activeAdBuff() {
          let listData = db.get_daily_damage_ad_map();
          for (let data of listData) {
              if (this.isAdBuffValid(data.id)) {
                  StageAttr.setAttrBySK(data.key, data.value);
              }
          }
      }
      static activeBuff() {
          StageAttr.resetAttr();
          StageAttr.setAttr(STAGE_ATTR.DD_MP_REVOVER_NO, 1);
          this.activeAdBuff();
      }
      static isAllActive() {
          let isAllActive = true;
          let listData = db.get_daily_damage_ad_map();
          for (let data of listData) {
              if (!this.isAdBuffValid(data.id)) {
                  isAllActive = false;
                  break;
              }
          }
          return isAllActive;
      }
  }
  mgrDailyDamage.RECORD_KEY = "game166_dailydamage_v1.0";
  mgrDailyDamage.dataDefault = {
      towerId2Point: {},
      id2DamageToday: {},
      id2DamageHistory: {},
      id2AdBuff: {},
      reward: false,
  };
  mgrDailyDamage.damageLast = 0;

  class mgrTalent extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrTalent.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static getTalentLv(id) {
          return this.data.talentId2Lv[id] || 0;
      }
      static setTalentLv(id, lv) {
          this.data.talentId2Lv[id] = lv;
          this.saveRecord();
      }
      static addTalentLv(id, lv) {
          this.setTalentLv(id, this.getTalentLv(id) + lv);
          let skillDb = db.get_talent_db(id);
          if (skillDb) {
              console.log("打点天赋技能", skillDb.name, lv);
              mgrStatis.statisCommonEvent(skillDb.statis_point, lv);
          }
          Global.sendMsg(MSG.TOWER_ATTR_UPDATE_MAIN);
      }
      static getTalentLvMax(id) {
          let talentDb = db.get_talent_db(id);
          if (talentDb) {
              return talentDb.lv_max;
          }
          else {
              return 0;
          }
      }
      static isTalentLvMax(id) {
          let lelevMax = this.getTalentLvMax(id);
          let talentLv = this.getTalentLv(id);
          if (talentLv >= lelevMax) {
              return true;
          }
          else {
              return false;
          }
      }
      static isAllTalentMax() {
          let isAllTalentMax = true;
          let dataMap = db.get_talent_db_map();
          for (let k in dataMap) {
              let talentDb = db.get_talent_db(k);
              if (talentDb.unlock && !this.isTalentLvMax(k)) {
                  isAllTalentMax = false;
                  break;
              }
          }
          return isAllTalentMax;
      }
      static randomLearn() {
          let listData = [];
          let dataMap = db.get_talent_db_map();
          for (let k in dataMap) {
              let talentDb = db.get_talent_db(k);
              if (talentDb.unlock && !talentDb.final && !this.isTalentLvMax(k)) {
                  listData.push(talentDb);
              }
          }
          if (listData.length == 0) {
              for (let k in dataMap) {
                  let talentDb = db.get_talent_db(k);
                  if (talentDb.final && !this.isTalentLvMax(k)) {
                      listData.push(talentDb);
                  }
              }
          }
          let talentDb = StageTool.calcWeightItem(listData);
          if (talentDb) {
              this.addTalentLv(talentDb.id, 1);
          }
          this.doTaskEvent();
          Global.sendMsg(MSG.REFRESH_RED_POINT);
          return talentDb;
      }
      static doTaskEvent() {
          mgrTask.setEvent(db.TASK_EVENT_ID.TALENT_LEARN, this.calcTotalLvupCount());
      }
      static calcTotalLvupCount() {
          let count = 0;
          for (let id in this.data.talentId2Lv) {
              let lv = this.data.talentId2Lv[id] || 0;
              count += lv;
          }
          return count;
      }
      static getTalentValueById(id) {
          return this.getTalentValue(db.get_talent_db(id));
      }
      static getTalentValue(talentDb, def = 0) {
          let lv = this.getTalentLv(talentDb.id) || def;
          if (lv == 0)
              return 0;
          if (!talentDb.final) {
              return talentDb["v" + lv];
          }
          else {
              return talentDb.v * lv;
          }
      }
      static getTalentDesc(talentDb) {
          let value = this.getTalentValue(talentDb, 1) * talentDb.u_factor;
          if (value < 1) {
              return Utils.sprintf(talentDb.desc, value.toFixed(1));
          }
          else {
              return Utils.sprintf(talentDb.desc, Math.floor(value));
          }
      }
      static calcAttrAdd(attr) {
          let dataMap = db.get_talent_db_map();
          for (let k in dataMap) {
              let talentDb = dataMap[k];
              let attr_k = BASE_ATTR[talentDb.attr];
              let attr_v = this.getTalentValue(talentDb) * talentDb.v_factor;
              if (attr_k != null && attr_v) {
                  if (talentDb.percent) {
                      let old = attr[attr_k];
                      attr[attr_k] = old + old * attr_v;
                  }
                  else {
                      let old = attr[attr_k];
                      attr[attr_k] = old + attr_v;
                  }
              }
          }
      }
      static haveRedPoint() {
          return mgrGame.isUnlockByGetWayId("9") && !this.isAllTalentMax() && mgrGame.getItemCount(1007) >= db.game_cnf.talent_learn_cost;
      }
  }
  mgrTalent.RECORD_KEY = "game166_talent_v1.0";
  mgrTalent.dataDefault = {
      talentId2Lv: {},
  };

  var SORT_SCORE$1;
  (function (SORT_SCORE) {
      SORT_SCORE[SORT_SCORE["SCORTE_5"] = 1] = "SCORTE_5";
      SORT_SCORE[SORT_SCORE["SCORTE_4"] = 1000] = "SCORTE_4";
      SORT_SCORE[SORT_SCORE["SCORTE_3"] = 10000] = "SCORTE_3";
      SORT_SCORE[SORT_SCORE["SCORTE_2"] = 100000] = "SCORTE_2";
      SORT_SCORE[SORT_SCORE["SCORTE_1"] = 1000000] = "SCORTE_1";
  })(SORT_SCORE$1 || (SORT_SCORE$1 = {}));
  class mgrTower extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrTower.loadRecord", this.data);
      }
      static resetRecord() {
          this.data = {};
          this.checkRecord(this.data, this.dataDefault);
          this.saveRecord();
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static isMainHeroUnlock(id) {
          return this.data.mainHeroId2unlock[id];
      }
      static markMainHeroUnlock(id) {
          this.data.mainHeroId2unlock[id] = true;
          this.saveRecord();
      }
      static isTowerShow(id) {
          return this.data.towerId2show[id];
      }
      static markTowerShow(id) {
          this.data.towerId2show[id] = true;
          this.saveRecord();
      }
      static tryUnlockMainHero(id, force = false) {
          let heroDb = db.get_main_hero(id - 1);
          if ((heroDb && !this.isMainHeroUnlock(id))) {
              if (force || mgrGame.subItem(1000, heroDb.cost, 44)) {
                  this.markMainHeroUnlock(id);
                  Global.sendMsg(MSG.MAIN_HERO_UNLOCK, id);
                  return true;
              }
          }
          return false;
      }
      static getMainHeroId() {
          return this.data.mainHeroId;
      }
      static changeMainHero(heroId) {
          if (heroId == this.data.mainHeroId)
              return;
          this.data.mainHeroId = heroId;
          this.saveRecord();
          Global.sendMsg(MSG.TOWER_MAIN_SKILL_CHANGE);
      }
      static getMainSkillId() {
          let heroDb = db.get_main_hero(this.data.mainHeroId - 1);
          if (heroDb)
              return heroDb.skill_id;
      }
      static getMainSuperId() {
          let heroDb = db.get_main_hero(this.data.mainHeroId - 1);
          if (heroDb)
              return heroDb.super_id;
      }
      static isTowerSlotUnlcok(index) {
          let slotDb = db.get_tower_pos(this.defaultPosGid, index);
          return slotDb && (slotDb.unlock || this.data.slotId2unlock[slotDb.uid]);
      }
      static isTowerSlotCanMove(index) {
          let slotDb = db.get_tower_pos(this.defaultPosGid, index);
          return slotDb && !slotDb.no_move && (slotDb.unlock || this.data.slotId2unlock[slotDb.uid]);
      }
      static markTowerSlotUnlcok(index) {
          let slotDb = db.get_tower_pos(this.defaultPosGid, index);
          if (slotDb) {
              this.data.slotId2unlock[slotDb.uid] = true;
              this.saveRecord();
          }
      }
      static getTowerLv(id) {
          return this.data.towerId2lv[id] || 0;
      }
      static setTowerLv(id, lv) {
          this.data.towerId2lv[id] = lv;
          this.saveRecord();
      }
      static setAllTowerLv(lv) {
          let towerMap = db.get_tower_db_map();
          for (let towerId in towerMap) {
              this.data.towerId2lv[towerId] = lv;
          }
          this.saveRecord();
      }
      static getTowerAmount(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb)
              return mgrGame.getItemCount(towerDb.item_id);
          else
              return 0;
      }
      static getTowerSkillId(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              if (towerDb.main)
                  return this.getMainSkillId();
              else
                  return towerDb.skill_id;
          }
          return "";
      }
      static getTowerSuperId(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              if (towerDb.main)
                  return this.getMainSuperId();
              else
                  return towerDb.super_skill_id;
          }
          return "";
      }
      static canLvupTowerLevel(id) {
          let limit = this.getTowerLvLimit(id);
          if (limit == 0 || this.getTowerLv(id) >= limit) {
              return false;
          }
          let cost = this.getTowerLvupCost(id);
          return mgrGame.getItemCount(1001) >= cost;
      }
      static lvupTowerLevel(id) {
          let limit = this.getTowerLvLimit(id);
          if (limit && this.getTowerLv(id) >= limit) {
              mgrTip.showMsgTip("等级已达到上限，请前往升阶");
              return false;
          }
          let cost = this.getTowerLvupCost(id);
          if (mgrGame.subItem(1001, cost, 41)) {
              this.addTowerLv(id, 1);
              mgrSound.playSound("lvup_tower_suc");
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          else {
              return false;
          }
      }
      static addTowerLv(id, add = 1) {
          this.setTowerLv(id, this.getTowerLv(id) + add);
          Global.sendMsg(MSG.TOWER_LVUP_LEVEL, id);
          return true;
      }
      static getTowerLvMax() {
          let levelMax = 0;
          let towerId2lv = this.data.towerId2lv;
          for (let id in towerId2lv) {
              let lv = towerId2lv[id];
              if (lv > levelMax) {
                  levelMax = lv;
              }
          }
          return levelMax;
      }
      static getTowerLvMaxCost(limitLv = 1000) {
          return Formula.towerLvupCost(Math.min(limitLv, mgrTower.getTowerLvMax()));
      }
      static getTowerLvupCost(id) {
          return Formula.towerLvupCost(this.getTowerLv(id));
      }
      static isTowerStarFull(id) {
          return this.getTowerStar(id) >= 5;
      }
      static getTowerStar(id) {
          return this.data.towerId2Star[id] || 0;
      }
      static setTowerStar(id, star) {
          this.data.towerId2Star[id] = star;
          this.saveRecord();
      }
      static getTowerQuality(id) {
          return this.getTowerQualityByDB(db.get_tower_db(id));
      }
      static getTowerQualityByDB(towerDb) {
          let quality = 0;
          if (towerDb) {
              quality = this.data.towerId2Quality[towerDb.id] || towerDb.default_quality;
          }
          let qualitMax = this.getTowerQualityMax();
          if (quality > qualitMax) {
              quality = qualitMax;
          }
          return quality;
      }
      static setTowerQuality(id, quality) {
          this.data.towerId2Quality[id] = quality;
          this.saveRecord();
      }
      static getTowerStarName(star) {
          let starDb = db.get_tower_star(star);
          if (starDb)
              return starDb.name;
          else
              return "";
      }
      static calcNeedPiece(id) {
          let curtStarDb = db.get_tower_star(this.getTowerStar(id));
          if (!curtStarDb) {
              return 0;
          }
          let nextStarDb = db.get_tower_star_map()[this.getTowerStar(id) + 1];
          if (!nextStarDb) {
              return 0;
          }
          let needExp = curtStarDb.star_exp;
          let curtExp = this.getTowerStarExp(id);
          let needPiece = needExp - curtExp;
          if (needPiece < 0) {
              needPiece = 0;
          }
          return needPiece;
      }
      static canLvupTowerStar(id) {
          let curtStarDb = db.get_tower_star(this.getTowerStar(id));
          if (!curtStarDb) {
              return false;
          }
          let nextStarDb = db.get_tower_star_map()[this.getTowerStar(id) + 1];
          if (!nextStarDb) {
              return false;
          }
          let needExp = curtStarDb.star_exp;
          let curtExp = this.getTowerStarExp(id);
          return curtExp >= needExp;
      }
      static tryLvupTowerStar(id, showTip = false) {
          let curtStarDb = db.get_tower_star(this.getTowerStar(id));
          if (!curtStarDb) {
              return false;
          }
          let nextStarDb = db.get_tower_star(this.getTowerStar(id) + 1);
          if (!nextStarDb) {
              return false;
          }
          let isSuccess = false;
          let needExp = curtStarDb.star_exp;
          let curtExp = this.getTowerStarExp(id);
          let needPiece = this.calcNeedPiece(id);
          if (needPiece) {
              if (mgrGame.getItemCount(1006) < needPiece) {
                  mgrTip.showMsgTip("箭塔碎片不足（通过祈愿召唤到重复英雄获取）!");
                  return false;
              }
              isSuccess = this.subTowerStarExp(id, curtExp) && mgrGame.subItem(1006, needPiece, 42);
          }
          else {
              isSuccess = this.subTowerStarExp(id, needExp);
          }
          return isSuccess;
      }
      static lvupTowerStar(id, force = false) {
          let towerDb = db.get_tower_db(id);
          if (towerDb && towerDb.main) {
              return false;
          }
          let isSuccess = force;
          if (!isSuccess) {
              isSuccess = this.tryLvupTowerStar(id, true);
          }
          if (isSuccess) {
              this.addTowerStar(id, 1);
              GameStatistics.statisCommonEvent(towerDb.star_statis_point, this.getTowerStar(towerDb.id));
              mgrSound.playSound("lvup_tower_suc");
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          else {
              return false;
          }
      }
      static getTowerStarExp(id) {
          return this.data.towerId2StarExp[id] || 0;
      }
      static setTowerStarExp(id, exp) {
          this.data.towerId2StarExp[id] = exp;
          this.saveRecord();
      }
      static subTowerStarExp(id, exp) {
          let leftExp = this.getTowerStarExp(id) - exp;
          if (leftExp >= 0) {
              this.setTowerStarExp(id, leftExp);
              return true;
          }
          else {
              return false;
          }
      }
      static addTowerStarExp(id, exp) {
          this.setTowerStarExp(id, this.getTowerStarExp(id) + exp);
      }
      static getTowerStarExpNeed(id) {
          let starDb = db.get_tower_star(this.getTowerStar(id));
          if (starDb) {
              return starDb.star_exp;
          }
          else {
              return 1;
          }
      }
      static getTowerStarupCost(id) {
          return Formula.towerLvupCost(this.getTowerLv(id));
      }
      static addTowerStar(id, add = 1) {
          this.setTowerStar(id, this.getTowerStar(id) + add);
          Global.sendMsg(MSG.TOWER_LVUP_STAR, id);
          return true;
      }
      static addTowerExternLvLimit(id, add = 1) {
          this.setTowerExternLvLimit(id, this.getTowerExternLvLimit(id) + add);
      }
      static getTowerExternLvLimit(id) {
          return this.data.towerId2LvLimit[id] || 0;
      }
      static setTowerExternLvLimit(id, lv) {
          this.data.towerId2LvLimit[id] = lv;
          this.saveRecord();
      }
      static getTowerLvLimit(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb && towerDb.main) {
              return 0;
          }
          let star = this.getTowerStar(id);
          let startDb = db.get_tower_star(star);
          if (startDb) {
              return (startDb.level_limit || 0) + this.getTowerExternLvLimit(id);
          }
          else {
              return 0;
          }
      }
      static tryBreakTowerLvLimit(id) {
          let itemIds = db.game_cnf.tower_lv_break_items;
          for (let i = 0; i < itemIds.length; i += 2) {
              let itemId = itemIds[i];
              let itemCn = itemIds[i + 1];
              if (itemId && itemCn) {
                  if (!mgrGame.checkItem(itemId, itemCn)) {
                      return false;
                  }
              }
          }
          for (let i = 0; i < itemIds.length; i += 2) {
              let itemId = itemIds[i];
              let itemCn = itemIds[i + 1];
              if (itemId && itemCn) {
                  mgrGame.subItem(itemId, itemCn, 63);
              }
          }
          this.addTowerExternLvLimit(id, db.game_cnf.tower_lv_break_add);
          Global.sendMsg(MSG.TOWER_LV_LIMIT_BREAK);
          return true;
      }
      static getTowerAttackNum(id, star = 0) {
          let towerDb = db.get_tower_db(id);
          if (towerDb && towerDb.main) {
              return 1;
          }
          let startDb = db.get_tower_star(star || mgrTower.getTowerStar(id));
          if (startDb) {
              return startDb.attack_num;
          }
          else {
              return 1;
          }
      }
      static setSlotTower(index, id) {
          let pos = db.get_tower_pos(this.defaultPosGid, index);
          if (pos) {
              this.data.slotId2towerId[pos.uid] = id;
              this.saveRecord();
          }
      }
      static getSlotTower(index) {
          let pos = db.get_tower_pos(this.defaultPosGid, index);
          if (!pos)
              return "";
          if (pos.unlock && pos.default_tid) {
              return pos.default_tid;
          }
          else {
              return this.data.slotId2towerId[pos.uid];
          }
      }
      static isTowerEquip(id) {
          let posArr = db.get_tower_pos_map()[this.defaultPosGid];
          if (posArr) {
              for (let pos of posArr) {
                  if (!pos.default_tid) {
                      let towerId = this.data.slotId2towerId[pos.uid];
                      if (towerId == id) {
                          return true;
                      }
                  }
              }
          }
          return false;
      }
      static equipTower(index, id) {
          if (this.isTowerSlotUnlcok(index)) {
              if (id && this.isTowerEquip(id)) {
                  return false;
              }
              this.setSlotTower(index, id);
              return true;
          }
          else {
              return false;
          }
      }
      static moveTower(indexOld, indexNew, id) {
          if (this.isTowerSlotUnlcok(indexOld) && this.isTowerSlotUnlcok(indexNew) && this.isTowerEquip(id)) {
              this.setSlotTower(indexOld, null);
              this.setSlotTower(indexNew, id);
              return true;
          }
          else {
              return false;
          }
      }
      static calcSlotUnlockCount() {
          let count = 0;
          let towerPos = db.get_tower_pos_map()[this.defaultPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              if (!pos.unlock && this.isTowerSlotUnlcok(pos.id - 1)) {
                  count++;
              }
          }
          return count;
      }
      static getSlotUnlockDesc() {
          let count = this.calcSlotUnlockCount();
          let unlockLv = db.game_cnf.slot_unlock_lv[count];
          let unlockCost = db.game_cnf.slot_unlock_cost[count];
          if (unlockLv && unlockCost) {
              return "领主塔等级>=" + unlockLv + "(当前等级" + this.getTowerLv("1") + ") 花费:" + unlockCost;
          }
      }
      static getMainTowerLv() {
          return this.getTowerLv(this.mainTowerId);
      }
      static tryUnlockSlot(index, force = false) {
          let count = this.calcSlotUnlockCount();
          let unlockLv = db.game_cnf.slot_unlock_lv[count];
          let unlockCost = db.game_cnf.slot_unlock_cost[count];
          let towerLv = this.getMainTowerLv();
          if (force || towerLv >= unlockLv) {
              if (force || mgrGame.subItem(1000, unlockCost, 40)) {
                  this.markTowerSlotUnlcok(index);
                  Global.sendMsg(MSG.SLOT_UNLOCK, index + 1);
                  Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
                  return true;
              }
          }
          return false;
      }
      static getTowerPointAdd(id) {
          return this.data.towerId2Point[id] || { base: 0, power: 0, mana: 0, point: 0 };
      }
      static setTowerPointAdd(id, data) {
          this.data.towerId2Point[id] = data;
          this.saveRecord();
      }
      static resetTowerPoint(id) {
          let data = this.getTowerPointAdd(id);
          data.point = 0;
          data.base = 0;
          data.power = 0;
          data.mana = 0;
          this.setTowerPointAdd(id, data);
      }
      static calcTowerPointLeft(id) {
          let towerLv = this.getTowerLv(id);
          if (towerLv <= 0)
              return 0;
          let totalPoint = towerLv * db.game_cnf.point_add_per_lv;
          let data = this.getTowerPointAdd(id);
          let leftPoint = totalPoint - data.point;
          if (leftPoint < 0)
              leftPoint = 0;
          return leftPoint;
      }
      static calcTowerPointLeftHalf(id) {
          return Math.floor(this.calcTowerPointLeft(id) / 2);
      }
      static addTowerPoint(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          data.point += add;
          this.setTowerPointAdd(id, data);
      }
      static assignTowerPointBase(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.base += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static assignTowerPointPower(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.power += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static assignTowerPointMana(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.mana += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static calcTowerAttrBase(id, attr) {
          if (attr) {
              Level.resetAttrArray(attr, BASE_ATTR.LEN_TOWER);
          }
          else {
              attr = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          }
          let towerDb = db.get_tower_db(id);
          attr[BASE_ATTR.HP] = towerDb.hp;
          attr[BASE_ATTR.AD] = towerDb.ad;
          attr[BASE_ATTR.AP] = towerDb.ap;
          attr[BASE_ATTR.RANGE] = towerDb.range;
          attr[BASE_ATTR.CRIT] = towerDb.crit;
          attr[BASE_ATTR.CRIT_DMG] = towerDb.crit_dmg;
          attr[BASE_ATTR.ATK_SPEED] = towerDb.atk_speed;
          attr[BASE_ATTR.MP_RECOVER] = towerDb.mp_recover;
          attr[BASE_ATTR.MP] = 100;
          attr[BASE_ATTR.HURT_FACTOR] = 1;
          attr[BASE_ATTR.DMG_REDUCT] = 1;
          let pointAdd = mgrTower.getTowerPointAdd(id);
          attr[BASE_ATTR.HP] += pointAdd.base * 10;
          attr[BASE_ATTR.AD] += pointAdd.power;
          attr[BASE_ATTR.AP] += pointAdd.mana;
          return attr;
      }
      static calcTowerAttrBaseByFinalWar(id, attr) {
          if (attr) {
              Level.resetAttrArray(attr, BASE_ATTR.LEN_TOWER);
          }
          else {
              attr = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          }
          let towerDb = db.get_tower_db(id);
          attr[BASE_ATTR.HP] = towerDb.hp;
          attr[BASE_ATTR.AD] = towerDb.ad;
          attr[BASE_ATTR.AP] = towerDb.ap;
          attr[BASE_ATTR.RANGE] = towerDb.range;
          attr[BASE_ATTR.CRIT] = towerDb.crit;
          attr[BASE_ATTR.CRIT_DMG] = towerDb.crit_dmg;
          attr[BASE_ATTR.ATK_SPEED] = towerDb.atk_speed;
          attr[BASE_ATTR.MP_RECOVER] = towerDb.mp_recover;
          attr[BASE_ATTR.MP] = 100;
          attr[BASE_ATTR.HURT_FACTOR] = 1;
          attr[BASE_ATTR.DMG_REDUCT] = 1;
          let pointAdd = mgrFinalWar.getTowerPointAdd(id);
          attr[BASE_ATTR.HP] += pointAdd.base * 10;
          attr[BASE_ATTR.AD] += pointAdd.power;
          attr[BASE_ATTR.AP] += pointAdd.mana;
          return attr;
      }
      static calcTowerAttrBaseByDailyDamage(id, attr) {
          if (attr) {
              Level.resetAttrArray(attr, BASE_ATTR.LEN_TOWER);
          }
          else {
              attr = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          }
          let towerDb = db.get_tower_db(id);
          attr[BASE_ATTR.HP] = towerDb.hp;
          attr[BASE_ATTR.AD] = towerDb.ad;
          attr[BASE_ATTR.AP] = towerDb.ap;
          attr[BASE_ATTR.RANGE] = towerDb.range;
          attr[BASE_ATTR.CRIT] = towerDb.crit;
          attr[BASE_ATTR.CRIT_DMG] = towerDb.crit_dmg;
          attr[BASE_ATTR.ATK_SPEED] = towerDb.atk_speed;
          attr[BASE_ATTR.MP_RECOVER] = towerDb.mp_recover;
          attr[BASE_ATTR.MP] = 100;
          attr[BASE_ATTR.HURT_FACTOR] = 1;
          attr[BASE_ATTR.DMG_REDUCT] = 1;
          let pointAdd = mgrDailyDamage.getTowerPointAdd(id);
          attr[BASE_ATTR.HP] += pointAdd.base * 10;
          attr[BASE_ATTR.AD] += pointAdd.power;
          attr[BASE_ATTR.AP] += pointAdd.mana;
          return attr;
      }
      static calcTowerAttrAdd(id, attr) {
          let towerDb = db.get_tower_db(id);
          let attrAdd = mgrHolyItem.calcAttrAdd(id);
          for (let i = 0; i < attrAdd.length; i++) {
              let add = attrAdd[i];
              if (add > 0) {
                  let attrDb = db.get_holy_item_attr_base_map()[i];
                  if (attrDb) {
                      if (attrDb.percent_value) {
                          add = attrAdd[i] / 100;
                      }
                      if (attrDb.percent_add) {
                          add = attr[i] * add;
                      }
                  }
                  attr[i] += add;
              }
          }
          if (towerDb.main) {
              mgrTalent.calcAttrAdd(attr);
          }
          mgrAllEquip.calcAttrAdd(attr);
          attr[BASE_ATTR.HP] = Math.round(attr[BASE_ATTR.HP]);
          attr[BASE_ATTR.AD] = Math.round(attr[BASE_ATTR.AD]);
          attr[BASE_ATTR.AP] = Math.round(attr[BASE_ATTR.AP]);
          return attr;
      }
      static calcTowerAttr(id, attr) {
          attr = this.calcTowerAttrBase(id, attr);
          attr = this.calcTowerAttrAdd(id, attr);
          StageAttr.calcAttrTower(attr);
          StageAttr.calcAttrTowerDailyDamage(attr);
          return attr;
      }
      static calcTowerAttrByFinalWar(id, attr) {
          attr = this.calcTowerAttrBaseByFinalWar(id, attr);
          attr = this.calcTowerAttrAdd(id, attr);
          StageAttr.calcAttrTower(attr);
          return attr;
      }
      static calcTowerAttrByDailyDamage(id, attr) {
          attr = this.calcTowerAttrBaseByDailyDamage(id, attr);
          attr = this.calcTowerAttrAdd(id, attr);
          StageAttr.calcAttrTower(attr);
          StageAttr.calcAttrTowerDailyDamage(attr);
          return attr;
      }
      static getTowerAttrInBattle(towerId) {
          return this.towerAttrCurInBattle[towerId] || this.calcTowerAttr(towerId);
      }
      static setTowerAttrInBattle(towerId, attr, attrMax) {
          this.towerAttrCurInBattle[towerId] = attr;
          this.towerAttrMaxInBattle[towerId] = attrMax;
      }
      static initTowerHolyData(id) {
          let arr = [];
          let towerDb = db.get_tower_db(id);
          let qualityDb = db.get_tower_quality(this.getTowerQualityByDB(towerDb));
          for (let i = 0; i < 8; i++) {
              let unlock = false;
              let valid = false;
              if (i < qualityDb.slot_num) {
                  valid = true;
                  if (i < qualityDb.slot_unlock) {
                      unlock = true;
                  }
              }
              arr.push({ id: i, unlock: unlock, unlock_type: 0, valid: valid });
          }
          return arr;
      }
      static calcTowerHolyUnlock(id, slots) {
          let towerDb = db.get_tower_db(id);
          if (!towerDb)
              return;
          let qualityDb = db.get_tower_quality(this.getTowerQualityByDB(towerDb));
          if (!qualityDb)
              return;
          let starCount = 0;
          let levelUnlockCount = 0;
          let starUnlockCount = 0;
          let towerLv = this.getTowerLv(id);
          let towerStar = this.getTowerStar(id);
          for (let i = 0; i < slots.length; i++) {
              let item = slots[i];
              if (i >= qualityDb.slot_unlock && i < qualityDb.slot_num) {
                  if (item.valid) {
                      if (towerDb.main) {
                          item.unlock_type = HOLY_ITEM_SLOT_STATE.UNLOCK_LEVEL;
                          let level = db.game_cnf.main_item_slot_unlock_lv[levelUnlockCount];
                          if (towerLv >= level) {
                              item.unlock = true;
                              levelUnlockCount++;
                          }
                      }
                      else {
                          if (starCount < qualityDb.slot_star) {
                              starCount++;
                              item.unlock_type = HOLY_ITEM_SLOT_STATE.UNLOCK_STAR;
                              let star = db.game_cnf.tower_item_slot_unlock_star[starUnlockCount];
                              if (towerStar >= star) {
                                  item.unlock = true;
                                  starUnlockCount++;
                              }
                          }
                          else {
                              item.unlock_type = HOLY_ITEM_SLOT_STATE.UNLOCK_COIN;
                          }
                      }
                  }
              }
          }
      }
      static getTowerHolyData(id) {
          let data = this.data.towerId2item[id];
          if (!data) {
              data = this.initTowerHolyData(id);
              this.setTowerHolyData(id, data);
          }
          this.calcTowerHolyUnlock(id, data);
          return data;
      }
      static calcAllHolyItemLv(towerId) {
          let level = 0;
          let slots = this.getTowerHolyData(towerId);
          for (let i = 0; i < 8; i++) {
              let slot = slots[i];
              if (slot) {
                  let item = mgrHolyItem.findBagItemByUIDAndTowerId(slot.item_uid, towerId);
                  if (item && item.holyitem) {
                      level += item.holyitem.level;
                  }
              }
          }
          return level;
      }
      static calcTowerStarUnlockCount(id) {
          let data = this.getTowerHolyData(id);
          let count = 0;
          for (let slot of data) {
              if (slot.unlock && slot.unlock_type == HOLY_ITEM_SLOT_STATE.UNLOCK_STAR) {
                  count++;
              }
          }
          return count;
      }
      static calcTowerLevelUnlockCount(id) {
          let data = this.getTowerHolyData(id);
          let count = 0;
          for (let slot of data) {
              if (slot.unlock && slot.unlock_type == HOLY_ITEM_SLOT_STATE.UNLOCK_LEVEL) {
                  count++;
              }
          }
          return count;
      }
      static calcTowerCoinUnlockCount(id) {
          let data = this.getTowerHolyData(id);
          let count = 0;
          for (let slot of data) {
              if (slot.unlock && slot.unlock_type == HOLY_ITEM_SLOT_STATE.UNLOCK_COIN) {
                  count++;
              }
          }
          return count;
      }
      static getUnlocklTowerSlotCost(id) {
          let index = this.calcTowerCoinUnlockCount(id);
          let cost = db.game_cnf.tower_item_slot_unlock_cost[index];
          return cost || 0;
      }
      static tryUnlcokTowerSlotByCoin(id, force = false) {
          let index = this.calcTowerCoinUnlockCount(id);
          let cost = db.game_cnf.tower_item_slot_unlock_cost[index];
          if (force || (cost && mgrGame.subItem(1000, cost, 43))) {
              let data = this.getTowerHolyData(id);
              for (let slot of data) {
                  if (!slot.unlock && slot.unlock_type == HOLY_ITEM_SLOT_STATE.UNLOCK_COIN) {
                      slot.unlock = true;
                      this.saveRecord();
                      Global.sendMsg(MSG.HOLY_ITEM_SLOT_UNLOCK, id);
                      return true;
                  }
              }
          }
          return false;
      }
      static getTowerItemSlot(id, slotId) {
          let data = this.getTowerHolyData(id);
          for (let slot of data) {
              if (slot.id == slotId) {
                  return slot;
              }
          }
          return null;
      }
      static setTowerHolyData(id, data) {
          this.data.towerId2item[id] = data;
          this.saveRecord();
      }
      static getTowerHolyItem(id, index) {
          let data = this.getTowerHolyData(id);
          if (data) {
              return data[index];
          }
          else {
              return null;
          }
      }
      static findTowerDbByItemId(itemId) {
          let towerDbMap = db.get_tower_db_map();
          for (let key in towerDbMap) {
              let towerDb = db.get_tower_db(key);
              if (towerDb.item_id == itemId) {
                  return towerDb;
              }
          }
          return null;
      }
      static findCollectDbByItemId(itemId) {
          let dataArr = db.get_collect_db_map()["tower"];
          for (let data of dataArr) {
              if (data.item_id == itemId) {
                  return data;
              }
          }
          return null;
      }
      static addTowerByItemId(itemId, amount, reason) {
          let towerDb = this.findTowerDbByItemId(itemId);
          if (towerDb) {
              this.addTowerByAmount(towerDb, amount, reason);
          }
      }
      static addTowerByAmount(towerDb, amount, reason, show = false, dropData) {
          for (let i = 0; i < amount; i++) {
              this.addTower(towerDb, reason, show, dropData);
          }
      }
      static addTower(towerDb, reason, show = false, dropData) {
          let item_id = towerDb.item_id;
          if (mgrGame.getItemCount(item_id)) {
              if (this.isTowerStarFull(towerDb.id)) {
                  let qualityDb = db.get_tower_quality(towerDb.default_quality);
                  if (qualityDb) {
                      mgrGame.addItem(1006, qualityDb.tower_piece, reason, false);
                      if (dropData) {
                          let itemInfo = {
                              itemId: 1006,
                              count: qualityDb.tower_piece,
                              quality: towerDb.default_quality,
                          };
                          dropData.push({ type: DROP_TYPE.TOWER, data: { itemId: towerDb.item_id, count: 1, towerDb: towerDb, convert: itemInfo } });
                      }
                  }
              }
              else {
                  this.addTowerStarExp(towerDb.id, towerDb.star_exp);
                  if (dropData) {
                      dropData.push({ type: DROP_TYPE.TOWER, data: { itemId: towerDb.item_id, count: 1, towerDb: towerDb } });
                  }
              }
          }
          else {
              if (dropData) {
                  dropData.push({ type: DROP_TYPE.TOWER, data: { itemId: towerDb.item_id, count: 1, towerDb: towerDb } });
              }
              if (show) {
                  this.showTowerNew(towerDb.id, 1);
              }
              Global.sendMsg(MSG.TOWER_NEW_GET);
          }
          BaseFacade.mItem.addItem(item_id, 1, reason);
      }
      static showTowerNew(towerId, amount, showElse = true) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb && !this.isTowerShow(towerId)) {
              this.markTowerShow(towerId);
              Director.openPanel("PanelTowerNew", { towerId: towerId });
          }
          else if (showElse) {
              let item = { itemId: towerDb.item_id, count: amount };
              Director.openPanel("PanelItemGet", { items: [{ type: DROP_TYPE.ITEM, data: item }] });
          }
      }
      static refreshStarLvupBar(progress, towerId, tween = false, tweenTime = 1) {
          let piece = mgrGame.getItemCount(1006);
          let curtExp = this.getTowerStarExp(towerId);
          let needExp = this.getTowerStarExpNeed(towerId);
          let percentExp = curtExp / needExp;
          let percentPiece = percentExp + piece / needExp;
          if (percentExp > 1)
              percentExp = 1;
          if (percentPiece > 1)
              percentPiece = 1;
          if (tween) {
              progress.value = 0;
              progress.tweenValue(percentExp * 100, tweenTime);
          }
          else {
              progress.value = percentExp * 100;
          }
          let progressText = progress.getChild("text").asTextField;
          progressText.text = curtExp + "/" + needExp;
          let progressBar2 = progress.getChild("bar2");
          if (progressBar2 instanceof fgui.GProgressBar) {
              if (tween) {
                  progressBar2.value = 0;
                  progressBar2.tweenValue(percentPiece * 100, tweenTime);
              }
              else {
                  progressBar2.value = percentPiece * 100;
              }
          }
      }
      static getSkillIcon(id) {
          let skillDb = db.get_skill_db(id);
          if (skillDb) {
              return skillDb.icon;
          }
          else {
              return "";
          }
      }
      static calcTowerScore(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let level = this.getTowerLv(id);
              let star = this.getTowerStar(id);
              let quality = this.getTowerQualityByDB(towerDb);
              let isFighit = this.isTowerEquip(id);
              return isFighit ? -SORT_SCORE$1.SCORTE_1 : 0 + SORT_SCORE$1.SCORTE_2 * level + SORT_SCORE$1.SCORTE_3 * star + SORT_SCORE$1.SCORTE_4 * quality + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreBag(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let level = this.getTowerLv(id);
              let star = this.getTowerStar(id);
              let quality = this.getTowerQualityByDB(towerDb);
              return SORT_SCORE$1.SCORTE_2 * level + SORT_SCORE$1.SCORTE_3 * star + SORT_SCORE$1.SCORTE_4 * quality + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreLevel(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let level = this.getTowerLv(id);
              return SORT_SCORE$1.SCORTE_2 * level + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreStar(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let star = this.getTowerStar(id);
              return SORT_SCORE$1.SCORTE_3 * star + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreQuality(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let quality = this.getTowerQualityByDB(towerDb);
              return SORT_SCORE$1.SCORTE_4 * quality + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreHolyItem(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let level = this.calcAllHolyItemLv(id);
              return SORT_SCORE$1.SCORTE_2 * level + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreSecret(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let level = this.getTowerLv(id);
              let star = this.getTowerStar(id);
              let quality = this.getTowerQualityByDB(towerDb);
              if (this.isTowerQualityMax(quality)) {
                  return -1000 + towerDb.index;
              }
              else {
                  return SORT_SCORE$1.SCORTE_2 * level + SORT_SCORE$1.SCORTE_3 * star + SORT_SCORE$1.SCORTE_4 * quality + towerDb.index;
              }
          }
          else {
              return 0;
          }
      }
      static calcTowerScoreExplore(id) {
          let towerDb = db.get_tower_db(id);
          if (towerDb) {
              let quality = this.getTowerQualityByDB(towerDb);
              return SORT_SCORE$1.SCORTE_4 * quality + towerDb.index;
          }
          else {
              return 0;
          }
      }
      static getTowerQualityMax() {
          return EQUIP_QUALITY.ORANGE;
      }
      static isTowerQualityMax(quality) {
          return quality >= this.getTowerQualityMax();
      }
      static haveEmptySlot(id) {
          let haveEmptySlot = false;
          let data = this.getTowerHolyData(id);
          if (data) {
              for (let slot of data) {
                  if (slot.unlock && !slot.item_uid) {
                      haveEmptySlot = true;
                      break;
                  }
              }
          }
          return haveEmptySlot;
      }
      static haveRedPoint(id, haveHolyItemCanEquip = null) {
          let haveEmptySlot = this.haveEmptySlot(id);
          let haveRedPoint = false;
          if (haveHolyItemCanEquip == null)
              haveRedPoint = haveEmptySlot && mgrHolyItem.haveAnyItemCanEquip();
          else
              haveRedPoint = haveEmptySlot && haveHolyItemCanEquip;
          return haveRedPoint || this.canLvupTowerStar(id) || this.canLvupTowerLevel(id) || this.calcTowerPointLeft(id) > 0;
          ;
      }
      static getTowerShowMoverPos(skillId) {
          return this.myTowerShowPos[skillId];
      }
      static setTowerShowMovePos(skillId, pos) {
          this.myTowerShowPos[skillId] = pos;
      }
      static checkTowerPosAndFix() {
          let slotList = db.get_tower_pos_map()[this.defaultPosGid];
          let equipedTower = {};
          for (let slot of slotList) {
              let index = slot.id - 1;
              let towerId = this.getSlotTower(index);
              if (towerId) {
                  if (equipedTower[towerId]) {
                      this.setSlotTower(index, "");
                  }
                  else {
                      equipedTower[towerId] = true;
                  }
              }
          }
      }
      static tryLvupTowerQuality(id) {
      }
      static tryLvupTowerQualityByDB(towerDb) {
          if (!towerDb)
              return false;
          let quality = this.getTowerQualityByDB(towerDb);
          if (quality >= this.getTowerQualityMax())
              return false;
          let qualityDb = db.get_tower_quality(quality);
          if (!qualityDb)
              return false;
          let item_ids = qualityDb.item_ids;
          for (let i = 0; i < item_ids.length; i += 2) {
              let itemId = item_ids[i];
              let itemCt = item_ids[i + 1];
              if (itemId && itemCt && !mgrGame.checkItem(itemId, itemCt)) {
                  return false;
              }
          }
          for (let i = 0; i < item_ids.length; i += 2) {
              let itemId = item_ids[i];
              let itemCt = item_ids[i + 1];
              if (itemId && itemCt) {
                  mgrGame.subItem(itemId, itemCt, 61);
              }
          }
          this.setTowerQuality(towerDb.id, quality + 1);
          let slots = this.getTowerHolyData(towerDb.id);
          if (slots) {
              for (let i = 0; i < slots.length; i++) {
                  let slot = slots[i];
                  if (slot) {
                      if (!slot.valid) {
                          slot.unlock = true;
                          slot.valid = true;
                          break;
                      }
                  }
              }
          }
          this.saveRecord();
          Global.sendMsg(MSG.TOWER_LVUP_QUALITY, towerDb.id);
          return true;
      }
      static getTowerName(towerId) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              return towerDb.name;
          }
          else {
              return "";
          }
      }
      static isHolyItemPresetHaveItemId(towerId, presetId, holyItemUid) {
          let preset = this.getHolyItemPresetByID(towerId, presetId);
          return this.isHolyItemPresetHaveItemIdByData(preset, holyItemUid);
      }
      static isHolyItemPresetHaveItemIdByData(preset, holyItemUid) {
          if (!holyItemUid) {
              return false;
          }
          for (let id of preset) {
              if (id == holyItemUid) {
                  return true;
              }
          }
          return false;
      }
      static setHolyItemPresetItemID(towerId, presetId, index, holyItemUid) {
          let preset = this.getHolyItemPresetByID(towerId, presetId);
          if (this.isHolyItemPresetHaveItemIdByData(preset, holyItemUid)) {
              return false;
          }
          preset[index] = holyItemUid;
          this.saveRecord();
          return true;
      }
      static getHolyItemPresetItemID(towerId, presetId, index) {
          let preset = this.getHolyItemPresetByID(towerId, presetId);
          return preset[index];
      }
      static getHolyItemPresetByID(towerId, presetId) {
          let data = this.getHolyItemPreset(towerId);
          let preset = data[presetId];
          if (!preset) {
              preset = [];
              for (let i = 0; i < 8; i++) {
                  preset.push("");
              }
              data[presetId] = preset;
              this.saveRecord();
          }
          return preset;
      }
      static getHolyItemPreset(towerId) {
          let data = this.data.towerId2preset[towerId];
          if (!data) {
              data = {};
              this.data.towerId2preset[towerId] = data;
              this.saveRecord();
          }
          return data;
      }
      static checkHolyItemPreset(towerId, presetId) {
          let msg = "";
          let preset = this.getHolyItemPresetByID(towerId, presetId);
          for (let i = 0; i < preset.length; i++) {
              let uid = preset[i];
              if (uid) {
                  let item = mgrHolyItem.findBagItemByUID(uid);
                  if (item && item.holyitem) {
                      let holyitem = item.holyitem;
                      if (holyitem.isEquiped() && holyitem.data.towerId != towerId) {
                          msg += holyitem + "" + holyitem.getEquipTowerName() + "\n";
                      }
                  }
              }
          }
          return msg;
      }
      static applyHolyItemPreset(towerId, presetId) {
          let towerDb = db.get_tower_db(towerId);
          if (!towerDb)
              return;
          let preset = this.getHolyItemPresetByID(towerId, presetId);
          for (let i = 0; i < preset.length; i++) {
              let uid = preset[i];
              if (uid) {
                  let item = mgrHolyItem.findBagItemByUID(uid);
                  if (item && item.holyitem) {
                      let holyitem = item.holyitem;
                      if (holyitem.isEquiped() && holyitem.data.towerId != towerId) {
                          mgrTip.alertPrompt("该圣物已被" + holyitem.getEquipTowerName() + "所装备，是否【装备给" + towerDb.name + "】？", "", () => {
                              mgrHolyItem.takeOnHolyItem(item, towerDb.id, i);
                          });
                      }
                      else {
                          mgrHolyItem.takeOnHolyItem(item, towerId, i);
                      }
                  }
                  else {
                      mgrHolyItem.takeOffHolyItem(towerId, i);
                  }
              }
              else {
                  mgrHolyItem.takeOffHolyItem(towerId, i);
              }
          }
      }
  }
  mgrTower.RECORD_KEY = "game166_tower_v1.0";
  mgrTower.mainTowerId = "0";
  mgrTower.dataDefault = {
      mainHeroId: 4,
      mainHeroId2unlock: {},
      slotId2unlock: {},
      slotId2towerId: {
          ["0"]: "0",
      },
      towerId2lv: {
          ["0"]: 0,
      },
      towerId2LvLimit: {},
      towerId2Star: {},
      towerId2Quality: {},
      towerId2StarExp: {},
      towerId2Point: {},
      towerId2item: {},
      towerId2show: {},
      towerId2preset: {}
  };
  mgrTower.defaultPosGid = "1";
  mgrTower.towerAttrCurInBattle = {};
  mgrTower.towerAttrMaxInBattle = {};
  mgrTower.myTowerShowPos = {};

  class mgrFinalWar extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrFinalWar.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static set winAutoNext(value) {
          this.data.bWinAutoNext = value;
          this.saveRecord();
      }
      static get winAutoNext() {
          return this.data.bWinAutoNext;
      }
      static getTowerLv(id) {
          let towerLv = mgrTower.getTowerLv(id);
          let limitLv = this.getFinalWarLvLimit();
          if (towerLv > limitLv) {
              towerLv = limitLv;
          }
          return towerLv;
      }
      static get defaultFinalWarId() {
          return this.getFinalWarDb().id;
      }
      static getFinalWarPointGroup() {
          let groupPoint = this.data.finalId2Point[this.defaultFinalWarId];
          if (!groupPoint) {
              groupPoint = {};
              this.data.finalId2Point[this.defaultFinalWarId] = groupPoint;
          }
          return groupPoint;
      }
      static setFinalWarPointGroup(groupPoint) {
          this.data.finalId2Point[this.defaultFinalWarId] = groupPoint;
          this.saveRecord();
      }
      static setFinalWarPoint(id, data) {
          let groupPoint = this.getFinalWarPointGroup();
          groupPoint[id] = data;
          this.setFinalWarPointGroup(groupPoint);
      }
      static getTowerPointAdd(id) {
          let data = this.getFinalWarPointGroup()[id];
          if (data == null) {
              data = { base: 0, power: 0, mana: 0, point: 0 };
              let pointAdd = mgrTower.getTowerPointAdd(id);
              if (pointAdd) {
                  data.base = pointAdd.base;
                  data.power = pointAdd.power;
                  data.mana = pointAdd.mana;
                  data.point = pointAdd.point;
              }
              this.setTowerPointAdd(id, data);
          }
          if (this.isTowerPointOutOfLv(data, id)) {
              data.point = 0;
              data.base = 0;
              data.power = 0;
              data.mana = 0;
          }
          return data;
      }
      static setTowerPointAdd(id, data) {
          this.setFinalWarPoint(id, data);
          this.saveRecord();
      }
      static resetTowerPoint(id) {
          let data = this.getTowerPointAdd(id);
          data.point = 0;
          data.base = 0;
          data.power = 0;
          data.mana = 0;
          this.setTowerPointAdd(id, data);
      }
      static calcTowerPointLeft(id) {
          let towerLv = this.getTowerLv(id);
          if (towerLv <= 0)
              return 0;
          let totalPoint = towerLv * db.game_cnf.point_add_per_lv;
          let data = this.getTowerPointAdd(id);
          let leftPoint = totalPoint - data.point;
          if (leftPoint < 0)
              leftPoint = 0;
          return leftPoint;
      }
      static isTowerPointOutOfLv(data, id) {
          let total = this.getTowerLv(id) * db.game_cnf.point_add_per_lv;
          return data.point > total;
      }
      static calcTowerPointLeftHalf(id) {
          return Math.floor(this.calcTowerPointLeft(id) / 2);
      }
      static addTowerPoint(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          data.point += add;
          this.setTowerPointAdd(id, data);
      }
      static assignTowerPointBase(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.base += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static assignTowerPointPower(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.power += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static assignTowerPointMana(id, add = 1) {
          let data = this.getTowerPointAdd(id);
          let left = this.calcTowerPointLeft(id);
          if (left > 0 && add > 0) {
              if (add > left)
                  add = left;
              data.point += add;
              data.mana += add;
              this.setTowerPointAdd(id, data);
              Global.sendMsg(MSG.REFRESH_RED_POINT_TOWER);
              return true;
          }
          return false;
      }
      static isAnyTowerHaveLeftPoint() {
          let isHave = false;
          let towerPos = db.get_tower_pos_map()[mgrTower.defaultPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              let id = mgrTower.getSlotTower(pos.id - 1);
              if (id) {
                  let leftPoint = this.calcTowerPointLeft(id);
                  if (leftPoint > 0) {
                      isHave = true;
                      break;
                  }
              }
          }
          return isHave;
      }
      static findFinalWarDb(id) {
          return db.get_finalwar_db(id - 1);
      }
      static resetFinalWarLevel() {
          this.data.finalId2Lv = {};
          this.saveRecord();
      }
      static setFinalWarLevel(id, lv) {
          this.data.finalId2Lv[id] = lv;
          let maxLv = this.data.finalId2LvHistory[id] || 0;
          if (lv > maxLv) {
              this.data.finalId2LvHistory[id] = lv;
          }
          this.saveRecord();
      }
      static getFinalWarLevel(id) {
          return this.data.finalId2Lv[id] || 1;
      }
      static getFinalWarMaxLv(id) {
          return this.data.finalId2LvHistory[id] || 0;
      }
      static addFinalWarLevel(id) {
          this.setFinalWarLevel(id, this.getFinalWarLevel(id) + 1);
      }
      static loadFinalWar(id) {
          this.finalWardDb = this.findFinalWarDb(id);
          this.loadFinalWarByDB(this.finalWardDb);
      }
      static getFinalWarDb() {
          return this.finalWardDb || this.findFinalWarDb(1);
      }
      static getFinalWarLvLimit() {
          let finalWarDb = this.getFinalWarDb();
          if (finalWarDb) {
              return finalWarDb.limit_lv;
          }
          return 1000;
      }
      static getFinalWarName() {
          let wardDb = this.getFinalWarDb();
          if (wardDb) {
              return wardDb.name;
          }
          else {
              return "";
          }
      }
      static loadFinalWarByDB(warDb) {
          this.finalWardDb = warDb;
      }
      static getFinalWarDiffcult() {
          if (this.finalWardDb) {
              return this.getFinalWarLevel(this.finalWardDb.id);
          }
          else {
              return 1;
          }
      }
      static canSweep(warDb) {
          let curLv = this.getFinalWarLevel(warDb.id);
          let maxLv = this.calcMaxSweepLv(warDb);
          return curLv < maxLv;
      }
      static calcMaxSweepLv(warDb) {
          return Math.floor(this.getFinalWarMaxLv(warDb.id) * warDb.sweep_percent);
      }
      static sweep(warDb) {
          let curLv = this.getFinalWarLevel(warDb.id);
          let swpLv = curLv + warDb.sweep_add;
          let maxLv = this.calcMaxSweepLv(warDb);
          if (curLv >= maxLv)
              return;
          if (swpLv > maxLv) {
              swpLv = maxLv;
          }
          let itemCount = 0;
          for (let i = curLv; i < swpLv; i++) {
              itemCount += Formula.rewardFinalWar(i, warDb.reward_scale);
              this.addFinalWarLevel(warDb.id);
          }
          mgrGame.addItem(warDb.item_id, itemCount, 66, true);
      }
  }
  mgrFinalWar.RECORD_KEY = "game166_finalwar_v1.0";
  mgrFinalWar.dataDefault = {
      finalId2Lv: {},
      finalId2LvHistory: {},
      bWinAutoNext: false,
      finalId2Point: {},
  };

  var Keyboard = Laya.Keyboard;
  class KeyboardDebugTool {
      constructor(bindPanel) {
          this.props = {};
          this.bindPanel = bindPanel;
          Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onMsgKeyDown);
      }
      static create(bindPanel) {
          if (this.remove(bindPanel)) {
              console.warn("覆盖之前的KeyboardDebugTool", bindPanel.sourceName);
          }
          let tool = new KeyboardDebugTool(bindPanel);
          this._instance.push(tool);
          return tool;
      }
      static remove(bindPanel) {
          for (let i = 0; i < this._instance.length; i++) {
              if (this._instance[i].bindPanel == bindPanel) {
                  this._instance[i].dispose();
                  this._instance.splice(i, 1);
                  return true;
              }
          }
          return false;
      }
      dispose() {
          this.destroyed = true;
          this.setter1 = null;
          this.getter1 = null;
          this.setter2 = null;
          this.getter2 = null;
          Laya.stage.offAllCaller(this);
      }
      onMsgKeyDown(e) {
          if (!this.bindPanel || this.bindPanel.destroyed) {
              this.dispose();
              return;
          }
          if (this.bindPanel.isFocus != null && !this.bindPanel.isFocus)
              return;
          switch (e.keyCode) {
              case Keyboard.W:
              case Keyboard.S:
              case Keyboard.A:
              case Keyboard.D:
                  var prop = this.props[e.keyCode];
                  if (prop) {
                      this.updateValue1(prop[0], prop[1]);
                  }
                  break;
              case Keyboard.UP:
              case Keyboard.DOWN:
              case Keyboard.LEFT:
              case Keyboard.RIGHT:
                  var prop = this.props[e.keyCode];
                  if (prop) {
                      this.updateValue2(prop[0], prop[1]);
                  }
                  break;
              case Keyboard.P:
                  this.debugInfo();
                  break;
          }
      }
      updateValue1(key, step) {
          this.setter1(key, this.getter1(key) + step);
      }
      updateValue2(key, step) {
          this.setter2(key, this.getter2(key) + step);
      }
      setProp(keyCode, key, step) {
          this.props[keyCode] = [key, step];
      }
      createFromTarget(target) {
          this.setter2 = function (key, value) {
              target[key] = value;
          };
          this.getter2 = function (key) {
              return target[key];
          };
      }
      target(target, getter) {
          if (!this.setter1) {
              if (target instanceof Function) {
                  this.setter2 = target;
                  this.getter2 = getter;
              }
              else {
                  this.createFromTarget(target);
              }
              this.setter1 = this.setter2;
              this.getter1 = this.getter2;
          }
          else {
              if (target instanceof Function) {
                  this.setter2 = target;
                  this.getter2 = getter;
              }
              else {
                  this.createFromTarget(target);
              }
          }
          return this;
      }
      up(key, step = -1) {
          this.setProp(Keyboard.W, key, step);
          return this;
      }
      down(key, step = 1) {
          this.setProp(Keyboard.S, key, step);
          return this;
      }
      left(key, step = -1) {
          this.setProp(Keyboard.A, key, step);
          return this;
      }
      right(key, step = 1) {
          this.setProp(Keyboard.D, key, step);
          return this;
      }
      up2(key, step = -1) {
          this.setProp(Keyboard.UP, key, step);
          return this;
      }
      down2(key, step = 1) {
          this.setProp(Keyboard.DOWN, key, step);
          return this;
      }
      left2(key, step = -1) {
          this.setProp(Keyboard.LEFT, key, step);
          return this;
      }
      right2(key, step = 1) {
          this.setProp(Keyboard.RIGHT, key, step);
          return this;
      }
      debugInfo() {
          console.log("------ start ctrl key info ------");
          let debugMap = {};
          for (const keyCodeStr in this.props) {
              let keyCode = parseInt(keyCodeStr);
              let key = this.props[keyCode][0];
              if (debugMap[key])
                  continue;
              debugMap[key] = true;
              if (keyCode < 50) {
                  console.log(`key:[${key}]=[${Mathf.round(this.getter1(key), 4)}]`);
              }
              else {
                  console.log(`key:[${key}]=[${Mathf.round(this.getter2(key), 4)}]`);
              }
          }
          console.log("------ end ctrl key info ------");
      }
      rotate(transform, moveStep = 1) {
          this.target(transform);
          this.up("localRotationEulerX", -moveStep);
          this.down("localRotationEulerX", moveStep);
          this.left("localRotationEulerY", moveStep);
          this.right("localRotationEulerY", -moveStep);
          this.left2("localRotationEulerZ", moveStep);
          this.right2("localRotationEulerZ", -moveStep);
          return this;
      }
      trasform(transform, moveStep = 0.02) {
          this.target(transform);
          this.up("localPositionY", -moveStep);
          this.down("localPositionY", moveStep);
          this.left("localPositionX", moveStep);
          this.right("localPositionX", -moveStep);
          this.up2("localRotationEulerX", 1);
          this.down2("localRotationEulerX", -1);
          this.left2("localPositionZ", moveStep);
          this.right2("localPositionZ", -moveStep);
          return this;
      }
  }
  KeyboardDebugTool._instance = [];

  var Keyboard$1 = Laya.Keyboard;
  var E_CAMERA_MODE;
  (function (E_CAMERA_MODE) {
      E_CAMERA_MODE[E_CAMERA_MODE["fixMode"] = 1] = "fixMode";
      E_CAMERA_MODE[E_CAMERA_MODE["targetDistance"] = 2] = "targetDistance";
      E_CAMERA_MODE[E_CAMERA_MODE["targetPosition"] = 3] = "targetPosition";
      E_CAMERA_MODE[E_CAMERA_MODE["easeMode"] = 4] = "easeMode";
  })(E_CAMERA_MODE || (E_CAMERA_MODE = {}));
  class CameraFollow extends Laya.Script3D {
      constructor() {
          super();
          this.__node = null;
          this.lerpValue = 0.025;
          this.position = new Laya.Vector3;
          this.endRotation = new Laya.Vector3(0, 0, 0);
          this.offset = new Laya.Vector3(0, 0, 0);
          this.distance = 5;
          this.lookMode = E_CAMERA_MODE.targetDistance;
          this.fov = 60;
          Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onMsgKeyDown);
      }
      set distance(value) {
          if (this._new_diatance == null) {
              this._old_distance = value;
              this._new_diatance = value;
          }
          else {
              this._old_distance = this._new_diatance;
              this._new_diatance = value;
          }
      }
      get distance() {
          return this._new_diatance;
      }
      set offset(value) {
          if (this._new_offset == null) {
              this._old_offset = value;
              this._new_offset = value;
          }
          else {
              this._old_offset = this._new_offset;
              this._new_offset = value;
          }
      }
      get offset() {
          return this._new_offset;
      }
      setEaseMode(easeFunc) {
          this._easeFunc = easeFunc || cc$1.Ease.linear;
          this.lookMode = E_CAMERA_MODE.easeMode;
          this.originRotation = this.__node.transform.rotationEuler.clone();
          this.originPosition = this.__node.transform.position.clone();
          this._startTime = Timer.now;
      }
      onAwake() {
          this.__node = this.owner;
      }
      onDisable() {
      }
      onLateUpdate() {
          if (!this.__node)
              return;
          let targetPos = new Laya.Vector3;
          if (!this.__target || this.__target.destroyed) {
          }
          else {
              targetPos = this.__target.transform.position.clone();
          }
          if (this.lookMode == E_CAMERA_MODE.easeMode && this._easeFunc) {
              let factor = (Timer.now - this._startTime) / this.lerpValue;
              factor = Mathf.clamp(factor, 0, 1);
              factor = this._easeFunc(factor);
              let outRot = new Laya.Vector3;
              Laya.Vector3.lerp(this.originRotation, this.endRotation, factor, outRot);
              this.__node.transform.rotationEuler = outRot;
              let forward = new Laya.Vector3;
              this.__node.transform.getForward(forward);
              Laya.Vector3.normalize(forward, forward);
              Laya.Vector3.scale(forward, -this.distance, forward);
              let outPos = new Laya.Vector3();
              Laya.Vector3.add(targetPos, forward, outPos);
              if (isNaN(forward.x) || isNaN(forward.y) || isNaN(forward.z))
                  return;
              Laya.Vector3.add(outPos, this.offset, outPos);
              Laya.Vector3.lerp(this.originPosition, outPos, factor, outPos);
              this.__node.transform.position = outPos;
              this.__node.fieldOfView = this.__node.fieldOfView * (1 - factor) + this.fov * factor;
              return;
          }
          if (this.lookMode == E_CAMERA_MODE.targetDistance) {
              let curRotation = this.__node.transform.rotationEuler.clone();
              let outRot = new Laya.Vector3;
              Laya.Vector3.lerp(curRotation, this.endRotation, this.lerpValue, outRot);
              this.__node.transform.rotationEuler = outRot;
              let forward = new Laya.Vector3;
              this.__node.transform.getForward(forward);
              Laya.Vector3.normalize(forward, forward);
              this._old_distance = this._old_distance * (1 - this.lerpValue) + this._new_diatance * this.lerpValue;
              let distance = this._old_distance;
              Laya.Vector3.scale(forward, -distance, forward);
              let outPos = new Laya.Vector3();
              Laya.Vector3.add(targetPos, forward, outPos);
              Laya.Vector3.lerp(this._old_offset, this._new_offset, this.lerpValue, this._old_offset);
              Laya.Vector3.add(outPos, this._old_offset, outPos);
              this.__node.transform.position = outPos;
              this.__node.fieldOfView = this.__node.fieldOfView * (1 - this.lerpValue) + this.fov * this.lerpValue;
          }
          else if (this.lookMode == E_CAMERA_MODE.targetPosition) {
              let outPos = new Laya.Vector3;
              Laya.Vector3.lerp(this.__node.transform.position.clone(), this.position, this.lerpValue, outPos);
              this.__node.transform.position = outPos;
              let OldRotation = this.__node.transform.rotation.clone();
              ;
              Laya.Vector3.add(targetPos, this.offset, targetPos);
              this.__node.transform.lookAt(targetPos, new Laya.Vector3, false);
              let newRotation = this.__node.transform.rotation.clone();
              Laya.Quaternion.lerp(OldRotation, newRotation, this.lerpValue, newRotation);
              this.__node.transform.rotation = newRotation;
              this.__node.fieldOfView = this.__node.fieldOfView * (1 - this.lerpValue) + this.fov * this.lerpValue;
          }
          else if (this.lookMode == E_CAMERA_MODE.fixMode) {
              let outPos = new Laya.Vector3;
              Laya.Vector3.lerp(this.__node.transform.position.clone(), this.position, this.lerpValue, outPos);
              this.__node.transform.position = outPos;
              let outRot = new Laya.Vector3;
              Laya.Vector3.lerp(this.__node.transform.rotationEuler, this.endRotation, this.lerpValue, outRot);
              this.__node.transform.rotationEuler = outRot;
              this.__node.fieldOfView = this.__node.fieldOfView * (1 - this.lerpValue) + this.fov * this.lerpValue;
          }
      }
      updateToEnd() {
          let lerpValue = this.lerpValue;
          this.lerpValue = 1;
          this.onLateUpdate();
          this.lerpValue = lerpValue;
      }
      onMsgKeyDown(e) {
          switch (e.keyCode) {
              case Keyboard$1.NUMBER_1:
                  this.distance += 0.05;
                  break;
              case Keyboard$1.NUMBER_2:
                  this.distance -= 0.05;
                  break;
              case Keyboard$1.NUMBER_7:
                  this.fov += 1;
                  break;
              case Keyboard$1.NUMBER_8:
                  this.fov -= 1;
                  break;
              case Keyboard$1.I:
                  this.offset.y += 0.05;
                  break;
              case Keyboard$1.K:
                  this.offset.y -= 0.05;
                  break;
              case Keyboard$1.J:
                  this.offset.x -= 0.05;
                  break;
              case Keyboard$1.L:
                  this.offset.x += 0.05;
                  break;
              case Keyboard$1.NUMPAD_8:
                  this.offset.z += 0.05;
                  break;
              case Keyboard$1.NUMPAD_2:
                  this.offset.z -= 0.05;
                  break;
              case Keyboard$1.UP:
                  this.endRotation.x += 1;
                  break;
              case Keyboard$1.DOWN:
                  this.endRotation.x -= 1;
                  break;
              case Keyboard$1.LEFT:
                  this.endRotation.y += 1;
                  break;
              case Keyboard$1.RIGHT:
                  this.endRotation.y -= 1;
                  break;
              case Keyboard$1.P:
                  console.log(`fov:${this.fov}`);
                  console.log(`dis:${this.distance}`);
                  console.log(`rot:${this.endRotation.x}:${this.endRotation.y}:${this.endRotation.z}`);
                  console.log(`off:${this.offset.x}:${this.offset.y}:${this.offset.z}`);
          }
      }
  }

  class PanelBase3D extends PanelBase {
      constructor() {
          super(...arguments);
          this._linkModels = {};
      }
      static setDefaultLightEular(x, y, z) {
          this.defaultLightEular.setValue(x, y, z);
      }
      dispose() {
          this.unlinkAllModelsAtBack();
          if (this.panelEffects) {
              for (let i = 0; i < this.panelEffects.length; i++) {
                  Global.poolManager.put(this.panelEffects[i]);
              }
              this.panelEffects.length = 0;
          }
          KeyboardDebugTool.remove(this);
          if (this.scene3DBack) {
              this.scene3DBack.destroy();
              this.scene3DBack = null;
          }
          if (this.scene3DEffect) {
              this.scene3DEffect.destroy();
              this.scene3DEffect = null;
              this.cameraEffect = null;
          }
          super.dispose();
      }
      createScene3DBack(idx = 0, fov = 60) {
          if (this.scene3DBack)
              return;
          this.scene3DBack = this.createScene3D(idx);
          if (fov) {
              this.camera = this.createCamera(fov, this.scene3DBack);
              this.lightBack = this.camera.addChild(this.createLight());
              let cf = this.camera.addComponent(CameraFollow);
              cf.fov = 60;
              cf.lerpValue = 0.05;
              cf.distance = 1.95;
              cf.endRotation = new Laya.Vector3;
              cf.offset = new Laya.Vector3(0.1, 1.2, 0);
          }
      }
      createScene3DFont(fov) {
          if (this.scene3DFront)
              return;
          this.scene3DFront = this.createScene3D(-1);
          if (fov) {
              this.cameraFront = this.createCamera(fov, this.scene3DFront);
              this.lightFront = this.cameraFront.addChild(this.createLight());
          }
      }
      createScene3DEffect(layer = 1) {
          if (this.scene3DEffect)
              return;
          this.scene3DEffect = this.createScene3D(layer);
          var camera = this.scene3DEffect.addChild(new Laya.Camera(0, 0.1, 20));
          camera.orthographic = true;
          camera.orthographicVerticalSize *= UIRoot.canvasHeight / 1024;
          camera.transform.position = new Laya.Vector3(0, 0, 10);
          camera.clearFlag = Laya.CameraClearFlags.DepthOnly;
          this.cameraEffect = camera;
      }
      global2camera(pos, out) {
          return UITools.global2camera(pos, this.cameraEffect, out);
      }
      node2Camera(node, out) {
          return UITools.node2camera(node, this.cameraEffect, out);
      }
      createScene3D(idx) {
          let scene = new Laya.Scene3D();
          let display;
          display = this.resNode.displayObject;
          for (let i = 0; i < this.resNode.numChildren; i++) {
              let child = this.resNode.getChildAt(i).displayObject;
              if (i >= idx) {
                  child.zOrder = i + 1;
              }
              else {
                  child.zOrder = i;
              }
          }
          display.addChild(scene);
          scene.zOrder = idx;
          return scene;
      }
      createLight() {
          let dlight = new Laya.DirectionLight();
          dlight.transform.localRotationEuler = PanelBase3D.defaultLightEular;
          dlight.color = new Laya.Vector3(1, 1, 1);
          return dlight;
      }
      createCamera(fov, scene3D) {
          let camera = scene3D.addChild(new Laya.Camera(0, 0.01, 100));
          camera.fieldOfView = fov;
          camera.clearFlag = Laya.CameraClearFlags.DepthOnly;
          return camera;
      }
      addEffect(effectId) {
          if (!this.panelEffects) {
              this.createScene3DEffect();
              this.panelEffects = [];
          }
          let effect = Global.poolManager.get(Particle, effectId);
          this.scene3DEffect.addChild(this.scene3DEffect);
          this.panelEffects.push(effect);
          return effect;
      }
      getEffect(effectId) {
          if (this.panelEffects) {
              for (let i = 0; i < this.panelEffects.length; i++) {
                  let ps = this.panelEffects[i];
                  if (ps.modelId == effectId) {
                      return ps;
                  }
              }
          }
          return this.addEffect(effectId);
      }
      removeEffect(effectId) {
          if (this.panelEffects) {
              for (let i = 0; i < this.panelEffects.length; i++) {
                  let ps = this.panelEffects[i];
                  if (ps.modelId == effectId) {
                      this.panelEffects.splice(i, 1);
                      Global.poolManager.put(ps);
                      break;
                  }
              }
          }
      }
      linkModelAtBack(model, root, linkPoint) {
          if (!model)
              return null;
          if (root && (root.destroyed || !root.scene || root.scene != this.scene3DBack))
              return null;
          this.createScene3DBack(0);
          let realModel = null;
          if (model instanceof Laya.Sprite3D) {
              if (model.destroyed)
                  return null;
              realModel = model;
          }
          else {
              realModel = Global.poolManager.get(Model, model);
          }
          if (!root) {
              this.scene3DBack.addChild(realModel);
              this._linkModels[realModel.id] = realModel;
              return realModel;
          }
          else if (!linkPoint) {
              root.addChild(realModel);
              this._linkModels[realModel.id] = realModel;
              return realModel;
          }
          else {
              if (Tools.link2Node(linkPoint, root, realModel)) {
                  this._linkModels[realModel.id] = realModel;
                  return realModel;
              }
              else {
                  return null;
              }
          }
      }
      unLinkModelAtBack(model) {
          if (!model || model.destroyed)
              return false;
          if (!this._linkModels[model.id])
              return false;
          delete this._linkModels[model.id];
          if (model instanceof Model) {
              Global.poolManager.put(model);
          }
          else {
              model.destroy();
          }
      }
      unlinkAllModelsAtBack() {
          Tools.forEachMap(this._linkModels, (k, v) => {
              if (v instanceof Model) {
                  this._linkModels[k] = null;
                  Global.poolManager.put(v);
              }
          });
          Tools.forEachMap(this._linkModels, (k, v) => {
              this._linkModels[k] = null;
              !v.destroyed && v.destroy();
          });
          this._linkModels = {};
      }
  }
  PanelBase3D.defaultLightEular = new Laya.Vector3(-5, -11, 0);

  class Spine extends Laya.Sprite {
      constructor(path, loadedCallback, frameRate = 60) {
          super();
          this.path = path;
          this.loadedCallback = loadedCallback;
          let templet = Spine.allTemplets[path];
          let templetLoading = Spine.loadingTemplets[path];
          if (templet && !templetLoading) {
              this.templet = templet;
              this.parseComplete();
              return;
          }
          else {
              templet = templet || templetLoading;
              if (!templet) {
                  templet = new Laya.Templet();
                  templet.rate = frameRate;
                  templet.on(Laya.Event.COMPLETE, this, this.parseComplete);
                  templet.on(Laya.Event.ERROR, this, this.onError);
                  templet.loadAni(path);
                  this.templet = templet;
                  Spine.loadingTemplets[path] = this.templet;
              }
              else {
                  templet.on(Laya.Event.COMPLETE, this, this.parseComplete);
                  templet.on(Laya.Event.ERROR, this, this.onError);
                  this.templet = templet;
              }
          }
      }
      onDestroy() {
      }
      onError() {
          console.log("骨骼动画初始化 parse error");
      }
      parseComplete() {
          console.log("骨骼动画初始化 成功!!!");
          this.bLoaded = true;
          Spine.allTemplets[this.path] = this.templet;
          Spine.loadingTemplets[this.path] = null;
          if (this.destroyed) {
              return;
          }
          let skeleton;
          skeleton = this.templet.buildArmature(0);
          this.templet.lock = true;
          skeleton.showSkinByName("normal");
          this.addChild(skeleton);
          this.skeleton = skeleton;
          this.parseAnimName();
          if (this.playingAnimationName)
              this.playAnimation(this.playingAnimationName, this.bPlayingLoop, this.playEndCallback);
          if (this.playingBackRate)
              this.playbackRate = this.playingBackRate;
          this.loadedCallback && this.loadedCallback();
      }
      playAnimation(name, loop = true, playEndCallback) {
          this.bPlayingLoop = loop;
          this.playingAnimationName = name;
          this.playEndCallback = playEndCallback;
          if (!this.bLoaded)
              return;
          this.skeleton.play(this.playingAnimationName, loop);
          this.playEndCallback && Timer.callLater(this.skeleton.player.playDuration / 1000, () => {
              let temp = this.playEndCallback;
              this.playEndCallback = null;
              temp && temp();
          }, this);
      }
      verifyAnim(index) {
          if (this.skeleton && this.skeleton.player && index >= 0)
              return this.skeleton.templet.getAnimation(index) != null;
          else
              return false;
      }
      parseAnimName() {
          this.name2index = {};
          for (let i = 0; i < this.skeleton.templet.getAnimationCount(); i++) {
              let animation = this.skeleton.templet.getAnimation(i);
              this.name2index[animation.name] = i;
          }
      }
      getAnimIdx(name) {
          let idx = this.name2index[name];
          if (idx == null)
              return -1;
          else
              return idx;
      }
      getFrameNum(name) {
          if (this.verifyAnim(this.getAnimIdx(name)))
              return this.skeleton.total;
          else
              return 0;
      }
      getAnimTime(name) {
          if (!this.bLoaded)
              return 0;
          let idx = this.getAnimIdx(name);
          if (this.verifyAnim(idx))
              return this.templet.getAniDuration(idx) / 1000;
          else
              return 0;
      }
      set playbackRate(value) {
          this.playingBackRate = value;
          if (!this.bLoaded)
              return;
          this.skeleton.playbackRate(this.playingBackRate);
      }
      destroyAndClear() {
          Spine.clearByPath(this.path);
          this.destroy();
      }
      static create(spineId, loadedCallback, frameRate = 60) {
          let spineData = db.get_spine_db(spineId);
          if (!spineData)
              return null;
          let spine = new Spine(spineData.resPath, loadedCallback, frameRate);
          spine.spineId = spineId;
          return spine;
      }
      static clear(spineId) {
          let spineData = db.get_spine_db(spineId);
          if (spineData) {
              this.clearByPath(spineData.resPath);
          }
      }
      static clearByPath(path) {
          let templet = this.allTemplets[path];
          if (templet) {
              templet.destroy();
              delete Spine.allTemplets[path];
          }
      }
  }
  Spine.allTemplets = {};
  Spine.loadingTemplets = {};

  class FollowTarget2D extends Laya.Script {
      constructor() {
          super(...arguments);
          this.targetTemp = { x: 0, y: 0, width: 0, height: 0 };
          this.funcEaseFollow = Laya.Ease.backOut;
          this.followToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, pass: 0, running: false, delay: 0 };
      }
      get node() {
          return this.owner;
      }
      get target_x() {
          return this.target.x;
      }
      get target_y() {
          return this.target.y - this.target.height * 0.5;
      }
      onUpdate() {
          this.updateFollowTo(GameConst.FrameDeltaTime);
      }
      set setTarget(target) {
          if (target.isTemp) {
              target = this.copyTarget(target);
          }
          this.target = target;
          this.targetUID = target.uid;
      }
      copyTarget(target) {
          for (let k in target) {
              this.targetTemp[k] = target[k];
          }
          return this.targetTemp;
      }
      isTargetValid() {
          if (this.target) {
              if (this.target.invalid) {
                  return false;
              }
              else {
                  if (this.targetUID && this.targetUID != this.target.uid) {
                      return false;
                  }
              }
              return true;
          }
          return false;
      }
      updateFollowTo(dt) {
          let followToData = this.followToData;
          if (!followToData.running)
              return;
          followToData.pass += dt;
          let timePass = followToData.pass;
          let timeMaxx = followToData.time;
          let timeDely = followToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          if (this.isTargetValid()) {
              followToData.dx = this.target_x - followToData.x;
              followToData.dy = this.target_y - followToData.y;
          }
          this.node.x = this.funcEaseFollow(timePass, followToData.x, followToData.dx, timeMaxx);
          this.node.y = this.funcEaseFollow(timePass, followToData.y, followToData.dy, timeMaxx);
          if (timePass >= timeMaxx) {
              followToData.running = false;
              this.onFollowEnd();
          }
      }
      onFollowEnd() {
          this.destroy();
      }
      followTarget(time, target) {
          this.setTarget = target;
          this.followToData.pass = 0;
          this.followToData.time = time;
          this.followToData.x = this.node.x;
          this.followToData.y = this.node.y;
          this.followToData.running = true;
          this.followToData.delay = 0;
          this.followToData.dx = target.x - this.node.x;
          this.followToData.dy = target.y - this.node.y;
      }
  }

  class LoaderHelper {
      static createWithModel(model) {
          let modelDb = db.get_model_db(model);
          if (modelDb) {
              return this.createSprite3D(modelDb.resPath);
          }
      }
      static createModelWithLoad(model, caller, func, args) {
          let modelDb = db.get_model_db(model);
          if (modelDb) {
              this.createSprite3DWithLoad(modelDb.resPath, caller, func, args);
          }
      }
      static createSprite3D(url) {
          let data = Laya.loader.getRes(url);
          if (data) {
              return Laya.Sprite3D.instantiate(data);
          }
          else {
          }
      }
      static createSprite3DWithLoad(url, caller, func, args) {
          let data = Laya.loader.getRes(url);
          let handler = Laya.Handler.create(caller, func, args);
          if (data) {
              handler.runWith(this.createSprite3D(url));
          }
          else {
              Laya.loader.create(url, Laya.Handler.create(this, this.onSprite3DLoad, [url, handler]));
          }
      }
      static onSprite3DLoad(url, handler) {
          handler.runWith(this.createSprite3D(url));
      }
      static createSprite(url) {
          let data = Laya.loader.getRes(url);
          if (data instanceof Laya.Prefab) {
              return data.create();
          }
          else {
          }
      }
      static createSpriteWithLoad(url, caller, func, args) {
          let data = Laya.loader.getRes(url);
          let handler = Laya.Handler.create(caller, func, args);
          if (data) {
              handler.runWith(this.createSprite(url));
          }
          else {
              Laya.loader.create(url, Laya.Handler.create(this, this.onSpriteLoad, [url, handler]));
          }
      }
      static onSpriteLoad(url, handler) {
          handler.runWith(this.createSprite(url));
      }
      static createView(name) {
          let viewClass = Global.require(name);
          if (viewClass) {
              let view = new viewClass();
              view.create();
              return view;
          }
      }
      static loadModelSlience(modelId) {
          let urls = [];
          if (modelId instanceof Array) {
              for (let id of modelId) {
                  let modelDb = db.get_model_db(id);
                  if (modelDb) {
                      urls.push({ url: modelDb.resPath, type: Laya.Loader.HIERARCHY });
                  }
              }
          }
          else {
              let modelDb = db.get_model_db(modelId);
              if (modelDb) {
                  urls.push({ url: modelDb.resPath, type: Laya.Loader.HIERARCHY });
              }
          }
          Laya.loader.create(urls, Laya.Handler.create(this, this.onModelSlienceLoad, [urls]), null, null, null, null, 4);
      }
      static onModelSlienceLoad(urls, res) {
      }
      static loadFguiPackageWithMessage(resKey) {
          fgui.UIPackage.loadPackage(resKey, Laya.Handler.create(this, this.onFguiPackageLoad, [resKey]));
      }
      static onFguiPackageLoad(resKey) {
          Global.sendMsg(LoaderHelper.MSG_FGUI_PACKAGE_LOAD, resKey);
      }
  }
  LoaderHelper.MSG_FGUI_PACKAGE_LOAD = "MSG_FGUI_PACKAGE_LOAD";

  class Effect extends Laya.Script3D {
      constructor() {
          super();
          this.passTime = 0;
          this.lifeTime = 0;
          this.effectId = "";
          this.effectScale = 1;
          this.flagSave = false;
          this._timeScale = 1;
          this.autoRecover = false;
          this.isFollowFguiNode = false;
          this.followOffsetX = 0;
          this.followOffsetY = 0;
          this.particleLooping = true;
          this.particleDuration = 0;
          Effect._count_effect_++;
      }
      static printCount() {
          console.log("特效持有数量", this._count_effect_);
      }
      onAwake() {
          this.node = this.owner;
          this.nodeTranfrom = this.node.transform;
          this.isFollowFguiNode = false;
      }
      onUse(timeScale = 1) {
          this.timeScale(timeScale);
      }
      timeScale(speed) {
          if (this._timeScale != speed) {
              this._timeScale = speed;
              this.changePlaySpeed(this.resNode, speed);
          }
      }
      loadRes(path, timeScale = 1) {
          this.resNode = null;
          LoaderHelper.createSprite3DWithLoad(path, this, this.onResLoad, [timeScale]);
      }
      onResLoad(timeScale, resNode) {
          if (!resNode)
              return;
          if (!this.node || this.destroyed) {
              resNode.destroy();
              return;
          }
          if (!this.effectDb) {
              this.parseShurikenParticle(resNode);
          }
          this.node.addChild(resNode);
          resNode.transform.localPositionX = 0;
          resNode.transform.localPositionY = 0;
          resNode.transform.localPositionZ = 0;
          this.setResNode(resNode);
          this.onUse(timeScale);
      }
      setResNode(resNode) {
          this.resNode = resNode;
      }
      play() {
          this.playEffect(this.node);
      }
      stop() {
          this.stopEffect(this.node);
      }
      playEffect(node) {
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.play();
          }
          if (node instanceof Laya.TrailSprite3D) {
              node.trailFilter.clear();
          }
          for (let i = 0; i < node.numChildren; i++) {
              this.playEffect(node.getChildAt(i));
          }
      }
      stopEffect(node) {
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.stop();
          }
          if (node instanceof Laya.TrailSprite3D) {
              node.trailFilter.clear();
          }
          for (let i = 0; i < node.numChildren; i++) {
              this.stopEffect(node.getChildAt(i));
          }
      }
      changePlaySpeed(node, speed = 1) {
          if (!node)
              return;
          if (node instanceof Laya.ShuriKenParticle3D) {
              node.particleSystem.simulationSpeed = speed;
          }
          for (let i = 0; i < node.numChildren; i++) {
              this.changePlaySpeed(node.getChildAt(i), speed);
          }
      }
      show() {
          this.getNode().active = true;
      }
      hide() {
          this.getNode().active = false;
      }
      getNode() {
          if (this.node)
              return this.node;
          else {
              this.node = this.owner;
              return this.node;
          }
      }
      setData(data, timeScale = 1) {
          this.effectDb = data;
          this.autoRecover = data.autoRecover;
          this.passTime = 0;
          this.setLifeTime(data.time / timeScale);
      }
      setLifeTime(lifeTime) {
          this.lifeTime = lifeTime;
          this.particleDuration = lifeTime;
      }
      set position(point) {
          point.z = 5;
          this.nodeTranfrom.position = point;
      }
      followFguiNode(camera, node, isFollowFguiNode = true, followOffsetX = 0, followOffsetY = 0) {
          this.nodeFgui = node;
          node.displayObject.pivotX = node.pivotX;
          node.displayObject.pivotY = node.pivotY;
          this.followNode2d(camera, node.displayObject, null, null, isFollowFguiNode, followOffsetX, followOffsetY);
      }
      bindAgentNode2d(node) {
          this.node2dAgent = node;
      }
      clearAgentNode2d() {
          if (this.node2dAgent && !this.node2dAgent.destroyed) {
              this.node2dAgent.destroy();
          }
          this.node2dAgent = null;
      }
      followNode2d(camera, node, node2drotation = null, node2dscale = null, isFollowFguiNode = true, followOffsetX = 0, followOffsetY = 0) {
          this.followOffsetX = followOffsetX || 0;
          this.followOffsetY = followOffsetY || 0;
          this.camera = camera;
          this.node2d = node;
          this.node2drotation = node2drotation;
          this.node2dscale = node2dscale || node;
          this.pointNodeFgui = new Laya.Vector2;
          this.pointTemp = new Laya.Point;
          this.updateFollowNode2d();
          this.isFollowFguiNode = isFollowFguiNode;
      }
      setPosFguiNode(camera, node, offsetx = 0, offsety = 0) {
          this.setPosNode2d(camera, node.displayObject, offsetx, offsety);
      }
      setPosFguiNodePivot(camera, node) {
          let offsetx = node.width * node.pivotX * node.scaleX;
          let offsety = node.height * node.pivotY * node.scaleY;
          this.setPosNode2d(camera, node.displayObject, offsetx, offsety);
      }
      setPosFguiNodeCenter(camera, node) {
          let offsetx = node.width * 0.5 * node.scaleX;
          let offsety = node.height * 0.5 * node.scaleY;
          this.setPosNode2d(camera, node.displayObject, offsetx, offsety);
      }
      setPosNode2d(camera, node, offsetx = 0, offsety = 0) {
          this.camera = camera;
          this.pointTemp = new Laya.Point;
          this.pointNodeFgui = new Laya.Vector2;
          this.pointTemp = node.localToGlobal(this.pointTemp);
          this.pointTemp.x += offsetx;
          this.pointTemp.y += offsety;
          this.pointTemp.x *= Laya.stage.clientScaleX;
          this.pointTemp.y *= Laya.stage.clientScaleY;
          this.pointNodeFgui.x = this.pointTemp.x;
          this.pointNodeFgui.y = this.pointTemp.y;
          this.camera.viewportPointToRay(this.pointNodeFgui, Effect.rayByScreen);
          ;
          this.position = Effect.rayByScreen.origin;
      }
      setPos2d(camera, pointTemp) {
          this.camera = camera;
          let x = pointTemp.x * Laya.stage.clientScaleX;
          let y = pointTemp.y * Laya.stage.clientScaleY;
          this.pointNodeFgui = new Laya.Vector2;
          this.pointNodeFgui.x = x;
          this.pointNodeFgui.y = y;
          this.camera.viewportPointToRay(this.pointNodeFgui, Effect.rayByScreen);
          this.position = Effect.rayByScreen.origin;
      }
      lookAt(dx, dy, offset = 90) {
          let degree = Utils.vectorToDegree(dx, dy);
          this.nodeTranfrom.localRotationEulerZ = -(degree + offset + 90);
      }
      setDegree(degree, offset = 90) {
          this.nodeTranfrom.localRotationEulerZ = -(degree + offset + 90);
      }
      updateFollowNode2d() {
          if (!this.node2d || this.node2d.destroyed) {
              this.remove();
              return;
          }
          if (this.resNode) {
              if (this.nodeFgui) {
                  this.resNode.active = this.nodeFgui.visible && this.nodeFgui.internalVisible;
              }
              else {
                  this.resNode.active = this.node2d.visible;
              }
              if (!this.resNode.active) {
                  return;
              }
          }
          if (!this.nodeTranfrom)
              return;
          this.pointTemp.x = this.followOffsetX;
          this.pointTemp.y = this.followOffsetY;
          this.node2d.localToGlobal(this.pointTemp);
          this.pointTemp.x += this.node2d.width * this.node2d.pivotX;
          this.pointTemp.y += this.node2d.height * this.node2d.pivotY;
          this.pointTemp.x *= Laya.stage.clientScaleX;
          this.pointTemp.y *= Laya.stage.clientScaleY;
          this.pointNodeFgui.x = this.pointTemp.x;
          this.pointNodeFgui.y = this.pointTemp.y;
          this.camera.viewportPointToRay(this.pointNodeFgui, Effect.rayByScreen);
          if (this.node2dscale) {
              let scale = this.effectScale * this.node2dscale.globalScaleX;
              this.nodeTranfrom.localScaleX = scale;
              this.nodeTranfrom.localScaleY = scale;
              this.nodeTranfrom.localScaleZ = scale;
          }
          if (this.node2drotation) {
              this.nodeTranfrom.localRotationEulerZ = -(this.node2drotation.rotation);
          }
          this.position = Effect.rayByScreen.origin;
      }
      parseShurikenParticle(resNode) {
          let particleSystem = this.findFirstShurikenParticleSystem(resNode);
          if (particleSystem) {
              this.particleLooping = particleSystem.looping;
              this.particleDuration = particleSystem.duration;
              if (!this.particleLooping && this.particleDuration <= 0) {
                  this.particleLooping = true;
                  console.error("特效不循环，但是时间为0", this.effectId, particleSystem.looping, particleSystem.duration);
              }
          }
      }
      calcCountShurikenParticleSystem(node) {
          let count = 0;
          if (node instanceof Laya.ShuriKenParticle3D) {
              count += 1;
          }
          for (var i = node.numChildren - 1; i >= 0; i--) {
              count += this.calcCountShurikenParticleSystem(node.getChildAt(i));
          }
          return count;
      }
      findFirstShurikenParticleSystem(node) {
          if (node instanceof Laya.ShuriKenParticle3D) {
              return node.particleSystem;
          }
          for (var i = node.numChildren - 1; i >= 0; i--) {
              var child = node.getChildAt(i);
              if (child instanceof Laya.ShuriKenParticle3D) {
                  return child.particleSystem;
              }
              return this.findFirstShurikenParticleSystem(child);
          }
          return null;
      }
      onUpdate() {
          if (this.particleLooping) {
              if (this.lifeTime) {
                  this.passTime += GameConst.FrameDeltaTime;
                  if (this.passTime >= this.lifeTime) {
                      this.passTime = 0;
                      this.onTimeEnd();
                  }
              }
          }
          else {
              this.passTime += GameConst.FrameDeltaTime;
              if (this.passTime >= this.particleDuration || (this.lifeTime && this.passTime >= this.lifeTime)) {
                  this.passTime = 0;
                  this.onTimeEnd();
              }
          }
          if (this.isFollowFguiNode) {
              this.updateFollowNode2d();
          }
      }
      onTimeEnd() {
          if (this.autoRecover)
              this.recover();
          else
              this.remove();
      }
      scale(effectScale, keepOrigin = false) {
          if (effectScale) {
              let localScale = this.nodeTranfrom.localScale;
              if (!keepOrigin) {
                  localScale.x = 1;
                  localScale.y = 1;
                  localScale.z = 1;
              }
              Laya.Vector3.scale(localScale, effectScale, localScale);
              this.nodeTranfrom.localScale = localScale;
          }
      }
      clear() {
          if (this.autoRecover)
              this.recover();
          else
              this.remove();
      }
      remove() {
          this.clearAgentNode2d();
          if (this.owner) {
              this.owner.destroy();
          }
      }
      recover() {
          if (this.owner == null)
              return;
          this.reset();
          this.owner.removeSelf();
          EffectFactory.putItem(this.poolKey, this.owner);
      }
      reset() {
          this.stop();
          this.isFollowFguiNode = false;
          this.node2d = null;
          if (this.tween) {
              this.tween.clear();
              this.tween = null;
          }
          this.clearAgentNode2d();
      }
      getTween() {
          if (this.tween == null) {
              this.tween = new Laya.Tween();
          }
          return this.tween;
      }
      onDestroy() {
          Effect._count_effect_--;
          this.reset();
      }
  }
  Effect._count_effect_ = 0;
  Effect.rayByScreen = new Laya.Ray(new Laya.Vector3(), new Laya.Vector3());
  class Effect2D extends Laya.Script {
      constructor() {
          super(...arguments);
          this.passTime = 0;
          this.lifeTime = 0;
          this.effectId = "";
          this.effectDb = null;
          this.autoRecover = false;
          this.lineOffsetX = 0;
          this.lineOffsetY = 0;
          this.followOffsetX = 0;
          this.followOffsetY = 0;
      }
      ;
      onAwake() {
      }
      setData(data, timeScale = 1) {
          this.effectDb = data;
          this.autoRecover = data.autoRecover;
          this.passTime = 0;
          this.lifeTime = data.time / timeScale;
          this.play();
      }
      setLifeTime(lifeTime) {
          this.lifeTime = lifeTime;
      }
      loadRes(path) {
          LoaderHelper.createSpriteWithLoad(path, this, this.onResLoad);
      }
      onResLoad(resNode) {
          if (!resNode)
              return;
          if (!this.owner || this.destroyed) {
              resNode.destroy();
              return;
          }
          let first = resNode.getChildAt(0);
          if (first instanceof Laya.Animation) {
              this.animation = first;
              this.play();
          }
          this.owner.addChild(resNode);
      }
      play() {
          if (this.effectDb && this.animation) {
              this.animation.interval = 1000 / this.effectDb.frame;
              this.animation.play(0, false, this.effectDb.anim);
          }
      }
      onUpdate() {
          if (this.lifeTime) {
              this.passTime += GameConst.FrameDeltaTime;
              if (this.passTime >= this.lifeTime) {
                  this.passTime = 0;
                  this.onTimeEnd();
              }
          }
          this.updateFollow();
          this.updateLine();
      }
      updateFollow() {
          if (this.node && this.nodeFollow && !this.nodeFollow.destroyed) {
              this.node.x = this.nodeFollow.x + this.followOffsetX;
              this.node.y = this.nodeFollow.y + this.followOffsetY;
          }
      }
      updateLine() {
      }
      lineNode(node, offsetx = 0, offsety = 0) {
          this.nodeLine = node;
          this.lineOffsetX = offsetx;
          this.lineOffsetY = offsety;
      }
      followNode(node, offsetx = 0, offsety = 0) {
          this.nodeFollow = node;
          this.followOffsetX = offsetx;
          this.followOffsetY = offsety;
      }
      onTimeEnd() {
          if (this.autoRecover)
              this.recover();
          else
              this.remove();
      }
      remove() {
          if (this.owner) {
              this.owner.destroy();
          }
      }
      recover() {
          if (this.owner == null)
              return;
          this.reset();
          this.owner.removeSelf();
          EffectFactory.putItem(this.poolKey, this.owner);
      }
      reset() {
      }
  }
  class EffectFgui extends Effect2D {
      constructor() {
          super(...arguments);
          this.passTime = 0;
          this.lifeTime = 0;
          this.effectId = "";
          this.effectDb = null;
          this._timeScale = 1;
          this.autoRecover = false;
          this.moffsetx = 0;
          this.moffsety = 0;
          this.bodyOriginWidth = 0;
      }
      ;
      onAwake() {
      }
      onUse(timeScale = 1) {
          this.timeScale(timeScale);
      }
      timeScale(speed) {
          if (this._timeScale != speed) {
              this._timeScale = speed;
              this.changePlaySpeed(this.resNode, speed);
          }
      }
      setData(data, timeScale = 1) {
          this.effectDb = data;
          this.autoRecover = data.autoRecover;
          this.passTime = 0;
          this.lifeTime = data.time / timeScale;
          this.play();
      }
      setLifeTime(lifeTime) {
          this.lifeTime = lifeTime;
      }
      loadRes(path, timeScale = 1) {
          let res = fgui.UIPackage.createObjectFromURL(path);
          if (res) {
              this.onResLoad(res.asCom, timeScale);
          }
          else {
              let pkgReg = /ui:\/\/(\S+)\//img;
              let result = pkgReg.exec(path);
              if (result) {
                  let pkgName = result[1];
                  fgui.UIPackage.loadPackage(`res/fgui/${pkgName}`, Laya.Handler.create(this, () => {
                      let res = fgui.UIPackage.createObjectFromURL(path);
                      if (res)
                          this.onResLoad(res.asCom, timeScale);
                  }));
                  return;
              }
          }
      }
      updateLine() {
          if (this.node && this.body && this.nodeLine && !this.nodeLine.destroyed) {
              let dx = this.nodeLine.x + this.lineOffsetX - this.node.x;
              let dy = this.nodeLine.y + this.lineOffsetY - this.node.y;
              let distance = Math.sqrt(dx * dx + dy * dy) / this.node.globalScaleX;
              this.body.scaleX = distance / this.bodyOriginWidth;
              let degree = Utils.vectorToDegree(dx, dy);
              this.node.rotation = degree;
          }
      }
      onResLoad(resNode, timeScale = 1) {
          if (!resNode)
              return;
          if (!this.owner || this.destroyed) {
              resNode.dispose();
              return;
          }
          this.movieClip = [];
          this.comBottom = [];
          this.transIn = resNode.getTransition("in") || resNode.getTransition("t0");
          this.transOut = resNode.getTransition("out");
          if (this.transOut)
              this.transOut.stop();
          this.body = resNode.getChild("body");
          if (this.body) {
              this.bodyOriginWidth = this.body.width;
          }
          this.parseLayer(resNode);
          this.ready();
          this.owner.addChild(resNode.displayObject);
          this.resNode = resNode;
          this.onUse(timeScale);
      }
      changePlaySpeed(node, speed = 1) {
          if (!node)
              return;
          if (node instanceof fgui.GMovieClip) {
              node.timeScale = speed;
          }
          if (node._transitions) {
              for (let i = 0; i < node._transitions.length; i++) {
                  let trans = node.getTransitionAt(i);
                  trans.timeScale = speed;
              }
          }
          for (let i = 0; i < node.numChildren; i++) {
              this.changePlaySpeed(node.getChildAt(i), speed);
          }
      }
      parseLayer(resNode) {
          for (let i = 0; i < resNode.numChildren; i++) {
              let child = resNode.getChildAt(i);
              if (child.name.startsWith("bottom")) {
                  this.comBottom.push({ object: child.asCom, x: child.x, y: child.y, scaleX: child.scaleX, scaleY: child.scaleY });
              }
              if (child instanceof fgui.GMovieClip) {
                  if (this.effectDb) {
                      child.setPlaySettings(0, -1, this.effectDb.loop_time);
                  }
                  else {
                      child.setPlaySettings(0, -1, 1);
                  }
                  this.movieClip.push(child);
              }
          }
      }
      onBulletEnd(bullet) {
          if (bullet.isDisposed)
              return;
          bullet.dispose();
      }
      play() {
          if (this.effectDb && this.movieClip) {
              for (let clip of this.movieClip) {
                  clip.setPlaySettings(0, -1, this.effectDb.loop_time);
              }
          }
      }
      onTimeEnd() {
          if (this.transOut) {
              if (this.transIn)
                  this.transIn.stop();
              this.transOut.play(Laya.Handler.create(this, super.onTimeEnd));
          }
          else {
              super.onTimeEnd();
          }
      }
      ready() {
          if (EffectFactory.layerBottom && this.comBottom) {
              for (let item of this.comBottom) {
                  EffectFactory.layerBottom.addChild(item.object.displayObject);
                  let node = this.owner;
                  item.object.x = node.x + item.x;
                  item.object.y = node.y + item.y;
                  item.object.scaleX = item.scaleX * node.scaleX;
                  item.object.scaleY = item.scaleY * node.scaleY;
              }
          }
      }
      remove() {
          if (this.comBottom) {
              for (let item of this.comBottom) {
                  item.object.displayObject.destroy();
              }
              this.comBottom = [];
          }
          if (this.owner) {
              this.owner.destroy();
          }
      }
      recover() {
          if (this.owner == null)
              return;
          this.reset();
          this.owner.removeSelf();
          if (this.comBottom) {
              for (let item of this.comBottom) {
                  this.owner.addChild(item.object.displayObject);
              }
          }
          EffectFactory.putItem(this.poolKey, this.owner);
      }
      reset() {
          this.nodeFollow = null;
      }
  }
  class EffectSpine extends Effect2D {
      constructor() {
          super(...arguments);
          this.passTime = 0;
          this.lifeTime = 0;
          this.effectId = "";
          this.effectDb = null;
          this._timeScale = 1;
          this.autoRecover = false;
          this.moffsetx = 0;
          this.moffsety = 0;
      }
      ;
      onAwake() {
      }
      onUse(timeScale = 1) {
          this.timeScale(timeScale);
      }
      timeScale(speed) {
          if (this._timeScale != speed) {
              this._timeScale = speed;
              this.changePlaySpeed(this.resNode, speed);
          }
      }
      changePlaySpeed(node, speed = 1) {
          if (!node)
              return;
          node.playbackRate = speed;
      }
      setData(data, timeScale = 1) {
          this.effectDb = data;
          this.autoRecover = data.autoRecover;
          this.passTime = 0;
          this.lifeTime = data.time / timeScale;
          this.play();
      }
      setLifeTime(lifeTime) {
          this.lifeTime = lifeTime;
      }
      loadRes(path, timeScale = 1) {
          let res = Spine.create(path);
          this.onResLoad(res, timeScale);
      }
      onResLoad(resNode, timeScale = 1) {
          if (!resNode)
              return;
          if (!this.owner || this.destroyed) {
              resNode.destroy();
              return;
          }
          this.owner.addChild(resNode);
          this.resNode = resNode;
          this.onUse(timeScale);
          this.play();
      }
      play() {
          if (this.resNode) {
              this.resNode.playAnimation("skill02", false);
          }
      }
      onBulletEnd(bullet) {
          if (bullet.isDisposed)
              return;
          bullet.dispose();
      }
      remove() {
          if (this.owner) {
              this.owner.destroy();
          }
      }
      recover() {
          if (this.owner == null)
              return;
          this.reset();
          this.owner.removeSelf();
          EffectFactory.putItem(this.poolKey, this.owner);
      }
      reset() {
          this.nodeFollow = null;
      }
  }
  class EffectFactory {
      static init() {
          FguiEffect.setEffectCreater(this.createEffectForFgui.bind(this));
          FguiEffect.setEffectDestroy(this.destroyEffectForFgui.bind(this));
      }
      static createEffectForFgui(node, root) {
          let effectName = node.guiNode.data;
          if (!effectName) {
              console.error("EffectFactory.createEffectForFgui is null", node.guiNode.name);
              return;
          }
          let effect = null;
          if (root instanceof PanelBase3D) {
              root.createScene3DEffect();
              effect = this.create(effectName, root.scene3DEffect);
              if (effect) {
                  effect.followFguiNode(root.cameraEffect, node.guiNode);
              }
          }
          else {
              let data = Director.getScene3DLayer(3);
              if (data) {
                  effect = this.create(effectName, data.scene3d);
                  if (effect) {
                      effect.followFguiNode(data.camera, node.guiNode);
                  }
              }
              else {
                  console.error("FguiEffect.createEffectForFgui: not found Scene3D layer", node.guiNode.name, effectName);
              }
          }
          return effect;
      }
      static destroyEffectForFgui(node, effect) {
          if (effect && !effect.destroyed) {
              effect.clear();
          }
      }
      static preload(loader, effectId) {
          let effectDb = db.get_effect_db(effectId);
          if (effectDb) {
              let modelDb = db.get_model_db(effectDb.model);
              if (modelDb) {
                  loader.addRes(modelDb.resPath, RES_TYPE.PREFAB3D);
              }
          }
      }
      static createByLayer(effectId, layer, position, direction, scale) {
          let sceneData = Director.getScene3DLayer(layer);
          if (sceneData) {
              return this.create(effectId, sceneData.scene3d, position, direction, scale);
          }
          else {
              return this.create(effectId, null, position, direction, scale);
          }
      }
      static create(effectId, parent, position, direction, scale, timeScale = 1) {
          if (!effectId)
              return;
          let modelID = effectId;
          let modelScale = 1;
          let effectDb = db.get_effect_db_map()[effectId];
          if (effectDb) {
              modelID = effectDb.model;
              modelScale = effectDb.scale;
          }
          else {
          }
          let modelDb = db.get_model_db(modelID);
          if (!modelDb) {
              console.error("EffectFactory.create model db not found", modelID);
              return;
          }
          let effect = this.getItem3D(modelID, modelDb.resPath, timeScale);
          if (effect) {
              effect.effectId = effectId;
              if (effectDb) {
                  effect.setData(effectDb, timeScale);
              }
              let node = effect.owner;
              if (parent) {
                  parent.addChild(node);
              }
              else if (this.scene3d) {
                  this.scene3d.addChild(node);
              }
              if (position) {
                  node.transform.position = position;
              }
              if (direction) {
                  Utils.zLookAtDrection(effect.getNode().transform, direction, GameConst.GLOBAL_UP);
              }
              let effectScale = modelScale;
              if (scale) {
                  effectScale = effectScale * scale;
              }
              if (effectScale) {
                  let localScale = node.transform.localScale;
                  localScale.x = effectScale;
                  localScale.y = effectScale;
                  localScale.z = effectScale;
                  node.transform.localScale = localScale;
                  effect.effectScale = effectScale;
              }
              return effect;
          }
      }
      static create2d(effectId, timeScale = 1) {
          if (!effectId)
              return;
          let modelID = effectId;
          let modelScale = 1;
          let effectDb = db.get_effect_db_map()[effectId];
          if (effectDb) {
              modelID = effectDb.model;
              modelScale = effectDb.scale;
          }
          else {
          }
          let effect = this.getItem2D(modelID, modelID);
          if (effect) {
              effect.effectId = effectId;
              if (effectDb) {
                  effect.setData(effectDb);
              }
              let node = effect.owner;
              effect.node = node;
              if (modelScale)
                  node.scale(modelScale, modelScale);
              return effect;
          }
      }
      static createFgui(effectId, timeScale = 1) {
          if (!effectId)
              return;
          let modelID = effectId;
          let modelScale = 1;
          let effectDb = db.get_effect_db_map()[effectId];
          if (effectDb) {
              modelID = effectDb.model;
              modelScale = effectDb.scale;
          }
          else {
          }
          let effect = this.getItemFgui(modelID, modelID, timeScale);
          if (effect) {
              effect.effectId = effectId;
              if (effectDb) {
                  effect.setData(effectDb, timeScale);
              }
              let node = effect.owner;
              effect.node = node;
              if (modelScale)
                  node.scale(modelScale, modelScale);
              return effect;
          }
      }
      static createSpine(effectId, timeScale = 1) {
          if (!effectId)
              return;
          let modelID = effectId;
          let modelScale = 1;
          let effectDb = db.get_effect_db_map()[effectId];
          if (effectDb) {
              modelID = effectDb.model;
              modelScale = effectDb.scale;
          }
          else {
          }
          let effect = this.getItemSpine(modelID, modelID, timeScale);
          if (effect) {
              effect.effectId = effectId;
              if (effectDb) {
                  effect.setData(effectDb, timeScale);
              }
              let node = effect.owner;
              effect.node = node;
              if (modelScale)
                  node.scale(modelScale, modelScale);
              return effect;
          }
      }
      static createByType(id, parent, node, time, scale, offsetx = 0, offsety = 0, node2dscale = null, timeScale = null) {
          return this.createByTypeByDB(db.get_effect_db_map()[id], parent, node, time, scale, offsetx, offsety, node2dscale, timeScale);
      }
      static createByTypeAndHeight(id, node, time, scale, height = 0) {
          let effectDb = db.get_effect_db_map()[id];
          if (effectDb) {
              let parent = this.layerFront;
              if (effectDb.is_bottom) {
                  parent = this.layerBottom;
              }
              return this.createByTypeByDB(effectDb, parent, node, time, scale, 0, height * effectDb.offset);
          }
      }
      static createByTypeByDB(effectDb, parent, node, time, scale, offsetx = 0, offsety = 0, node2dscale = null, timeScale = null) {
          timeScale = timeScale || StageConfig.gameTimeScale;
          let nodeRet;
          if (effectDb) {
              let id = effectDb.id;
              switch (effectDb.type) {
                  case "2d": {
                      let effect = EffectFactory.create2d(id, timeScale);
                      if (effect) {
                          parent.addChild(effect.node);
                          effect.node.x = node.x + offsetx;
                          effect.node.y = node.y + offsety;
                          nodeRet = effect;
                          if (effectDb.follow) {
                              effect.followNode(node, offsetx, offsety);
                          }
                      }
                      break;
                  }
                  case "fgui": {
                      let effect = EffectFactory.createFgui(id, timeScale);
                      if (effect) {
                          parent.addChild(effect.node);
                          effect.node.x = node.x + offsetx;
                          effect.node.y = node.y + offsety;
                          if (scale)
                              effect.node.scale(scale, scale);
                          if (time) {
                              effect.setLifeTime(time);
                          }
                          effect.ready();
                          nodeRet = effect;
                          if (effectDb.line) {
                              effect.lineNode(node, offsetx, offsety);
                          }
                          else if (effectDb.follow) {
                              if (effectDb.init_rand_pos) {
                                  let range = 256;
                                  effect.node.x = node.x + Utils.random(-range, range);
                                  effect.node.y = node.y + Utils.random(-range, range);
                                  let follow = effect.node.addComponent(FollowTarget2D);
                                  time = time || effectDb.time;
                                  follow.followTarget(time, node);
                              }
                              else {
                                  effect.followNode(node, offsetx, offsety);
                              }
                          }
                      }
                      break;
                  }
                  case "spine": {
                      let effect = EffectFactory.createSpine(id, timeScale);
                      if (effect) {
                          parent.addChild(effect.node);
                          effect.node.x = node.x + offsetx;
                          effect.node.y = node.y + offsety;
                          if (scale)
                              effect.node.scale(scale, scale);
                          if (time) {
                              effect.setLifeTime(time);
                          }
                          nodeRet = effect;
                      }
                      break;
                  }
                  default: {
                      let data = Director.getScene3DLayer(1);
                      let effect = EffectFactory.create(id, data.scene3d, null, null, scale, timeScale);
                      let nodeFollow = new Laya.Sprite;
                      parent.addChild(nodeFollow);
                      nodeFollow.x = node.x + offsetx;
                      nodeFollow.y = node.y + offsety;
                      effect.bindAgentNode2d(nodeFollow);
                      effect.followNode2d(data.camera, nodeFollow, nodeFollow, node2dscale);
                      if (time) {
                          effect.setLifeTime(time);
                      }
                      nodeRet = effect;
                      break;
                  }
              }
          }
          return nodeRet;
      }
      static cache(effectId) {
          let effectDb = db.get_effect_db(effectId);
          if (effectDb) {
              let effect = this.getItem3D(effectDb.model, db.get_model_db(effectDb.model).resPath);
              if (effect) {
                  effect.setData(effectDb);
                  effect.recover();
              }
          }
      }
      static setScene3d(scene3d) {
          this.scene3d = scene3d;
      }
      static setCamera(camera) {
          this.camera = camera;
      }
      static getItem3D(id, resPath, timeScale = 1) {
          let poolKey = EffectFactory.POOL_KEY_PRE + id;
          let sprite = Laya.Pool.getItem(poolKey);
          let effect = null;
          if (sprite) {
              effect = sprite.getComponent(Effect);
              if (effect) {
                  effect.getNode();
                  effect.onUse(timeScale);
              }
          }
          else {
              sprite = new Laya.Sprite3D();
              effect = sprite.addComponent(Effect);
              effect.getNode();
              effect.loadRes(resPath, timeScale);
          }
          if (effect)
              effect.poolKey = poolKey;
          return effect;
      }
      static getItem2D(id, resPath) {
          let poolKey = EffectFactory.POOL_KEY_PRE + id;
          let sprite = Laya.Pool.getItem(poolKey);
          let effect = null;
          if (sprite) {
              effect = sprite.getComponent(Effect2D);
          }
          else {
              sprite = LoaderHelper.createSprite(resPath);
              let needLoad = false;
              if (!sprite) {
                  sprite = new Laya.Sprite();
                  needLoad = true;
              }
              effect = sprite.addComponent(Effect2D);
              if (needLoad) {
                  effect.loadRes(resPath);
              }
          }
          if (effect)
              effect.poolKey = poolKey;
          return effect;
      }
      static getItemFgui(id, resPath, timeScale = 1) {
          let poolKey = EffectFactory.POOL_KEY_PRE + id;
          let sprite = Laya.Pool.getItem(poolKey);
          let effect = null;
          if (sprite) {
              effect = sprite.getComponent(EffectFgui);
              if (effect) {
                  effect.onUse(timeScale);
              }
          }
          else {
              let nodeFgui = fgui.UIPackage.createObjectFromURL(resPath);
              if (nodeFgui) {
                  sprite = nodeFgui.displayObject;
              }
              let needLoad = false;
              if (!sprite) {
                  sprite = new Laya.Sprite();
                  needLoad = true;
              }
              effect = sprite.addComponent(EffectFgui);
              if (needLoad) {
                  effect.loadRes(resPath, timeScale);
              }
              else {
                  effect.onResLoad(nodeFgui, timeScale);
              }
          }
          if (effect)
              effect.poolKey = poolKey;
          return effect;
      }
      static getItemSpine(id, resPath, timeScale = 1) {
          let poolKey = EffectFactory.POOL_KEY_PRE + id;
          let sprite = Laya.Pool.getItem(poolKey);
          let effect = null;
          if (sprite) {
              effect = sprite.getComponent(EffectSpine);
              effect.onUse(timeScale);
          }
          else {
              sprite = new Laya.Sprite();
              effect = sprite.addComponent(EffectSpine);
              effect.loadRes(resPath, timeScale);
          }
          if (effect)
              effect.poolKey = poolKey;
          return effect;
      }
      static putItem(key, obj) {
          Laya.Pool.recover(key, obj);
      }
      static prepare() {
          if (this.isPrepare)
              return;
          this.isPrepare = true;
          let effectDb = db.get_effect_db_map();
          for (let key in effectDb) {
              let effect = effectDb[key];
              for (let i = 0; i < effect.cache; i++) {
                  EffectFactory.cache(key);
              }
          }
      }
      static setLayer2D(front, bottom) {
          this.layerFront = front;
          this.layerBottom = bottom;
      }
  }
  EffectFactory.POOL_KEY_PRE = "EFFECT_";
  EffectFactory.isPrepare = false;

  var GUIDE_STATE;
  (function (GUIDE_STATE) {
      GUIDE_STATE[GUIDE_STATE["STATE_NONE"] = 0] = "STATE_NONE";
      GUIDE_STATE[GUIDE_STATE["STATE_CLICK"] = 1] = "STATE_CLICK";
      GUIDE_STATE[GUIDE_STATE["STATE_DRAG"] = 2] = "STATE_DRAG";
      GUIDE_STATE[GUIDE_STATE["STATE_DIALOG_R"] = 3] = "STATE_DIALOG_R";
      GUIDE_STATE[GUIDE_STATE["STATE_CLICK_FREE"] = 4] = "STATE_CLICK_FREE";
      GUIDE_STATE[GUIDE_STATE["STATE_SOLO"] = 5] = "STATE_SOLO";
      GUIDE_STATE[GUIDE_STATE["STATE_INTRO"] = 6] = "STATE_INTRO";
      GUIDE_STATE[GUIDE_STATE["STATE_DIALOG_L"] = 7] = "STATE_DIALOG_L";
      GUIDE_STATE[GUIDE_STATE["STATE_CLICK_ENEMY"] = 8] = "STATE_CLICK_ENEMY";
      GUIDE_STATE[GUIDE_STATE["STATE_CLICK_SLOT"] = 9] = "STATE_CLICK_SLOT";
      GUIDE_STATE[GUIDE_STATE["STATE_DRAG_TOWER"] = 10] = "STATE_DRAG_TOWER";
      GUIDE_STATE[GUIDE_STATE["STATE_CLICK_TOWER"] = 11] = "STATE_CLICK_TOWER";
  })(GUIDE_STATE || (GUIDE_STATE = {}));
  class PanelGuide extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/PanelGuide";
          this.panelLayer = 4;
          this.panelStyle = 1;
          this.bMask = false;
          this.skipCount = 0;
          this.isNeedUpdeate = false;
          this.guideMode = GUIDE_STATE.STATE_NONE;
          this.timeAtkCast = 0;
          this.pointTemp = new Laya.Point;
          this.exportNodeNames = {
              cc_guide: "fgui.GComponent",
              cc_click_mask: "fgui.GComponent",
              cc_hole: "fgui.GGraph",
              cc_dialog_mask: "fgui.GComponent",
              cc_click_finger: "fgui.GComponent",
              cc_intro: "fgui.GComponent",
              cc_label_intro: "fgui.GBasicTextField",
              cc_dialog_r: "CustomGuideDialogRight",
              cc_dialog_l: "CustomGuideDialogLeft",
              cc_tip: "fgui.GComponent",
              cc_img_tip: "fgui.GImage",
              cc_label_tip: "fgui.GBasicTextField",
              cc_skip: "fgui.GLoader",
              cc_drag_finger: "fgui.GLoader",
              cc_label_solo: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.ctrlState = this.guide.getController("state");
          this.ctrlMask = this.guide.getController("mask");
          this.tweenDrag = new Laya.Tween();
          if (this.context) {
              this.updateGuide(this.context);
          }
          this.click_mask.onClick(this, this.onClickMask);
          this.dialog_mask.onClick(this, this.onClickMask);
          this.hole.onClick(this, this.onClickHole);
          this.initEvent();
          this.skipCount = 0;
          this.skip.onClick(this, this.onClickSkip);
      }
      onClickSkip() {
          this.skipCount++;
          if (this.skipCount >= 10) {
              mgrGuide.skipGuide();
          }
      }
      initTimer() {
          Laya.timer.frameLoop(1, this, this.onUpdate);
      }
      onUpdate() {
          if (this.isNeedUpdeate) {
              switch (this.guideMode) {
                  case GUIDE_STATE.STATE_CLICK:
                      if (this.guideData && this.currenGuide) {
                          this.showClickFingerWithNode(this.guideData.node, this.currenGuide);
                      }
                      break;
                  case GUIDE_STATE.STATE_DRAG:
                      break;
                  case GUIDE_STATE.STATE_DIALOG_R:
                      break;
                  case GUIDE_STATE.STATE_CLICK_FREE:
                      break;
                  case GUIDE_STATE.STATE_CLICK_ENEMY:
                      this.showClickFingerWithEnemy(this.currenGuide);
                      break;
              }
          }
      }
      clearTween() {
          if (this.tweenDrag) {
              this.tweenDrag.clear();
          }
      }
      clearTimer() {
          Laya.timer.clearAll(this);
      }
      updateGuide(data) {
          this.clearTimer();
          this.clearTween();
          this.initTimer();
          this.isNeedUpdeate = false;
          let guide = data.guide;
          let panel = data.panel;
          if (panel) {
              this.visible = panel.visible;
          }
          this.currenGuide = guide;
          if (guide.delay) {
              this.ctrlState.selectedIndex = GUIDE_STATE.STATE_NONE;
              Laya.timer.once(guide.delay * 1000, this, this.updateGuideSub, [data, guide]);
          }
          else {
              this.updateGuideSub(data, guide);
          }
      }
      updateGuideSub(data, guide) {
          this.guideData = data;
          this.guideMode = data.mode;
          this.clearHoleEffect();
          switch (this.guideMode) {
              case GUIDE_STATE.STATE_CLICK:
                  this.isNeedUpdeate = true;
                  this.showClickFingerWithNode(data.node, guide);
                  break;
              case GUIDE_STATE.STATE_DRAG:
                  this.showDragFingerWithNode(data.nodeFrom, data.nodeTo, guide);
                  break;
              case GUIDE_STATE.STATE_DRAG_TOWER:
                  this.showDragFingerWithTower(data.nodeFrom, guide);
                  break;
              case GUIDE_STATE.STATE_DIALOG_R:
                  this.showDialogRight(guide);
                  break;
              case GUIDE_STATE.STATE_DIALOG_L:
                  this.showDialogLeft(guide);
                  break;
              case GUIDE_STATE.STATE_CLICK_FREE:
                  this.showClickFingerFreeWithNode(data.node, guide);
                  break;
              case GUIDE_STATE.STATE_SOLO:
                  this.showSolo(data.node, guide);
                  break;
              case GUIDE_STATE.STATE_INTRO:
                  this.showIntro(data.node, guide);
                  break;
              case GUIDE_STATE.STATE_CLICK_ENEMY:
                  this.isNeedUpdeate = true;
                  this.showClickFingerWithEnemy(guide);
                  break;
              case GUIDE_STATE.STATE_CLICK_SLOT:
                  this.showClickFingerWithSlot(guide);
                  break;
              case GUIDE_STATE.STATE_CLICK_TOWER:
                  let node = Level.stage.findTowerAny();
                  this.showClickFingerWithSprite(node, guide);
                  break;
          }
          this.updateGuideMask(guide);
      }
      updateGuideMask(guide) {
          this.ctrlMask.selectedIndex = guide.mask;
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.GUIDE_CLOSE_PANEL]: this.onGuideClosePanel.bind(this),
              [MSG.GUIDE_UPDATE]: this.onGuideUpdate.bind(this),
              [MSG.GUIDE_COMPLETE]: this.onGuideComplete.bind(this),
              [MSG.SLOT_UNLOCK]: this.onSlotUnlock.bind(this),
              [MSG.TOWER_OPTION_SHOW]: this.onTowerOptionShow.bind(this),
          });
      }
      isClickTooFast(time = 500) {
          let curtTime = Utils.getTime();
          if (this.timeAtkCast) {
              let passTime = curtTime - this.timeAtkCast;
              if (passTime < time) {
                  console.log("点击太快了");
                  return true;
              }
          }
          this.timeAtkCast = curtTime;
          return false;
      }
      onClickMask(e) {
          if (this.isClickTooFast())
              return;
          switch (this.guideMode) {
              case GUIDE_STATE.STATE_CLICK:
                  break;
              case GUIDE_STATE.STATE_DRAG:
                  break;
              case GUIDE_STATE.STATE_DIALOG_R:
              case GUIDE_STATE.STATE_DIALOG_L:
                  if (this.dialog_l.isShowing()) {
                      this.dialog_l.showNow();
                      return;
                  }
                  if (this.dialog_r.isShowing()) {
                      this.dialog_r.showNow();
                      return;
                  }
                  this.completeGuide();
                  break;
              case GUIDE_STATE.STATE_CLICK_FREE:
                  break;
              case GUIDE_STATE.STATE_SOLO:
                  this.completeGuide();
                  break;
              case GUIDE_STATE.STATE_INTRO:
                  break;
          }
      }
      onClickHole(e) {
          console.log("O_O Guide.onClickHole", e);
      }
      dispose() {
          this.clearHoleEffect();
          this.unloadSpine();
          this.clearTimer();
          super.dispose();
      }
      unloadSpine() {
          if (this.spineAvatar) {
              this.spineAvatar.destroy();
              this.spineAvatar = null;
          }
      }
      onGuideClosePanel() {
          this.close();
      }
      onGuideUpdate(data) {
          if (data)
              this.updateGuide(data);
      }
      onGuideComplete() {
          this.clearHoleEffect();
      }
      onPanelShow(panel) {
          if (this.currenGuide && panel.sourceName == this.currenGuide.panel) {
              this.show();
          }
      }
      onPanelHide(panel) {
          if (this.currenGuide && panel.sourceName == this.currenGuide.panel) {
              this.hide();
          }
      }
      onSlotUnlock() {
          if (this.guideMode == GUIDE_STATE.STATE_CLICK_SLOT) {
              this.completeGuide();
          }
      }
      onTowerOptionShow() {
          if (this.guideMode == GUIDE_STATE.STATE_CLICK_TOWER) {
              this.completeGuide();
          }
      }
      showClickFingerWithEnemy(guide) {
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let enemy = Level.stage.findEnemyAny();
          if (enemy) {
              this.pointTemp.x = 0;
              this.pointTemp.y = 0;
              let point = enemy.localToGlobal(this.pointTemp);
              let x = point.x + offsetX;
              let y = point.y + offsetY;
              this.showClickFingerWithState(x, y, guide, GUIDE_STATE.STATE_CLICK_ENEMY);
          }
      }
      showClickFingerWithSlot(guide) {
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let slot = Level.stage.findTowerSlotById(2);
          if (slot) {
              this.pointTemp.x = 0;
              this.pointTemp.y = 0;
              let point = slot.node.localToGlobal();
              let x = point.x + offsetX;
              let y = point.y + offsetY;
              this.showClickFingerWithState(x, y, guide, GUIDE_STATE.STATE_CLICK_SLOT);
          }
      }
      showClickFingerWithNode(node, guide) {
          if (!node || node.isDisposed) {
              this.close();
              return;
          }
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let point = node.localToGlobal();
          let x = point.x + offsetX;
          let y = point.y + offsetY;
          if (!node.pivotAsAnchor) {
              x += node.width / 2;
              y += node.height / 2;
          }
          else {
              x -= node.width * node.pivotX;
              y -= node.height * node.pivotY;
              x += node.width / 2;
              y += node.height / 2;
          }
          this.showClickFinger(x, y, guide);
          if (guide.title) {
              this.tip.visible = true;
              this.tip.y = y - node.height;
              this.label_tip.text = guide.title;
              let halfW = UIRoot.canvasWidth / 2;
              if (x <= halfW) {
                  this.img_tip.scaleX = 1;
              }
              else {
                  this.img_tip.scaleX = -1;
              }
          }
          else {
              this.tip.visible = false;
          }
      }
      showClickFingerWithSprite(node, guide) {
          if (!node || node.destroyed) {
              this.close();
              return;
          }
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let pointTemp = this.pointTemp;
          pointTemp.x = 0;
          pointTemp.y = 0;
          let point = node.localToGlobal(pointTemp);
          let x = point.x + offsetX;
          let y = point.y + offsetY;
          this.showClickFingerWithState(x, y, guide, GUIDE_STATE.STATE_CLICK_TOWER);
      }
      showClickFingerFreeWithNode(node, guide) {
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let point = node.localToGlobal();
          let x = point.x + offsetX;
          let y = point.y + offsetY;
          if (!node.pivotAsAnchor) {
              x += node.width / 2;
              y += node.height / 2;
          }
          else {
              x -= node.width * node.pivotX;
              y -= node.height * node.pivotY;
              x += node.width / 2;
              y += node.height / 2;
          }
          this.showClickFingerFree(x, y, guide);
      }
      showSolo(node, guide) {
          this.label_solo.text = guide.title;
          this.ctrlState.setSelectedIndex(GUIDE_STATE.STATE_SOLO);
      }
      showIntro(node, guide) {
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let point = node.localToGlobal();
          let x = point.x;
          let y = point.y;
          if (!node.pivotAsAnchor) {
              x += node.width / 2;
              y += node.height / 2;
          }
          else {
              x -= node.width * node.pivotX;
              y -= node.height * node.pivotY;
              x += node.width / 2;
              y += node.height / 2;
          }
          let holeScale = guide.hole_scale;
          if (holeScale) {
              this.hole.setScale(holeScale, holeScale);
          }
          else {
              this.hole.setScale(1, 1);
          }
          this.hole.x = x;
          this.hole.y = y;
          this.createHoleEffect();
          this.intro.x = x + offsetX;
          this.intro.y = y + offsetY;
          this.label_intro.text = guide.title;
          this.ctrlState.setSelectedIndex(GUIDE_STATE.STATE_INTRO);
      }
      createHoleEffect() {
          let sceneData = Director.getScene3DLayer(5);
          if (!this.holeEffect) {
              this.holeEffect = EffectFactory.create("guide_hole", sceneData.scene3d);
          }
          if (this.holeEffect)
              this.holeEffect.setPosFguiNodeCenter(sceneData.camera, this.hole);
      }
      clearHoleEffect() {
          if (this.holeEffect) {
              this.holeEffect.clear();
              this.holeEffect = null;
          }
      }
      showClickFinger(x, y, guide) {
          this.ctrlState.selectedIndex = GUIDE_STATE.STATE_CLICK;
          this.click_finger.x = x;
          this.click_finger.y = y;
          this.hole.x = x;
          this.hole.y = y;
          let holeScale = guide.hole_scale;
          if (holeScale) {
              this.hole.setScale(holeScale, holeScale);
          }
          else {
              this.hole.setScale(1, 1);
          }
          this.showTip(guide);
      }
      showClickFingerFree(x, y, guide) {
          console.log("O_O showClickFingerFree", x, y);
          this.ctrlState.selectedIndex = GUIDE_STATE.STATE_CLICK_FREE;
          this.click_finger.x = x;
          this.click_finger.y = y;
          this.showTip(guide);
      }
      showClickFingerWithState(x, y, guide, index) {
          console.log("O_O showClickFingerEnemy", x, y);
          this.ctrlState.selectedIndex = index;
          this.click_finger.x = x;
          this.click_finger.y = y;
          this.hole.x = x;
          this.hole.y = y;
          let holeScale = guide.hole_scale;
          if (holeScale) {
              this.hole.setScale(holeScale, holeScale);
          }
          else {
              this.hole.setScale(1, 1);
          }
          this.showTip(guide);
      }
      showTip(guide) {
          if (guide.title) {
              this.label_title.visible = true;
          }
          else {
              this.label_title.visible = false;
          }
          this.label_title.text = guide.title;
      }
      showDragFingerWithNode(nodeFrom, nodeTo, guide) {
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          let point = nodeFrom.localToGlobal();
          let x = point.x + offsetX;
          let y = point.y + offsetY;
          if (!nodeFrom.pivotAsAnchor) {
              x += nodeFrom.width / 2;
              y += nodeFrom.height / 2;
          }
          else {
              x -= nodeFrom.width * nodeFrom.pivotX;
              y -= nodeFrom.height * nodeFrom.pivotY;
              x += nodeFrom.width / 2;
              y += nodeFrom.height / 2;
          }
          let pointTo = nodeTo.localToGlobal();
          let xTo = pointTo.x + offsetX;
          let yTo = pointTo.y + offsetY;
          if (!nodeTo.pivotAsAnchor) {
              xTo += nodeTo.width / 2;
              yTo += nodeTo.height / 2;
          }
          else {
              xTo -= nodeTo.width * nodeTo.pivotX;
              yTo -= nodeTo.height * nodeTo.pivotY;
              xTo += nodeTo.width / 2;
              yTo += nodeTo.height / 2;
          }
          this.ctrlState.selectedIndex = GUIDE_STATE.STATE_DRAG;
          this.showDragFinger(guide, x, y, xTo, yTo, guide.time_move, 0, 0);
      }
      showDragFingerWithTower(nodeFrom, guide) {
          let slot = Level.stage.findTowerSlotUnlock();
          let nodeTo = slot.node;
          let offsetX = guide.offset_x;
          let offsetY = guide.offset_y;
          if (nodeFrom instanceof fgui.GList) {
              nodeFrom = nodeFrom.getChildAt(nodeFrom.getFirstChildInView()).asCom;
          }
          let point = nodeFrom.localToGlobal();
          let x = point.x + offsetX;
          let y = point.y + offsetY;
          if (!nodeFrom.pivotAsAnchor) {
              x += nodeFrom.width / 2;
              y += nodeFrom.height / 2;
          }
          else {
              x -= nodeFrom.width * nodeFrom.pivotX;
              y -= nodeFrom.height * nodeFrom.pivotY;
              x += nodeFrom.width / 2;
              y += nodeFrom.height / 2;
          }
          let pointTo = nodeTo.localToGlobal();
          let xTo = pointTo.x + offsetX;
          let yTo = pointTo.y + offsetY;
          if (!nodeTo.pivotAsAnchor) {
              xTo += nodeTo.width / 2;
              yTo += nodeTo.height / 2;
          }
          else {
              xTo -= nodeTo.width * nodeTo.pivotX;
              yTo -= nodeTo.height * nodeTo.pivotY;
              xTo += nodeTo.width / 2;
              yTo += nodeTo.height / 2;
          }
          this.ctrlState.selectedIndex = GUIDE_STATE.STATE_DRAG_TOWER;
          this.showDragFinger(guide, x, y, xTo, yTo, guide.time_move, 0, 0);
          this.showTip(guide);
      }
      showDragFinger(guide, from_x, from_y, to_x, to_y, moveSecond = 2, delaySecond = 0, repeat = 1) {
          this.drag_finger.x = from_x;
          this.drag_finger.y = from_y;
          let drag_finger = this.drag_finger;
          cc$1.tween(drag_finger, true)
              .sequence(cc$1.tween(drag_finger).set({
                  x: from_x,
                  y: from_y,
                  scaleX: 1,
                  scaleY: 1,
              }), cc$1.tween(drag_finger).to(0.3, {
                  scaleX: 0.8,
                  scaleY: 0.8,
              }), cc$1.tween(drag_finger).to(moveSecond, {
                  x: to_x,
                  y: to_y,
              }), cc$1.tween(drag_finger).to(0.3, {
                  scaleX: 1,
                  scaleY: 1,
              }), cc$1.tween(drag_finger).delay(0.3))
              .repeat(repeat > 0 ? repeat : Infinity)
              .start();
      }
      showDialogRight(guide) {
          this.ctrlState.selectedIndex = GUIDE_STATE.STATE_DIALOG_R;
          this.dialog_r.show(guide.role_name, guide.title, "res/guide/guide_role02.png");
      }
      showDialogLeft(guide) {
          this.ctrlState.selectedIndex = GUIDE_STATE.STATE_DIALOG_L;
          this.dialog_l.show(guide.role_name, guide.title, "res/guide/guide_role01.png");
      }
      loadSpineAvatar() {
          if (this.spineAvatar)
              return;
      }
      randomTalk() {
          if (this.spineAvatar)
              this.spineAvatar.playAnimation(Utils.randomItem(["talk1", "talk2"]));
      }
      completeGuide() {
          if (this.context.guide) {
              mgrGuide.markGuideCompelte(this.context.guide);
          }
      }
      onClickDialog() {
          this.completeGuide();
          fgui.GRoot.inst.playOneShotSound(fgui.UIConfig.buttonSound);
      }
  }

  class mgrGuide extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [BASE_MSG.PANEL_OPEN_COMPLETE]: this.onPanelOpenComplete.bind(this),
              [BASE_MSG.PANEL_CLOSE]: this.onPanelClose.bind(this),
              [BASE_MSG.SDK_GUIDE_SKIP]: this.onGuideSkip.bind(this),
              [MSG.GUIDE_MSG_TRIGGER]: this.onGuideMsgTrigger.bind(this),
          });
      }
      static onStart() {
          if (mgrGame.isNewBie()) {
              this.initAllGuide();
          }
      }
      static loadRecord() {
          this.guideTemp = {};
          this.guideData = FileRecord.getData(this.RECORD_KEY);
          if (!this.guideData) {
              this.guideData = {};
              this.saveRecord();
          }
          console.log("mgrGuide.loadRecord", this.guideData);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.guideData);
      }
      static resetRecord() {
          this.guideData = {};
          this.saveRecord();
      }
      static initAllGuide() {
          let guideList = db.get_guide_db_map();
          for (let key in guideList) {
              this.clacCurrentGuide(key);
          }
      }
      static skipGuide() {
          let guideList = db.get_guide_db_map();
          for (let key in guideList) {
              let list = guideList[key];
              for (let guide of list) {
                  if (guide.need_save) {
                      this.setGuideCompelte(guide.save_id);
                  }
              }
          }
          Global.isGuiding = false;
          Global.sendMsg(MSG.GUIDE_SKIP);
          this.currentGuide = new Map();
          this.closeGuidePanel();
          this.saveRecord();
      }
      static onPanelOpenComplete(panel) {
          if (!panel)
              return;
          if (panel.isSystemPanel)
              return;
          this.stackPanel.push(panel);
          this.updatePanelForGuide(panel);
      }
      static findGuidePanel(guide) {
          for (let panel of this.stackPanel) {
              if (this.isGuidePanel(panel, guide)) {
                  return panel;
              }
          }
      }
      static updatePanelForBanner(panel) {
          if (panel) {
              panel.adaptBannerAdv();
          }
      }
      static updatePanelForGuide(panel) {
          if (panel && this.currentGuide) {
              for (let key in this.currentGuide) {
                  let guide = this.currentGuide[key];
                  if (guide && guide.panel_trigger) {
                      if (panel && panel.sourceName.indexOf(guide.panel) >= 0) {
                          this.currentPanel = panel;
                          this.execGuide(guide);
                          return true;
                      }
                  }
              }
          }
          return false;
      }
      static getTopPanel() {
          if (this.stackPanel.length > 0) {
              return this.stackPanel[this.stackPanel.length - 1];
          }
          else {
              return null;
          }
      }
      static onPanelClose(panel) {
          if (panel.isSystemPanel)
              return;
          Utils.removeArrayItem(this.stackPanel, panel);
          let topPanel = this.getTopPanel();
          this.updatePanelForBanner(topPanel);
          this.updatePanelForGuide(topPanel);
          for (let key in this.currentGuide) {
              let guide = this.currentGuide[key];
              if (guide) {
                  if (guide.check_interrupt && !this.isGuideComplete(guide)) {
                      if (this.isGuidePanel(panel, guide)) {
                          this.setCurrentGuide(guide.group, null);
                          mgrGuide.clacCurrentGuide(guide.group);
                          Global.sendMsg(MSG.GUIDE_CLOSE_PANEL);
                      }
                  }
              }
          }
      }
      static onGuideSkip() {
          this.skipGuide();
      }
      static onGuideMsgTrigger(msg) {
          let guide = this.guideListenMsg[msg];
          if (guide) {
              let panel = this.findGuidePanel(guide);
              if (panel && this.isGuidePanel(panel, guide)) {
                  this.closeMsgListen(guide);
                  this.currentPanel = panel;
                  this.onGuideUpdate(guide);
              }
          }
      }
      static forceGuideEnd() {
          if (Global.isGuiding) {
              Global.isGuiding = false;
              let guideMap = db.get_guide_db_map();
              for (let key in guideMap) {
                  let guideDb = guideMap[key];
              }
          }
      }
      static openGuideController(panel) {
          let ctrlGuide = panel.resNode.getController(mgrGuide.GUIDE_CONTROLLER_NAME);
          if (ctrlGuide) {
              ctrlGuide.setSelectedIndex(1);
          }
      }
      static closeGuideController(panel) {
          let ctrlGuide = panel.resNode.getController(mgrGuide.GUIDE_CONTROLLER_NAME);
          if (ctrlGuide) {
              ctrlGuide.setSelectedIndex(0);
          }
      }
      static openMsgListen(guide) {
          this.guideListenMsg[guide.msg_trigger] = guide;
          console.log("引导：开始监听", guide.msg_trigger);
      }
      static closeMsgListen(guide) {
          this.guideListenMsg[guide.msg_trigger] = null;
          console.log("引导：注销监听", guide.msg_trigger);
      }
      static get isGuiding() {
          return this.execGuideDb != null;
      }
      static execGuide(guide) {
          if (this.execGuideDb && this.execGuideDb != guide) {
              console.log("引导：正在引导中", this.execGuideDb.group, this.execGuideDb.id, "|", guide.group, guide.id);
              return;
          }
          let panel = this.currentPanel;
          if (!panel)
              return;
          if (this.isGuideComplete(guide)) {
              return;
          }
          if (guide.condition_level_id_begin && mgrGame.levelId < guide.condition_level_id_begin) {
              return;
          }
          if (guide.condition_level_id_end && mgrGame.levelId > guide.condition_level_id_end) {
              return;
          }
          this.execGuideDb = guide;
          if (guide.statisPoint) {
              GameStatistics.statisOnStageStart(guide.statisPoint);
          }
          if (guide.soundId) {
              mgrSound.stopSoundAll();
              mgrSound.playSound(guide.soundId);
          }
          if (guide.open_panel) {
              Director.openPanel(guide.open_panel);
          }
          if (guide.open_msg) {
              Global.sendMsg(guide.open_msg);
          }
          this.openGuideController(panel);
          switch (guide.mode) {
              case "click": {
                  let node = this.findNode(panel, guide.clickNodeName, guide.clickChildIndex);
                  if (node) {
                      this.insertButtonGuideCallback(panel, guide);
                      let msg = { mode: GUIDE_STATE.STATE_CLICK, node: node, guide: guide, panel: panel };
                      Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                      Director.openPanelWithSingleton("PanelGuide", msg);
                  }
                  break;
              }
              case "click_free": {
                  let node = this.findNode(panel, guide.clickNodeName, guide.clickChildIndex);
                  if (node) {
                      this.insertButtonGuideCallback(panel, guide);
                      let msg = { mode: GUIDE_STATE.STATE_CLICK_FREE, node: node, guide: guide, panel: panel };
                      Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                      Director.openPanelWithSingleton("PanelGuide", msg);
                  }
                  break;
              }
              case "click_enemy": {
                  let msg = { mode: GUIDE_STATE.STATE_CLICK_ENEMY, guide: guide, panel: panel };
                  Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                  Director.openPanelWithSingleton("PanelGuide", msg);
                  break;
              }
              case "click_tower": {
                  let msg = { mode: GUIDE_STATE.STATE_CLICK_TOWER, guide: guide, panel: panel };
                  Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                  Director.openPanelWithSingleton("PanelGuide", msg);
                  break;
              }
              case "click_slot": {
                  let msg = { mode: GUIDE_STATE.STATE_CLICK_SLOT, guide: guide, panel: panel };
                  Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                  Director.openPanelWithSingleton("PanelGuide", msg);
                  break;
              }
              case "click_stage": {
                  let stage = Level.stage;
                  let node = this.findNodeByStage(stage, guide.clickNodeName);
                  if (node) {
                      this.insertButtonGuideCallbackByStage(stage, guide);
                      let msg = { mode: GUIDE_STATE.STATE_CLICK, node: node, guide: guide, panel: panel };
                      Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                      Director.openPanelWithSingleton("PanelGuide", msg);
                  }
                  break;
              }
              case "drag": {
                  let nodeFrom = this.findNode(panel, guide.clickNodeName, guide.clickChildIndex);
                  let nodeTo = this.findNode(panel, guide.dragNodeName, guide.dragChildIndex);
                  if (nodeFrom && nodeTo) {
                      this.insertButtonGuideCallback(panel, guide);
                      let msg = { mode: GUIDE_STATE.STATE_DRAG, nodeFrom: nodeFrom, nodeTo: nodeTo, guide: guide, panel: panel };
                      Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                      Director.openPanelWithSingleton("PanelGuide", msg);
                  }
                  break;
              }
              case "drag_tower": {
                  let nodeFrom = this.findNode(panel, guide.clickNodeName, guide.clickChildIndex);
                  if (nodeFrom) {
                      this.insertButtonGuideCallback(panel, guide);
                      let msg = { mode: GUIDE_STATE.STATE_DRAG_TOWER, nodeFrom: nodeFrom, guide: guide, panel: panel };
                      Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                      Director.openPanelWithSingleton("PanelGuide", msg);
                  }
                  break;
              }
              case "dialog_r": {
                  let msg = { mode: GUIDE_STATE.STATE_DIALOG_R, guide: guide, panel: panel };
                  Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                  Director.openPanelWithSingleton("PanelGuide", msg);
                  break;
              }
              case "dialog_l": {
                  let msg = { mode: GUIDE_STATE.STATE_DIALOG_L, guide: guide, panel: panel };
                  Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                  Director.openPanelWithSingleton("PanelGuide", msg);
                  break;
              }
              case "function": {
                  this.insertButtonGuideCallback(panel, guide);
                  break;
              }
              case "solo": {
                  let msg = { mode: GUIDE_STATE.STATE_SOLO, guide: guide, panel: panel };
                  Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                  Director.openPanelWithSingleton("PanelGuide", msg);
                  break;
              }
              case "intro": {
                  let node = this.findNode(panel, guide.clickNodeName, guide.clickChildIndex);
                  if (node) {
                      this.insertButtonGuideCallback(panel, guide);
                      let msg = { mode: GUIDE_STATE.STATE_INTRO, guide: guide, panel: panel, node: node };
                      Global.sendMsg(MSG.GUIDE_UPDATE, msg);
                      Director.openPanelWithSingleton("PanelGuide", msg);
                  }
                  break;
              }
          }
      }
      static execGuideById(panel, group, id) {
          let guideDb = db.get_guide_db(group, id - 1);
          if (guideDb && this.getCurrentGuide(group) != guideDb) {
              this.currentPanel = panel;
              this.execGuide(guideDb);
          }
      }
      static execGuideByIdNoPanel(group, id) {
          let guideDb = db.get_guide_db(group, id - 1);
          if (guideDb && this.getCurrentGuide(group) != guideDb) {
              this.currentPanel = this.findGuidePanel(guideDb);
              this.execGuide(guideDb);
          }
      }
      static findNode(view, path, childIds) {
          let node = view[path];
          if (!node) {
              node = view.resNode.getChildByPath(path);
              if (node == null) {
                  console.error("mgrGuide.findNode: not found path", path);
                  return null;
              }
              if (childIds && childIds.length > 0) {
                  for (let id of childIds) {
                      let child = null;
                      if (node.getChildAt)
                          child = node.getChildAt(id);
                      if (child) {
                          node = child;
                      }
                      else
                          console.error("mgrGuide.findNode: not found childIds", node, childIds);
                  }
              }
              if (node instanceof fgui.GList) {
                  let firstIndex = node.getFirstChildInView();
                  let child = null;
                  if (childIds && childIds.length > 0) {
                      child = node._children[firstIndex + childIds[0]];
                  }
                  if (child)
                      node = child;
              }
          }
          if (!node) {
              console.error("mgrGuide.findNode: 没有找到引导节点", path);
          }
          else {
              if (node instanceof ScaleButton) {
                  node = node.guiNode;
              }
          }
          return node;
      }
      static findNodeByStage(stage, path) {
          let node = stage[path];
          if (!node) {
              let childs = path.split(".");
              let parent = stage;
              for (let i = 0; i < childs.length; i++) {
                  parent = parent[childs[i]];
                  if (!parent) {
                      break;
                  }
              }
              if (parent != stage) {
                  node = parent;
              }
          }
          if (!node) {
              console.error("mgrGuide.findNodeByStage: 没有找到引导节点", path);
          }
          else {
              if (node instanceof ScaleButton) {
                  node = node.guiNode;
              }
          }
          return node;
      }
      static clacCurrentGuide(group) {
          let guideList = db.get_guide_db_map()[group];
          let currentGuide = null;
          for (let guide of guideList) {
              if (guide && guide.panel_trigger && !this.isGuideComplete(guide)) {
                  currentGuide = guide;
                  break;
              }
              if (guide && guide.msg_trigger && !this.isGuideComplete(guide)) {
                  currentGuide = guide;
                  break;
              }
          }
          this.setCurrentGuide(group, currentGuide);
      }
      static setCurrentGuide(group, guide) {
          this.currentGuide[group] = guide;
          if (guide) {
              if (guide.msg_trigger) {
                  this.openMsgListen(guide);
              }
              else {
                  this.onGuideUpdate(guide);
              }
          }
      }
      static setCurrentGuideById(group, id) {
          let guide = this.getGuideDB(group, id);
          this.setCurrentGuide(group, guide);
      }
      static isGuidePanel(panel, guide) {
          return panel.sourceName.indexOf(guide.panel) >= 0;
      }
      static onGuideUpdate(guide) {
          if (guide.type == mgrGuide.TYPE_NEWBEE) {
              Global.isGuiding = true;
          }
          if (this.currentPanel && this.isGuidePanel(this.currentPanel, guide)) {
              this.execGuide(guide);
          }
          else {
              let panel = this.getTopPanel();
              if (!this.updatePanelForGuide(panel)) {
                  if (panel && panel.sourceName.indexOf("PanelGuide") < 0)
                      this.closeGuidePanel();
              }
          }
      }
      static getCurrentGuide(group) {
          return this.currentGuide[group];
      }
      static markGuideCompelteById(group, id) {
          let guide = this.getGuideDB(group, id);
          if (guide) {
              this.markGuideCompelte(guide);
          }
      }
      static markGuideCompelte(guide) {
          if (guide.save_id) {
              if (guide.need_save) {
                  this.setGuideCompelte(guide.save_id);
              }
              else {
                  this.guideTemp[guide.save_id] = true;
              }
          }
          this.execGuideDb = null;
          Global.sendMsg(MSG.GUIDE_COMPLETE, guide);
          if (guide.statisPoint) {
              GameStatistics.statisOnStageEnd(guide.statisPoint);
              console.log("打点 引导步骤结束", guide.statisPoint, guide.group, guide.id);
          }
          let nextGuide = this.getGuideDB(guide.group, guide.id + 1);
          if (nextGuide) {
              if (guide.auto_next) {
                  this.setCurrentGuide(guide.group, nextGuide);
              }
              else {
                  this.closeGuidePanel();
              }
          }
          else {
              this.setCurrentGuide(guide.group, null);
              this.closeGuidePanel();
              if (guide.type == mgrGuide.TYPE_NEWBEE) {
                  Global.isGuiding = false;
                  Global.sendMsg(MSG.GUIDE_END);
                  if (this.currentPanel) {
                      this.closeGuideController(this.currentPanel);
                  }
              }
          }
          if (guide.complete_msg) {
              Global.sendMsg(guide.complete_msg);
          }
          if (guide.open_panel_complete) {
              Director.openPanel(guide.open_panel_complete);
          }
          if (guide.reward_item_id) {
              mgrGame.addItem(guide.reward_item_id, 1, 53);
          }
      }
      static closeGuidePanel() {
          Global.sendMsg(MSG.GUIDE_CLOSE_PANEL);
      }
      static getGuideDB(group, id) {
          return db.get_guide_db(group, id - 1);
      }
      static isGuideCompletById(group, id) {
          let guideDb = this.getGuideDB(group, id);
          if (guideDb) {
              return this.isGuideComplete(guideDb);
          }
          else {
              return false;
          }
      }
      static isGuideSavedById(group, id) {
          return this.isGuideSaved(db.get_guide_db(group, id));
      }
      static isGuideSaved(guide) {
          if (guide) {
              return this.guideData[guide.save_id];
          }
          else {
              return true;
          }
      }
      static isGuideComplete(guide) {
          if (guide) {
              return this.guideTemp[guide.save_id] || this.guideData[guide.complete_id];
          }
          else {
              return true;
          }
      }
      static setGuideCompelte(id) {
          this.guideData[id] = true;
          this.saveRecord();
      }
      static insertButtonGuideCallback(panel, guide) {
          if (guide.subNode) {
              this.insertButtonGuideCallbackSub(panel[guide.subNode], guide);
          }
          else {
              this.insertButtonGuideCallbackSub(panel, guide);
          }
      }
      static insertButtonGuideCallbackSub(view, guide) {
          let callbackName = guide.clickFunc;
          if (!callbackName)
              callbackName = "on_click_" + guide.clickNodeName;
          let funcClickOld = view[callbackName];
          if (funcClickOld) {
              view[callbackName] = function () {
                  funcClickOld.bind(view)();
                  view[callbackName] = funcClickOld;
                  mgrGuide.markGuideCompelte(guide);
              }.bind(view);
          }
          else {
              view[callbackName] = function () {
                  view[callbackName] = null;
                  mgrGuide.markGuideCompelte(guide);
              }.bind(view);
          }
      }
      static insertButtonGuideCallbackByStage(view, guide) {
          let callbackName = guide.clickFunc;
          let funcClickOld = view[callbackName];
          if (!funcClickOld) {
              let childs = callbackName.split(".");
              if (childs.length) {
                  callbackName = childs[childs.length - 1];
                  let parent = view;
                  for (let i = 0; i < childs.length - 1; i++) {
                      parent = parent[childs[i]];
                      if (!parent) {
                          break;
                      }
                  }
                  if (parent) {
                      view = parent;
                      funcClickOld = view[callbackName];
                  }
              }
          }
          if (funcClickOld) {
              view[callbackName] = function () {
                  funcClickOld.bind(view)();
                  view[callbackName] = funcClickOld;
                  mgrGuide.markGuideCompelte(guide);
              }.bind(view);
          }
          else {
              view[callbackName] = function () {
                  view[callbackName] = null;
                  mgrGuide.markGuideCompelte(guide);
              }.bind(view);
          }
      }
  }
  mgrGuide.RECORD_KEY = "game166_guide_v1.0";
  mgrGuide.TYPE_NEWBEE = 0;
  mgrGuide.TYPE_SELF = 1;
  mgrGuide.GUIDE_CONTROLLER_NAME = "guide";
  mgrGuide.guideListenMsg = {};
  mgrGuide.execGuideDb = null;
  mgrGuide.currentPanel = null;
  mgrGuide.stackPanel = [];
  mgrGuide.currentGuide = new Map();

  class mgrMonster extends Manager {
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrMonster.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static onDifferentDay() {
          this.data.challenge2count = {};
          this.data.monsterid2count = {};
          this.data.monsterAD2count = {};
          this.saveRecord();
      }
      static onMonsterChallengeSucces(monsterDb) {
          let id = monsterDb.id;
          this.setMonsterChallengeCount(id, this.getMonsterChallengeCount(id) + 1);
          this.markMonsterBeated(id);
          Global.sendMsg(BASE_MSG.ITEM_CHANGE);
          console.log("打点 挑战模式 成功", monsterDb.name);
          mgrStatis.statisCommonEvent(monsterDb.statis_point, 1);
      }
      static isMonsterBeated(id) {
          return this.data.monsterid2succs[id];
      }
      static markMonsterBeated(id) {
          this.data.monsterid2succs[id] = 1;
      }
      static getMonsterChallengeCount(id) {
          return this.data.challenge2count[id] || 0;
      }
      static setMonsterChallengeCount(id, count) {
          this.data.challenge2count[id] = count;
          this.saveRecord();
      }
      static getMonsterADCount(id) {
          return this.data.monsterAD2count[id] || 0;
      }
      static setMonsterADCount(id, count) {
          this.data.monsterAD2count[id] = count;
          this.saveRecord();
      }
      static addMonsterADCount(id, add = 1) {
          this.setMonsterADCount(id, this.getMonsterADCount(id) + add);
      }
      static getMonsterCount(id) {
          return this.data.monsterid2count[id] || 0;
      }
      static setMonsterCount(id, count) {
          this.data.monsterid2count[id] = count;
      }
      static getMonsterDb(id) {
          return db.get_challenge_level(id - 1);
      }
      static getLeftChallengeCount(id) {
          let left = this.getMonsterDb(id).count + this.getMonsterADCount(id) - this.getMonsterChallengeCount(id);
          return left;
      }
      static canChallenge(id) {
          let maxCount = this.getMonsterDb(id).count + this.getMonsterADCount(id);
          return this.isMonsterUnlock(id) && this.getMonsterChallengeCount(id) < maxCount;
      }
      static canSweep(id) {
          let maxCount = this.getMonsterDb(id).count + this.getMonsterADCount(id);
          return this.isMonsterBeated(id) && this.getMonsterChallengeCount(id) < maxCount;
      }
      static isMonsterUnlock(id) {
          let monsterDb = this.getMonsterDb(id);
          if (monsterDb.prev_id == 0) {
              return true;
          }
          else {
              if (this.isMonsterBeated(monsterDb.prev_id)) {
                  return true;
              }
              else {
                  return this.isMonsterBeated(id);
              }
          }
      }
      static challengeMonster(id, force = false) {
          if (force || this.canChallenge(id)) {
              this.setMonsterCount(id, this.getMonsterCount(id) + 1);
              Global.sendMsg(MSG.REFRESH_RED_POINT);
              let monsterDb = this.getMonsterDb(id);
              if (monsterDb) {
                  Global.sendMsg(MSG.CHALLENGE_BOSS_BEGIN, monsterDb);
                  console.log("打点 挑战模式 开始", monsterDb.name);
                  mgrStatis.statisCommonEvent(monsterDb.statis_point, 0);
              }
              return true;
          }
          else {
              return false;
          }
      }
      static haveRedPoint() {
          let listData = db.get_challenge_level_map();
          for (let monsterDb of listData) {
              if (this.getMonsterCount(monsterDb.id) == 0 && this.canChallenge(monsterDb.id)) {
                  return true;
              }
          }
          return false;
      }
      static getSweepCount() {
          let sweepCount = 0;
          let listData = db.get_challenge_level_map();
          for (let monsterDb of listData) {
              if (this.canSweep(monsterDb.id)) {
                  sweepCount++;
              }
          }
          return sweepCount;
      }
      static getBossSweepReward() {
          let listData = db.get_challenge_level_map();
          for (let config of listData) {
              let id = config.id;
              if (this.canSweep(id)) {
                  this.setMonsterChallengeCount(id, this.getMonsterChallengeCount(id) + 1);
                  let dropData = [];
                  let first_reward_ids = config.reward_ids;
                  for (let i = 0; i < first_reward_ids.length; i += 2) {
                      let itemId = first_reward_ids[i];
                      let count = first_reward_ids[i + 1];
                      if (itemId && count) {
                          mgrGame.addItem(itemId, count, 22, false, dropData);
                      }
                  }
                  mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_BOSS);
                  Level.showItemGet(dropData);
              }
          }
      }
  }
  mgrMonster.RECORD_KEY = "game166_monster_v1.0";
  mgrMonster.dataDefault = {
      challenge2count: {},
      monsterid2succs: {},
      monsterid2count: {},
      monsterAD2count: {},
  };

  const DAY_SECOND = 24 * 3600;
  class mgrNewyear extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDailySwitchActive.bind(this),
              [MSG.MGR_TIME_UPDATE]: this.onMgrTimeUpdate.bind(this),
          });
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrNewyear.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onDailySwitchActive() {
          this.calcCurtDay();
          this.rewardNumToday = 0;
          this.redPoint = 1;
      }
      static onMgrTimeUpdate() {
      }
      static markSigned(day) {
          this.data.day2reward[day] = true;
          this.saveRecord();
      }
      static isSigned(day) {
          return this.data.day2reward[day];
      }
      static getInitTime() {
          return this.data.time;
      }
      static setInitTime(time) {
          this.data.time = time;
          this.saveRecord();
      }
      static getCurtTime() {
          return Math.floor(mgrTime.serverTime / 1000);
      }
      static calcNeedFixCount() {
          let count = 0;
          let day = this.day;
          let signDataMap = db.get_sign_db_map();
          for (let data of signDataMap) {
              if (data.day < day && !this.isSigned(data.day)) {
                  count++;
              }
          }
          return count;
      }
      static calcCurtDay() {
          let curtTime = this.getCurtTime();
          let initTime = this.getInitTime();
          if (initTime == 0) {
              let date = new Date(curtTime * 1000);
              let y = date.getFullYear();
              let m = date.getMonth() + 1;
              let d = date.getDate();
              curtTime = Math.floor(new Date(y + "/" + m + "/" + d).getTime() / 1000);
              initTime = curtTime;
              this.setInitTime(initTime);
          }
          let curtDay = Math.floor((curtTime - initTime) / (3600 * 24));
          return curtDay + 1;
      }
      static findSignDbByDay(day) {
          let signDataMap = db.get_newyear_sign_db_map();
          for (let data of signDataMap) {
              if (data.day == day) {
                  return data;
              }
          }
          return null;
      }
      static canFix(day) {
          if (!this.isSigned(day) && day < this.day) {
              return true;
          }
          return false;
      }
      static canSign(day) {
          if (!mgrTime.isReady()) {
              return false;
          }
          let signDb = this.findSignDbByDay(day);
          if (signDb && day <= this.day && !this.isSigned(day)) {
              return true;
          }
          return false;
      }
      static get day() {
          return this.calcCurtDay();
      }
      static showUI() {
          if (Global.isGuiding)
              return;
          if (this.canSign(this.day)) {
              Director.openPanel("PanelSign");
          }
      }
      static sign(day, scale = 1, force = false) {
          if (force || this.canSign(day)) {
              this.markSigned(day);
              let signDb = this.findSignDbByDay(day);
              if (signDb) {
                  GameStatistics.statisCommonEvent(1101, day);
                  this.getReward(signDb, scale);
                  Global.sendMsg(MSG.NEWYEAR_SIGN_UPDATE);
                  mgrTask.doEvent(db.TASK_EVENT_ID.NEWYEAR_SIGN);
                  return true;
              }
          }
          return false;
      }
      static getReward(signDb, scale = 1) {
          mgrGame.addItem(signDb.item_id, signDb.item_num * scale, 23);
      }
      static isTimeValid() {
          return mgrTime.checkDateValid(mgrTime.curtTimeMS(), db.cop_db.newyear_time_total[0], db.cop_db.newyear_time_total[1]);
      }
      static isTaskAndFBValid() {
          return mgrTime.checkDateValid(mgrTime.curtTimeMS(), db.cop_db.newyear_time_task_and_fb[0], db.cop_db.newyear_time_task_and_fb[1]);
      }
      static calcLeftTime() {
          let dateEnd = mgrTime.getDateByDateNum(db.cop_db.newyear_time_total[1], 0);
          let timeEnd = dateEnd.getTime() / 1000 + DAY_SECOND;
          let timeNow = mgrTime.curtTime();
          let timeLeft = timeEnd - timeNow;
          if (timeLeft < 0)
              timeLeft = 0;
          return timeLeft;
      }
      static costFu2Firecracker() {
          if (mgrGame.subItem(1024, db.game_cnf.newyear_firecracker_cost_fu, 71)) {
              let num = Utils.random(db.game_cnf.newyear_firecracker_get_num[0] || 0, db.game_cnf.newyear_firecracker_get_num[1] || 1);
              if (num > 0) {
                  mgrGame.addItem(1025, num, 71);
              }
          }
      }
      static get damageHistory() {
          return this.data.damageHistory;
      }
      static set damageHistory(d) {
          this.data.damageHistory = d;
          this.saveRecord();
      }
      static get rewardNumToday() {
          return this.data.rewardNumToday;
      }
      static set rewardNumToday(d) {
          this.data.rewardNumToday = d;
          this.saveRecord();
      }
      static get redPoint() {
          return this.data.redPoint;
      }
      static set redPoint(d) {
          this.data.redPoint = d;
          this.saveRecord();
      }
      static getRewardNumtTodayMax() {
          let config = db.get_fb_custom_db(db.FB_CUSTOM_DB_ID.NEWYEAR);
          if (config)
              return config.reward_limit;
          else
              return 0;
      }
      static isRewardNumMax() {
          return this.rewardNumToday >= this.getRewardNumtTodayMax();
      }
      static getRewardNumLeft() {
          let numLeft = this.getRewardNumtTodayMax() - this.rewardNumToday;
          if (numLeft < 0)
              numLeft = 0;
          return numLeft;
      }
      static markDamage(damage) {
          this.damageLast = damage;
          this.rewardConfig = this.calcReward(damage);
          let numLeft = this.getRewardNumLeft();
          if (this.rewardConfig) {
              let num1 = this.rewardConfig.item_amount[0] || 0;
              let num2 = this.rewardConfig.item_amount[1] || num1;
              this.rewardNum = Utils.random(num1, num2);
          }
          else {
              this.rewardNum = 0;
          }
          if (this.rewardNum > numLeft)
              this.rewardNum = numLeft;
          if (damage > this.damageHistory) {
              this.damageHistory = damage;
          }
      }
      static getDamageReward(scale = 1) {
          let config = this.rewardConfig;
          if (config) {
              this.rewardConfig = null;
              let num = this.rewardNum * scale;
              if (num) {
                  this.rewardNumToday += num;
                  let numMax = this.getRewardNumtTodayMax();
                  if (this.rewardNumToday > numMax) {
                      this.rewardNumToday = numMax;
                  }
                  mgrGame.addItem(config.item_id, num, 71, true);
                  return false;
              }
          }
          return true;
      }
      static calcReward(damage) {
          let rewardList = db.get_newyear_fb_reward_map();
          if (rewardList) {
              for (let i = 0; i < rewardList.length; i++) {
                  let rewardCurt = rewardList[i];
                  let rewardNext = rewardList[i + 1];
                  let damageCurt = 0;
                  let damageNext = 0;
                  if (rewardNext) {
                      damageNext = rewardNext.damage;
                  }
                  else {
                      damageNext = Number.MAX_VALUE;
                  }
                  if (rewardCurt) {
                      damageCurt = rewardCurt.damage;
                      if (damage >= damageCurt && damage < damageNext) {
                          return rewardCurt;
                      }
                  }
              }
          }
          return null;
      }
      static unlockRedPoint() {
          if (this.redPoint) {
              this.redPoint = 0;
              Global.sendMsg(MSG.REFRESH_RED_POINT);
          }
      }
      static haveRedPoint() {
          return this.redPoint > 0;
      }
  }
  mgrNewyear.RECORD_KEY = "game166_newyear_v1.0";
  mgrNewyear.dataDefault = {
      time: 0,
      day2reward: {},
      damageHistory: 0,
      rewardNumToday: 0,
      redPoint: 1,
  };
  mgrNewyear.dataShowAdStatis = {};
  mgrNewyear.damageLast = 0;
  mgrNewyear.rewardConfig = null;
  mgrNewyear.rewardNum = 0;

  var LogicMessage;
  (function (LogicMessage) {
      LogicMessage[LogicMessage["NONE"] = 0] = "NONE";
      LogicMessage[LogicMessage["MOVE_STOP"] = 1] = "MOVE_STOP";
  })(LogicMessage || (LogicMessage = {}));
  var LogicCamp;
  (function (LogicCamp) {
      LogicCamp[LogicCamp["NONE"] = 0] = "NONE";
      LogicCamp[LogicCamp["FRIEND"] = 1] = "FRIEND";
      LogicCamp[LogicCamp["ENEMY"] = 2] = "ENEMY";
      LogicCamp[LogicCamp["SELF"] = 3] = "SELF";
      LogicCamp[LogicCamp["VIRTUAL"] = 4] = "VIRTUAL";
      LogicCamp[LogicCamp["LEN"] = 5] = "LEN";
  })(LogicCamp || (LogicCamp = {}));
  var LogicObjectFlag;
  (function (LogicObjectFlag) {
      LogicObjectFlag[LogicObjectFlag["NO_MOVE"] = 2] = "NO_MOVE";
      LogicObjectFlag[LogicObjectFlag["NO_ATTACK"] = 4] = "NO_ATTACK";
      LogicObjectFlag[LogicObjectFlag["SLOW"] = 8] = "SLOW";
      LogicObjectFlag[LogicObjectFlag["SHIELD"] = 16] = "SHIELD";
      LogicObjectFlag[LogicObjectFlag["SHIELD_ONCE"] = 32] = "SHIELD_ONCE";
  })(LogicObjectFlag || (LogicObjectFlag = {}));
  class LogicConfig {
      static resetSkillData(data) {
          data.skillId = "";
          data.template = "";
          data.timeCast = 0;
          data.timeCD = 0;
          data.prepare = false;
          data.count = 0;
          data.skillDb = null;
          data.ground = false;
          data.limit = 0;
          data.limitRebound = null;
          data.searchInAttack = null;
          data.double = false;
          data.doubleUsed = false;
          data.delayRebound = 0;
          data.ranage = null;
          data.camp = null;
          data.targetX = null;
          data.targetY = null;
          data.isSuper = null;
          ;
          data.triggerSuper = false;
      }
  }
  LogicConfig.LOGIC_FRAME_ITME = 1 / 10;
  LogicConfig.enableEnemySkill = true;
  class LogicDebug {
      static drawPath(path) {
          Level.stage.drawPath(path);
      }
      static drawStep(x, y, color) {
          Level.stage.drawStep(x, y, color);
      }
  }
  class LogicPoint {
      constructor(x = 0, y = 0) {
          this.x = x;
          this.y = y;
      }
      normalize() {
          var d = Math.sqrt(this.x * this.x + this.y * this.y);
          if (d > 0) {
              var id = 1.0 / d;
              this.x *= id;
              this.y *= id;
          }
      }
      distance() {
          return Math.sqrt(this.x * this.x + this.y * this.y);
      }
  }

  class TowerMaker {
      static dropByDropDb(dropDb) {
          let dropCount = 0;
          let dropCountIdx = this.calcWeightIndex(dropDb.tower_weight);
          if (dropCountIdx < dropDb.tower_count.length) {
              dropCount = dropDb.tower_count[dropCountIdx];
          }
          let listItems = [];
          if (dropCount) {
              let listData = [];
              for (let i = 0; i < dropDb.tower_ids.length; i++) {
                  let id = dropDb.tower_ids[i];
                  let towerDb = db.get_tower_db_map()[id];
                  if (towerDb) {
                      if (dropDb.tower_ids_weight.length) {
                          let weight = dropDb.tower_ids_weight[i] || 0;
                          listData.push({ id: id, towerDb: towerDb, weight: weight });
                      }
                      else {
                          listData.push({ id: id, towerDb: towerDb, weight: 10 });
                      }
                  }
              }
              for (let i = 0; i < dropCount; i++) {
                  let item = this.calcWeightItem(listData);
                  let info = { itemId: item.towerDb.item_id, count: 1, towerDb: item.towerDb };
                  listItems.push(info);
              }
          }
          return listItems;
      }
      static calcWeightIndex(weights) {
          let weightTotal = 0;
          for (let i = 0; i < weights.length; i++) {
              weightTotal += weights[i];
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let idx = 0;
          for (let i = 0; i < weights.length; i++) {
              vpt += weights[i];
              if (r < vpt) {
                  idx = i;
                  break;
              }
          }
          return idx;
      }
      static calcWeightItem(items) {
          let weightTotal = 0;
          for (let i = 0; i < items.length; i++) {
              weightTotal += items[i].weight || 0;
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let item = null;
          for (let i = 0; i < items.length; i++) {
              vpt += items[i].weight || 0;
              if (r < vpt) {
                  item = items[i];
                  break;
              }
          }
          return item;
      }
  }

  class LinkListItem {
      constructor(data) {
          if (data)
              this.bindData(data);
      }
      bindData(data) {
          this.data = data;
      }
      getData() {
          return this.data;
      }
      reset() {
          this.data = null;
          this.list = null;
          this.prev = null;
          this.next = null;
      }
      removeFromList() {
          if (this.list)
              this.list.remove(this);
      }
      isOwner(list) {
          return this.list == list;
      }
  }
  class LinkList {
      constructor() {
          this.length = 0;
          this.head = null;
          this.tail = null;
      }
      static getWrapFromPool() {
          let wrap = LinkList.poolWrapItems.shift();
          if (wrap == null) {
              wrap = new LinkListItem();
          }
          else {
          }
          return wrap;
      }
      static putWrapToPool(wrap) {
          LinkList.poolWrapItems.push(wrap);
      }
      append(data) {
          let warp = LinkList.getWrapFromPool();
          warp.reset();
          warp.bindData(data);
          warp.list = this;
          if (!this.head) {
              this.head = warp;
          }
          if (this.tail) {
              this.tail.next = warp;
              warp.prev = this.tail;
          }
          this.tail = warp;
          this.length++;
          return warp;
      }
      remove(item) {
          if (!item.isOwner(this)) {
              console.error("LinkList.remove not my item", this, item);
              return;
          }
          if (this.head == item)
              this.head = item.next;
          if (this.tail == item)
              this.tail = item.prev;
          let prev = item.prev;
          let next = item.next;
          if (prev) {
              prev.next = next;
          }
          if (next) {
              next.prev = prev;
          }
          item.prev = null;
          item.next = null;
          item.data = null;
          this.length--;
          LinkList.putWrapToPool(item);
      }
      clear() {
          let tail = this.tail;
          while (tail) {
              let curt = tail;
              tail = tail.prev;
              this.remove(curt);
          }
          this.head = null;
          this.tail = null;
      }
      get size() {
          return this.length;
      }
      find(data) {
          let node = this.head;
          let find = null;
          while (node) {
              if (data == node.data) {
                  find = node;
                  break;
              }
              node = node.next;
          }
          return find;
      }
  }
  LinkList.poolWrapItems = [];

  class Astar {
      constructor(isSupportSkew) {
          this._width = 0;
          this._height = 0;
          this._VALUE = 10;
          this._VALUE_SLANT = 14;
          if (isSupportSkew) {
              this._arround_point = [
                  { x: 1, y: 0 },
                  { x: -1, y: 0 },
                  { x: 0, y: 1 },
                  { x: 0, y: -1 },
                  { x: 1, y: 1 },
                  { x: -1, y: -1 },
                  { x: -1, y: 1 },
                  { x: 1, y: -1 },
              ];
          }
          else {
              this._arround_point = [
                  { x: 1, y: 0 },
                  { x: -1, y: 0 },
                  { x: 0, y: 1 },
                  { x: 0, y: -1 },
              ];
          }
      }
      setBarrierCheckCallback(callback) {
          this._callback_barrier_check = callback;
      }
      checkIsBarrier(x, y, flag) {
          if (this._callback_barrier_check)
              return this._callback_barrier_check(x, y, flag);
          else
              return false;
      }
      setMap(width, height) {
          this._width = width;
          this._height = height;
          this._map_point = [];
          for (let i = 0; i < this._width; i++) {
              for (let j = 0; j < this._height; j++) {
                  let index = i * this._height + j;
                  this._map_point[index] = {
                      x: i,
                      y: j,
                      G: 0,
                      H: 0,
                      F: 0,
                      parent: null
                  };
              }
          }
      }
      resetPointScore() {
          if (this._map_point != null) {
              for (let point of this._map_point) {
                  point.G = 0;
                  point.H = 0;
                  point.F = 0;
                  point.parent = null;
              }
          }
      }
      getPoint(x, y) {
          if (x >= 0 && x < this._width && y >= 0 && y < this._height) {
              var point = this._map_point[x * this._height + y];
              if (point.x != x || point.y != y) {
                  console.error("getPoint fuck:", x, y, point);
              }
              return point;
          }
          else {
              return null;
          }
      }
      calcG(x1, y1, x2, y2) {
          return ((x1 - x2) * (y1 - y2) == 0 ? this._VALUE : this._VALUE_SLANT);
      }
      calcH(x1, y1, x2, y2) {
          return Math.abs(x1 - x2) * this._VALUE + Math.abs(y1 - y2) * this._VALUE;
      }
      deleteOpenList(openList, index) {
          openList.splice(index, 1);
      }
      insertOpenList(openList, point) {
          let index = 0;
          let is_found = false;
          for (let i = 0; i < openList.length; i++) {
              index = i;
              let cursor = openList[i];
              if (point.F <= cursor.F) {
                  is_found = true;
                  break;
              }
          }
          if (!is_found)
              index++;
          openList.splice(index, 0, point);
      }
      printMapImage(flag) {
          console.log("---------------------------");
          for (let j = 0; j < this._height; j++) {
              var content = "";
              for (let i = 0; i < this._width; i++) {
                  content += ((this.checkIsBarrier(i, j, flag) ? "#" : "_") + ",");
              }
              console.log(content, j);
          }
          var content = "";
          for (let i = 0; i < this._width; i++) {
              content += (i + ",");
          }
          console.log(content + "x\\y");
          console.log("---------------------------");
      }
      _searchEndPoint(start_x, start_y, end_x, end_y, flag) {
          let openList = [];
          let closeList = [];
          let endPoint = null;
          this.insertOpenList(openList, this.getPoint(start_x, start_y));
          do {
              let curtPoint = openList.shift();
              if (curtPoint == null)
                  break;
              closeList.push(curtPoint);
              for (let around of this._arround_point) {
                  let x = curtPoint.x + around.x;
                  let y = curtPoint.y + around.y;
                  let point = this.getPoint(x, y);
                  if (point &&
                      point.y >= 0 &&
                      point.x >= 0 &&
                      point.y < this._height &&
                      point.x < this._width &&
                      (!this.checkIsBarrier(point.x, point.y, flag) ||
                          (point.x == end_x && point.y == end_y)) &&
                      !this.isExistList(point, closeList)) {
                      let g = curtPoint.G + this.calcG(curtPoint.x, curtPoint.y, point.x, point.y);
                      let index = this.getListIndex(point, openList);
                      if (index < 0) {
                          point.H = this.calcH(point.x, point.y, end_x, end_y);
                          point.G = g;
                          point.F = point.H + point.G;
                          point.parent = curtPoint;
                          this.insertOpenList(openList, point);
                      }
                      else {
                          if (g < point.G) {
                              point.G = g;
                              point.F = point.H + g;
                              point.parent = curtPoint;
                              this.deleteOpenList(openList, index);
                              this.insertOpenList(openList, point);
                          }
                      }
                  }
              }
              if (curtPoint.x == end_x && curtPoint.y == end_y) {
                  endPoint = curtPoint;
                  break;
              }
              if (openList.length == 0) {
                  break;
              }
          } while (true);
          return endPoint;
      }
      findPath(start_x, start_y, end_x, end_y, flag) {
          this.resetPointScore();
          let result = [];
          let endPoint = this._searchEndPoint(start_x, start_y, end_x, end_y, flag);
          while (endPoint != null) {
              result.unshift({ x: endPoint.x, y: endPoint.y });
              endPoint = endPoint.parent;
          }
          return result;
      }
      findNearestPoint(start_x, start_y, end_x, end_y, flag) {
          this.resetPointScore();
          let endPoint = this._searchEndPoint(start_x, start_y, end_x, end_y, flag);
          while (endPoint != null) {
              let parent = endPoint.parent;
              if (parent != null && parent.x == start_x && parent.y == start_y) {
                  return endPoint;
              }
              endPoint = parent;
          }
          return null;
      }
      isExistList(point, list) {
          return this.getListIndex(point, list) >= 0;
      }
      getListIndex(point, list) {
          let index = list.findIndex(v => v.y === point.y && v.x === point.x);
          return index;
      }
  }

  class LogicTool {
      static safeCall(func, ...arg) {
          if (func) {
              return func(...arg);
          }
      }
      static rotatex(x, y, angel, cx, cy) {
          return (x - cx) * Math.cos(angel) - (y - cy) * Math.sin(angel) + cx;
      }
      static rotatey(x, y, angel, cx, cy) {
          return (y - cy) * Math.cos(angel) + (x - cx) * Math.sin(angel) + cy;
      }
      static inRange(sx, sy, tx, ty, range) {
          let dx = tx - sx;
          let dy = ty - sy;
          return this.inRangeByDxDy(dx, dy, range);
      }
      static inRangeByDxDy(dx, dy, range) {
          let distanceSq = dx * dx + dy * dy - 1;
          let rangeSq = range * range;
          if (distanceSq <= rangeSq) {
              return true;
          }
          else {
              return false;
          }
      }
      static isPointInSector(cx, cy, rx, ry, px, py, degree) {
          let x1 = rx - cx;
          let y1 = ry - cy;
          let x2 = px - cx;
          let y2 = py - cy;
          return Math.abs(this.calcVectorDegree(x1, y1, x2, y2)) <= degree;
      }
      static calcVectorDegree(x1, y1, x2, y2) {
          let radian_angle = Math.atan2(y2, x2) - Math.atan2(y1, x1);
          return radian_angle * 180 / Math.PI;
      }
  }

  var MAP_FLAG;
  (function (MAP_FLAG) {
      MAP_FLAG[MAP_FLAG["NONE"] = 0] = "NONE";
      MAP_FLAG[MAP_FLAG["BUILDING"] = 1] = "BUILDING";
      MAP_FLAG[MAP_FLAG["UNIT_STAND"] = 2] = "UNIT_STAND";
      MAP_FLAG[MAP_FLAG["UNIT_MOVING"] = 4] = "UNIT_MOVING";
      MAP_FLAG[MAP_FLAG["UNIT_DEST"] = 8] = "UNIT_DEST";
      MAP_FLAG[MAP_FLAG["BARRIER"] = 16] = "BARRIER";
      MAP_FLAG[MAP_FLAG["ALPHA"] = 32] = "ALPHA";
  })(MAP_FLAG || (MAP_FLAG = {}));
  class LogicMap {
      constructor(world) {
          this.aroundOffset = [
              { x: -1, y: 0 }, { x: 1, y: 0 }, { x: 0, y: -1 }, { x: 0, y: 1 },
              { x: -1, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: 1, y: 1 }
          ];
          this.tempPosition = { x: 0, y: 0 };
          this.stepOffset = [1, -1];
          this.offsetQueue = [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: -1, y: 0 }, { x: 0, y: -1 }];
          this.BEST_FIND_RAD = Math.PI / 180 * 36;
          this._tempPoint1 = new LogicPoint;
          this._tempPoint2 = new LogicPoint;
          this.world = world;
          this.width = 0;
          this.height = 0;
      }
      initGrid(width, height) {
          this.width = width;
          this.height = height;
          this.sectionTable = [];
          this.gridFlag = [];
          this.gridLock = [];
          this.gridDest = [];
          for (let w = 0; w < width; w++) {
              let table = [];
              let flag = [];
              let lock = [];
              let dest = [];
              for (let h = 0; h < height; h++) {
                  table.push(new LinkList);
                  flag.push(0);
                  lock.push(0);
                  dest.push(0);
              }
              this.sectionTable[w] = table;
              this.gridFlag[w] = flag;
              this.gridLock[w] = lock;
              this.gridDest[w] = dest;
          }
          this.initAstar();
          console.log("LogicMap.initGrid", this.sectionTable, this.gridFlag);
      }
      initAstar() {
          this.astar = new Astar(true);
          this.astar.setMap(this.width, this.height);
          this.astar.setBarrierCheckCallback(this.onBarrierCheck.bind(this));
      }
      onBarrierCheck(gx, gy, flag = MAP_FLAG.BUILDING | MAP_FLAG.BARRIER) {
          return this.checkFlag(gx, gy, flag);
      }
      findPath(fx, fy, tx, ty, flag) {
          return this.astar.findPath(fx, fy, tx, ty, flag);
      }
      moveObjectTo(object, x, y) {
          let oldX = object.gx;
          let oldY = object.gy;
          let sectionOld = this.getSectionTable(oldX, oldY);
          let sectionNew = this.getSectionTable(x, y);
          if (sectionOld) {
              let item = sectionOld.find(object);
              if (item) {
                  item.removeFromList();
              }
              if (sectionOld.size == 0) {
                  this.remFlag(oldX, oldY, MAP_FLAG.UNIT_STAND);
              }
          }
          else {
              object.mx = x;
              object.my = y;
          }
          if (sectionNew) {
              sectionNew.append(object);
              object.mapLinkList = sectionNew;
              object.gx = x;
              object.gy = y;
              this.addFlag(x, y, MAP_FLAG.UNIT_STAND);
          }
      }
      remBuilding(object, shape) {
          let oldX = object.gx;
          let oldY = object.gy;
          for (let offset of shape) {
              let ox = oldX + offset.x;
              let oy = oldY + offset.y;
              let sectionOld = this.getSectionTable(ox, oy);
              if (sectionOld) {
                  let item = sectionOld.find(object);
                  if (item) {
                      item.removeFromList();
                  }
                  if (sectionOld.size == 0) {
                      this.remBuildingFlag(ox, oy);
                  }
              }
          }
      }
      remBuildingFlag(x, y) {
      }
      moveBuildingTo(object, x, y, shape) {
          let oldX = object.gx;
          let oldY = object.gy;
          for (let offset of shape) {
              let ox = oldX + offset.x;
              let oy = oldY + offset.y;
              let nx = x + offset.x;
              let ny = y + offset.y;
              let sectionOld = this.getSectionTable(ox, oy);
              let sectionNew = this.getSectionTable(nx, ny);
              if (sectionOld) {
                  let item = sectionOld.find(object);
                  if (item) {
                      item.removeFromList();
                  }
                  if (sectionOld.size == 0) {
                      this.remBuildingFlag(ox, oy);
                  }
              }
              else {
                  object.mx = x;
                  object.my = y;
              }
              if (sectionNew) {
                  sectionNew.append(object);
                  object.mapLinkList = sectionNew;
                  object.gx = x;
                  object.gy = y;
                  this.addFlag(nx, ny, MAP_FLAG.BUILDING);
              }
          }
      }
      remObject(object) {
          let oldX = object.gx;
          let oldY = object.gy;
          let sectionOld = this.sectionTable[oldX][oldY];
          if (sectionOld) {
              let item = sectionOld.find(object);
              if (item) {
                  item.removeFromList();
              }
              if (sectionOld.size == 0) {
                  this.remFlag(oldX, oldY, MAP_FLAG.UNIT_STAND);
              }
          }
          else {
              console.error("移除的时候发现没有在地图上", object.uid);
          }
      }
      isGridLock(x, y) {
          return this.getGridLockCount(x, y) > 0;
      }
      getGridLockCount(x, y) {
          let row = this.gridLock[x];
          if (row)
              return row[y];
      }
      lockGrid(x, y, uid) {
          let row = this.gridLock[x];
          if (row) {
              let n = row[y] || 0;
              row[y] = n + 1;
              this.addFlag(x, y, MAP_FLAG.UNIT_MOVING);
              return true;
          }
          return false;
      }
      unlockGrid(x, y, uid) {
          let n = this.getGridLockCount(x, y);
          if (n) {
              let row = this.gridLock[x];
              if (row) {
                  n--;
                  row[y] = n;
                  if (n == 0) {
                      this.remFlag(x, y, MAP_FLAG.UNIT_MOVING);
                  }
                  return true;
              }
          }
          return false;
      }
      addDest(x, y) {
          this.gridDest[x][y] += 1;
      }
      subDest(x, y) {
          this.gridDest[x][y] -= 1;
      }
      getDest(x, y) {
          return this.gridDest[x][y];
      }
      checkPos(x, y) {
          let row = this.gridFlag[x];
          if (!row)
              return false;
          return row[y] != null;
      }
      checkFlag(x, y, flag) {
          let row = this.gridFlag[x];
          if (!row) {
              return false;
          }
          return row[y] & flag;
      }
      addFlag(x, y, flag) {
          this.gridFlag[x][y] |= flag;
      }
      remFlag(x, y, flag) {
          this.gridFlag[x][y] ^= flag;
      }
      clearFlagAll() {
          let width = this.width;
          let height = this.height;
          for (let w = 0; w < width; w++) {
              for (let h = 0; h < height; h++) {
                  if (this.checkFlag(w, h, MAP_FLAG.BARRIER))
                      this.remFlag(w, h, MAP_FLAG.BARRIER);
                  if (this.checkFlag(w, h, MAP_FLAG.ALPHA))
                      this.remFlag(w, h, MAP_FLAG.ALPHA);
              }
          }
      }
      clearFlag(x, y) {
          this.gridFlag[x][y] = 0;
      }
      getSectionTable(x, y) {
          let row = this.sectionTable[x];
          if (row)
              return row[y];
      }
      findAroundEmpty(x, y) {
          for (let offset of this.aroundOffset) {
              let nx = x + offset.x;
              let ny = y + offset.y;
              if (this.checkPos(nx, ny) && !this.checkFlag(nx, ny, MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND)) {
                  this.tempPosition.x = nx;
                  this.tempPosition.y = ny;
                  return this.tempPosition;
              }
          }
          return null;
      }
      findAroundEmptyNear(fx, fy, tx, ty) {
          for (let offset of this.aroundOffset) {
              let nx = tx + offset.x;
              let ny = ty + offset.y;
              if (fx != nx || fy != ny) {
                  let ax = Math.abs(nx - fx);
                  let ay = Math.abs(ny - fy);
                  if (ax <= 1 && ay <= 1 && this.checkPos(nx, ny) && !this.checkFlag(nx, ny, MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND)) {
                      this.tempPosition.x = nx;
                      this.tempPosition.y = ny;
                      return this.tempPosition;
                  }
              }
          }
          return null;
      }
      findNextMovePos(object, tx, ty, flag = MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND) {
          let ox = object.gx;
          let oy = object.gy;
          let dx = tx - ox;
          let dy = ty - oy;
          let stepx = 0;
          let stepy = 0;
          if (dx > 0) {
              stepx = 1;
          }
          else if (dx < 0) {
              stepx = -1;
          }
          if (dy > 0) {
              stepy = 1;
          }
          else if (dy < 0) {
              stepy = -1;
          }
          let nx = ox + stepx;
          let ny = oy + stepy;
          if (!this.checkFlag(nx, ny, flag)) {
              this.tempPosition.x = nx;
              this.tempPosition.y = ny;
              return this.tempPosition;
          }
          let pos = this.findAroundEmptyNear(ox, oy, nx, ny);
          if (pos) {
              this.tempPosition.x = pos.x;
              this.tempPosition.y = pos.y;
              return this.tempPosition;
          }
          let ax = Math.abs(dx);
          let ay = Math.abs(dy);
          if (ax > ay) {
              for (let offset of this.stepOffset) {
                  let nx = ox;
                  let ny = oy + offset;
                  if (this.checkPos(nx, ny) && !this.checkFlag(nx, ny, flag)) {
                      this.tempPosition.x = nx;
                      this.tempPosition.y = ny;
                      return this.tempPosition;
                  }
              }
          }
          else {
              for (let offset of this.stepOffset) {
                  let nx = ox + offset;
                  let ny = oy;
                  if (this.checkPos(nx, ny) && !this.checkFlag(nx, ny, flag)) {
                      this.tempPosition.x = nx;
                      this.tempPosition.y = ny;
                      return this.tempPosition;
                  }
              }
          }
      }
      addObjectByPos(listObject, x, y, camp, limit = 0, selectUids, distinct = false) {
          let section = this.getSectionTable(x, y);
          if (!section)
              return false;
          let head = section.head;
          while (head) {
              let obj = head.data;
              if (obj && obj.camp == camp) {
                  if (!selectUids || !selectUids[obj.uid]) {
                      if (selectUids && distinct) {
                          selectUids[obj.uid] = true;
                      }
                      listObject.push(obj);
                      if (limit && listObject.length >= limit) {
                          return true;
                      }
                  }
              }
              head = head.next;
          }
          return false;
      }
      findObjectsByOffset(x, y, offsets, flag, camp, limit = 0, debug = false, flipX = 1, selectUids = null, distinct = false) {
          let listObject = [];
          for (let i = 0; i < offsets.length; i = i + 2) {
              let tx = x + flipX * offsets[i];
              let ty = y + offsets[i + 1];
              if (debug)
                  LogicDebug.drawStep(tx, ty);
              if (this.checkPos(tx, ty) && this.checkFlag(tx, ty, flag)) {
                  if (this.addObjectByPos(listObject, tx, ty, camp, limit, selectUids, distinct)) {
                      return listObject;
                  }
              }
          }
          return listObject;
      }
      findObjectsByRange(x, y, flag, camp, range = 0, limit = 0, cirle = true, debug = false, selectUids = null, distinct = false, includeStart = true) {
          let listObject = [];
          if (includeStart) {
              if (debug)
                  LogicDebug.drawStep(x, y);
              if (this.addObjectByPos(listObject, x, y, camp, limit, selectUids, distinct)) {
                  return listObject;
              }
          }
          let step = 2;
          let rangeDouble = range * 2;
          let rangeSq = range * range;
          while (true) {
              let offsetCurt = null;
              let halfs = step / 2;
              let fromx = x - halfs;
              let fromy = y - halfs;
              let offsetx = 0;
              let offsety = 0;
              for (let i = 0; i < this.offsetQueue.length; i++) {
                  offsetCurt = this.offsetQueue[i];
                  for (let j = 1; j <= step; j++) {
                      offsetx += offsetCurt.x;
                      offsety += offsetCurt.y;
                      let tx = fromx + offsetx;
                      let ty = fromy + offsety;
                      let outOfRange = false;
                      if (cirle) {
                          let dx = tx - x;
                          let dy = ty - y;
                          let distanceSq = dx * dx + dy * dy - 1;
                          if (distanceSq > rangeSq) {
                              outOfRange = true;
                          }
                      }
                      if (debug && !outOfRange) {
                          LogicDebug.drawStep(tx, ty);
                      }
                      if (!outOfRange && this.checkPos(tx, ty) && this.checkFlag(tx, ty, flag)) {
                          if (this.addObjectByPos(listObject, tx, ty, camp, limit, selectUids, distinct)) {
                              return listObject;
                          }
                      }
                  }
              }
              step += 2;
              if (range && step > rangeDouble) {
                  break;
              }
              if (step > this.width && step > this.height) {
                  break;
              }
          }
          return listObject;
      }
      findAroundEmptyByRange(x, y, range, cirle = false, flag = MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND, onlyOut = false) {
          let step = Math.floor(range) * 2;
          let rangeSq = range * range;
          while (step > 0) {
              let offsetCurt = null;
              let halfs = step / 2;
              let fromx = x - halfs;
              let fromy = y - halfs;
              let offsetx = 0;
              let offsety = 0;
              for (let i = 0; i < this.offsetQueue.length; i++) {
                  offsetCurt = this.offsetQueue[i];
                  for (let j = 1; j <= step; j++) {
                      offsetx += offsetCurt.x;
                      offsety += offsetCurt.y;
                      let tx = fromx + offsetx;
                      let ty = fromy + offsety;
                      let outOfRange = false;
                      if (cirle) {
                          let dx = tx - x;
                          let dy = ty - y;
                          let distanceSq = dx * dx + dy * dy - 1;
                          if (distanceSq > rangeSq) {
                              outOfRange = true;
                          }
                      }
                      if (!outOfRange && this.checkPos(tx, ty) && !this.checkFlag(tx, ty, flag)) {
                          this.tempPosition.x = tx;
                          this.tempPosition.y = ty;
                          return this.tempPosition;
                      }
                  }
              }
              if (onlyOut) {
                  break;
              }
              step -= 2;
              if (step < 0) {
                  break;
              }
          }
          return null;
      }
      findCirleByRange(x, y, range, flag = MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND, offset = 0.5) {
          let step = Math.floor(range) * 2;
          let posList = [];
          while (step > 0) {
              let offsetCurt = null;
              let halfs = step / 2;
              let fromx = x - halfs;
              let fromy = y - halfs;
              let offsetx = 0;
              let offsety = 0;
              for (let i = 0; i < this.offsetQueue.length; i++) {
                  offsetCurt = this.offsetQueue[i];
                  for (let j = 1; j <= step; j++) {
                      offsetx += offsetCurt.x;
                      offsety += offsetCurt.y;
                      let tx = fromx + offsetx;
                      let ty = fromy + offsety;
                      let outOfRange = false;
                      let dx = tx - x;
                      let dy = ty - y;
                      let distance = Math.sqrt(dx * dx + dy * dy);
                      if (distance > range + offset || distance < range - offset) {
                          outOfRange = true;
                      }
                      if (!outOfRange && this.checkPos(tx, ty) && !this.checkFlag(tx, ty, flag)) {
                          posList.push({ x: tx, y: ty });
                      }
                  }
              }
              step -= 2;
              if (step < 0) {
                  break;
              }
          }
          return posList;
      }
      findBestAttackPos(x, y, cx, cy, flag = MAP_FLAG.BUILDING, range = 0) {
          let weightMin = Number.MAX_VALUE;
          let bestPosX = 0;
          let bestPosY = 0;
          let find = false;
          let BEST_FIND_RAD = this.BEST_FIND_RAD;
          let count = 2;
          for (let i = 0; i <= count; i++) {
              let rx = LogicTool.rotatex(x, y, BEST_FIND_RAD * i, cx, cy);
              let ry = LogicTool.rotatey(x, y, BEST_FIND_RAD * i, cx, cy);
              let tx = Math.round(rx);
              let ty = Math.round(ry);
              if (this.checkPos(tx, ty) && !this.checkFlag(tx, ty, flag)) {
                  if (range) {
                      let dx = tx - x;
                      let dy = ty - y;
                      if (!LogicTool.inRangeByDxDy(dx, dy, range)) {
                          continue;
                      }
                  }
                  let weight = this.getDest(tx, ty) + this.getSectionTable(tx, ty).size;
                  if (weight < weightMin) {
                      find = true;
                      weightMin = weight;
                      bestPosX = tx;
                      bestPosY = ty;
                  }
              }
          }
          for (let i = 1; i <= count; i++) {
              let rx = LogicTool.rotatex(x, y, -BEST_FIND_RAD * i, cx, cy);
              let ry = LogicTool.rotatey(x, y, -BEST_FIND_RAD * i, cx, cy);
              let tx = Math.round(rx);
              let ty = Math.round(ry);
              if (this.checkPos(tx, ty) && !this.checkFlag(tx, ty, flag)) {
                  if (range) {
                      let dx = tx - x;
                      let dy = ty - y;
                      if (!LogicTool.inRangeByDxDy(dx, dy, range)) {
                          continue;
                      }
                  }
                  let weight = this.getDest(tx, ty) + this.getSectionTable(tx, ty).size;
                  if (weight < weightMin) {
                      find = true;
                      weightMin = weight;
                      bestPosX = tx;
                      bestPosY = ty;
                  }
              }
          }
          if (find)
              return { x: bestPosX, y: bestPosY };
          else
              return null;
      }
      findBestAttackPosByLeftRight(sx, sy, tx, ty, flag = MAP_FLAG.BUILDING, range = 0) {
          let dx = tx - sx;
          let scale = dx > 0 ? -1 : 1;
          for (let i = range; i > 0; i--) {
              let nx = tx + i * scale;
              let ny = ty;
              if (this.checkPos(nx, ny) && !this.checkFlag(nx, ny, flag)) {
                  return { x: nx, y: ny };
              }
          }
          return null;
      }
      findCirleByRangeAndDegree2(x, y, cx, cy, degree, flag = MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND, offset = 0.5) {
          let posList = [];
          let step = 360 / degree;
          let stepRad = Math.PI / 180 * degree;
          for (let i = 0; i < step; i++) {
              let rd = stepRad * i;
              let rx = LogicTool.rotatex(x, y, rd, cx, cy);
              let ry = LogicTool.rotatey(x, y, rd, cx, cy);
              let tx = Math.round(rx);
              let ty = Math.round(ry);
              if (this.checkPos(tx, ty) && !this.checkFlag(tx, ty, flag)) {
                  posList.push({ x: tx, y: ty });
              }
          }
          return posList;
      }
      findObjectsBySector(x, y, rx, ry, range, degree, flag, camp, limit = 0, debug = false, selectUids = null) {
          let listObject = [];
          if (debug)
              LogicDebug.drawStep(x, y);
          if (this.addObjectByPos(listObject, x, y, camp, limit, selectUids)) {
              return listObject;
          }
          let step = 2;
          let rangeDouble = range * 2;
          let rangeSq = range * range;
          while (true) {
              let offsetCurt = null;
              let halfs = step / 2;
              let fromx = x - halfs;
              let fromy = y - halfs;
              let offsetx = 0;
              let offsety = 0;
              for (let i = 0; i < this.offsetQueue.length; i++) {
                  offsetCurt = this.offsetQueue[i];
                  for (let j = 1; j <= step; j++) {
                      offsetx += offsetCurt.x;
                      offsety += offsetCurt.y;
                      let tx = fromx + offsetx;
                      let ty = fromy + offsety;
                      let outOfRange = false;
                      let dx = tx - x;
                      let dy = ty - y;
                      let distanceSq = dx * dx + dy * dy - 1;
                      if (distanceSq > rangeSq) {
                          outOfRange = true;
                      }
                      else {
                          if (!LogicTool.isPointInSector(x, y, rx, ry, tx, ty, degree)) {
                              outOfRange = true;
                          }
                      }
                      if (debug && !outOfRange) {
                          LogicDebug.drawStep(tx, ty);
                      }
                      if (!outOfRange && this.checkPos(tx, ty) && this.checkFlag(tx, ty, flag)) {
                          if (this.addObjectByPos(listObject, tx, ty, camp, limit, selectUids)) {
                              return listObject;
                          }
                      }
                  }
              }
              step += 2;
              if (range && step > rangeDouble) {
                  break;
              }
              if (step > this.width && step > this.height) {
                  break;
              }
          }
          return listObject;
      }
      findObjectsByRect(cx, cy, tx, ty, width, height, flag, camp, limit = 0, debug = false, selectUids = null) {
          let listObject = [];
          let widthHalf = Math.floor(width / 2);
          let dx = tx - cx;
          let dy = ty - cy;
          let p = this._tempPoint1;
          p.x = dx;
          p.y = dy;
          p.normalize();
          let rx = 0;
          let ry = 0;
          if (p.x != 0) {
              ry = 1;
              rx = -p.y / p.x * ry;
          }
          else if (p.y != 0) {
              rx = 1;
              ry = -p.x / p.y * rx;
          }
          else {
              rx = -p.y;
              ry = p.x;
          }
          let rp = this._tempPoint2;
          rp.x = rx;
          rp.y = ry;
          rp.normalize();
          for (let w = -widthHalf; w <= widthHalf; w++) {
              let ox = cx + rp.x * w;
              let oy = cy + rp.y * w;
              for (let h = 1; h < height; h++) {
                  let nx = Math.round(ox + p.x * h);
                  let ny = Math.round(oy + p.y * h);
                  LogicDebug.drawStep(nx, ny);
                  if (this.checkPos(nx, ny) && this.checkFlag(nx, ny, flag)) {
                      if (this.addObjectByPos(listObject, nx, ny, camp, limit, selectUids)) {
                          return listObject;
                      }
                  }
              }
          }
          return listObject;
      }
  }

  class StateMachine {
      constructor() {
          this.stateCurt = 0;
          this.stateNext = 0;
          this.state2name = {};
          this.funcEnter = {};
          this.funcExecute = {};
          this.funcExit = {};
          this.funcExecuteCurt = StateMachine.FuncEmpty;
          this.state2relation = {};
          this.state2nextstate = {};
          this.caller = this;
      }
      update(dt) {
          this.updateLogic(dt);
      }
      updateLogic(dt) {
          this.funcExecuteCurt(dt);
          if (this.stateNext) {
              this.callFunc(this.funcExit[this.stateCurt], dt);
              this.stateLast = this.stateCurt;
              this.stateCurt = this.stateNext;
              this.stateNext = 0;
              this.funcExecuteCurt = this.funcExecute[this.stateCurt];
              this.callFunc(this.funcEnter[this.stateCurt], dt);
          }
      }
      static FuncEmpty() { }
      ;
      registerState(state, stateName, caller, funcEnter, funcExecute, funcExit) {
          this.state2name[state] = stateName;
          if (caller)
              this.caller = caller;
          if (funcEnter) {
              this.funcEnter[state] = funcEnter;
          }
          else {
              this.funcEnter[state] = this.caller["enter" + stateName];
          }
          if (funcExecute) {
              this.funcExecute[state] = funcExecute.bind(this.caller);
          }
          else {
              this.funcExecute[state] = (this.caller["exec" + stateName] || StateMachine.FuncEmpty).bind(this.caller);
          }
          if (funcExit) {
              this.funcExit[state] = funcExit;
          }
          else {
              this.funcExit[state] = this.caller["exit" + stateName];
          }
      }
      registerRelation(state, toStates, nextState) {
          if (nextState) {
              this.state2nextstate[state] = nextState;
          }
          var relation = this.state2relation[state];
          if (!relation) {
              relation = {};
          }
          var len = toStates.length;
          for (var i = 0; i < len; i++) {
              relation[toStates[i]] = true;
          }
          this.state2relation[state] = relation;
      }
      resetMachine() {
          this.stateCurt = 0;
          this.stateNext = 0;
      }
      setCurrentState(state) {
          this.callFunc(this.funcExit[this.stateCurt]);
          this.callFunc(this.funcEnter[state]);
          this.stateCurt = state;
          this.stateNext = 0;
          this.funcExecuteCurt = this.funcExecute[this.stateCurt] || StateMachine.FuncEmpty;
      }
      exitState(force) {
          var stateNext = this.state2nextstate[this.stateCurt];
          if (stateNext) {
              this.setState(stateNext, force);
          }
          else {
              this.setState(this.stateLast, force);
          }
      }
      setNextStateByName(name) {
          this.setNextState(this.name2state[name], false);
      }
      setState(state, force) {
          let result = this.setNextState(state, force);
          if (!result) {
          }
          else {
          }
      }
      setStateNoReEnter(state, force) {
          if (!force && this.stateCurt == state)
              return false;
          this.setState(state, force);
          return true;
      }
      getState() {
          return this.stateCurt;
      }
      getLastState() {
          return this.stateLast;
      }
      getNextState(state) {
          return this.state2nextstate[state];
      }
      getStateName(state) {
          return this.state2name[state];
      }
      checkRelation(fromState, toState) {
          var relation = this.state2relation[fromState];
          if (relation) {
              let friend = relation[toState];
              if (!friend) {
                  return false;
              }
          }
          return true;
      }
      setNextState(state, force) {
          if (!force && (this.stateCurt == state || this.stateNext == state))
              return true;
          if (this.stateNext && !force) {
              if (!this.checkRelation(this.stateNext, state)) {
                  return false;
              }
          }
          else {
              if (this.stateCurt && !force) {
                  if (!this.checkRelation(this.stateCurt, state)) {
                      return false;
                  }
              }
          }
          this.stateNext = state;
          return true;
      }
      callFunc(func, dt) {
          if (func) {
              func.call(this.caller, dt);
          }
      }
  }

  class LogicPool {
      static getItem(clas, ...arg) {
          let key = clas.prototype.constructor.poolkey;
          if (!key) {
              console.error("LogicPool.getItem not found poolkey", clas);
              return new clas(...arg);
          }
          let pool = this.pools[key];
          if (pool && pool.length) {
              this.debug("复用", key, pool.length);
              return pool.shift();
          }
          else {
              return new clas();
          }
      }
      static putItem(obj) {
          let key = obj.constructor.prototype.constructor.poolkey;
          if (!key) {
              console.error("LogicPool.putItem not found poolkey", obj);
              return;
          }
          let pool = this.pools[key];
          if (!pool) {
              pool = [];
              this.pools[key] = pool;
          }
          pool.push(obj);
          this.debug("回收", key, pool.length);
      }
      static debug(...arg) {
      }
  }
  LogicPool.pools = {};

  class LogicComponent extends StateMachine {
      static create(componentType) {
          return LogicPool.getItem(componentType).reset();
      }
      static recover(obj) {
          LogicPool.putItem(obj);
      }
      reset() {
          this.onReset();
          return this;
      }
      onCreate() {
      }
      onUpdate(t) {
      }
      onDestroy() {
          LogicComponent.recover(this);
      }
      onReset() {
      }
  }

  var ENEMY_ATTACK_STATE;
  (function (ENEMY_ATTACK_STATE) {
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["IDLE"] = 1] = "IDLE";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["READY"] = 2] = "READY";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["CAST"] = 3] = "CAST";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["ATTACK"] = 4] = "ATTACK";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["CD"] = 5] = "CD";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["KEEP_LOCK"] = 6] = "KEEP_LOCK";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["KEEP_ATTACK"] = 7] = "KEEP_ATTACK";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["KEEP_CD"] = 8] = "KEEP_CD";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["ATTACK_END"] = 9] = "ATTACK_END";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["ATTACK_DOUBLE"] = 10] = "ATTACK_DOUBLE";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["STOP"] = 11] = "STOP";
      ENEMY_ATTACK_STATE[ENEMY_ATTACK_STATE["WAIT"] = 12] = "WAIT";
  })(ENEMY_ATTACK_STATE || (ENEMY_ATTACK_STATE = {}));
  class LogicComponentAttackerEnemy extends LogicComponent {
      constructor() {
          super(...arguments);
          this.loop = true;
          this.timeInState = 0;
          this.timeWtstate = 0;
          this.targetId = 0;
          this.targetPos = new LogicPoint;
          this.index = 0;
          this.attackCount = 0;
          this.skillData = {
              skillId: "1",
              template: "",
              timeCast: 0.25,
              timeCD: 2,
              count: 1,
              prepare: false,
              ground: false,
              skillDb: null,
              limit: 0,
          };
          this.skillDataSet = {
              skillId: "1",
              template: "",
              timeCast: 0.25,
              timeCD: 2,
              count: 1,
              prepare: false,
              ground: false,
              skillDb: null,
              limit: 0,
          };
          this.keepUids = [];
      }
      onCreate() {
          this.registerState(ENEMY_ATTACK_STATE.IDLE, "Idle");
          this.registerState(ENEMY_ATTACK_STATE.READY, "Ready");
          this.registerState(ENEMY_ATTACK_STATE.CAST, "Cast");
          this.registerState(ENEMY_ATTACK_STATE.ATTACK, "Attack");
          this.registerState(ENEMY_ATTACK_STATE.CD, "CD");
          this.registerState(ENEMY_ATTACK_STATE.ATTACK_END, "AttackEnd");
          this.registerState(ENEMY_ATTACK_STATE.ATTACK_DOUBLE, "AttackDouble");
          this.registerState(ENEMY_ATTACK_STATE.KEEP_LOCK, "KeepLock");
          this.registerState(ENEMY_ATTACK_STATE.KEEP_ATTACK, "KeepAttack");
          this.registerState(ENEMY_ATTACK_STATE.KEEP_CD, "KeepCD");
          this.registerState(ENEMY_ATTACK_STATE.STOP, "Stop");
          this.registerRelation(ENEMY_ATTACK_STATE.STOP, {});
          this.registerState(ENEMY_ATTACK_STATE.WAIT, "Wait");
          this.registerRelation(ENEMY_ATTACK_STATE.WAIT, {});
          this.setState(ENEMY_ATTACK_STATE.IDLE);
      }
      onUpdate(t) {
          if (!this.owner.checkFlag(LogicObjectFlag.NO_ATTACK)) {
              this.update(t);
          }
      }
      onDestroy() {
          super.onDestroy();
      }
      onReset() {
          this.idle(true);
      }
      isIdle() {
          return this.getState() == ENEMY_ATTACK_STATE.IDLE;
      }
      idle(force = false) {
          this.targetId = 0;
          this.loop = true;
          this.setState(ENEMY_ATTACK_STATE.IDLE, force);
      }
      ready(force = false) {
          if (force || this.getState() == ENEMY_ATTACK_STATE.IDLE) {
              this.setState(ENEMY_ATTACK_STATE.READY, force);
          }
      }
      cast(force = false) {
          if (force || this.getState() == ENEMY_ATTACK_STATE.IDLE) {
              this.setState(ENEMY_ATTACK_STATE.CAST, force);
          }
      }
      isCasting() {
          return this.getState() == ENEMY_ATTACK_STATE.CAST;
      }
      attack() {
          if (this.owner.camp == LogicCamp.ENEMY && !LogicConfig.enableEnemySkill) {
              this.setState(ENEMY_ATTACK_STATE.CD);
              return;
          }
          let world = this.owner.world;
          let target = world.getObjectMgr().getObjectById(this.targetId);
          if (!target) {
              if (this.skillData.count == 0) {
                  this.setState(ENEMY_ATTACK_STATE.ATTACK_END);
                  return;
              }
              else {
                  if (this.skillData.searchInAttack) {
                      target = this.findAttackTarget();
                  }
                  if (!target) {
                      target = world.addVirtual(this.targetPos.x, this.targetPos.y);
                      this.targetId = 0;
                  }
                  else {
                      this.targetId = target.uid;
                  }
              }
          }
          if (target) {
              this.owner.useSkill(target, this.skillData, this.index, this.attackCount);
          }
          else {
              console.error("LogicComponentAttackerEnemy.attack: 这个地方不应该为空");
          }
          if (this.skillData.double) {
              this.skillData.double = false;
              this.setState(ENEMY_ATTACK_STATE.ATTACK_DOUBLE);
          }
          else {
              this.setState(ENEMY_ATTACK_STATE.CD);
          }
      }
      attackKeep() {
          if (this.owner.camp == LogicCamp.ENEMY && !LogicConfig.enableEnemySkill) {
              this.setState(ENEMY_ATTACK_STATE.KEEP_CD);
              return;
          }
          let world = this.owner.world;
          let isAllDead = true;
          for (let uid of this.keepUids) {
              let target = world.getObjectMgr().getObjectById(uid);
              if (target) {
                  isAllDead = false;
                  world.skillMgr.useSkill(this.owner, target, this.skillData, this.index, this.attackCount);
              }
          }
          if (isAllDead) {
              this.setState(ENEMY_ATTACK_STATE.ATTACK_END);
          }
          else {
              this.setState(ENEMY_ATTACK_STATE.KEEP_CD);
          }
      }
      canCastSkill(target, skillData) {
          return this.owner.isTargetInRange(target) && this.owner.canCastSkillToTarget(target, skillData);
      }
      findSkillTarget(target) {
          let skillData = this.skillData;
          return this.owner.world.skillMgr.findTarget2Cast(skillData.template, this.owner, target, skillData, this.index);
      }
      findAttackTarget() {
          let world = this.owner.world;
          let targetFinal = null;
          if (this.targetId) {
              let target = world.getObjectMgr().getObjectById(this.targetId);
              if (target && this.canCastSkill(target, this.skillData)) {
                  targetFinal = target;
              }
          }
          if (!targetFinal) {
              if (this.skillData.camp == LogicCamp.SELF) {
                  targetFinal = this.owner;
              }
              else {
                  let target = world.getObjectMgr().getObjectById(this.owner.targetId);
                  if (target && this.canCastSkill(target, this.skillData)) {
                      targetFinal = target;
                  }
              }
          }
          return targetFinal;
      }
      stop(force = false) {
          this.setState(ENEMY_ATTACK_STATE.STOP, force);
      }
      wait() {
          this.setState(ENEMY_ATTACK_STATE.WAIT, true);
      }
      enterReady() {
          if (!this.skillData.prepare) {
              this.owner.prepareSkillData(this.skillData);
          }
          this.skillData.prepare = false;
      }
      execReady(t) {
          let targetFinal = this.findAttackTarget();
          if (targetFinal) {
              targetFinal = this.findSkillTarget(targetFinal);
              this.targetPos.x = targetFinal.gx;
              this.targetPos.y = targetFinal.gy;
              if (this.skillData.ground) {
                  targetFinal = this.owner.world.addVirtual(this.targetPos.x, this.targetPos.y);
              }
              this.targetId = targetFinal.uid;
              this.setState(ENEMY_ATTACK_STATE.CAST);
          }
          else {
              this.targetId = 0;
              this.setState(ENEMY_ATTACK_STATE.IDLE);
          }
      }
      enterCast() {
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCast;
          this.attackCount = 0;
          this.owner.onSkillCast(this.timeWtstate, this.index, this.targetId, this.skillData);
      }
      execCast(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.skillData.count == 0) {
                  this.setState(ENEMY_ATTACK_STATE.KEEP_LOCK);
              }
              else {
                  this.setState(ENEMY_ATTACK_STATE.ATTACK);
              }
          }
      }
      enterAttack() {
          this.attack();
          this.attackCount++;
      }
      enterCD() {
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCD;
      }
      execCD(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.loop) {
                  if (this.attackCount < this.skillData.count) {
                      this.setState(ENEMY_ATTACK_STATE.ATTACK);
                  }
                  else {
                      this.setState(ENEMY_ATTACK_STATE.ATTACK_END);
                  }
              }
              else {
                  this.setState(ENEMY_ATTACK_STATE.IDLE);
              }
          }
      }
      enterKeepLock() {
          this.attackCount = 0;
          let world = this.owner.world;
          let target = world.getObjectMgr().getObjectById(this.targetId);
          let targets = world.skillMgr.findTargets(this.owner, target, this.skillData, this.index, this.attackCount);
          this.keepUids.length = 0;
          for (let target of targets) {
              if (target)
                  this.keepUids.push(target.uid);
          }
          this.setState(ENEMY_ATTACK_STATE.KEEP_ATTACK);
      }
      enterKeepAttack() {
          this.attackKeep();
          this.attackCount++;
      }
      enterKeepCD() {
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCD;
      }
      execKeepCD(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.loop) {
                  this.setState(ENEMY_ATTACK_STATE.KEEP_ATTACK);
              }
              else {
                  this.setState(ENEMY_ATTACK_STATE.IDLE);
              }
          }
      }
      enterAttackEnd() {
          this.targetId = 0;
          this.owner.onSkillUseEnd(this.skillData, this.index);
          this.setState(ENEMY_ATTACK_STATE.READY);
      }
      enterAttackDouble() {
          this.timeInState = 0;
          this.timeWtstate = 0.1;
      }
      execAttackDouble(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              this.setState(ENEMY_ATTACK_STATE.ATTACK);
          }
      }
      enterStop() {
      }
      execStop(t) {
          this.skillData.prepare = false;
          this.setState(ENEMY_ATTACK_STATE.READY, true);
      }
      enterWait() {
      }
  }
  LogicComponentAttackerEnemy.poolkey = "LogicComponentAttackerEnemy";

  var MOVE_STATE;
  (function (MOVE_STATE) {
      MOVE_STATE[MOVE_STATE["THINK"] = 1] = "THINK";
      MOVE_STATE[MOVE_STATE["MOVETO"] = 2] = "MOVETO";
      MOVE_STATE[MOVE_STATE["JUMPTO"] = 3] = "JUMPTO";
      MOVE_STATE[MOVE_STATE["STOP"] = 4] = "STOP";
  })(MOVE_STATE || (MOVE_STATE = {}));
  class LogicComponentMove extends LogicComponent {
      constructor() {
          super(...arguments);
          this.mSpeed = 0;
          this.mSpeedStandard = 0;
          this.mSpeedScale = 1;
          this.mPathIndex = 0;
          this.mMoveDistance = 0;
          this.lockSuccess = false;
          this.stateTimePass = 0;
          this.stateTimeJump = 0;
          this.logicSpeedScale = 0;
          this.destx = -1;
          this.desty = -1;
      }
      onCreate() {
          this.mSpeedStandard = this.mSpeed = 0.5;
          this.mDest = new LogicPoint();
          this.mLock = new LogicPoint();
          this.mMoveDir = new LogicPoint();
          this.lockSuccess = false;
          this.mPath = [];
          this.registerState(MOVE_STATE.THINK, "Think");
          this.registerState(MOVE_STATE.MOVETO, "MoveTo");
          this.registerState(MOVE_STATE.STOP, "Stop");
          this.registerState(MOVE_STATE.JUMPTO, "JumpTo");
          this.setState(MOVE_STATE.STOP);
      }
      onReset() {
          if (this.mPath)
              this.mPath.length = 0;
          this.lockSuccess = false;
          this.mPathIndex = 0;
          this.logicSpeedScale = 0;
          this.setState(MOVE_STATE.STOP);
      }
      set speed(speed) {
          this.mSpeedStandard = this.mSpeed = speed;
      }
      scaleSpeed(scale) {
          if (scale < this.mSpeedScale) {
              this.mSpeedScale = scale;
          }
          this.mSpeed = this.mSpeedStandard * this.mSpeedScale;
      }
      getScaleSpeed() {
          return this.mSpeedScale;
      }
      recoverSpeed() {
          this.mSpeedScale = 1;
          this.mSpeed = this.mSpeedStandard;
      }
      onUpdate(t) {
          if (!this.owner.checkFlag(LogicObjectFlag.NO_MOVE)) {
              if (this.logicSpeedScale) {
                  for (let i = 0; i < this.logicSpeedScale; i++) {
                      this.update(t);
                  }
              }
              else {
                  this.update(t);
              }
          }
      }
      onDestroy() {
          super.onDestroy();
          this.unlockGrid();
      }
      addDest(x, y) {
          this.destx = x;
          this.desty = y;
          this.owner.world.map.addDest(this.destx, this.desty);
      }
      subDest() {
          if (this.destx >= 0 && this.destx >= 0) {
              this.owner.world.map.subDest(this.destx, this.desty);
          }
          this.destx = -1;
          this.desty = -1;
      }
      lockGrid(x, y) {
          let owner = this.owner;
          if (owner.world.map.lockGrid(x, y, owner.uid)) {
              this.lockSuccess = true;
              this.mLock.x = x;
              this.mLock.y = y;
          }
      }
      unlockGrid() {
          if (this.lockSuccess) {
              let owner = this.owner;
              owner.world.map.unlockGrid(this.mLock.x, this.mLock.y, owner.uid);
          }
          this.lockSuccess = false;
      }
      moveByPath(path) {
          if (this.getState() == MOVE_STATE.JUMPTO)
              return;
          this.mPath = path;
          this.mPathIndex = 0;
          this.setState(MOVE_STATE.THINK);
      }
      clearPath() {
          this.mPath = null;
          this.mPathIndex = 0;
      }
      jumpTo(time, tx, ty) {
          this.clearPath();
          this.stateTimeJump = time;
          this.mDest.x = tx;
          this.mDest.y = ty;
          this.setState(MOVE_STATE.JUMPTO);
      }
      moveTo(tx, ty) {
          if (this.getState() == MOVE_STATE.JUMPTO || this.getState() == MOVE_STATE.MOVETO) {
              return;
          }
          this.mDest.x = tx;
          this.mDest.y = ty;
          let dx = tx - this.owner.mx;
          let dy = ty - this.owner.my;
          this.mMoveDir.x = dx;
          this.mMoveDir.y = dy;
          this.mMoveDistance = this.mMoveDir.distance();
          this.mMoveDir.normalize();
          this.setState(MOVE_STATE.MOVETO);
      }
      isStop() {
          return this.getState() == MOVE_STATE.STOP;
      }
      stop() {
          this.setState(MOVE_STATE.STOP);
      }
      onMovePointEnd() {
          if (this.mPath) {
              if (this.mPath.length && this.mPathIndex < this.mPath.length) {
                  this.setState(MOVE_STATE.THINK);
              }
              else {
                  this.subDest();
                  this.mPathIndex = 0;
                  this.setState(MOVE_STATE.STOP);
              }
          }
      }
      enterThink() {
          if (this.mPath) {
              let p = this.mPath[this.mPathIndex];
              if (p) {
                  if (this.mPathIndex == 0) {
                      let p = this.mPath[this.mPath.length - 1];
                      this.addDest(p.x, p.y);
                  }
                  this.moveTo(p.x, p.y);
              }
              else {
                  this.setState(MOVE_STATE.STOP);
              }
              this.mPathIndex++;
          }
          else {
              this.setState(MOVE_STATE.STOP);
          }
      }
      enterMoveTo() {
          this.lockGrid(this.mDest.x, this.mDest.y);
      }
      execMoveTo(t) {
          let disMove = this.mSpeed * t;
          let mx = this.owner.mx + this.mMoveDir.x * disMove;
          let my = this.owner.my + this.mMoveDir.y * disMove;
          this.owner.moveTo(t, this.mMoveDir.x, this.mMoveDir.y, mx, my);
          this.mMoveDistance -= disMove;
          if (this.mMoveDistance <= 0) {
              this.onMovePointEnd();
          }
      }
      exitMoveTo() {
          this.unlockGrid();
      }
      enterStop() {
          this.owner.handleMessage(LogicMessage.MOVE_STOP);
      }
      enterJumpTo() {
          this.stateTimePass = 0;
      }
      execJumpTo(t) {
          this.stateTimePass += t;
          if (this.stateTimePass >= this.stateTimeJump) {
              let dx = this.mDest.x - this.owner.mx;
              let dy = this.mDest.y - this.owner.my;
              this.owner.moveTo(t, dx, dy, this.mDest.x, this.mDest.y);
              this.setState(MOVE_STATE.THINK);
          }
      }
  }
  LogicComponentMove.poolkey = "LogicComponentMove";

  class LogicBuff {
      constructor() {
          this.valid = false;
          this.timepass = 0;
          this.timedelay = 0;
          this.interval = 1;
          this.curCount = 0;
          this.maxcount = 1;
          this.prev = null;
          this.next = null;
          this.casterId = 0;
          this.tidCaster = "";
          this.data = null;
      }
      bind(uid, id, template) {
          this.uid = uid;
          this.id = id;
          this.template = template;
          this.next = null;
          this.prev = null;
          this.data = null;
          return this;
      }
      static create() {
          return LogicPool.getItem(LogicBuff);
      }
      static recover(obj) {
          LogicPool.putItem(obj);
      }
      tick(t, target) {
          if (!this.valid) {
              return;
          }
          this.timepass += t;
          if (this.timedelay && this.timepass < this.timedelay) {
              return;
          }
          if (this.timedelay) {
              this.timedelay = 0;
              this.execute(target, this);
          }
          if (this.timepass >= this.interval) {
              this.timepass = 0;
              if (this.curCount >= this.maxcount) {
                  this.valid = false;
                  this.removeFrom(target);
              }
              else {
                  this.execute(target, this);
              }
          }
      }
      removeFrom(target) {
          let prev = this.prev;
          let next = this.next;
          if (prev) {
              prev.next = next;
          }
          if (next) {
              next.prev = prev;
          }
          this.prev = null;
          this.next = null;
          LogicBuff.recover(this);
          this.end(target, this);
      }
      start(caster, target, buff, time, delay, count, param) {
          if (count <= 0)
              return;
          this.valid = true;
          this.timepass = 0;
          this.timedelay = delay;
          this.interval = time / count;
          this.curCount = 0;
          this.maxcount = count;
          this.casterId = caster.uid;
          this.onBuffStart(caster, target, buff, param);
          if (!delay) {
              this.execute(target, buff);
          }
      }
      restart(caster, target, buff, time, delay, count, param) {
          if (count <= 0)
              return;
          this.valid = true;
          this.timepass = 0;
          this.timedelay = delay;
          this.interval = time / count;
          this.curCount = 0;
          this.maxcount = count;
          this.casterId = caster.uid;
          this.onBuffRestart(caster, target, buff, param);
          if (!delay) {
              this.execute(target, buff);
          }
      }
      calc(target) {
          this.onBuffCalc(target, this);
      }
      execute(target, buff) {
          this.curCount++;
          this.onBuffExec(target, buff);
      }
      end(target, buff) {
          this.onBuffEnd(target, buff);
      }
      execAndClear(target, skillDb) {
          return this.onBuffExecAndClear(target, this, skillDb);
      }
      onBuffStart(caster, target, buff, param) {
          target.onBuffStart(buff);
          target.world.skillMgr.buffStart(this.template, caster, target, buff, param);
      }
      onBuffRestart(caster, target, buff, param) {
          target.onBuffRestart(buff);
          target.world.skillMgr.buffRestart(this.template, caster, target, buff, param);
      }
      onBuffExec(target, buff) {
          target.onBuffExec(buff);
          target.world.skillMgr.buffExec(this.template, target, buff);
      }
      onBuffCalc(target, buff) {
          target.onBuffCalc(buff);
          target.world.skillMgr.buffCalc(this.template, target, buff);
      }
      onBuffEnd(target, buff) {
          target.onBuffEnd(buff);
          target.world.skillMgr.buffEnd(this.template, target, buff);
      }
      onBuffExecAndClear(target, buff, skillDb) {
          return target.world.skillMgr.buffExecAndClear(this.template, target, buff, skillDb);
      }
  }
  LogicBuff.poolkey = "LogicBuff";

  class LogicTicker {
      constructor() {
          this.tickAtOnce = false;
      }
      tick() {
      }
  }
  class LogicTickManager {
      constructor(world) {
          this.timePass = 0;
          this.timeStep = LogicConfig.LOGIC_FRAME_ITME;
          this.timeClock = 0;
          this.world = world;
          this.listTickers = [];
      }
      addTicker(ticker) {
          this.listTickers.push(ticker);
      }
      removeTicker(ticker) {
      }
      tick() {
          for (let i = 0; i < this.listTickers.length; i++) {
              this.listTickers[i].tick();
          }
      }
      tickTime(dt) {
          this.timePass += dt;
          this.timeClock += dt;
          while (this.timePass > this.timeStep) {
              this.tick();
              this.timePass -= this.timeStep;
          }
      }
      get time() {
          return this.timeClock;
      }
  }

  class LogicObjectManager extends LogicTicker {
      constructor(world) {
          super();
          this.world = world;
          this.linkObject = new LinkList();
          this.uid2Object = new Map();
      }
      static genObjectId() {
          this.autoIncreaseId++;
          return this.autoIncreaseId;
      }
      tick() {
          let head = this.linkObject.head;
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object) {
                  object.tick();
              }
          }
      }
      isObjectInLinkList(target) {
          let head = this.linkObject.head;
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object && object.uid == target.uid) {
                  return true;
              }
          }
          return false;
      }
      addObject(object) {
          if (this.isObjectInLinkList(object)) {
              console.error("目标已经在LogicObjectManager的管理之中了!", object.uid);
              return;
          }
          this.uid2Object[object.uid] = this.linkObject.append(object);
      }
      remObject(object) {
          let item = this.uid2Object[object.uid];
          if (item) {
              item.removeFromList();
          }
          else {
              console.error("没有找到目标的关联链表");
          }
          delete this.uid2Object[object.uid];
      }
      getObjectById(id) {
          let item = this.uid2Object[id];
          if (item)
              return item.data;
      }
      getLinkHead() {
          return this.linkObject.head;
      }
  }
  LogicObjectManager.autoIncreaseId = 0;

  class LogicObject {
      constructor(tid, lv) {
          this.valid = true;
          this.virtual = false;
          this.removed = false;
          this.gx = -1;
          this.gy = -1;
          this.mx = -1;
          this.my = -1;
          this.targetId = 0;
          this.targetIds = [];
          this.camp = LogicCamp.NONE;
          this.flag = 0;
          this.flagCount = {};
          this.skillId2Time = {};
          this.tempSkillData = {
              skillId: "1",
              template: "",
              timeCast: 0.25,
              timeCD: 2,
              count: 1,
              limit: 1,
              prepare: false,
              ground: false,
              skillDb: null,
          };
          this.buffHead = { prev: null, next: null };
          this.hitEffectEx = null;
          this.init(tid, lv);
          this.skillId2Time = {};
      }
      set range(value) {
      }
      get range() {
          return 0;
      }
      init(tid, lv) {
          this.tid = tid;
          this.lv = lv || 0;
          this.removed = false;
          this.uid = LogicObjectManager.genObjectId();
          this.logicComponents = [];
          this.buffHead.prev = null;
          this.buffHead.next = null;
          this.gx = -1;
          this.gy = -1;
          this.mx = -1;
          this.my = -1;
          this.targetId = 0;
          this.targetIds = [];
          this.camp = LogicCamp.NONE;
          this.flag = 0;
          this.flagCount = {};
          this.onInit();
          return this;
      }
      create(world) {
          this.world = world;
          this.world.getObjectMgr().addObject(this);
          this.onCreate();
      }
      remove() {
          this.removed = true;
          this.clearLogicCompnent();
          this.onRemove();
          LogicObject.recover(this);
      }
      tick() {
          if (this.valid) {
              this.updateLogicComponent();
              this.onUpdate(LogicConfig.LOGIC_FRAME_ITME);
              this.updateBuff(LogicConfig.LOGIC_FRAME_ITME);
          }
      }
      onInit() {
      }
      onCreate() {
      }
      onUpdate(t) {
      }
      onRemove() {
      }
      useSkill(target, skillData, index, attackCount, slience = false) {
          this.world.skillMgr.findTarget2Exec(this, target, skillData, index, attackCount);
          if (!slience) {
              this.onSkillUse(target, skillData, index, attackCount);
          }
      }
      useSkillById(target, skillId, index = 0, attackCount = 0, skillData) {
          if (!skillData) {
              this.world.skillMgr.packSkillData(this.tempSkillData, skillId);
              skillData = this.tempSkillData;
          }
          this.world.skillMgr.findTarget2Exec(this, target, skillData, index, attackCount);
          this.onSkillUse(target, skillData, index, attackCount);
      }
      onSkillCast(time, index = 0, targetId = 0, skillData) {
      }
      onSkillUse(target, skillData, index, count) {
      }
      onSkillUseEnd(skillData, index) {
      }
      onTargetDead(index = 0) {
      }
      set mapLinkList(mapLink) {
          this.mapLink = mapLink;
      }
      get mapLinkList() {
          return this.mapLink;
      }
      addLogicComponent(componentType) {
          let com = LogicComponent.create(componentType);
          this.logicComponents.push(com);
          com.owner = this;
          com.onCreate();
          return com;
      }
      updateLogicComponent() {
          for (let i = 0; i < this.logicComponents.length; i++) {
              let com = this.logicComponents[i];
              com.onUpdate(LogicConfig.LOGIC_FRAME_ITME);
          }
      }
      clearLogicCompnent() {
          for (let i = 0; i < this.logicComponents.length; i++) {
              let com = this.logicComponents[i];
              com.onDestroy();
          }
          this.logicComponents.length = 0;
      }
      setGrid(gx, gy) {
          this.world.getMap().moveObjectTo(this, gx, gy);
      }
      moveTo(time, dx, dy, mx, my) {
          this.mx = mx;
          this.my = my;
          this.setGrid(Math.round(mx), Math.round(my));
          this.onMoveTo(time, dx, dy, mx, my);
      }
      onMoveTo(time, ox, oy, mx, my) {
      }
      jumpTo(time, x, y, msg) {
      }
      calcBuffBySkillCaster(caster, skillId, skillData) {
      }
      calcBuffBySkillTarget(caster, skillId, skillData) {
      }
      calcDamage(caster, data, damageData) {
          return { damage: 0 };
      }
      execSkill(caster, data) {
      }
      execSkillWithDamage(caster, damageData, data) {
      }
      hurt(data) {
      }
      cure(data) {
      }
      cureByValue(addhp) {
      }
      handleMessage(id) {
      }
      getShootPoint(index = 0, pointIndex = 0) {
          return null;
      }
      getHitPoint(index = 0) {
          return null;
      }
      addBuffById(caster, buffId, param = null, time = 0) {
      }
      appendBuff(buff) {
          let next = this.buffHead.next;
          buff.next = next;
          if (next) {
              next.prev = buff;
          }
          this.buffHead.next = buff;
          buff.prev = this.buffHead;
      }
      buildBuffUId(caster, id) {
          return id;
      }
      addBuff(caster, id, template, time, delay, count = 1, param = null) {
          if (count <= 0)
              return;
          let uid = this.buildBuffUId(caster, id);
          let buff = this.findBuff(uid);
          if (!buff) {
              buff = LogicBuff.create().bind(uid, id, template);
              this.appendBuff(buff);
              buff.start(caster, this, buff, time, delay, count, param);
          }
          else {
              buff.restart(caster, this, buff, time, delay, count, param);
          }
          if (param)
              buff.param = param;
      }
      updateBuff(t) {
          let head = this.buffHead.next;
          while (head) {
              let curtBuff = head;
              head = curtBuff.next;
              curtBuff.tick(t, this);
          }
      }
      findBuff(uid) {
          let buff = this.buffHead.next;
          let find = null;
          let loop = 0;
          while (buff) {
              if (uid == buff.uid) {
                  find = buff;
                  break;
              }
              buff = buff.next;
              loop++;
              if (loop > 100) {
                  console.error("buff: 卡死");
                  break;
              }
          }
          return find;
      }
      calcBuffAll(exceptIds) {
          this.recoverAttrAll(exceptIds);
          let head = this.buffHead.next;
          while (head) {
              let buff = head;
              head = buff.next;
              if (buff) {
                  buff.calc(this);
              }
          }
      }
      clearAllBuff(exceptIds) {
          this.recoverAttrAll(exceptIds);
          let head = this.buffHead.next;
          while (head) {
              let buff = head;
              head = buff.next;
              if (buff) {
                  buff.removeFrom(this);
              }
          }
      }
      execAndClearAllBuff(skillDb) {
          let isAnyClear = false;
          let head = this.buffHead.next;
          while (head) {
              let buff = head;
              head = buff.next;
              if (buff) {
                  if (buff.execAndClear(this, skillDb)) {
                      isAnyClear = true;
                  }
              }
          }
          return isAnyClear;
      }
      isTargetInRange(target) {
          return LogicTool.inRange(this.gx, this.gy, target.gx, target.gy, this.range);
      }
      prepareSkillData(data) {
      }
      canCastSkillToTarget(target, data) {
          return true;
      }
      onBuffStart(buff) {
      }
      onBuffRestart(buff) {
      }
      onBuffExec(buff) {
      }
      onBuffCalc(buff) {
      }
      onBuffEnd(buff) {
      }
      checkFlag(flag) {
          return this.flag & flag;
      }
      addFlag(flag) {
          this.flag |= flag;
          this.flagCount[flag] = (this.flagCount[flag] || 0) + 1;
      }
      remFlag(flag, clear = false) {
          let count = (this.flagCount[flag] || 0) - 1;
          if (clear || count <= 0) {
              count = 0;
              this.flag ^= flag;
          }
          this.flagCount[flag] = count;
          return count == 0;
      }
      clearFlag() {
          this.flag = 0;
          this.flagCount = {};
      }
      getAttrPercent(i) {
          if (!this.attrCur)
              return 1;
          if (!this.attrStd)
              return 1;
          let attrStd = this.attrStd[i];
          if (!attrStd) {
              return 0;
          }
          else {
              return this.attrCur[i] / attrStd;
          }
      }
      getAttr(i) {
          if (!this.attrCur)
              return 0;
          return this.attrCur[i] || 0;
      }
      getAttrMax(i) {
          if (!this.attrStd)
              return 0;
          return this.attrStd[i] || 0;
      }
      isAttrMax(i) {
          if (!this.attrCur)
              return false;
          if (!this.attrStd)
              return false;
          return this.attrCur[i] >= this.attrStd[i];
      }
      addAttr(i, add) {
          if (!this.attrCur)
              return;
          this.setAttr(i, this.getAttr(i) + add);
      }
      setAttr(i, v, init = false) {
          if (!this.attrCur)
              return;
          if (!this.attrStd)
              return;
          if (init) {
              this.attrStd[i] = v;
              this.attrCur[i] = v;
          }
          else {
              let max = this.getAttrMax(i);
              if (v > max)
                  v = max;
              if (v < 0)
                  v = 0;
              this.attrCur[i] = v;
          }
      }
      getAttrLost(i) {
          if (!this.attrCur)
              return 0;
          if (!this.attrStd)
              return 0;
          return this.attrStd[i] - this.attrCur[i];
      }
      scaleAttr(index, scale) {
          if (!this.attrCur)
              return;
          if (!this.attrStd)
              return;
          this.attrCur[index] = this.attrStd[index] * scale;
          this.onAttrChange();
      }
      scaleAttrOverLay(index, scale) {
      }
      changeAttr(index, value) {
          if (!this.attrCur)
              return;
          this.attrCur[index] = value;
          this.onAttrChange();
      }
      recoverAttr(index) {
          if (!this.attrCur)
              return;
          if (!this.attrStd)
              return;
          this.attrCur[index] = this.attrStd[index];
          this.onAttrChange();
      }
      recoverAttrAll(exceptIds) {
          if (!this.attrCur)
              return;
          if (!this.attrStd)
              return;
          for (let i = 0; i < this.attrCur.length; i++) {
              if (!exceptIds[i]) {
                  this.attrCur[i] = this.attrStd[i];
              }
          }
          this.onAttrChange();
      }
      onAttrChange() {
      }
      scaleSpeed(scale) {
      }
      recoverSpeed() {
      }
      beatBack(caster, moveDistance) {
          let dx = this.gx - caster.gx;
          let dy = this.gy - caster.gy;
          let d = Math.sqrt(dx * dx + dy * dy);
          if (d > 0) {
              var id = 1.0 / d;
              dx *= id;
              dy *= id;
          }
          else {
              dx = 0;
              dy = 0;
          }
          let mx = this.mx + dx * moveDistance;
          let my = this.my + dy * moveDistance;
          let lw = this.world.map.width - 1;
          let lh = this.world.map.height - 1;
          if (mx > lw) {
              mx = lw;
          }
          else if (mx < 0) {
              mx = 0;
          }
          if (my > lh) {
              my = lh;
          }
          else if (my < 0) {
              my = 0;
          }
          this.moveTo(0, dx, dy, mx, my);
          this.onBeatBack(mx, my);
      }
      onBeatBack(x, y) {
      }
      getSpeedScale() {
          return 1;
      }
      unbindSkin() {
      }
      skinTransform(id) {
      }
      changeSkill(skillId = null, superId = null) {
      }
      getAttackSpeed() {
          return 1;
      }
      getSuperSkillId() {
          return "";
      }
      getSuperSkillDb() {
          return null;
      }
      stopMove() {
      }
      addEnergy(add = 1, show = false) {
      }
      rebornById(roleId, canDead) {
      }
      isFuncCDing(key, curtTime) {
          return false;
      }
      beginFuncCDing(key, curtTime, cd) {
      }
      createEffectLock(skillDb) {
      }
      createEffect(effect, hit_offset = 0) {
      }
      setHitEffectEx(effect) {
          this.hitEffectEx = effect;
      }
      getHitEffectEx() {
          return this.hitEffectEx;
      }
      static create(clas, id, lv) {
          return LogicPool.getItem(clas).init(id, lv);
      }
      static recover(obj) {
          LogicPool.putItem(obj);
      }
  }

  class LogicBuilding extends LogicObject {
      constructor() {
          super(...arguments);
          this.nearestPoint = new LogicPoint;
      }
      setShape(shape) {
          this.shape = shape;
      }
      findNearestBlock(fx, fy) {
          let disanceMax = Number.MAX_VALUE;
          for (let offset of this.shape) {
              let bx = this.gx + offset.x;
              let by = this.gy + offset.y;
              let dx = fx - bx;
              let dy = fy - by;
              let distanceSq = dx * dx + dy * dy;
              if (distanceSq < disanceMax) {
                  disanceMax = distanceSq;
                  this.nearestPoint.x = bx;
                  this.nearestPoint.y = by;
              }
          }
          return this.nearestPoint;
      }
  }

  var ATTACK_STATE;
  (function (ATTACK_STATE) {
      ATTACK_STATE[ATTACK_STATE["IDLE"] = 1] = "IDLE";
      ATTACK_STATE[ATTACK_STATE["READY"] = 2] = "READY";
      ATTACK_STATE[ATTACK_STATE["CAST"] = 3] = "CAST";
      ATTACK_STATE[ATTACK_STATE["CAST_HAND"] = 4] = "CAST_HAND";
      ATTACK_STATE[ATTACK_STATE["ATTACK"] = 5] = "ATTACK";
      ATTACK_STATE[ATTACK_STATE["KEEP_LOCK"] = 6] = "KEEP_LOCK";
      ATTACK_STATE[ATTACK_STATE["KEEP_ATTACK"] = 7] = "KEEP_ATTACK";
      ATTACK_STATE[ATTACK_STATE["KEEP_CD"] = 8] = "KEEP_CD";
      ATTACK_STATE[ATTACK_STATE["ATTACK_DOUBLE"] = 9] = "ATTACK_DOUBLE";
  })(ATTACK_STATE || (ATTACK_STATE = {}));
  class LogicComponentAttackerTower extends LogicComponent {
      constructor() {
          super(...arguments);
          this.loop = true;
          this.multiTarget = false;
          this.timeInState = 0;
          this.timeWtstate = 0;
          this.targetId = 0;
          this.targetPos = new LogicPoint;
          this.index = 0;
          this.attackCount = 0;
          this.skillData = {
              skillId: "1",
              template: "",
              timeCast: 0.25,
              timeCD: 2,
              count: 1,
              prepare: false,
              ground: false,
              skillDb: null,
              limit: 0,
          };
          this.skillDataHand = {
              skillId: "1",
              template: "",
              timeCast: 0.25,
              timeCD: 2,
              count: 1,
              prepare: false,
              ground: false,
              skillDb: null,
              limit: 0,
          };
          this.keepUids = [];
      }
      onCreate() {
          this.registerState(ATTACK_STATE.IDLE, "Idle");
          this.registerState(ATTACK_STATE.READY, "Ready");
          this.registerState(ATTACK_STATE.CAST, "Cast");
          this.registerState(ATTACK_STATE.CAST_HAND, "CastHand");
          this.registerState(ATTACK_STATE.ATTACK, "Attack");
          this.registerState(ATTACK_STATE.ATTACK_DOUBLE, "AttackDouble");
          this.registerState(ATTACK_STATE.KEEP_LOCK, "KeepLock");
          this.registerState(ATTACK_STATE.KEEP_ATTACK, "KeepAttack");
          this.registerState(ATTACK_STATE.KEEP_CD, "KeepCD");
          this.registerRelation(ATTACK_STATE.CAST_HAND, {});
          this.setState(ATTACK_STATE.IDLE);
      }
      onUpdate(t) {
          if (!this.owner.checkFlag(LogicObjectFlag.NO_ATTACK)) {
              this.update(t);
          }
      }
      onDestroy() {
          super.onDestroy();
      }
      onReset() {
          this.idle(true);
      }
      isIdle() {
          return this.getState() == ATTACK_STATE.IDLE;
      }
      idle(force = false) {
          this.targetId = 0;
          this.loop = true;
          this.setState(ATTACK_STATE.IDLE, force);
      }
      ready(force = false) {
          if (force || this.getState() == ATTACK_STATE.IDLE) {
              this.setState(ATTACK_STATE.READY, force);
          }
      }
      castHand(force = false) {
          if (force || this.getState() == ATTACK_STATE.IDLE) {
              this.setState(ATTACK_STATE.CAST_HAND, force);
          }
      }
      attack() {
          let world = this.owner.world;
          let target = world.getObjectMgr().getObjectById(this.targetId);
          if (!target) {
              if (this.skillData.count == 0) {
                  this.attackEnd();
                  return;
              }
              else {
                  if (this.skillData.searchInAttack) {
                      target = this.findAttackTarget();
                  }
                  if (!target) {
                      target = world.addVirtual(this.targetPos.x, this.targetPos.y);
                      this.targetId = 0;
                  }
                  else {
                      this.targetId = target.uid;
                  }
              }
          }
          if (target) {
              this.owner.useSkill(target, this.skillData, this.index, this.attackCount);
          }
          else {
              console.error("LogicComponentAttackerTower.attack: 这个地方不应该为空");
          }
          if (this.skillData.double) {
              this.skillData.double = false;
              this.skillData.doubleUsed = true;
              this.setState(ATTACK_STATE.ATTACK_DOUBLE);
          }
          else {
              return true;
          }
          return false;
      }
      attackKeep() {
          let world = this.owner.world;
          let isAllDead = true;
          for (let uid of this.keepUids) {
              let target = world.getObjectMgr().getObjectById(uid);
              if (target) {
                  isAllDead = false;
                  world.skillMgr.useSkill(this.owner, target, this.skillData, this.index, this.attackCount);
              }
          }
          if (isAllDead) {
              this.attackEnd();
          }
          else {
              this.setState(ATTACK_STATE.KEEP_CD);
          }
      }
      canCastSkill(target, skillData) {
          return this.owner.isTargetInRange(target) && this.owner.canCastSkillToTarget(target, skillData);
      }
      findSkillTarget(skillData, target) {
          return this.owner.world.skillMgr.findTarget2Cast(skillData.template, this.owner, target, skillData, this.index);
      }
      findAttackTarget() {
          let world = this.owner.world;
          let targetFinal = null;
          if (StageConfig.towerTargetSearchType == TOWER_TARGET_SEARCH_TYPE.NEAREST_LOCK) {
              if (this.targetId) {
                  let target = world.getObjectMgr().getObjectById(this.targetId);
                  if (target && this.canCastSkill(target, this.skillData)) {
                      targetFinal = target;
                  }
              }
          }
          if (!targetFinal) {
              if (this.skillData.camp == LogicCamp.SELF) {
                  targetFinal = this.owner;
              }
              else {
                  let targetId = 0;
                  let targetLen = this.owner.targetIds.length;
                  if (this.multiTarget && targetLen) {
                      targetId = this.owner.targetIds[this.index % targetLen];
                  }
                  else {
                      targetId = this.owner.targetId;
                  }
                  let target = world.getObjectMgr().getObjectById(targetId);
                  if (target && this.canCastSkill(target, this.skillData)) {
                      targetFinal = target;
                  }
              }
          }
          return targetFinal;
      }
      enterReady(t) {
          if (!this.skillData.prepare) {
              this.owner.prepareSkillData(this.skillData);
          }
          this.skillData.prepare = false;
      }
      execReady(t) {
          let targetFinal = this.findAttackTarget();
          if (targetFinal) {
              targetFinal = this.findSkillTarget(this.skillData, targetFinal);
              this.targetPos.x = targetFinal.gx;
              this.targetPos.y = targetFinal.gy;
              if (this.skillData.ground) {
                  targetFinal = this.owner.world.addVirtual(this.targetPos.x, this.targetPos.y);
              }
              this.targetId = targetFinal.uid;
              this.setState(ATTACK_STATE.CAST);
          }
          else {
              if (this.skillData.isSuper) {
              }
              else {
                  this.targetId = 0;
                  this.setState(ATTACK_STATE.IDLE);
              }
          }
      }
      enterCast() {
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCast;
          this.attackCount = 0;
          this.owner.onSkillCast(this.timeWtstate, this.index, this.targetId, this.skillData);
      }
      execCast(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.skillData.count == 0) {
                  this.setState(ATTACK_STATE.KEEP_LOCK);
              }
              else {
                  this.setState(ATTACK_STATE.ATTACK);
              }
          }
      }
      enterCastHand() {
          if (this.skillData.count == 0) {
              this.owner.onSkillUseEnd(this.skillData, this.index);
          }
          for (let k in this.skillDataHand) {
              this.skillData[k] = this.skillDataHand[k];
          }
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCast;
          this.attackCount = 0;
          let target = this.owner.world.getObjectMgr().getObjectById(this.targetId);
          if (!target) {
              target = this.findAttackTarget();
              if (target) {
                  this.targetId = target.uid;
              }
          }
          this.owner.onSkillCast(this.timeWtstate, this.index, this.targetId, this.skillData);
      }
      execCastHand(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.skillData.count == 0) {
                  this.setState(ATTACK_STATE.KEEP_LOCK, true);
              }
              else {
                  this.setState(ATTACK_STATE.ATTACK, true);
              }
          }
      }
      enterAttack() {
          this.attack();
          this.attackCount++;
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCD;
      }
      execAttack(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.loop) {
                  if (this.attackCount < this.skillData.count) {
                      this.setState(ATTACK_STATE.ATTACK, true);
                  }
                  else {
                      this.attackEnd();
                  }
              }
              else {
                  this.setState(ATTACK_STATE.IDLE);
              }
          }
      }
      enterKeepLock() {
          this.attackCount = 0;
          let world = this.owner.world;
          let target = world.getObjectMgr().getObjectById(this.targetId);
          let targets = world.skillMgr.findTargets(this.owner, target, this.skillData, this.index, this.attackCount);
          this.keepUids.length = 0;
          for (let target of targets) {
              if (target)
                  this.keepUids.push(target.uid);
          }
          this.setState(ATTACK_STATE.KEEP_ATTACK);
      }
      enterKeepAttack() {
          this.attackKeep();
          this.attackCount++;
      }
      enterKeepCD() {
          this.timeInState = 0;
          this.timeWtstate = this.skillData.timeCD;
      }
      execKeepCD(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              if (this.loop) {
                  this.setState(ATTACK_STATE.KEEP_ATTACK);
              }
              else {
                  this.setState(ATTACK_STATE.IDLE);
              }
          }
      }
      attackEnd() {
          this.targetId = 0;
          this.owner.onSkillUseEnd(this.skillData, this.index);
          this.setState(ATTACK_STATE.READY);
      }
      enterAttackDouble() {
          this.timeInState = 0;
          this.timeWtstate = 0.1;
      }
      execAttackDouble(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              this.setState(ATTACK_STATE.ATTACK);
          }
      }
  }
  LogicComponentAttackerTower.poolkey = "LogicComponentAttackerTower";

  var TOWER_STATE;
  (function (TOWER_STATE) {
      TOWER_STATE[TOWER_STATE["IDLE"] = 1] = "IDLE";
      TOWER_STATE[TOWER_STATE["WATCH"] = 2] = "WATCH";
      TOWER_STATE[TOWER_STATE["ATTACK"] = 3] = "ATTACK";
  })(TOWER_STATE || (TOWER_STATE = {}));
  class LogicTower extends LogicBuilding {
      constructor() {
          super(...arguments);
          this.rangex = 0;
          this.rangey = 0;
          this.indexAttacker = 0;
          this.timeInState = 0;
          this.timeWtState = 2;
      }
      onInit() {
          this.comAttackers = [];
          this.rangex = 0;
          this.rangey = 0;
      }
      onCreate() {
          this.state = new StateMachine();
          this.state.registerState(TOWER_STATE.IDLE, "Idle", this);
          this.state.registerState(TOWER_STATE.WATCH, "Watch", this);
          this.state.registerState(TOWER_STATE.ATTACK, "Attack", this);
          this.state.setState(TOWER_STATE.WATCH);
          console.log("O_O LogicTower onCreate");
      }
      onUpdate(t) {
          this.state.update(t);
      }
      addAttacker() {
          let comAttacker = this.addLogicComponent(LogicComponentAttackerTower);
          this.comAttackers.push(comAttacker);
          comAttacker.index = this.indexAttacker;
          comAttacker.multiTarget = true;
          this.indexAttacker++;
          return comAttacker;
      }
      resetAttacker() {
          this.state.setState(TOWER_STATE.WATCH);
          for (let attacker of this.comAttackers) {
              attacker.ready(true);
          }
      }
      isStateInAttack() {
          return this.state.getState() == TOWER_STATE.ATTACK;
      }
      isTargetInRange(target) {
          return LogicTool.inRange(this.gx + this.rangex, this.gy + this.rangey, target.gx, target.gy, this.range);
      }
      attack() {
          let objectList = this.searchTargets();
          this.targetIds.length = 0;
          for (let i = 0; i < objectList.length; i++) {
              let object = objectList[i];
              this.targetIds.push(object.uid);
          }
          if (this.targetIds.length) {
              for (let attacker of this.comAttackers) {
                  attacker.ready();
              }
          }
      }
      getSkillCampID() {
          return LogicCamp.FRIEND;
      }
      findObjectsByRange(debug = false) {
          return this.findObjectsByRangeAndCampId(this.getSkillCampID(), null, debug);
      }
      findObjectsByRangeAndCampId(campId, selectUids, debug = false) {
          return this.world.getMap().findObjectsByRange(this.gx + this.rangex, this.gy + this.rangey, MAP_FLAG.UNIT_STAND | MAP_FLAG.BUILDING, campId, this.range, 0, true, debug, selectUids, true);
      }
      searchTargets() {
          let targetList = this.findObjectsByRange();
          return targetList;
      }
      searchTargetsToAttack() {
          let targetList = this.searchTargets();
          if (targetList.length) {
              let target = targetList[0];
              if (target) {
                  this.targetId = target.uid;
              }
          }
      }
      enterWatch() {
          this.timeInState = 0;
          console.log("O_O LogicTower enterWatch");
      }
      execWatch(t) {
          this.timeInState += t;
          if (this.timeInState >= 1) {
              this.timeInState = 0;
              this.searchTargetsToAttack();
              if (this.targetId) {
                  this.state.setState(TOWER_STATE.ATTACK);
              }
          }
      }
      enterAttack() {
          this.timeInState = 0;
          this.timeWtState = 1;
      }
      execAttack(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtState) {
              this.timeInState = 0;
              this.attack();
          }
      }
  }

  var ENEMY_STATE;
  (function (ENEMY_STATE) {
      ENEMY_STATE[ENEMY_STATE["IDLE"] = 1] = "IDLE";
      ENEMY_STATE[ENEMY_STATE["BORN"] = 2] = "BORN";
      ENEMY_STATE[ENEMY_STATE["THINK"] = 3] = "THINK";
      ENEMY_STATE[ENEMY_STATE["ATTACK"] = 4] = "ATTACK";
      ENEMY_STATE[ENEMY_STATE["EMPTY"] = 5] = "EMPTY";
      ENEMY_STATE[ENEMY_STATE["FAKE_DEAD"] = 6] = "FAKE_DEAD";
  })(ENEMY_STATE || (ENEMY_STATE = {}));
  class LogicEnemy extends LogicObject {
      constructor() {
          super(...arguments);
          this.timeInBorn = 0;
          this.timeInState = 0;
          this.flagFindPath = MAP_FLAG.UNIT_MOVING | MAP_FLAG.BUILDING | MAP_FLAG.UNIT_STAND;
          this.isFoundNearstTowerBlock = false;
          this.targetBlockX = 0;
          this.targetBlockY = 0;
      }
      onCreate() {
          this.state = new StateMachine();
          this.state.registerState(ENEMY_STATE.IDLE, "Idle", this);
          this.state.registerState(ENEMY_STATE.BORN, "Born", this);
          this.state.registerState(ENEMY_STATE.THINK, "Think", this);
          this.state.registerState(ENEMY_STATE.ATTACK, "Attack", this);
          this.state.registerState(ENEMY_STATE.EMPTY, "Empty", this);
          this.state.registerState(ENEMY_STATE.FAKE_DEAD, "FakeDead", this);
          this.state.setState(ENEMY_STATE.IDLE);
          this.state.registerRelation(ENEMY_STATE.BORN, {});
          this.state.registerRelation(ENEMY_STATE.FAKE_DEAD, {});
          this.comMove = this.addLogicComponent(LogicComponentMove);
          this.comAttacker = this.addLogicComponent(LogicComponentAttackerEnemy);
      }
      onUpdate(t) {
          this.state.update(t);
      }
      onRemove() {
      }
      getSpeedScale() {
          if (this.comMove)
              return this.comMove.getScaleSpeed();
          else
              return 1;
      }
      wantMoveTo(tx, ty) {
          this.comMove.moveTo(tx, ty);
      }
      changeTargetId(targetId) {
          if (this.targetId != targetId) {
              this.targetId = targetId;
              this.comMove.stop();
              this.comAttacker.wait();
              this.state.setState(ENEMY_STATE.THINK);
          }
      }
      stopMove() {
          this.comMove.stop();
      }
      isTargetInRange(target) {
          let tx = target.gx;
          let ty = target.gy;
          if (this.isFoundNearstTowerBlock) {
              tx = this.targetBlockX;
              ty = this.targetBlockY;
          }
          return this.isTargetInRangeByPos(tx, ty);
      }
      isTargetInRangeByPos(tx, ty) {
          let dx = tx - this.gx;
          let dy = ty - this.gy;
          return this.isTargetInRangeByDxDy(dx, dy);
      }
      isTargetInRangeByDxDy(dx, dy) {
          let offset = 0;
          let range = this.range + offset;
          if (range <= 2) {
              let ds = Math.max(Math.abs(dx), Math.abs(dy));
              return ds <= range;
          }
          else {
              return LogicTool.inRangeByDxDy(dx, dy, range);
          }
      }
      findPath(tx, ty) {
          let flag = MAP_FLAG.BUILDING | MAP_FLAG.BARRIER;
          if (this.world.map.checkFlag(this.gx, this.gy, flag)) {
              flag = MAP_FLAG.NONE;
          }
          return this.world.map.findPath(this.gx, this.gy, tx, ty, flag);
      }
      findBestAttackPos(bx, by, tx, ty) {
          return this.world.map.findBestAttackPos(bx, by, tx, ty, MAP_FLAG.BUILDING | MAP_FLAG.BARRIER, this.range);
      }
      lockTarget(target) {
      }
      stopAttack() {
          this.comAttacker.stop(true);
      }
      reborn() {
          this.state.setState(ENEMY_STATE.IDLE, true);
      }
      fakedead() {
          this.state.setState(ENEMY_STATE.FAKE_DEAD, true);
      }
      born(time) {
          this.timeInBorn = time;
          this.state.setState(ENEMY_STATE.BORN, true);
      }
      isFakeDead() {
          return this.state.getState() == ENEMY_STATE.FAKE_DEAD;
      }
      enterIdle() {
          this.timeInState = 0;
      }
      execIdle(t) {
          this.state.setState(ENEMY_STATE.THINK);
      }
      enterBorn() {
          this.stopMove();
          this.comAttacker.stop();
          this.timeInState = 0;
      }
      execBorn(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeInBorn) {
              this.state.setState(ENEMY_STATE.THINK, true);
          }
      }
      exitBorn() {
      }
      enterThink() {
          this.isFoundNearstTowerBlock = false;
          if (this.mapLinkList) {
              if (!this.targetId) {
                  let target = this.world.findBuildingNearest(this.gx, this.gy);
                  if (target) {
                      this.targetId = target.uid;
                  }
                  else {
                  }
              }
              if (this.targetId) {
                  let target = this.world.getObjectMgr().getObjectById(this.targetId);
                  if (target) {
                      let tx = target.gx;
                      let ty = target.gy;
                      if (target instanceof LogicTower) {
                          let p = target.findNearestBlock(this.gx, this.gy);
                          tx = p.x;
                          ty = p.y;
                          this.targetBlockX = tx;
                          this.targetBlockY = ty;
                          this.isFoundNearstTowerBlock = true;
                      }
                      if (this.isTargetInRangeByPos(tx, ty)) {
                          this.state.setState(ENEMY_STATE.ATTACK);
                          return;
                      }
                      let dx = tx - this.gx;
                      let dy = ty - this.gy;
                      let ds = Math.sqrt(dx * dx + dy * dy);
                      let range = this.range;
                      if (range > 1)
                          range -= 1;
                      let bx = Math.round(tx - (dx / ds * range));
                      let by = Math.round(ty - (dy / ds * range));
                      let bestPos = this.findBestAttackPos(bx, by, tx, ty);
                      if (bestPos) {
                          let path = this.findPath(bestPos.x, bestPos.y);
                          this.comMove.moveByPath(path);
                          this.lockTarget(target);
                      }
                      else {
                          let pos = this.world.getMap().findNextMovePos(this, tx, ty, this.flagFindPath);
                          if (pos) {
                              this.wantMoveTo(pos.x, pos.y);
                          }
                          else {
                              this.state.setState(ENEMY_STATE.IDLE);
                          }
                      }
                  }
                  else {
                      this.targetId = 0;
                      this.state.setState(ENEMY_STATE.IDLE);
                  }
              }
          }
          else {
          }
      }
      execThink() {
          let target = this.world.getObjectMgr().getObjectById(this.targetId);
          if (!target) {
              this.state.setState(ENEMY_STATE.IDLE);
          }
          else {
              if (this.isTargetInRange(target)) {
                  this.state.setState(ENEMY_STATE.ATTACK);
                  return;
              }
              if (this.comMove.isStop()) {
                  this.state.setState(ENEMY_STATE.IDLE);
              }
          }
      }
      enterAttack() {
          this.comAttacker.ready(true);
          this.timeInState = 0;
      }
      execAttack(t) {
          this.timeInState += t;
          if (this.timeInState >= 1) {
              this.timeInState = 0;
              this.onAttackUpdate();
              if (this.comAttacker.isIdle()) {
                  let target = this.world.getObjectMgr().getObjectById(this.targetId);
                  if (target) {
                      if (!this.isTargetInRange(target)) {
                          this.state.setState(ENEMY_STATE.THINK);
                      }
                      else {
                          this.comAttacker.ready();
                      }
                  }
                  else {
                      this.state.setState(ENEMY_STATE.THINK);
                  }
              }
          }
      }
      exitAttack() {
      }
      enterFakeDead() {
          this.stopMove();
          this.comAttacker.wait();
      }
      handleMessage(id) {
          switch (id) {
              case LogicMessage.MOVE_STOP:
                  if (this.state.getState() != ENEMY_STATE.ATTACK) {
                      this.state.setState(ENEMY_STATE.IDLE);
                  }
                  break;
          }
      }
      onAttackUpdate() {
      }
  }

  class CustomComponent extends fgui.GComponent {
      constructor() {
          super(...arguments);
          this.destroyed = false;
      }
      get viewName() {
          if (this.packageItem) {
              return this.packageItem.name;
          }
          else {
              return "";
          }
      }
      constructFromResource() {
          super.constructFromResource();
          this.bindObject(this);
          this.onCreate();
      }
      setup_afterAdd(buffer, beginPos) {
          super.setup_afterAdd(buffer, beginPos);
          this.onAfterAdd();
      }
      bindObject(object) {
          ExportViewTool.bindViewToObject(this, object);
          return this;
      }
      dispose() {
          super.dispose();
      }
      onCreate() { }
      onAfterAdd() { }
  }

  var DAMAGE_TYPE;
  (function (DAMAGE_TYPE) {
      DAMAGE_TYPE[DAMAGE_TYPE["DMG_AD"] = 0] = "DMG_AD";
      DAMAGE_TYPE[DAMAGE_TYPE["DMG_AP"] = 1] = "DMG_AP";
      DAMAGE_TYPE[DAMAGE_TYPE["CRIT_AD"] = 2] = "CRIT_AD";
      DAMAGE_TYPE[DAMAGE_TYPE["CRIT_AP"] = 3] = "CRIT_AP";
      DAMAGE_TYPE[DAMAGE_TYPE["RECOVER_HP"] = 4] = "RECOVER_HP";
      DAMAGE_TYPE[DAMAGE_TYPE["RECOVER_MP"] = 5] = "RECOVER_MP";
      DAMAGE_TYPE[DAMAGE_TYPE["SHIELD"] = 6] = "SHIELD";
      DAMAGE_TYPE[DAMAGE_TYPE["FLEE"] = 7] = "FLEE";
  })(DAMAGE_TYPE || (DAMAGE_TYPE = {}));
  class CustomDamageText extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomDamageText";
          this.exportNodeNames = {
              cc_dmg_ad: "fgui.GComponent",
              cc_label_damage_ad: "fgui.GBasicTextField",
              cc_trans_dmg_ad: "fgui.Transition",
              cc_dmg_ap: "fgui.GComponent",
              cc_label_damage_ap: "fgui.GBasicTextField",
              cc_trans_dmg_ap: "fgui.Transition",
              cc_recover_hp: "fgui.GComponent",
              cc_label_recover_hp: "fgui.GBasicTextField",
              cc_trans_recover_hp: "fgui.Transition",
              cc_recover_mp: "fgui.GComponent",
              cc_label_recover_mp: "fgui.GBasicTextField",
              cc_trans_recover_mp: "fgui.Transition",
              cc_crit_ad: "fgui.GComponent",
              cc_label_crit_ad: "fgui.GBasicTextField",
              cc_trans_crit_ad: "fgui.Transition",
              cc_crit_ap: "fgui.GComponent",
              cc_label_crit_ap: "fgui.GBasicTextField",
              cc_trans_crit_ap: "fgui.Transition",
              cc_shield: "fgui.GComponent",
              cc_trans_shield: "fgui.Transition",
              cc_flee: "fgui.GComponent",
              cc_trans_flee: "fgui.Transition",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      onCreate() {
          this.touchable = false;
      }
      dispose() {
          super.dispose();
      }
      static create() {
          return FguiHelper.getItem("ui://base/CustomDamageText");
      }
      recover() {
          if (this.displayObject) {
              this.displayObject.removeSelf();
          }
          this.removeFromParent();
          FguiHelper.putItem("ui://base/CustomDamageText", this);
      }
      showDamage(data, damage) {
          damage = damage || data.damage;
          let label;
          let trans;
          let index = DAMAGE_TYPE.DMG_AD;
          if (data.isFlee) {
              index = DAMAGE_TYPE.FLEE;
              trans = this.trans_flee;
          }
          else if (data.isShield) {
              index = DAMAGE_TYPE.SHIELD;
              trans = this.trans_shield;
          }
          else if (data.isAP) {
              if (data.isCrit) {
                  label = this.label_crit_ap;
                  trans = this.trans_crit_ap;
                  index = DAMAGE_TYPE.CRIT_AP;
              }
              else {
                  label = this.label_damage_ap;
                  trans = this.trans_dmg_ap;
                  index = DAMAGE_TYPE.DMG_AP;
              }
          }
          else {
              if (data.isCrit) {
                  label = this.label_crit_ad;
                  trans = this.trans_crit_ad;
                  index = DAMAGE_TYPE.CRIT_AD;
              }
              else {
                  label = this.label_damage_ad;
                  trans = this.trans_dmg_ad;
                  index = DAMAGE_TYPE.DMG_AD;
              }
          }
          this.ctrl_type.selectedIndex = index;
          if (label)
              label.text = "-" + StageTool.formatDamage(damage);
          trans.play(Laya.Handler.create(this, this.onShowDamageEnd));
          let direction = data.direction;
          if (direction.x != 0 || direction.y != 0) {
              let jumParams = db.game_cnf.damge_text_jump;
              let moveDistance = Utils.random(jumParams[1], jumParams[2]);
              let dx = 0;
              if (direction.x > 0) {
                  dx = moveDistance;
              }
              else {
                  dx = -moveDistance;
              }
              cc$1.tween(this, true).then(cc$1.jumpTo(jumParams[0], this.x + dx, this.y - Utils.random(jumParams[3], jumParams[4]), Utils.random(jumParams[5], jumParams[6]), 1)).start();
          }
      }
      onShowDamageEnd() {
          this.recover();
      }
      showRecoverHP(value) {
          this.ctrl_type.selectedIndex = DAMAGE_TYPE.RECOVER_HP;
          this.label_recover_hp.text = "+" + StageTool.formatDamage(value);
          this.trans_recover_hp.play(Laya.Handler.create(this, this.onShowDamageEnd));
      }
      showRecoverMP(value) {
          this.ctrl_type.selectedIndex = DAMAGE_TYPE.RECOVER_MP;
          this.label_recover_mp.text = "+" + StageTool.formatDamage(value);
          this.trans_recover_mp.play(Laya.Handler.create(this, this.onShowDamageEnd));
      }
  }

  class DamageCalculation {
      static get damageData() {
          this.resetDamageData(this.tempDamageData);
          return this.tempDamageData;
      }
      static resetDamageData(data) {
          if (data) {
              data.damage = 0;
              data.damageEx = 0;
              data.blood = 0;
              data.isCrit = false;
              data.isFlee = false;
              data.isAP = false;
              data.direction.x = 0;
              data.direction.y = 0;
              data.isShield = false;
              data.tidCaster = "";
          }
          return data;
      }
      static get tempAttr() {
          Level.resetAttrArray(this.attr, BASE_ATTR.LEN_TOWER);
          return this.attr;
      }
      static calcIsCrit(crit) {
          let m = crit * 100;
          let r = Utils.random(0, 99);
          return r < m;
      }
      static holyDebug(str) {
      }
      static talentDebug(str) {
      }
      static getHolyBuffId(id) {
          let data = db.get_holy_item_db(id);
          if (data)
              return data.buff_id;
          else
              return "";
      }
      static calcDamage(caster, target, skillData, dd, isCrossbow = false) {
          dd = this.resetDamageData(dd) || this.damageData;
          let skillDb = skillData.skillDb;
          let attrCaster = caster.attrCur;
          let dx = target.mx - caster.mx;
          let dy = target.my - caster.my;
          dd.direction.x = dx;
          dd.direction.y = dy;
          dd.direction.normalize();
          let rt = this.calcDamageWithAttr(caster.tid, caster, target, skillDb, dd, isCrossbow);
          if (rt.damage > 0) {
              let SK_STUN = attrCaster[BASE_ATTR.SK_STUN];
              if (SK_STUN && SK_STUN > 0) {
                  if (this.calcProb(SK_STUN)) {
                      target.addBuffById(caster, this.getHolyBuffId("10"));
                      this.holyDebug("伤害命中目标后有%d%的概率使敌方眩晕");
                  }
              }
          }
          return rt;
      }
      static calcEnemyDead(caster, target) {
          let attrCaster = caster.attrCur;
          let attrStand = caster.attrStd;
          if (attrCaster && attrStand) {
              let SK_KILL_MP_RECOVER = attrCaster[BASE_ATTR.SK_KILL_MP_RECOVER];
              if (SK_KILL_MP_RECOVER && SK_KILL_MP_RECOVER > 0) {
                  caster.addAttr(BASE_ATTR.MP, attrStand[BASE_ATTR.MP] * SK_KILL_MP_RECOVER);
                  this.holyDebug("击杀敌人后，回复%d%的气");
              }
          }
      }
      static calcSkillUse(caster, target, skillData, index, count) {
          let skillDb = skillData.skillDb;
          let attrCaster = caster.attrCur;
          if (!skillDb.is_super) {
              let SK_DOUBLE = attrCaster[BASE_ATTR.SK_DOUBLE];
              if (SK_DOUBLE) {
                  if (!skillData.doubleUsed && !skillData.double) {
                      if (this.calcProb(SK_DOUBLE)) {
                          skillData.double = true;
                      }
                  }
                  else {
                      skillData.double = false;
                  }
              }
          }
          else {
              skillData.double = false;
          }
          if (skillDb.is_super) {
              if (!skillData.triggerSuper) {
                  let SK_SUPER_MP_RECOVER = attrCaster[BASE_ATTR.SK_SUPER_MP_RECOVER];
                  if (SK_SUPER_MP_RECOVER > 0) {
                      if (this.calcProb(SK_SUPER_MP_RECOVER)) {
                          caster.addAttr(BASE_ATTR.MP, caster.getAttrMax(BASE_ATTR.MP) * db.game_cnf.holyitem_moon_stone);
                      }
                  }
              }
              let SK_SUPER_BUFF_AD_AP = attrCaster[BASE_ATTR.SK_SUPER_BUFF_AD_AP];
              if (SK_SUPER_BUFF_AD_AP > 0) {
                  caster.addBuffById(caster, this.getHolyBuffId("22"), [1 + SK_SUPER_BUFF_AD_AP]);
              }
              let SK_SUPER_BUFF_CRIT = attrCaster[BASE_ATTR.SK_SUPER_BUFF_CRIT];
              if (SK_SUPER_BUFF_CRIT > 0) {
                  caster.addBuffById(caster, this.getHolyBuffId("24"), [BASE_ATTR.CRIT, SK_SUPER_BUFF_CRIT]);
              }
              let SK_SUPER_BUFF_ATK_SPEED = attrCaster[BASE_ATTR.SK_SUPER_BUFF_ATK_SPEED];
              if (SK_SUPER_BUFF_ATK_SPEED > 0) {
                  caster.addBuffById(caster, this.getHolyBuffId("26"), [BASE_ATTR.ATK_SPEED, 1 + SK_SUPER_BUFF_ATK_SPEED]);
              }
              let SK_SUPER_BUFF_RANGE = attrCaster[BASE_ATTR.SK_SUPER_BUFF_RANGE];
              if (SK_SUPER_BUFF_RANGE > 0) {
                  caster.addBuffById(caster, this.getHolyBuffId("27"), [SK_SUPER_BUFF_RANGE]);
              }
              let SK_SKILL_RECOVER_HP = attrCaster[BASE_ATTR.SK_SKILL_RECOVER_HP];
              if (SK_SKILL_RECOVER_HP > 0) {
                  let curtTime = Timer.time;
                  if (!caster.isFuncCDing("SK_SKILL_RECOVER_HP", curtTime) && this.calcProb(db.game_cnf.holyitem_config_38)) {
                      caster.beginFuncCDing("SK_SKILL_RECOVER_HP", curtTime, db.game_cnf.holyitem_config_38_cd);
                      let addhp = Math.floor(caster.getAttrMax(BASE_ATTR.HP) * SK_SKILL_RECOVER_HP);
                      caster.cureByValue(addhp);
                  }
              }
              let SK_TA_05 = attrCaster[BASE_ATTR.SK_TA_05];
              if (SK_TA_05 > 0) {
                  if (this.calcProb(SK_TA_05)) {
                      caster.addBuffById(caster, this.getHolyBuffId("51"));
                  }
              }
              let SK_TA_10 = attrCaster[BASE_ATTR.SK_TA_10];
              if (SK_TA_10 > 0) {
                  if (this.calcProb(SK_TA_10)) {
                      attrCaster[BASE_ATTR.NEXT_SKILL_SUPER] = 1;
                  }
              }
              let SK_TA_20 = attrCaster[BASE_ATTR.SK_TA_20];
              if (SK_TA_20 > 0) {
                  if (this.calcProb(SK_TA_20)) {
                      caster.useSkillById(target, "2020");
                  }
              }
              let AE_HAMMER = StageAttr.getAttr(STAGE_ATTR.AE_HAMMER);
              if (AE_HAMMER > 0) {
                  if (mgrAllEquip.isAttrValid(STAGE_ATTR.AE_HAMMER)) {
                      if (this.calcProb(AE_HAMMER)) {
                          let keyStr = STAGE_ATTR[STAGE_ATTR.AE_HAMMER];
                          mgrAllEquip.beginCDing(STAGE_ATTR.AE_HAMMER, mgrAllEquip.getEquipValue(keyStr, 2));
                          caster.addBuffById(caster, mgrAllEquip.getBuffId(STAGE_ATTR.AE_HAMMER), [BASE_ATTR.MP_RECOVER, 2], mgrAllEquip.getEquipValue(keyStr, 1));
                      }
                  }
              }
          }
      }
      static calcSkillRebound(caster, target, skillDb, skillData) {
          let isRebound = false;
          let attrCaster = caster.attrCur;
          if (!attrCaster) {
              console.warn("DamageCalculation.calcSkillRebound: 属性为空");
              return isRebound;
          }
          let tempAttr = DamageCalculation.tempAttr;
          let attr_add = skillDb.attr_add;
          for (let i = 0; i < attr_add.length; i = i + 2) {
              let k = attr_add[i];
              let v = attr_add[i + 1];
              if (k && v) {
                  let kn = BASE_ATTR[k];
                  let vn = Number(v);
                  if (kn && vn) {
                      tempAttr[kn] = vn;
                  }
              }
          }
          let SK_REBOUND = attrCaster[BASE_ATTR.SK_REBOUND] + tempAttr[BASE_ATTR.SK_REBOUND];
          if (SK_REBOUND) {
              if (this.calcProb(SK_REBOUND)) {
                  this.holyDebug("弹射");
                  isRebound = true;
              }
          }
          return isRebound;
      }
      static calcHalo(caster, enemyList, friendList) {
          let attrCaster = caster.attrCur;
          let SK_CIRCLE_DMG_HP = attrCaster[BASE_ATTR.SK_CIRCLE_DMG_HP];
          if (SK_CIRCLE_DMG_HP > 0) {
              for (let target of enemyList) {
                  target.addBuffById(caster, this.getHolyBuffId("13"), [SK_CIRCLE_DMG_HP]);
              }
              this.holyDebug("射程内敌人每秒受到当前生命*%d%的伤害");
          }
          let SK_CIRCLE_ADD_HP = attrCaster[BASE_ATTR.SK_CIRCLE_ADD_HP];
          if (SK_CIRCLE_ADD_HP > 0) {
              let COUNT_SK_CIRCLE_ADD_HP = caster.COUNT_SK_CIRCLE_ADD_HP || 0;
              COUNT_SK_CIRCLE_ADD_HP++;
              if (COUNT_SK_CIRCLE_ADD_HP >= 3) {
                  COUNT_SK_CIRCLE_ADD_HP = 0;
                  for (let target of friendList) {
                      let left = target.getAttrMax(BASE_ATTR.HP) - target.getAttr(BASE_ATTR.HP);
                      if (left > 0) {
                          let cure = Math.round(left * SK_CIRCLE_ADD_HP);
                          let dd = this.damageData;
                          dd.damage = cure;
                          target.cure(dd);
                      }
                  }
                  this.holyDebug("射程内友方每3秒回复损失生命*%d%");
              }
              caster.COUNT_SK_CIRCLE_ADD_HP = COUNT_SK_CIRCLE_ADD_HP;
          }
          let SK_CIRCLE_ADD_AD = attrCaster[BASE_ATTR.SK_CIRCLE_ADD_AD];
          if (SK_CIRCLE_ADD_AD > 0) {
              for (let target of friendList) {
                  target.addBuffById(caster, this.getHolyBuffId("15"), [BASE_ATTR.AD, 1 + SK_CIRCLE_ADD_AD]);
              }
              this.holyDebug("射程内友方攻击提升%d%");
          }
          let SK_CIRCLE_ADD_AP = attrCaster[BASE_ATTR.SK_CIRCLE_ADD_AP];
          if (SK_CIRCLE_ADD_AP > 0) {
              for (let target of friendList) {
                  target.addBuffById(caster, this.getHolyBuffId("16"), [BASE_ATTR.AP, 1 + SK_CIRCLE_ADD_AP]);
              }
              this.holyDebug("射程内友方法术强度提升%d%");
          }
          let SK_CIRCLE_ADD_ATK_SPEED = attrCaster[BASE_ATTR.SK_CIRCLE_ADD_ATK_SPEED];
          if (SK_CIRCLE_ADD_ATK_SPEED > 0) {
              for (let target of friendList) {
                  target.addBuffById(caster, this.getHolyBuffId("17"), [BASE_ATTR.ATK_SPEED, 1 + SK_CIRCLE_ADD_ATK_SPEED]);
              }
              this.holyDebug("射程内友方攻速提升%d%");
          }
          let SK_CIRCLE_ADD_CRIT = attrCaster[BASE_ATTR.SK_CIRCLE_ADD_CRIT];
          if (SK_CIRCLE_ADD_CRIT > 0) {
              for (let target of friendList) {
                  target.addBuffById(caster, this.getHolyBuffId("18"), [BASE_ATTR.CRIT, SK_CIRCLE_ADD_CRIT]);
              }
              this.holyDebug("射程内友方暴击提升%d%");
          }
          let SK_CIRCLE_ADD_CRIT_DMG = attrCaster[BASE_ATTR.SK_CIRCLE_ADD_CRIT_DMG];
          if (SK_CIRCLE_ADD_CRIT_DMG > 0) {
              for (let target of friendList) {
                  target.addBuffById(caster, this.getHolyBuffId("19"), [BASE_ATTR.CRIT_DMG, SK_CIRCLE_ADD_CRIT_DMG]);
              }
              this.holyDebug("射程内友方暴伤提升%d%");
          }
          let SK_CIRCLE_SLOW_ATK = attrCaster[BASE_ATTR.SK_CIRCLE_SLOW_ATK];
          if (SK_CIRCLE_SLOW_ATK > 0) {
              for (let target of enemyList) {
                  target.addBuffById(caster, this.getHolyBuffId("20"), [BASE_ATTR.ATK_SPEED, 1 - SK_CIRCLE_SLOW_ATK]);
              }
              this.holyDebug("射程内敌人攻击速度降低%d%");
          }
          let SK_CIRCLE_SLOW_SPEED = attrCaster[BASE_ATTR.SK_CIRCLE_SLOW_SPEED];
          if (SK_CIRCLE_SLOW_SPEED > 0) {
              for (let target of enemyList) {
                  target.addBuffById(caster, this.getHolyBuffId("21"), [1 - SK_CIRCLE_SLOW_SPEED]);
              }
              this.holyDebug("射程内敌人移动速度降低%d%");
          }
      }
      static calcProb(prob) {
          return Utils.random(0, 99) < prob;
      }
      static calcIsFlee(flee) {
          if (flee && flee > 0) {
              let r = Utils.random(0, 99);
              return r < flee;
          }
          return false;
      }
      static damageFloat() {
          return Utils.randomRange(db.game_cnf.damage_float_range[0], db.game_cnf.damage_float_range[1]);
      }
      static calcDamageWithAttr(tidCaster, caster, target, skillDb, dd, isCrossbow = false) {
          let attrCaster = caster.attrCur;
          let isHpFull = caster.isAttrMax(BASE_ATTR.HP);
          let damageData = dd || this.damageData;
          damageData.tidCaster = tidCaster;
          if (skillDb.cmd == "cure") {
              return this.calcCureWithAttr(attrCaster, target, skillDb, damageData);
          }
          let tempAttr = DamageCalculation.tempAttr;
          let attr_add = skillDb.attr_add;
          for (let i = 0; i < attr_add.length; i = i + 2) {
              let k = attr_add[i];
              let v = attr_add[i + 1];
              if (k && v) {
                  let kn = BASE_ATTR[k];
                  if (kn) {
                      tempAttr[kn] = v;
                  }
              }
          }
          if (this.calcIsFlee(target.attrCur[BASE_ATTR.FLEE])) {
              damageData.isFlee = true;
          }
          else {
              let SK_TA_09 = attrCaster[BASE_ATTR.SK_TA_09];
              if (skillDb.is_super && SK_TA_09 > 0) {
                  if (this.calcProb(SK_TA_09)) {
                      caster.useSkillById(target, "2009");
                  }
              }
              let damageId = BASE_ATTR[skillDb.attr_dmg];
              let damage = attrCaster[damageId] || 0;
              let damageEx = 0;
              let canCrit = damageId == BASE_ATTR.AD;
              let isAP = damageId == BASE_ATTR.AP;
              if (!skillDb.is_super) {
                  let SK_TARGET_ADD = attrCaster[BASE_ATTR.SK_TARGET_ADD];
                  if (SK_TARGET_ADD && SK_TARGET_ADD > 0) {
                      damage = damage * SK_TARGET_ADD;
                      this.holyDebug("攻击数量+1 伤害减少");
                  }
                  let SK_TA_12 = attrCaster[BASE_ATTR.SK_TA_12];
                  if (SK_TA_12 > 0) {
                      if (this.calcProb(SK_TA_12)) {
                          attrCaster[BASE_ATTR.NEXT_SKILL_SUPER] = 1;
                      }
                  }
                  let SK_TA_13 = attrCaster[BASE_ATTR.SK_TA_13];
                  if (SK_TA_13 > 0) {
                      if (this.calcProb(SK_TA_13)) {
                          attrCaster[BASE_ATTR.NEXT_SKILL_SUPER] = 1;
                      }
                  }
                  let SK_TA_18 = attrCaster[BASE_ATTR.SK_TA_18];
                  if (SK_TA_18) {
                      if (this.calcProb(SK_TA_18)) {
                          attrCaster[BASE_ATTR.NEXT_DMG_CRIT] = 1;
                      }
                  }
                  let SK_TA_21 = attrCaster[BASE_ATTR.SK_TA_21];
                  if (SK_TA_21) {
                      if (this.calcProb(SK_TA_21)) {
                          attrCaster[BASE_ATTR.NEXT_SKILL_SUPER] = 1;
                      }
                  }
              }
              damage = damage * skillDb.damage;
              let damageIdAdd = BASE_ATTR[skillDb.attr_dmg_add];
              if (damageIdAdd != null) {
                  let damageAdd = attrCaster[damageIdAdd] || 0;
                  damageAdd = damageAdd * skillDb.damage_add;
                  if (damageAdd) {
                      damage += damageAdd;
                  }
              }
              let SK_ENERGE_NONE = attrCaster[BASE_ATTR.SK_ENERGE_NONE];
              if (SK_ENERGE_NONE && SK_ENERGE_NONE > 0) {
                  let damgeAdd = damage * SK_ENERGE_NONE;
                  damage += damgeAdd;
                  this.holyDebug("气回复变为0，但伤害提升%d%");
              }
              let SK_HP_MAX_DMG = attrCaster[BASE_ATTR.SK_HP_MAX_DMG];
              if (SK_HP_MAX_DMG && SK_HP_MAX_DMG > 0 && target.isAttrMax(BASE_ATTR.HP)) {
                  let damgeAdd = damage * SK_HP_MAX_DMG;
                  damage += damgeAdd;
                  this.holyDebug("当敌方生命满血时，对敌方造成的伤害增加%d%");
              }
              let hpPercentTarget = target.getAttrPercent(BASE_ATTR.HP);
              let atk_kill = attrCaster[BASE_ATTR.SK_KILL];
              if (atk_kill && atk_kill > 0) {
                  let damgeAdd = damage * hpPercentTarget * atk_kill;
                  damage += damgeAdd;
                  this.holyDebug("攻击逆斩杀");
              }
              let atk_kill_r = attrCaster[BASE_ATTR.SK_KILL_R];
              if (atk_kill_r && atk_kill_r > 0) {
                  let damgeAdd = damage * (1 - hpPercentTarget) * atk_kill_r;
                  damage += damgeAdd;
                  this.holyDebug("攻击斩杀");
              }
              let crit = attrCaster[BASE_ATTR.CRIT] + tempAttr[BASE_ATTR.CRIT];
              let crit_dmg = attrCaster[BASE_ATTR.CRIT_DMG] + tempAttr[BASE_ATTR.CRIT_DMG];
              let isCrit = false;
              let SK_HP_CRIT = attrCaster[BASE_ATTR.SK_HP_CRIT];
              if (!isAP && SK_HP_CRIT && SK_HP_CRIT > 0 && hpPercentTarget >= SK_HP_CRIT) {
                  isCrit = true;
                  canCrit = true;
                  this.holyDebug("当敌方血量大于%d%时，伤害必暴击");
              }
              let NEXT_DMG_CRIT = attrCaster[BASE_ATTR.NEXT_DMG_CRIT];
              if (NEXT_DMG_CRIT > 0) {
                  crit *= db.game_cnf.next_dmg_crit_factor;
                  ;
                  crit_dmg *= db.game_cnf.next_dmg_crit_damage_factor;
                  attrCaster[BASE_ATTR.NEXT_DMG_CRIT] = 0;
              }
              let SK_AP_CRIT = attrCaster[BASE_ATTR.SK_AP_CRIT];
              if (isHpFull) {
                  let AE_NECKLACE = StageAttr.getAttr(STAGE_ATTR.AE_NECKLACE);
                  if (AE_NECKLACE > 0) {
                      let out_crit = 0;
                      if (isAP) {
                          if (SK_AP_CRIT >= 1) {
                              out_crit = AE_NECKLACE;
                          }
                          else {
                              SK_AP_CRIT += AE_NECKLACE;
                              if (SK_AP_CRIT > 1) {
                                  out_crit = SK_AP_CRIT - 1;
                              }
                          }
                      }
                      else {
                          if (crit >= 1) {
                              out_crit = AE_NECKLACE;
                          }
                          else {
                              crit += AE_NECKLACE;
                              if (crit > 1) {
                                  out_crit = crit - 1;
                              }
                          }
                      }
                      if (out_crit > 0) {
                          crit_dmg += (out_crit * db.game_cnf.all_equip_crit_2_crit_dmg);
                      }
                  }
              }
              if (!canCrit && SK_AP_CRIT && SK_AP_CRIT > 0) {
                  canCrit = true;
                  crit = SK_AP_CRIT;
                  this.holyDebug("法术能进行暴击，暴击概率为%d%");
              }
              if (canCrit) {
                  let SK_NO_CRIT_4_DAMAGE = attrCaster[BASE_ATTR.SK_NO_CRIT_4_DAMAGE];
                  if (SK_NO_CRIT_4_DAMAGE > 0) {
                      canCrit = false;
                  }
                  if (crit > 0) {
                      let CALM = StageAttr.getAttr(STAGE_ATTR.CALM);
                      if (CALM > 0) {
                          crit = crit * (1 - CALM);
                      }
                  }
              }
              if (canCrit && (isCrit || this.calcIsCrit(crit))) {
                  damage *= crit_dmg;
                  damageData.isCrit = true;
              }
              let SK_DMG_LUCK = attrCaster[BASE_ATTR.SK_DMG_LUCK];
              if (SK_DMG_LUCK && SK_DMG_LUCK > 0) {
                  if (this.calcProb(6)) {
                      let damgeAdd = damage * SK_DMG_LUCK;
                      damage += damgeAdd;
                      this.holyDebug("幸运一击");
                  }
              }
              if (!skillDb.is_super) {
                  let sk_dmg_hp = attrCaster[BASE_ATTR.SK_DMG_HP];
                  if (sk_dmg_hp && sk_dmg_hp > 0) {
                      let damgeAdd = attrCaster[BASE_ATTR.HP] * sk_dmg_hp;
                      damage += damgeAdd;
                      this.holyDebug("血量攻击");
                  }
              }
              if (target instanceof Enemy) {
                  let roleDb = target.roleDb;
                  if (roleDb) {
                      if (roleDb.boss) {
                          let TT_HUNT_BOSS = attrCaster[BASE_ATTR.TT_HUNT_BOSS];
                          if (TT_HUNT_BOSS && TT_HUNT_BOSS > 0) {
                              damage += (damage * TT_HUNT_BOSS);
                              this.talentDebug("精英猎人");
                          }
                          let TT_CROSSBOW_HUNT_BOSS = attrCaster[BASE_ATTR.TT_CROSSBOW_HUNT_BOSS];
                          if (TT_CROSSBOW_HUNT_BOSS && TT_CROSSBOW_HUNT_BOSS > 0) {
                              damage += (damage * TT_CROSSBOW_HUNT_BOSS);
                              this.talentDebug("攻城弩：精英猎人");
                          }
                      }
                      else {
                          let TT_HUNT_ENEMY = attrCaster[BASE_ATTR.TT_HUNT_ENEMY];
                          if (TT_HUNT_ENEMY && TT_HUNT_ENEMY > 0) {
                              damage += (damage * TT_HUNT_ENEMY);
                              this.talentDebug("小怪猎人");
                          }
                      }
                  }
              }
              let SK_HURT_SELF_4_DAMAGE = attrCaster[BASE_ATTR.SK_HURT_SELF_4_DAMAGE];
              if (SK_HURT_SELF_4_DAMAGE > 0) {
                  let damgeAdd = damage * SK_HURT_SELF_4_DAMAGE;
                  damage += damgeAdd;
              }
              if (!isCrossbow && !skillDb.is_super) {
                  let SK_ATK_SPEED_DOWN_4_DAMAGE = attrCaster[BASE_ATTR.SK_ATK_SPEED_DOWN_4_DAMAGE];
                  if (SK_ATK_SPEED_DOWN_4_DAMAGE > 0) {
                      let damgeAdd = damage * SK_ATK_SPEED_DOWN_4_DAMAGE;
                      damage += damgeAdd;
                  }
              }
              let SK_NO_CRIT_4_DAMAGE = attrCaster[BASE_ATTR.SK_NO_CRIT_4_DAMAGE];
              if (SK_NO_CRIT_4_DAMAGE > 0) {
                  let damgeAdd = damage * SK_NO_CRIT_4_DAMAGE;
                  damage += damgeAdd;
              }
              let SK_BLOOD_4_DAMAGE = attrCaster[BASE_ATTR.SK_BLOOD_4_DAMAGE];
              if (SK_BLOOD_4_DAMAGE > 0) {
                  let damgeAdd = damage * SK_BLOOD_4_DAMAGE;
                  damage += damgeAdd;
              }
              let TT_BLOOD = attrCaster[BASE_ATTR.TT_BLOOD];
              if (TT_BLOOD && TT_BLOOD > 0) {
                  let blood = Math.ceil(damage * TT_BLOOD);
                  this.talentDebug("吸血");
                  damageData.blood = blood;
              }
              let damageFactor = target.getAttr(BASE_ATTR.HURT_FACTOR);
              let damageReduct = target.getAttr(BASE_ATTR.DMG_REDUCT);
              damage = damage * damageFactor * damageReduct;
              let NEXT_DMG_UP = attrCaster[BASE_ATTR.NEXT_DMG_UP];
              if (NEXT_DMG_UP) {
                  damage = damage * NEXT_DMG_UP;
                  caster.setAttr(BASE_ATTR.NEXT_DMG_UP, 0);
              }
              let SK_HP_R_DAMGE = attrCaster[BASE_ATTR.SK_HP_R_DAMGE];
              if (SK_HP_R_DAMGE > 0) {
                  let hpPercent = caster.getAttrPercent(BASE_ATTR.HP);
                  let factor = (1 - hpPercent) * SK_HP_R_DAMGE;
                  let damgeAdd = Math.ceil(damage * factor);
                  damage += damgeAdd;
              }
              if (isAP) {
                  let SK_MP_4_DAMAGE = attrCaster[BASE_ATTR.SK_MP_4_DAMAGE];
                  if (SK_MP_4_DAMAGE > 0) {
                      let mpPercent = caster.getAttrPercent(BASE_ATTR.MP);
                      let factor = Math.min(mpPercent, SK_MP_4_DAMAGE);
                      let damgeAdd = Math.ceil(damage * factor);
                      damage += damgeAdd;
                  }
                  let AP_ARMOUR = StageAttr.getAttr(STAGE_ATTR.AP_ARMOUR) + target.getAttr(BASE_ATTR.DEF_AP);
                  if (AP_ARMOUR > 0) {
                      damage = damage * (1 - AP_ARMOUR);
                      if (damage < 0)
                          damage = 0;
                  }
              }
              else {
                  let AD_ARMOUR = StageAttr.getAttr(STAGE_ATTR.AD_ARMOUR) + target.getAttr(BASE_ATTR.DEF_AD);
                  if (AD_ARMOUR > 0) {
                      damage = damage * (1 - AD_ARMOUR);
                      if (damage < 0)
                          damage = 0;
                  }
              }
              damage = damage * this.damageFloat();
              let DMG_EX = attrCaster[BASE_ATTR.DMG_EX];
              if (DMG_EX > 0) {
                  damageEx += damage * DMG_EX;
              }
              damageData.damageEx = Math.ceil(damageEx);
              damageData.damage = Math.ceil(damage);
              damageData.isAP = isAP;
          }
          return damageData;
      }
      static calcDamageWithAttrByEnemy(attrCaster, target, skillDb, dd) {
          let damageData = dd || this.damageData;
          if (skillDb.cmd == "cure") {
              return this.calcCureWithAttr(attrCaster, target, skillDb, damageData);
          }
          if (skillDb.cmd == "hppercent") {
              let damageId = BASE_ATTR[skillDb.attr_dmg];
              let isAP = damageId == BASE_ATTR.AP;
              damageData.damage = Math.ceil(target.getAttr(BASE_ATTR.HP) * skillDb.damage);
              damageData.isAP = isAP;
              damageData.isCrit = true;
              return damageData;
          }
          let tempAttr = DamageCalculation.tempAttr;
          let attr_add = skillDb.attr_add;
          for (let i = 0; i < attr_add.length; i = i + 2) {
              let k = attr_add[i];
              let v = attr_add[i + 1];
              if (k && v) {
                  let kn = BASE_ATTR[k];
                  let vn = Number(v);
                  if (kn && vn) {
                      tempAttr[kn] = vn;
                  }
              }
          }
          let flee = target.getAttr(BASE_ATTR.FLEE);
          let AE_FLEE = StageAttr.getAttr(STAGE_ATTR.AE_FLEE);
          if (AE_FLEE > 0) {
              flee += (100 * AE_FLEE);
          }
          if (this.calcIsFlee(flee)) {
              damageData.isFlee = true;
              if (AE_FLEE > 0) {
                  target.attrCur[BASE_ATTR.NEXT_DMG_UP] = mgrAllEquip.getEquipValue(STAGE_ATTR[STAGE_ATTR.AE_FLEE], 1);
              }
          }
          else {
              let damageId = BASE_ATTR[skillDb.attr_dmg];
              let damage = attrCaster[damageId] || 0;
              let canCrit = damageId == BASE_ATTR.AD;
              let isAP = damageId == BASE_ATTR.AP;
              damage = damage * skillDb.damage;
              let damageIdAdd = BASE_ATTR[skillDb.attr_dmg_add];
              if (damageIdAdd != null) {
                  let damageAdd = attrCaster[damageIdAdd] || 0;
                  damageAdd = damageAdd * skillDb.damage_add;
                  if (damageAdd) {
                      damage += damageAdd;
                  }
              }
              let crit = attrCaster[BASE_ATTR.CRIT] + tempAttr[BASE_ATTR.CRIT];
              let crit_dmg = attrCaster[BASE_ATTR.CRIT_DMG] + tempAttr[BASE_ATTR.CRIT_DMG];
              let isCrit = false;
              if (canCrit && (isCrit || this.calcIsCrit(crit))) {
                  damage *= crit_dmg;
                  damageData.isCrit = true;
              }
              if (skillDb.hp_curt_damage > 0) {
                  damage += target.attrCur[BASE_ATTR.HP] * skillDb.hp_curt_damage;
              }
              let damageReduct = target.getAttr(BASE_ATTR.DMG_REDUCT);
              damage = damage * damageReduct;
              damageData.damage = Math.ceil(damage * this.damageFloat());
              damageData.isAP = isAP;
          }
          return damageData;
      }
      static calcDamageWithAttrByDamageId(attrCaster, target, damageId, damageFactor, critProb, dd, hp_curt_damage = 0) {
          let damageData = dd || this.damageData;
          if (this.calcIsFlee(target.attrCur[BASE_ATTR.FLEE])) {
              damageData.isFlee = true;
          }
          else {
              let damage = attrCaster[damageId] || 0;
              let canCrit = damageId == BASE_ATTR.AD;
              let isAP = damageId == BASE_ATTR.AP;
              damage = damage * damageFactor;
              let crit = attrCaster[BASE_ATTR.CRIT] + critProb;
              let crit_dmg = attrCaster[BASE_ATTR.CRIT_DMG];
              let isCrit = false;
              if (canCrit && (isCrit || this.calcIsCrit(crit))) {
                  damage *= crit_dmg;
                  damageData.isCrit = true;
              }
              if (hp_curt_damage > 0) {
                  damage += target.attrCur[BASE_ATTR.HP] * hp_curt_damage;
              }
              damageData.damage = Math.ceil(damage * this.damageFloat());
              damageData.isAP = isAP;
          }
          return damageData;
      }
      static calcDamageByEnemy(caster, target, skillData, dd) {
          dd = this.resetDamageData(dd) || this.damageData;
          let skillDb = skillData.skillDb;
          let attrCaster = caster.attrCur;
          let dx = target.mx - caster.mx;
          let dy = target.my - caster.my;
          dd.direction.x = dx;
          dd.direction.y = dy;
          dd.direction.normalize();
          let rt = this.calcDamageWithAttrByEnemy(attrCaster, target, skillDb, dd);
          return rt;
      }
      static calcCureWithAttr(attrCaster, target, skillDb, dd) {
          let damageData = dd || this.damageData;
          let damageId = BASE_ATTR[skillDb.attr_dmg];
          let isAP = damageId == BASE_ATTR.AP;
          let damage = attrCaster[damageId] || 0;
          damage = damage * skillDb.damage;
          damageData.damage = Math.ceil(damage * this.damageFloat());
          damageData.isAP = isAP;
          return damageData;
      }
      static dealDamageByBuff(data, target) {
          let damage = data.damage;
          if (data.isAP) {
              let DEF_AP = target.getAttr(BASE_ATTR.DEF_AP);
              if (DEF_AP > 0) {
                  damage = damage * (1 - DEF_AP);
                  if (damage < 0)
                      damage = 0;
              }
          }
          else {
              let DEF_AD = target.getAttr(BASE_ATTR.DEF_AD);
              if (DEF_AD > 0) {
                  damage = damage * (1 - DEF_AD);
                  if (damage < 0)
                      damage = 0;
              }
          }
          data.damage = damage;
      }
  }
  DamageCalculation.tempDamageData = { tidCaster: "", damage: 0, blood: 0, damageEx: 0, isCrit: false, isFlee: false, direction: new LogicPoint() };
  DamageCalculation.attr = [];

  class StageGameStatis {
      static addDamage(tid, add) {
          if (!this.isRunning)
              return;
          this.damageAll += add;
          if (tid)
              this.setDamage(tid, this.getDamage(tid) + add);
          else
              console.error("StageGameStatis.addDamage 没有伤害来源");
      }
      static getDamage(tid) {
          return this.dataDamageTotal[tid] || 0;
      }
      static setDamage(tid, val) {
          this.dataDamageTotal[tid] = val;
      }
      static getDamageAll() {
          return this.damageAll;
      }
      static reset() {
          this.passtime = 0;
          this.damageAll = 0;
          this.dataDamageTotal = {};
      }
      static udpate(dt) {
          if (this.isRunning) {
              this.passtime += dt;
          }
      }
      static getHistoryData() {
          return this.dataHistory;
      }
      static start() {
          this.reset();
          this.isRunning = true;
      }
      static pause() {
          this.isRunning = false;
      }
      static resume() {
          this.isRunning = true;
      }
      static stop(mode, id) {
          this.isRunning = false;
          let towerPos = db.get_tower_pos_map()[mgrTower.defaultPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              let id = mgrTower.getSlotTower(pos.id - 1);
              if (id) {
                  if (!this.dataDamageTotal[id]) {
                      this.dataDamageTotal[id] = 0;
                  }
              }
          }
          this.dataHistory.push({ mode: mode, id: id, data: this.dataDamageTotal });
          if (this.dataHistory.length > 3) {
              this.dataHistory.shift();
          }
          console.log("################################伤害统计");
          console.warn(this.dataDamageTotal);
          console.warn(this.passtime);
          console.log("################################伤害统计");
          this.reset();
      }
  }
  StageGameStatis.dataDamageTotal = {};
  StageGameStatis.dataHistory = [];
  StageGameStatis.passtime = 0;
  StageGameStatis.damageAll = 0;
  StageGameStatis.isRunning = false;

  class AtlasHelper {
      static loadAtlas(url, callback) {
          let res = Laya.loader.getRes(url);
          if (!res) {
              Laya.loader.load(url, Laya.Handler.create(this, this.onAtlasLoad, [url, callback]), null, Laya.Loader.ATLAS);
          }
          else {
              this.onAtlasLoad(url, callback, res);
          }
      }
      static onAtlasLoad(url, callback, atlas) {
          AtlasHelper.createAnimFrame(url, atlas);
          if (callback)
              callback();
      }
      static createAnimFrame(url, atlasJson) {
          if (this.allAtlasLoaded[url])
              return;
          let cacheData = [];
          let frames = atlasJson["frames"];
          let totalConfig = {};
          for (let filename in frames) {
              let enemyName;
              let animName;
              let animIndex;
              let indexN = filename.indexOf("-");
              if (indexN < 0) {
                  indexN = filename.indexOf("_");
              }
              let indexI = filename.lastIndexOf("_");
              enemyName = filename.substring(0, indexN);
              animName = filename.substring(indexN + 1, indexI);
              animIndex = Number(filename.substring(indexI + 1, filename.indexOf(".png")));
              let data = totalConfig[enemyName];
              if (!data) {
                  data = {};
                  totalConfig[enemyName] = data;
              }
              if (!data[animName]) {
                  data[animName] = [];
              }
              data[animName].push({ file: atlasJson.meta.prefix + filename, id: animIndex });
          }
          for (let k in totalConfig) {
              let v = totalConfig[k];
              for (let kk in v) {
                  let frames = v[kk];
                  frames.sort(function (a, b) {
                      return a.id - b.id;
                  });
              }
              Level.enemyNameList.push(k);
          }
          for (let name in totalConfig) {
              let config = totalConfig[name];
              for (let anim in config) {
                  let animConfig = config[anim];
                  var urls = [];
                  for (let frame of animConfig) {
                      urls.push(frame.file);
                  }
                  let animName = name + "_" + anim;
                  cacheData.push(animName);
                  this.allAnims2Urls[animName] = urls;
                  Laya.Animation.createFrames(urls, animName);
              }
          }
          this.allAtlasLoaded[url] = cacheData;
      }
      static recreateAnimation() {
          for (let animName in this.allAnims2Urls) {
              let urls = this.allAnims2Urls[animName];
              if (urls) {
                  Laya.Animation.clearCache(animName);
                  Laya.Animation.createFrames(urls, animName);
              }
          }
      }
      static clearAtlas(url) {
          let cacheData = this.allAtlasLoaded[url];
          if (cacheData) {
              for (let name of cacheData) {
                  Laya.Animation.clearCache(name);
                  delete this.allAnims2Urls[name];
              }
          }
          Laya.loader.clearRes(url);
          delete this.allAtlasLoaded[url];
      }
      static clearAll() {
          for (let url in this.allAtlasLoaded) {
              this.clearAtlas(url);
          }
          this.allAtlasLoaded = {};
      }
  }
  AtlasHelper.allAtlasLoaded = {};
  AtlasHelper.allAnims2Urls = {};

  class ResEnemyManager {
      static clearAll() {
          for (let url in this.res_atlas) {
              AtlasHelper.clearAtlas(url);
              console.log("ResEnemy.release", url);
          }
          for (let pkgName in this.res_fgui_package) {
              this.removePackage(pkgName);
          }
          for (let url in this.res_effect) {
              Laya.loader.clearRes(url);
              console.log("ResEnemy.release", url);
          }
          for (let url in this.res_spine) {
              Spine.clear(url);
              console.log("ResEnemy.release", url);
          }
          this.resEnemyFlag = {};
          this.res_atlas = {};
          this.res_spine = {};
          this.res_fgui_package = {};
          this.res_effect = {};
      }
      static clearPackageRes(pkg) {
          if (pkg) {
              let cnt = pkg._items.length;
              for (let j = 0; j < cnt; j++) {
                  let pi = pkg._items[j];
                  if (pi.type == fgui.PackageItemType.Atlas) {
                      let url = pi.file;
                      console.log("ResEnemy.clearPackageRes", url);
                      Laya.Loader.clearRes(url);
                  }
              }
          }
      }
      static removePackage(pkgName) {
          console.log("ResEnemy.removePackage", pkgName);
          let pkg = fgui.UIPackage.getByName(pkgName);
          if (pkg) {
              this.clearPackageRes(pkg);
              fgui.UIPackage.removePackage(pkgName);
          }
      }
      static onEnemyAdd(roleId) {
          if (!this.resEnemyFlag[roleId]) {
              this.resEnemyFlag[roleId] = true;
              this.onEnemyResAdd(roleId);
          }
      }
      static onEnemyResAdd(roleId) {
          console.log("ResEnemy.add", roleId);
          let roleDb = db.get_role_db(roleId);
          if (roleDb) {
              let modelDb = db.get_role_model_db(roleDb.model_id);
              if (modelDb) {
                  if (modelDb.spine) {
                      this.res_spine[modelDb.res] = true;
                  }
                  else {
                      this.res_atlas[modelDb.res] = true;
                  }
              }
              this.parseSkillDb(db.get_skill_db_map()[roleDb.skill_id]);
              this.parseSkillDb(db.get_skill_db_map()[roleDb.super_skill_id]);
          }
      }
      static parseSkillDb(skillDb) {
          if (!skillDb)
              return;
          this.addEffectDb(skillDb.effect_cast);
          this.addEffectDb(skillDb.effect_shoot);
          this.addEffectDbArr(skillDb.effect_lock);
          this.addEffectDb(skillDb.effect_hurt);
          this.addEffectDb(skillDb.effect_hit);
          this.parseBulletDb(db.get_bullet_db_map()[skillDb.bullet_id]);
          this.parseBuffDb(db.get_buff_db_map()[skillDb.buff_caster_id]);
          this.parseBuffDb(db.get_buff_db_map()[skillDb.buff_target_id]);
      }
      static parseBulletDb(bulletDb) {
          if (!bulletDb)
              return;
          this.addEffectDb(bulletDb.effect_lock);
          this.addEffectDb(bulletDb.effect_shoot);
          this.addEffectDb(bulletDb.effect_hit);
          this.addEffectDb(bulletDb.effect_bullet);
      }
      static parseBuffDb(buffDb) {
          if (!buffDb)
              return;
          switch (buffDb.template) {
              case "Trap":
              case "Skill":
                  this.parseSkillDb(db.get_skill_db_map()[buffDb.param[0]]);
                  break;
          }
          this.addEffectDb(buffDb.effect);
      }
      static addEffectDb(effectId) {
          if (effectId) {
              let effectDb = db.get_effect_db_map()[effectId];
              if (effectDb) {
                  switch (effectDb.type) {
                      case "2d":
                      case "fgui":
                          this.addEffectRes(effectDb.model);
                          break;
                      default:
                          let modelDb = db.get_model_db_map()[effectDb.model];
                          if (modelDb) {
                              this.addEffectRes(modelDb.resPath);
                          }
                          else {
                              this.addEffectRes(effectDb.model);
                          }
                          break;
                  }
              }
          }
      }
      static addEffectDbArr(effectIds) {
          for (let effectId of effectIds) {
              this.addEffectDb(effectId);
          }
      }
      static addEffectRes(url) {
          if (url) {
              if (url.startsWith("ui://")) {
                  let pkgReg = /ui:\/\/(\S+)\//img;
                  let result = pkgReg.exec(url);
                  if (result) {
                      let pkgName = result[1];
                      if (!this.res_fgui_package[pkgName]) {
                          this.res_fgui_package[pkgName] = true;
                          console.log("ResEnemy.addEffectRes fgui", pkgName);
                      }
                  }
              }
              else {
                  if (!this.res_effect[url]) {
                      this.res_effect[url] = true;
                      console.log("ResEnemy.addEffectRes", url);
                  }
              }
          }
      }
  }
  ResEnemyManager.resEnemyFlag = {};
  ResEnemyManager.res_atlas = {};
  ResEnemyManager.res_spine = {};
  ResEnemyManager.res_fgui_package = {};
  ResEnemyManager.res_effect = {};

  class Enemy extends LogicEnemy {
      constructor() {
          super(...arguments);
          this.score = 0;
          this._tempPoint = new Laya.Point;
          this.skinTransformId = 0;
      }
      onCreate() {
          super.onCreate();
          this.attrCur = Level.buildAttrArray(BASE_ATTR.LEN_ENEMY);
          this.attrStd = Level.buildAttrArray(BASE_ATTR.LEN_ENEMY);
          this.loadRoleById(this.tid);
          this.prepareSkillData(this.comAttacker.skillData, false);
          this.comAttacker.skillData.prepare = true;
      }
      onUpdate(t) {
          super.onUpdate(t);
          this.updateFlag(t);
          this.addEnergy(t * this.getEnergyRecover());
      }
      onRemove() {
          super.onRemove();
          this.unbindSkin();
      }
      setDropId(dropId) {
          this.dropId = dropId;
          return this;
      }
      getDropId() {
          return this.dropId;
      }
      bindData(dropId, score) {
          this.score = score;
          this.setDropId(dropId);
          return this;
      }
      scaleAttr(index, scale) {
          if (index == BASE_ATTR.ATK_SPEED) {
              if (scale < db.game_cnf.enemy_atk_speed_min) {
                  scale = db.game_cnf.enemy_atk_speed_min;
              }
          }
          super.scaleAttr(index, scale);
      }
      scaleSpeed(scale) {
          if (scale < db.game_cnf.enemy_speed_min) {
              scale = db.game_cnf.enemy_speed_min;
          }
          this.comMove.scaleSpeed(scale);
      }
      recoverSpeed() {
          this.comMove.recoverSpeed();
      }
      set range(value) {
          this.attrCur[BASE_ATTR.RANGE] = value;
      }
      get range() {
          return this.attrCur[BASE_ATTR.RANGE] + this.comAttacker.skillData.ranage;
      }
      setGrid(gx, gy) {
          super.setGrid(gx, gy);
          if (this.world.map.checkFlag(gx, gy, MAP_FLAG.ALPHA)) {
              if (this.skin) {
                  this.skin.alpha = 0.8;
              }
          }
          else {
              if (this.skin) {
                  this.skin.alpha = 1;
              }
          }
      }
      calcBuffBySkillCaster(caster, skillId, skillData) {
          let skillDb = skillData.skillDb;
          if (skillDb && skillDb.buff_caster_id) {
              this.addBuffByProb(caster, skillDb.buff_caster_id, skillDb.buff_caster_prob);
          }
      }
      calcBuffBySkillTarget(caster, skillId, skillData) {
          let skillDb = skillData.skillDb;
          if (skillDb && skillDb.buff_target_id) {
              this.addBuffByProb(caster, skillDb.buff_target_id, skillDb.buff_target_prob);
          }
      }
      addBuffByProb(caster, buffId, prob) {
          let r = Utils.random(0, 99);
          if (r < prob) {
              this.addBuffById(caster, buffId);
          }
      }
      calcDamage(caster, data, dmgData) {
          return DamageCalculation.calcDamage(caster, this, data, dmgData);
      }
      execSkill(caster, skillData) {
          let data = skillData.skillDb;
          switch (data.cmd) {
              case "none":
                  break;
              case "sneer":
                  this.changeTargetId(caster.uid);
                  break;
              case "curepercent":
                  let dd = DamageCalculation.damageData;
                  dd.damage = Math.ceil(this.getAttrMax(BASE_ATTR.HP) * data.damage);
                  this.cure(dd);
                  break;
              case "buffnow":
                  {
                      if (this.execAndClearAllBuff(data)) {
                          if (StageConfig.enableGameEffect && data.effect_hurt && this.skin) {
                              EffectFactory.createByType(data.effect_hurt, EffectFactory.layerFront, this.skin);
                          }
                      }
                  }
                  break;
              default:
                  let damge = this.calcDamage(caster, skillData);
                  this.execSkillWithDamage(caster, damge, skillData);
                  if (data.damage_add_by_count > 0) {
                      damge.damage = Math.ceil(damge.damage * (skillData.count * data.damage_add_by_count));
                  }
                  if (data.blood) {
                      damge.blood += Math.ceil(damge.damage * data.blood);
                  }
                  if (data.blood_hp_r) {
                      let lostHp = caster.getAttrLost(BASE_ATTR.HP);
                      damge.blood += Math.ceil(lostHp * data.blood_hp_r);
                  }
                  if (caster && damge.blood) {
                      damge.damage = damge.blood;
                      caster.cure(damge);
                  }
                  break;
          }
      }
      execSkillWithDamage(caster, damageData, skillData) {
          let skillDb = skillData.skillDb;
          if (StageConfig.enableGameEffect && skillDb.effect_hurt && this.skin) {
              EffectFactory.createByType(skillDb.effect_hurt, EffectFactory.layerFront, this.skin);
          }
          this.hurt(damageData);
          if (caster && skillDb.hit_energy) {
              caster.addEnergy(skillDb.hit_energy);
          }
          if (caster && this.attrCur[BASE_ATTR.HP] <= 0) {
              DamageCalculation.calcEnemyDead(caster, this);
          }
      }
      hurt(data) {
          let damage = data.damage + data.damageEx;
          if (this.checkFlag(LogicObjectFlag.SHIELD)) {
              data.isShield = true;
              damage = 0;
          }
          if (damage <= 0)
              return;
          let attrSelf = this.attrCur;
          let hpBefore = attrSelf[BASE_ATTR.HP];
          let hpLeft = hpBefore - damage;
          if (hpLeft < 0) {
              hpLeft = 0;
          }
          attrSelf[BASE_ATTR.HP] = hpLeft;
          StageGameStatis.addDamage(data.tidCaster, damage);
          if (this.skin) {
              this.skin.playHurt();
              this.showDamage(data);
              this.showDamageEx(data);
          }
          this.updateHpBar();
          if (hpBefore > 0 && hpLeft <= 0) {
              this.onDead();
          }
      }
      cure(data) {
          let addhp = data.damage;
          this.cureByValue(addhp);
      }
      cureByValue(addhp) {
          if (addhp <= 0)
              return;
          let attrSelf = this.attrCur;
          let SHADOW = StageAttr.getAttr(STAGE_ATTR.SHADOW);
          if (SHADOW > 0) {
              addhp = Math.floor(addhp * (1 - SHADOW));
              if (addhp <= 0) {
                  return;
              }
          }
          let hpMax = this.attrStd[BASE_ATTR.HP];
          let hpLeft = attrSelf[BASE_ATTR.HP] + addhp;
          if (hpLeft > hpMax) {
              hpLeft = hpMax;
          }
          attrSelf[BASE_ATTR.HP] = hpLeft;
          this.updateHpBar();
          this.showCure(addhp);
      }
      showCure(damage) {
          if (damage <= 0)
              return;
          if (!this.skin)
              return;
          let text = CustomDamageText.create();
          text.showRecoverHP(damage);
          Level.stage.layerGameUI.addChild(text.displayObject);
          text.x = this.skin.x;
          text.y = this.skin.y - 50;
          text.displayObject.zOrder = text.y;
      }
      onDead() {
          this.world.remUnit(this, UNIT_REMOVE_REASON.DEAD);
      }
      hurtWithDamge(damage) {
          let attrSelf = this.attrCur;
          let atk = Math.round(damage * Utils.randomRange(0.8, 1.2));
          let hpLeft = attrSelf[BASE_ATTR.HP] - atk;
          if (hpLeft < 0) {
              hpLeft = 0;
          }
          attrSelf[BASE_ATTR.HP] = hpLeft;
          if (this.skin) {
              this.skin.playHurt();
              let dmg = DamageCalculation.damageData;
              dmg.damage = atk;
              this.showDamage(dmg);
          }
          this.updateHpBar();
          if (hpLeft <= 0) {
              this.world.remUnit(this, UNIT_REMOVE_REASON.DEAD);
          }
      }
      showDamage(damage) {
          if (!mgrGame.dmgFontEnable)
              return;
          let text = CustomDamageText.create();
          Level.stage.layerGameUI.addChild(text.displayObject);
          text.x = this.skin.x;
          text.y = this.skin.y - this.roleDb.height * 0.5;
          text.showDamage(damage);
          text.displayObject.zOrder = text.y;
      }
      showDamageEx(damage) {
          if (!mgrGame.dmgFontEnable)
              return;
          if (damage.damageEx <= 0)
              return;
          let text = CustomDamageText.create();
          Level.stage.layerGameUI.addChild(text.displayObject);
          text.x = this.skin.x;
          text.y = this.skin.y - this.roleDb.height * 0.5;
          text.showDamage(damage, damage.damageEx);
          text.displayObject.zOrder = text.y;
      }
      loadRoleRandom() {
          this.loadRoleById(Utils.randomItem(Level.allRoleIds));
      }
      loadRoleById(roleId) {
          let roleDb = db.get_role_db(roleId);
          if (roleDb) {
              ResEnemyManager.onEnemyAdd(roleId);
              this.modelDb = db.get_role_model_db(roleDb.model_id);
              if (!this.modelDb) {
                  console.error("Enemy.loadRoleById没有配置模型ID：", roleId, roleDb.model_id);
              }
              if (this.modelDb && mgrGame.getItemCount(this.modelDb.item_id) == 0) {
                  mgrGame.addItem(this.modelDb.item_id, 1, 54, false);
              }
              if (roleDb.custom_attr) {
                  this.attrCur[BASE_ATTR.HP] = roleDb.hp;
                  this.attrCur[BASE_ATTR.AD] = roleDb.atk;
                  this.attrCur[BASE_ATTR.AP] = roleDb.atk;
              }
              else {
                  this.calcAttr(roleDb);
              }
              this.range = roleDb.range;
              this.attrCur[BASE_ATTR.MP] = roleDb.mp_max;
              this.attrCur[BASE_ATTR.MP_RECOVER] = roleDb.mp_recover;
              this.attrCur[BASE_ATTR.CRIT_DMG] = 1.5;
              this.attrCur[BASE_ATTR.HURT_FACTOR] = 1;
              this.attrCur[BASE_ATTR.DMG_REDUCT] = 1;
              this.attrCur[BASE_ATTR.DEF_AD] = roleDb.def_ad;
              this.attrCur[BASE_ATTR.DEF_AP] = roleDb.def_ap;
              Level.copyAttrArray(this.attrCur, this.attrStd);
              this.attrCur[BASE_ATTR.MP] = roleDb.mp;
              let speed = roleDb.speed;
              let CHARGE = StageAttr.getAttr(STAGE_ATTR.CHARGE);
              if (CHARGE > 0) {
                  speed += speed * CHARGE;
              }
              this.comMove.speed = speed;
              this.comMove.logicSpeedScale = roleDb.speed_scale;
              if (speed <= 0) {
                  this.addFlag(LogicObjectFlag.NO_MOVE);
              }
              this.skillDb = db.get_skill_db_map()[roleDb.skill_id];
              this.superDb = db.get_skill_db_map()[roleDb.super_skill_id];
              this.onAttrChange();
              if (this.modelDb.time_in) {
                  this.born(this.modelDb.time_in);
              }
          }
          this.roleDb = roleDb;
      }
      calcAttr(roleDb) {
          Level.calcEnemyAttr(roleDb, this.attrCur, this.lv || mgrGame.levelId);
      }
      onAttrChange() {
      }
      bindSkin(skin, view = false) {
          this.skin = skin;
          skin.initSkin(this);
          if (!view) {
              this.onSkinBind();
          }
      }
      onSkinBind() {
      }
      unbindSkin() {
          this.skin = null;
      }
      updateHpBar() {
          if (this.skin) {
              let hp = this.attrCur[BASE_ATTR.HP];
              let hpMax = this.attrStd[BASE_ATTR.HP];
              this.skin.updateHpBar(hp, hpMax);
          }
      }
      onMoveTo(time, dx, dy, mx, my) {
          if (this.skin) {
              this.skin.updatePosition(this, time, dx, dy, mx, my);
          }
      }
      updateFlag(t) {
          if (this.skin) {
              this.skin.updateNoMove(this.checkFlag(LogicObjectFlag.NO_MOVE));
              this.skin.updateNoAttack(this.checkFlag(LogicObjectFlag.NO_ATTACK));
          }
      }
      onBeatBack(x, y) {
          if (this.skin) {
              this.skin.moveTo(LogicConfig.LOGIC_FRAME_ITME, x, y);
          }
      }
      getShootPoint(index) {
          if (this.skin) {
              return this.skin.getHitPoint(index);
          }
          else {
              let posf = Level.convertGridPosToRealPos(this.mx, this.my, false);
              this._tempPoint.x = posf.x;
              this._tempPoint.y = posf.y;
              return this._tempPoint;
          }
      }
      getHitPoint(index) {
          if (this.skin) {
              return this.skin.getHitPoint(index);
          }
          else {
              let posf = Level.convertGridPosToRealPos(this.mx, this.my, false);
              this._tempPoint.x = posf.x;
              this._tempPoint.y = posf.y;
              return this._tempPoint;
          }
      }
      isBuffOfCrazy(buffDb) {
          switch (buffDb.template) {
              case "Stun":
              case "Slow":
              case "AttrScale":
              case "Frozen":
              case "BeatBack":
                  return true;
          }
          return false;
      }
      addBuffById(caster, buffId, param = null) {
          if (buffId) {
              let buffDb = db.get_buff_db(buffId);
              if (buffDb) {
                  if (StageAttr.getAttr(STAGE_ATTR.CRAZY)) {
                      if (this.isBuffOfCrazy(buffDb)) {
                          return;
                      }
                  }
                  this.addBuff(caster, buffDb.id, buffDb.template, buffDb.time, buffDb.delay, buffDb.count, param);
              }
          }
      }
      onBuffStart(buff) {
          if (this.skin) {
              this.skin.onBuffStart(this, buff.id, buff.data);
          }
      }
      onBuffExec(buff) {
          if (this.skin) {
              this.skin.onBuffExec(this, buff.id, buff.data);
          }
      }
      onBuffEnd(buff) {
          if (this.skin) {
              this.skin.onBuffEnd(this, buff.id, buff.data);
          }
      }
      isEnergyFull() {
          return StageConfig.keepSuperSkill || this.isAttrMax(BASE_ATTR.MP);
      }
      letEnergyEmpty() {
          this.attrCur[BASE_ATTR.MP] = 0;
      }
      letEnergyFull() {
          this.attrCur[BASE_ATTR.MP] = this.attrStd[BASE_ATTR.MP];
      }
      showCureMP(add) {
      }
      addEnergy(add = 1, show = false) {
          this.addAttr(BASE_ATTR.MP, add);
      }
      addEnergyPercent(percent = 1, show = false) {
          let add = this.getAttrMax(BASE_ATTR.MP) * percent;
          this.addAttr(BASE_ATTR.MP, add);
          if (show) {
              this.showCureMP(add);
          }
      }
      getEnergyPercent() {
          return this.getAttrPercent(BASE_ATTR.MP);
      }
      getEnergyRecover() {
          return this.attrCur[BASE_ATTR.MP_RECOVER];
      }
      prepareSkillData(data, attack = true) {
          let skillDb = this.skillDb;
          let modelDb = this.modelDb;
          if (this.superDb && this.isEnergyFull()) {
              skillDb = this.superDb;
          }
          if (skillDb && modelDb) {
              Level.packSkillData(data, skillDb);
              if (!skillDb.is_super) {
                  data.timeCast = modelDb.cast_time1 * skillDb.cast_time / this.getAttackSpeed();
                  data.timeCD = skillDb.cd_time / this.getAttackSpeed();
              }
              else {
                  data.timeCast = modelDb.cast_time2 * skillDb.cast_time / StageConfig.gameTimeScale;
                  data.timeCD = skillDb.cd_time / StageConfig.gameTimeScale;
              }
          }
      }
      getAttackSpeed() {
          return this.attrCur[BASE_ATTR.ATK_SPEED] * StageConfig.gameTimeScale;
          ;
      }
      exitAttack() {
          if (this.skin) {
              this.skin.playMove();
          }
      }
      lockTarget(target) {
          if (target && this.skin) {
              this.skin.lookAtTarget(this, target);
          }
      }
      onSkillCast(time, index = 0, targetId = 0, skillData) {
          if (this.skin) {
              let skillDb = skillData.skillDb;
              if (skillDb.is_super) {
                  this.letEnergyEmpty();
              }
              let target = this.world.objectMgr.getObjectById(targetId);
              if (target) {
                  this.skin.lookAtTarget(this, target);
              }
              if (StageConfig.enableGameEffect && !skillDb.multi_effect_lock && skillDb.effect_lock.length) {
                  let skin = Level.stage.getUnitSkinById(targetId);
                  if (skin) {
                      let index = skillDb.point_index;
                      if (index == 0) {
                          index = skillDb.is_super ? 1 : 0;
                      }
                      let shootPoint = this.skin.getShootPoint(0, index);
                      let offsety = -skin.height * skillDb.hit_offset;
                      for (let effect of skillDb.effect_lock) {
                          let effectDb = db.get_effect_db(effect);
                          if (effectDb.line) {
                              let eLock = EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
                              let node = eLock.node;
                              node.x = shootPoint.x;
                              node.y = shootPoint.y;
                          }
                          else {
                              EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
                          }
                      }
                  }
              }
              if (StageConfig.enableGameEffect && skillDb.effect_cast) {
                  let effectDb = db.get_effect_db_map()[skillDb.effect_cast];
                  if (effectDb) {
                      let index = effectDb.point_index || skillDb.point_index;
                      if (index == 0) {
                          index = skillDb.is_super ? 1 : 0;
                      }
                      let point = this.skin.getShootPoint(0, index);
                      let offsetX = point.x - this.skin.x;
                      let offsetY = point.y - this.skin.y;
                      let effect = EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, this.skin, null, null, offsetX, offsetY, null, this.getAttackSpeed());
                      let node = effect.node;
                      if (this.skin.getFlip() < 0) {
                          if (node instanceof Laya.Sprite) {
                              node.scaleX = -node.scaleX;
                          }
                          else if (node instanceof Laya.Sprite3D) {
                              node.transform.localRotationEulerY = 180;
                          }
                      }
                      else {
                          if (node instanceof Laya.Sprite3D) {
                              node.transform.localRotationEulerY = 0;
                          }
                      }
                  }
              }
              if (skillDb.sound_cast) {
                  mgrSound.playSound(skillDb.sound_cast);
              }
              if (skillDb.is_super) {
                  this.skin.playAttack(0, skillDb.action, this.modelDb.point_atk_time2);
              }
              else {
                  this.skin.playAttack(time, skillDb.action, this.modelDb.point_atk_time1);
              }
          }
      }
      onSkillUse(target, skillData, index, count) {
          let skillDb = skillData.skillDb;
          if (!skillDb.is_super && this.skinTransformId == 0) {
              this.addEnergy(this.roleDb.mp_recover_atk);
          }
          let dx = target.gx - this.gx;
          if (this.skin) {
              if (skillDb && skillDb.effect_shoot && count == 0) {
                  let effectDb = db.get_effect_db_map()[skillDb.effect_shoot];
                  if (effectDb) {
                      let effect = null;
                      if (StageConfig.enableGameEffect) {
                          if (skillDb.effect_shoot_tower) {
                              effect = EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, this.skin, null, null, null, null, null, this.getAttackSpeed());
                          }
                          else {
                              let shootPoint = this.skin.getShootPoint(0, effectDb.point_index || skillDb.point_index);
                              effect = EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, shootPoint, null, null, null, null, null, this.getAttackSpeed());
                          }
                      }
                      this.skin.flip(this, dx);
                      if (effect && this.skin.getFlip() < 0) {
                          let node = effect.node;
                          node.scaleX = -node.scaleX;
                      }
                  }
              }
          }
      }
      jumpTo(time, x, y, msg) {
          this.comMove.jumpTo(time, x, y);
          if (this.skin) {
              this.skin.jumpTo(time, x, y, msg);
          }
      }
      skinTransform(id) {
          this.skinTransformId = id;
          console.log("变身", id);
          if (this.skin) {
              this.skin.onSkinTranform(id);
          }
      }
      changeSkill(skillId = null, superId = null) {
          let skillDb = db.get_skill_db_map()[skillId || this.roleDb.skill_id];
          let superDb = db.get_skill_db_map()[superId || this.roleDb.super_skill_id];
          if (skillDb) {
              this.skillDb = skillDb;
          }
          if (superDb) {
              this.superDb = superDb;
          }
          console.warn("更换技能", skillId, superId);
      }
      findBestAttackPos(bx, by, tx, ty) {
          if (this.roleDb.attak_in_lr) {
              let pos = this.world.map.findBestAttackPosByLeftRight(this.gx, this.gy, tx, ty, MAP_FLAG.BUILDING | MAP_FLAG.BARRIER, this.range);
              if (pos)
                  return pos;
          }
          return this.world.map.findBestAttackPos(bx, by, tx, ty, MAP_FLAG.BUILDING | MAP_FLAG.BARRIER, this.range);
      }
      get x() {
          if (this.skin) {
              return this.skin.x + this.skin.collisionOffsetX;
          }
          return Level.convertGridPosToRealPosX(this.mx);
      }
      get y() {
          if (this.skin) {
              return this.skin.y + this.skin.collisionOffsetY;
          }
          return Level.convertGridPosToRealPosY(this.my);
      }
      get radius() {
          if (this.skin) {
              return this.skin.collisionRadius;
          }
          return 0;
      }
      getSortScore() {
          let score = this.getAttr(BASE_ATTR.HP);
          if (this.roleDb) {
              if (this.roleDb.boss) {
                  score += Number.MAX_VALUE / 2;
              }
          }
          return score;
      }
      onAttackUpdate() {
      }
      clearCrazy() {
      }
      setCanDead(value) {
      }
      exitBorn() {
          if (this.skin) {
              this.skin.playMove();
          }
      }
  }
  Enemy.poolkey = "Enemy";

  class EnemyBoss extends Enemy {
      constructor() {
          super(...arguments);
          this.timeCrazyPass = 0;
          this.timeCrazyMaxx = 0;
          this.curCrazyCount = 0;
      }
      calcAttr(roleDb) {
          Level.calcBossAttr(roleDb, this.attrCur, this.lv || mgrGame.levelId);
      }
      loadRoleById(id) {
          super.loadRoleById(id);
          this.initCrazy();
      }
      onUpdate(t) {
          super.onUpdate(t);
          this.updateCrazy(t);
      }
      onDead() {
          this.world.remUnit(this, UNIT_REMOVE_REASON.DEAD_BOSS);
      }
      addBuffById(caster, buffId, param = null) {
          if (buffId) {
              let buffDb = db.get_buff_db(buffId);
              if (buffDb) {
                  switch (buffDb.template) {
                      case "Stun":
                      case "Stun4Tower1":
                      case "AttrScale":
                      case "Frozen":
                      case "BeatBack":
                          return;
                  }
              }
          }
          super.addBuffById(caster, buffId, param);
      }
      initCrazy() {
          let roleDb = this.roleDb;
          this.timeCrazyPass = 0;
          this.timeCrazyMaxx = roleDb.crazy_time;
          this.curCrazyCount = 0;
      }
      updateCrazy(t) {
          let roleDb = this.roleDb;
          if (this.curCrazyCount >= roleDb.crazy_count)
              return;
          this.timeCrazyPass += t;
          if (this.timeCrazyPass >= this.timeCrazyMaxx) {
              this.setAttr(BASE_ATTR.AD, this.getAttr(BASE_ATTR.AD) * roleDb.crazy_atk_add, true);
              this.setAttr(BASE_ATTR.AP, this.getAttr(BASE_ATTR.AP) * roleDb.crazy_atk_add, true);
              this.setAttr(BASE_ATTR.ATK_SPEED, this.getAttr(BASE_ATTR.ATK_SPEED) * roleDb.crazy_atk_speed_add, true);
              this.curCrazyCount++;
              this.timeCrazyPass = 0;
              this.timeCrazyMaxx = roleDb.crazy_interval;
              mgrTip.showMsgTip(roleDb.name + "愈加狂暴了");
              if (this.skin) {
                  this.skin.showCrazyLayer(this.curCrazyCount);
              }
          }
      }
      clearCrazy() {
          this.initCrazy();
          this.recoverAttr(BASE_ATTR.AD);
          this.recoverAttr(BASE_ATTR.AP);
          this.recoverAttr(BASE_ATTR.ATK_SPEED);
          if (this.skin) {
              this.skin.showCrazyLayer(this.curCrazyCount);
          }
      }
  }
  EnemyBoss.poolkey = "EnemyBoss";

  class EnemyBossFinalWar extends EnemyBoss {
      constructor() {
          super(...arguments);
          this.canDead = true;
          this.skillIdx = 0;
      }
      init(tid, lv) {
          this.canDead = true;
          return super.init(tid, lv);
      }
      onSkinBind() {
          if (this.roleDb && this.roleDb.buff_id_born) {
              this.addBuffById(this, this.roleDb.buff_id_born);
          }
      }
      hurt(data) {
          if (this.state.getState() == ENEMY_STATE.FAKE_DEAD) {
              return;
          }
          super.hurt(data);
      }
      onDead() {
          if (this.canDead) {
              this.world.remUnit(this, UNIT_REMOVE_REASON.DEAD);
          }
          else {
              this.fakedead();
          }
          if (this.roleDb && this.roleDb.dead_cmd) {
              switch (this.roleDb.dead_cmd) {
                  case "clear_enemy_buff":
                      this.world.clearAllEnemyBuff(StageConfig.attrNoRecover);
                      break;
                  case "clear_enemy":
                      this.world.clearAllEnemyById(this.roleDb.dead_cmd_param);
                      break;
                  case "clear_enemy_all":
                      this.world.remAllUnit(LogicCamp.ENEMY);
                      break;
                  case "add_buff":
                      this.addBuffById(this, this.roleDb.dead_cmd_param);
                      break;
                  case "dmg_reduct_25":
                      let findTarget = this.world.findEnemyByRoleId(this.roleDb.dead_cmd_param);
                      if (findTarget) {
                          let reduct = findTarget.attrCur[BASE_ATTR.DMG_REDUCT] + 0.25;
                          if (reduct >= 1) {
                              reduct = 1;
                              findTarget.clearAllBuff(StageConfig.attrNoRecover);
                          }
                          findTarget.attrCur[BASE_ATTR.DMG_REDUCT] = reduct;
                      }
                      break;
                  case "finish":
                      Level.stage.enemyWave.towerRushSuccess();
                      break;
              }
          }
          Global.sendMsg(MSG.WAVE_CMD_FINAL_BOSS_DEAD);
      }
      setCanDead(value) {
          this.canDead = value;
      }
      revive(canDead) {
          this.setCanDead(canDead);
          this.clearCrazy();
          this.recoverAttr(BASE_ATTR.HP);
          this.reborn();
          if (this.skin) {
              if (canDead) {
                  this.skin.loadHpBar(0, -this.roleDb.height, this.roleDb.boss ? 1 : 0);
              }
              this.skin.playRevive();
          }
          this.updateHpBar();
      }
      showHpBar() {
          if (this.skin && this.roleDb) {
              this.skin.loadHpBar(0, -this.roleDb.height, this.roleDb.boss ? 1 : 0);
          }
      }
      loadRoleById(id) {
          super.loadRoleById(id);
          this.angryDb = db.get_skill_db_map()[this.roleDb.angry_skill_id];
          this.attrStd[BASE_ATTR.ANGRY] = 100;
          this.attrCur[BASE_ATTR.ANGRY] = 0;
          this.attrStd[BASE_ATTR.ANGRY_RECOVER] = this.attrCur[BASE_ATTR.ANGRY_RECOVER] = this.roleDb.angry_recover;
          this.skillArr = [];
          this.skillIdx = 0;
          if (this.roleDb.skill_ids.length) {
              for (let id of this.roleDb.skill_ids) {
                  let skillDb = db.get_skill_db_map()[id];
                  if (skillDb) {
                      this.skillArr.push(skillDb);
                  }
              }
          }
          else {
          }
      }
      removeSkill(skillId) {
          if (skillId) {
              let index = -1;
              for (let i = 0; i < this.skillArr.length; i++) {
                  let skill = this.skillArr[i];
                  if (skill.id == skillId) {
                      index = i;
                  }
              }
              if (index >= 0) {
                  this.skillArr.splice(index, 1);
              }
          }
      }
      onUpdate(t) {
          super.onUpdate(t);
          this.addAngry(t * this.getAttr(BASE_ATTR.ANGRY_RECOVER));
      }
      addAngry(add = 1, show = false) {
          this.addAttr(BASE_ATTR.ANGRY, add);
      }
      prepareSkillData(data, attack = true) {
          let skillDb;
          if (this.skillArr.length) {
              skillDb = this.skillArr[this.skillIdx % this.skillArr.length];
          }
          else {
              skillDb = this.skillDb;
          }
          let modelDb = this.modelDb;
          if (this.superDb && this.isEnergyFull()) {
              skillDb = this.superDb;
          }
          else if (this.angryDb && this.isAttrMax(BASE_ATTR.ANGRY)) {
              skillDb = this.angryDb;
              this.attrCur[BASE_ATTR.ANGRY] = 0;
          }
          else {
              if (attack)
                  this.skillIdx++;
          }
          if (skillDb && modelDb) {
              Level.packSkillData(data, skillDb);
              if (!skillDb.is_super) {
                  data.timeCast = modelDb.cast_time1 * skillDb.cast_time / this.getAttackSpeed();
                  data.timeCD = skillDb.cd_time / this.getAttackSpeed();
              }
              else {
                  data.timeCast = modelDb.cast_time2 * skillDb.cast_time / StageConfig.gameTimeScale;
                  data.timeCD = skillDb.cd_time / StageConfig.gameTimeScale;
              }
          }
      }
      rebornById(roleId, canDead) {
          this.setCanDead(canDead);
          this.clearCrazy();
          let roleDb = db.get_role_db(roleId);
          if (roleDb) {
              this.roleDb = roleDb;
              this.tid = roleId;
              console.warn("变身:", roleDb.name);
              this.modelDb = db.get_role_model_db(roleDb.model_id);
              if (!this.modelDb) {
                  console.error("EnemyBossFinalWar.rebornById 没有配置模型ID：", roleId, roleDb.model_id);
              }
              if (roleDb.custom_attr) {
                  this.attrCur[BASE_ATTR.HP] = roleDb.hp;
                  this.attrCur[BASE_ATTR.AD] = roleDb.atk;
                  this.attrCur[BASE_ATTR.AP] = roleDb.atk;
              }
              else {
                  this.calcAttr(roleDb);
              }
              this.range = roleDb.range;
              this.attrCur[BASE_ATTR.MP] = roleDb.mp_max;
              this.attrCur[BASE_ATTR.MP_RECOVER] = roleDb.mp_recover;
              this.attrCur[BASE_ATTR.CRIT_DMG] = 1.5;
              this.attrCur[BASE_ATTR.HURT_FACTOR] = 1;
              this.attrCur[BASE_ATTR.DMG_REDUCT] = 1 - roleDb.dmg_reduct;
              Level.copyAttrArray(this.attrCur, this.attrStd);
              this.attrCur[BASE_ATTR.MP] = roleDb.mp;
              let speed = roleDb.speed;
              let CHARGE = StageAttr.getAttr(STAGE_ATTR.CHARGE);
              if (CHARGE > 0) {
                  speed += speed * CHARGE;
              }
              this.comMove.speed = speed;
              this.comMove.logicSpeedScale = roleDb.speed_scale;
              this.skillDb = db.get_skill_db_map()[roleDb.skill_id];
              this.superDb = db.get_skill_db_map()[roleDb.super_skill_id];
              this.onAttrChange();
              this.updateHpBar();
              Global.sendMsg(MSG.WAVE_CMD_FINAL_BOSS_REBORN);
              this.reborn();
              if (this.roleDb.buff_id_born) {
                  this.addBuffById(this, this.roleDb.buff_id_born);
              }
          }
          if (this.skin) {
              this.skin.playRevive();
          }
      }
      enterFakeDead() {
          super.enterFakeDead();
          if (this.skin) {
              this.skin.playFakeDead();
          }
      }
  }
  EnemyBossFinalWar.poolkey = "EnemyBossFinalWar";

  class EnemyIdle extends Enemy {
      constructor() {
          super(...arguments);
          this.path = null;
          this.pathIndex = 0;
      }
      findNearestIndex(path) {
          if (!path)
              return 0;
          let gx = this.gx;
          let gy = this.gy;
          let minDistance = Number.MAX_VALUE;
          let index = 0;
          for (let i = 0; i < path.length; i++) {
              let p = path[i];
              let dx = p.x - gx;
              let dy = p.y - gy;
              let ds = dx * dx + dy * dy;
              if (ds < minDistance) {
                  minDistance = ds;
                  index = i;
              }
          }
          return index;
      }
      enterThink() {
          if (this.mapLinkList) {
              if (!this.path) {
                  this.path = Utils.randomItem(Level.tileMapPath);
                  this.pathIndex = this.findNearestIndex(this.path);
              }
              if (this.path) {
                  let pos = this.path[this.pathIndex % this.path.length];
                  let path = this.findPath(pos.x, pos.y);
                  this.comMove.moveByPath(path);
                  this.pathIndex++;
              }
          }
      }
      execThink() {
      }
  }
  EnemyIdle.poolkey = "EnemyIdle";

  class EnemyIdleBoss extends EnemyBoss {
      constructor() {
          super(...arguments);
          this.pathIndex = 0;
          this.path = null;
      }
      updateCrazy(t) {
      }
      findNearestIndex(path) {
          if (!path)
              return 0;
          let gx = this.gx;
          let gy = this.gy;
          let minDistance = Number.MAX_VALUE;
          let index = 0;
          for (let i = 0; i < path.length; i++) {
              let p = path[i];
              let dx = p.x - gx;
              let dy = p.y - gy;
              let ds = dx * dx + dy * dy;
              if (ds < minDistance) {
                  minDistance = ds;
                  index = i;
              }
          }
          return index;
      }
      enterThink() {
          if (this.mapLinkList) {
              if (!this.path) {
                  this.path = Utils.randomItem(Level.tileMapPath);
                  this.pathIndex = this.findNearestIndex(this.path);
              }
              if (this.path) {
                  let pos = this.path[this.pathIndex % this.path.length];
                  let path = this.findPath(pos.x, pos.y);
                  this.comMove.moveByPath(path);
                  this.pathIndex++;
              }
          }
      }
      execThink() {
      }
  }
  EnemyIdleBoss.poolkey = "EnemyIdleBoss";

  class EnemyNewyear extends EnemyBoss {
      constructor() {
          super(...arguments);
          this.pathIndex = 0;
          this.pathStep = 0;
          this.path = null;
      }
      onCreate() {
          super.onCreate();
          this.path = null;
          this.pathIndex = 0;
          this.pathStep = 0;
      }
      updateCrazy(t) {
      }
      findNearestIndex(path) {
          if (!path)
              return 0;
          let gx = this.gx;
          let gy = this.gy;
          let minDistance = Number.MAX_VALUE;
          let index = 0;
          for (let i = 0; i < path.length; i++) {
              let p = path[i];
              let dx = p.x - gx;
              let dy = p.y - gy;
              let ds = dx * dx + dy * dy;
              if (ds < minDistance) {
                  minDistance = ds;
                  index = i;
              }
          }
          return index;
      }
      enterThink() {
          if (this.mapLinkList) {
              if (!this.path) {
                  this.path = Level.tileMapPath[5] || [];
                  this.pathIndex = this.findNearestIndex(this.path);
                  this.pathStep = 0;
              }
              if (this.path) {
                  let index = this.pathIndex % this.path.length;
                  let pos = this.path[index];
                  let path = this.findPath(pos.x, pos.y);
                  this.comMove.moveByPath(path);
                  this.pathIndex++;
                  this.pathStep++;
                  if (this.pathStep > this.path.length + 1) {
                      this.killSelf(DamageCalculation.damageData);
                  }
              }
          }
      }
      execThink() {
      }
      killSelf(data) {
          let attrSelf = this.attrCur;
          data.damage = attrSelf[BASE_ATTR.HP];
          let damage = data.damage;
          if (damage > 0) {
              let hpBefore = attrSelf[BASE_ATTR.HP];
              let hpLeft = hpBefore - damage;
              this.updateHpBar();
              if (hpLeft <= 0 && !this.removed) {
                  this.onDead();
              }
          }
      }
      remove() {
          this.removed = true;
          this.clearLogicCompnent();
          this.onRemove();
      }
  }
  EnemyNewyear.poolkey = "EnemyNewyear";

  class EnemyQueue {
      constructor() {
          this.idx = 0;
          this.num = 0;
          this.gx = 0;
          this.gy = 0;
          this.passtime = 0;
          this.interval = 5;
          this.roleIds = [];
      }
      init(gx, gy, num, interval, roleIds = null) {
          this.gx = gx;
          this.gy = gy;
          this.interval = interval;
          this.num = num;
          this.idx = 0;
          this.passtime = 0;
          if (roleIds)
              this.roleIds = roleIds;
          return this;
      }
      canBorn(t) {
          if (this.isEmpty())
              return false;
          this.passtime += t;
          if (this.passtime >= this.interval) {
              this.passtime = 0;
              this.idx++;
              return true;
          }
          return false;
      }
      isEmpty() {
          return this.idx >= this.num;
      }
  }

  ;
  var WaveMode;
  (function (WaveMode) {
      WaveMode[WaveMode["IDLE"] = 0] = "IDLE";
      WaveMode[WaveMode["TOWER_ENDNESS"] = 1] = "TOWER_ENDNESS";
      WaveMode[WaveMode["TOWER_MAIN_STORY"] = 2] = "TOWER_MAIN_STORY";
      WaveMode[WaveMode["TOWER_CHALLENGE"] = 3] = "TOWER_CHALLENGE";
      WaveMode[WaveMode["GUIDE"] = 4] = "GUIDE";
      WaveMode[WaveMode["FB_COIN"] = 5] = "FB_COIN";
      WaveMode[WaveMode["FB_ITEM"] = 6] = "FB_ITEM";
      WaveMode[WaveMode["SECRET"] = 7] = "SECRET";
      WaveMode[WaveMode["FINAL_WAR"] = 8] = "FINAL_WAR";
      WaveMode[WaveMode["DAILY_DAMAGE"] = 9] = "DAILY_DAMAGE";
      WaveMode[WaveMode["NEWYEAR"] = 10] = "NEWYEAR";
  })(WaveMode || (WaveMode = {}));
  class EnemyWave extends Laya.Script {
      constructor() {
          super(...arguments);
          this.mode = WaveMode.IDLE;
          this.isSkipDialog = false;
          this.timePass = 0;
          this.timeStep = LogicConfig.LOGIC_FRAME_ITME;
          this.totalScore = 0;
          this.currtScore = 0;
          this.waveData = { waveDb: null, isComplete: false, timepass: 0 };
          this.waveIndex = 0;
          this.waveCount = 0;
          this.waveLayer = 0;
          this.waveDropId = null;
          this.uniqueBossId = 0;
          this.tempPoint = new Laya.Point;
      }
      onAwake() {
      }
      onStart() {
          this.root = this.owner;
          this.listEnemyQueue = new LinkList;
          this.openModeIdle();
      }
      updateLogic(t) {
          if (StageConfig.enableEnemyWave) {
              this.timePass += t;
              if (this.timePass > this.timeStep) {
                  this.update(this.timeStep);
                  this.timePass = 0;
              }
          }
      }
      update(t) {
          this.updateEnemyQueue(t);
          this.updateWave(t);
      }
      buildRandomRoleId() {
          return Utils.randomItem(Level.allRoleIds);
      }
      addEnemyQueue(queue) {
          this.listEnemyQueue.append(queue);
      }
      updateEnemyQueue(t) {
          let head = this.listEnemyQueue.head;
          while (head) {
              let curt = head;
              head = head.next;
              let data = curt.data;
              if (data) {
                  if (data.canBorn(t)) {
                      let roleId;
                      let index = data.idx - 1;
                      let length = data.roleIds.length;
                      if (index < length) {
                          roleId = data.roleIds[index];
                      }
                      else {
                          roleId = data.roleIds[length - 1];
                      }
                      let enemy = this.world.addEnemy(this.getEnemyClass(roleId), data.gx, data.gy, roleId, this.getEnemyLayer()).bindData(this.waveDropId, 1);
                      enemy.flagFindPath = MAP_FLAG.BUILDING;
                  }
                  if (data.isEmpty()) {
                      curt.removeFromList();
                  }
              }
          }
      }
      setRushWave(rushId) {
          this.rushWave = [];
          this.totalScore = 0;
          this.currtScore = 0;
          let rushWave = db.get_rush_wave_db_map()[rushId];
          if (rushWave) {
              for (let i = 0; i < rushWave.length; i++) {
                  let waveDb = rushWave[i];
                  let wave = { waveDb: waveDb, num: 0, roleIds: [], data: null };
                  this.buildWaveNum(wave, waveDb);
                  this.buildWaveRoleId(wave, waveDb);
                  this.rushWave.push(wave);
                  this.totalScore += this.calcWaveScore(wave);
              }
          }
          console.log("关卡分数: 总分", this.totalScore);
      }
      setBossWave(rushId) {
          this.rushWave = [];
          this.totalScore = 0;
          this.currtScore = 0;
          let rushWave = db.get_boss_wave_db_map()[rushId];
          if (rushWave) {
              for (let i = 0; i < rushWave.length; i++) {
                  let waveDb = rushWave[i];
                  let wave = { waveDb: waveDb, num: 0, roleIds: [] };
                  this.buildWaveNum(wave, waveDb);
                  this.buildWaveRoleId(wave, waveDb);
                  this.rushWave.push(wave);
                  this.totalScore += this.calcWaveScore(wave);
              }
          }
          console.log("BOSS关卡分数: 总分", this.totalScore);
      }
      setRushGuide() {
          this.rushWave = [];
          this.totalScore = 0;
          this.currtScore = 0;
          let rushWave = db.get_guide_rush_db_map();
          if (rushWave) {
              for (let i = 0; i < rushWave.length; i++) {
                  let waveDb = rushWave[i];
                  let wave = { waveDb: waveDb, num: 0, roleIds: [] };
                  this.buildWaveNum(wave, waveDb);
                  this.buildWaveRoleId(wave, waveDb);
                  this.rushWave.push(wave);
                  this.totalScore += this.calcWaveScore(wave);
              }
          }
          console.log("关卡分数: 总分", this.totalScore);
      }
      getScorePercent() {
          if (this.totalScore > 0) {
              return this.currtScore / this.totalScore * 100;
          }
          else {
              return 100;
          }
      }
      calcWaveScore(wave) {
          let waveDb = wave.waveDb;
          let score = 0;
          switch (waveDb.cmd) {
              case "queue":
              case "summon":
              case "circle":
                  score = wave.num;
                  break;
              case "summon_boss": {
                  score = wave.num * 10;
                  break;
              }
          }
          return score;
      }
      onEnemyDead(enemy) {
          this.currtScore += enemy.score;
          this.onScoreChange();
      }
      onBossDead(enemy) {
          this.currtScore += enemy.score;
          this.onScoreChange();
      }
      onScoreChange() {
          Global.sendMsg(MSG.GAME_PROGRESS_CHANGE, this.getScorePercent());
      }
      getWaveByIndex(index) {
          return this.rushWave[index];
      }
      getIdleByIndex(index) {
          return this.rushWave[index % this.rushWave.length];
      }
      calcNextWave() {
          let waveDb;
          switch (this.mode) {
              case WaveMode.IDLE:
                  waveDb = this.getIdleByIndex(this.waveIndex++);
                  if (waveDb) {
                      this.waveData.waveDb = waveDb;
                      this.waveData.timepass = 0;
                      this.waveData.isComplete = false;
                  }
                  break;
              default:
                  waveDb = this.rushWave[this.waveIndex++];
                  if (waveDb) {
                      this.waveData.waveDb = waveDb;
                      this.waveData.timepass = 0;
                      this.waveData.isComplete = false;
                  }
                  break;
          }
      }
      getEnemyClass(roleId) {
          let roleDb = db.get_role_db(roleId);
          if (roleDb && roleDb.boss) {
              switch (this.mode) {
                  case WaveMode.IDLE:
                      return EnemyIdleBoss;
                  case WaveMode.NEWYEAR:
                      return EnemyNewyear;
                  default:
                      return EnemyBoss;
              }
          }
          else {
              switch (this.mode) {
                  case WaveMode.IDLE:
                  case WaveMode.NEWYEAR:
                      return EnemyIdle;
                  default:
                      return Enemy;
              }
          }
      }
      clear() {
          this.isSkipDialog = false;
          if (this.listEnemyQueue)
              this.listEnemyQueue.clear();
          if (this.waveData)
              this.waveData.isComplete = true;
          if (this.rushWave)
              this.rushWave.length = 0;
      }
      openModeGuide() {
          this.clear();
          this.mode = WaveMode.GUIDE;
          this.waveIndex = 0;
          this.waveDropId = Level.levelDb.drop_id;
          this.setRushGuide();
          this.calcNextWave();
      }
      openModeIdle() {
          this.clear();
          this.mode = WaveMode.IDLE;
          this.waveIndex = 0;
          this.waveDropId = Level.levelDb.drop_id;
          this.setRushWave(Level.idleWaveId);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleBegin();
      }
      openModeEndness() {
          this.clear();
          this.mode = WaveMode.TOWER_ENDNESS;
          this.waveIndex = 0;
          this.waveDropId = Level.levelDb.drop_id;
          this.setRushWave(Level.rushWaveId);
          this.calcNextWave();
          StageConfig.gameTimeScale = mgrGame.gameScaleNum;
          Level.onIdleEnd();
          Level.onEndessBegin();
      }
      openModelStory(config) {
          this.configStory = config;
          this.clear();
          this.mode = WaveMode.TOWER_MAIN_STORY;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = config.drop_id;
          this.isSkipDialog = mgrGame.getLevelStoryAward(config.index) > 0;
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onStoryRushBegin(config);
      }
      openModelChallenge(config) {
          this.configChallenge = config;
          this.clear();
          this.mode = WaveMode.TOWER_CHALLENGE;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = config.drop_id;
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onChallengeRushBegin(config);
      }
      openModelFBCoin(config) {
          this.configFBCoin = config;
          this.clear();
          this.mode = WaveMode.FB_COIN;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = "";
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onFbCoinBegin(config);
      }
      openModelFBItem(config) {
          this.configFBItem = config;
          this.clear();
          this.mode = WaveMode.FB_ITEM;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = "";
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onFbItemBegin(config);
      }
      openModelSecret(config) {
          this.configSecret = config;
          this.clear();
          this.mode = WaveMode.SECRET;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = "";
          StageAttr.calcAttrBySecret(config.id);
          Global.sendMsg(MSG.TOWER_ATTR_UPDATE_ALL);
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onSecretBegin(config);
      }
      openModelFinalWar(config) {
          this.configFinalWar = config;
          this.clear();
          this.mode = WaveMode.FINAL_WAR;
          this.waveIndex = 0;
          let lv = mgrFinalWar.getFinalWarLevel(config.id);
          this.waveLayer = Formula.layerFinalWar(config.layer, lv, config.layer_add);
          this.waveDropId = "";
          this.isSkipDialog = lv > 1;
          this.setBossWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onFinalWarBegin(config);
      }
      openModelDailyDamage(config) {
          this.configDailyDamage = config;
          this.clear();
          this.mode = WaveMode.DAILY_DAMAGE;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = "";
          mgrDailyDamage.activeBuff();
          Global.sendMsg(MSG.TOWER_ATTR_UPDATE_ALL);
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onDailyDamageBegin(config);
      }
      openModeNewyear(config) {
          this.configNewyear = config;
          this.clear();
          this.mode = WaveMode.NEWYEAR;
          this.waveIndex = 0;
          this.waveLayer = config.layer;
          this.waveDropId = "";
          mgrDailyDamage.activeBuff();
          Global.sendMsg(MSG.TOWER_ATTR_UPDATE_ALL);
          this.setRushWave(config.rush_id);
          this.calcNextWave();
          StageConfig.gameTimeScale = 1;
          Level.onIdleEnd();
          Level.onNewyearFBBegin(config);
      }
      isTowerRushMode() {
          return this.mode != WaveMode.IDLE && this.mode != WaveMode.GUIDE;
      }
      isIdleMode() {
          return this.mode == WaveMode.IDLE;
      }
      isFinalWar() {
          return this.mode == WaveMode.FINAL_WAR;
      }
      isFBMode() {
          return this.mode == WaveMode.FB_COIN || this.mode == WaveMode.FB_ITEM || this.mode == WaveMode.SECRET;
      }
      updateWave(t) {
          let wave = this.waveData;
          if (!wave.isComplete) {
              wave.timepass += t;
              if (wave.timepass >= wave.waveDb.waveDb.time) {
                  wave.timepass = 0;
                  wave.isComplete = this.execWave(wave.waveDb);
                  if (wave.isComplete) {
                      this.waveCount++;
                      this.calcNextWave();
                  }
              }
          }
      }
      getEnemyLayer() {
          switch (this.mode) {
              case WaveMode.TOWER_MAIN_STORY:
              case WaveMode.TOWER_CHALLENGE:
              case WaveMode.FB_COIN:
              case WaveMode.FB_ITEM:
              case WaveMode.SECRET:
              case WaveMode.FINAL_WAR:
              case WaveMode.DAILY_DAMAGE:
              case WaveMode.NEWYEAR:
                  return this.waveLayer;
          }
          return mgrGame.levelId;
      }
      execWave(wave) {
          let waveDb = wave.waveDb;
          let layer = this.getEnemyLayer();
          switch (waveDb.cmd) {
              case "remove_all_trap": {
                  this.world.remAllTrap();
                  break;
              }
              case "finalwar_boss": {
                  let roleId = this.getWaveRoleId(wave);
                  let enemy;
                  if (waveDb.pos.length >= 2) {
                      enemy = this.world.addEnemy(EnemyBossFinalWar, waveDb.pos[0], waveDb.pos[1], roleId, layer).bindData(this.waveDropId, 10);
                  }
                  else {
                      let pos = Level.tileMapBorn[0];
                      enemy = this.world.addEnemy(EnemyBossFinalWar, pos.x, pos.y, roleId, layer).bindData(this.waveDropId, 10);
                  }
                  if (enemy) {
                      this.uniqueBossId = enemy.uid;
                      enemy.setCanDead(waveDb.param[0] == 0);
                  }
                  Global.sendMsg(MSG.WAVE_CMD_FINAL_BOSS, { roleId: roleId, uid: this.uniqueBossId });
                  break;
              }
              case "finalwar_boss_reborn": {
                  let boss = this.world.objectMgr.getObjectById(this.uniqueBossId);
                  if (boss instanceof Enemy) {
                      boss.stopAttack();
                      boss.changeSkill(waveDb.role_ids[0], waveDb.role_ids[0]);
                  }
                  break;
              }
              case "change_skill": {
                  let boss = this.world.objectMgr.getObjectById(this.uniqueBossId);
                  if (boss instanceof Enemy) {
                      boss.stopAttack();
                      boss.changeSkill(waveDb.role_ids[0], waveDb.role_ids[1]);
                  }
                  break;
              }
              case "remove_skill": {
                  let boss = this.world.objectMgr.getObjectById(this.uniqueBossId);
                  if (boss instanceof EnemyBossFinalWar) {
                      boss.stopAttack();
                      boss.removeSkill(waveDb.role_ids[0]);
                  }
                  break;
              }
              case "check_slot_tower_dead": {
                  let data = wave.data;
                  if (!data) {
                      data = {};
                      for (let id of wave.waveDb.param) {
                          data[id] = true;
                      }
                      wave.data = data;
                  }
                  return Level.stage.isTowerDeadBySlotIds(wave.data);
              }
              case "waitbossdead": {
                  if (this.uniqueBossId) {
                      let boss = this.world.objectMgr.getObjectById(this.uniqueBossId);
                      if (boss instanceof Enemy) {
                          return boss.getAttr(BASE_ATTR.HP) <= 0 || boss.isFakeDead();
                      }
                      else {
                          return true;
                      }
                  }
                  else {
                      return true;
                  }
              }
              case "screen_red": {
                  Director.openPanel("PanelBossComing2");
                  return true;
              }
              case "show_view": {
                  let viewName = waveDb.role_ids[0];
                  if (viewName) {
                      Director.openPanel(viewName);
                  }
                  return true;
              }
              case "queue": {
                  let pos = this.getWavePos(waveDb);
                  let num = wave.num;
                  this.addEnemyQueue(new EnemyQueue().init(pos.x, pos.y, num, waveDb.param[0] || 2, wave.roleIds));
                  break;
              }
              case "portal":
                  {
                      if (waveDb.pos.length >= 2) {
                          let gx = waveDb.pos[0];
                          let gy = waveDb.pos[1];
                          Level.stage.createPortal(gx, gy);
                      }
                      break;
                  }
              case "summon_boss":
                  {
                      Director.openPanel("PanelBossComing");
                      let num = wave.num;
                      Utils.randomSort(Level.tileMapBorn);
                      for (let i = 0; i < num; i++) {
                          let roleId = this.getWaveRoleId(wave);
                          if (waveDb.pos.length >= 2) {
                              this.world.addEnemy(this.getEnemyClass(roleId), waveDb.pos[0], waveDb.pos[1], roleId, layer).bindData(this.waveDropId, 10);
                          }
                          else {
                              let pos = Level.tileMapBorn[i % Level.tileMapBorn.length];
                              this.world.addEnemy(this.getEnemyClass(roleId), pos.x, pos.y, roleId, layer).bindData(this.waveDropId, 10);
                          }
                      }
                      break;
                  }
              case "summon": {
                  let num = wave.num;
                  Utils.randomSort(Level.tileMapBorn);
                  for (let i = 0; i < num; i++) {
                      let roleId = this.getWaveRoleId(wave);
                      if (waveDb.pos.length >= 2) {
                          this.world.addEnemy(this.getEnemyClass(roleId), waveDb.pos[0], waveDb.pos[1], roleId, layer).bindData(this.waveDropId, 1);
                      }
                      else {
                          let pos = Level.tileMapBorn[i % Level.tileMapBorn.length];
                          this.world.addEnemy(this.getEnemyClass(roleId), pos.x, pos.y, roleId, layer).bindData(this.waveDropId, 1);
                      }
                  }
                  break;
              }
              case "circle": {
                  let pos = waveDb.pos;
                  let r = waveDb.param[0];
                  let d = 360 / wave.num;
                  let pList = this.world.map.findCirleByRangeAndDegree2(pos[0] - r, pos[1], pos[0], pos[1], d, MAP_FLAG.NONE);
                  for (let p of pList) {
                      let roleId = this.getWaveRoleId(wave);
                      this.world.addEnemy(this.getEnemyClass(roleId), p.x, p.y, roleId, layer).bindData(this.waveDropId, 1);
                  }
                  break;
              }
              case "waitalldead": {
                  return Level.stage.isAllEnemyDead(waveDb.param[0] || 0);
                  ;
              }
              case "finish": {
                  let allDead = Level.stage.isAllEnemyDead(0);
                  if (allDead) {
                      if (this.isTowerRushMode()) {
                          console.log("冲塔结束");
                          this.towerRushSuccess();
                      }
                  }
                  return allDead;
              }
              case "dialog": {
                  if (this.isSkipDialog) {
                      return true;
                  }
                  Director.openPanelWithSingleton("PanelStoryDialog", { dialogId: waveDb.role_ids[0] || "1" });
                  return true;
              }
              case "guide": {
                  let currenGuide = mgrGuide.getCurrentGuide("main");
                  if (currenGuide && currenGuide.auto_complete && !mgrGuide.isGuideCompletById(currenGuide.group, currenGuide.id)) {
                      mgrGuide.markGuideCompelte(currenGuide);
                  }
                  mgrGuide.execGuideByIdNoPanel(waveDb.role_ids[0], waveDb.param[0]);
                  return true;
              }
              case "camera": {
                  Level.stage.moveCamera(waveDb.param[0], waveDb.param[1]);
                  return true;
              }
          }
          return true;
      }
      towerRushSuccess() {
          this.clear();
          switch (this.mode) {
              case WaveMode.TOWER_ENDNESS:
                  Level.onEndnessEnd(true);
                  break;
              case WaveMode.TOWER_MAIN_STORY:
                  Level.onStoryRushEnd(true, this.configStory);
                  break;
              case WaveMode.TOWER_CHALLENGE:
                  Level.onChallengeRushEnd(true, this.configChallenge);
                  break;
              case WaveMode.FB_COIN:
                  Level.onFbCoinEnd(true, this.configFBCoin);
                  break;
              case WaveMode.FB_ITEM:
                  Level.onFbItemEnd(true, this.configFBItem);
                  break;
              case WaveMode.SECRET:
                  Level.onSecretEnd(true, this.configSecret);
                  break;
              case WaveMode.FINAL_WAR:
                  Level.onFinalWarEnd(true, this.configFinalWar);
                  break;
              case WaveMode.DAILY_DAMAGE:
                  Level.onDailyDamageEnd(true, this.configDailyDamage);
                  break;
              case WaveMode.NEWYEAR:
                  Level.onNewyearFBEnd(true, this.configNewyear);
                  break;
          }
          Global.sendMsg(MSG.TOWER_RUSH_END_FOCUS);
          this.openModeIdle();
      }
      towerRushFail(force = false) {
          this.clear();
          switch (this.mode) {
              case WaveMode.TOWER_ENDNESS:
                  Level.onEndnessEnd(false, force);
                  break;
              case WaveMode.TOWER_MAIN_STORY:
                  Level.onStoryRushEnd(false, this.configStory, force);
                  break;
              case WaveMode.TOWER_CHALLENGE:
                  Level.onChallengeRushEnd(false, this.configChallenge, force);
                  break;
              case WaveMode.FB_COIN:
                  Level.onFbCoinEnd(false, this.configFBCoin, force);
                  break;
              case WaveMode.FB_ITEM:
                  Level.onFbItemEnd(false, this.configFBItem, force);
                  break;
              case WaveMode.SECRET:
                  Level.onSecretEnd(false, this.configSecret, force);
                  break;
              case WaveMode.FINAL_WAR:
                  Level.onFinalWarEnd(false, this.configFinalWar, force);
                  break;
              case WaveMode.DAILY_DAMAGE:
                  Level.onDailyDamageEnd(false, this.configDailyDamage, force);
                  break;
          }
          Global.sendMsg(MSG.TOWER_RUSH_END_FOCUS);
      }
      delaySendMsg(msg, win = false) {
          Laya.timer.once(1000, this, this.sendMsg, [msg, win]);
      }
      sendMsg(msg, win) {
          Global.sendMsg(msg, win);
      }
      buildWaveNum(wave, waveDb) {
          let num = waveDb.num[0] || 0;
          if (waveDb.num.length >= 2) {
              num = Utils.random(num, waveDb.num[1]);
          }
          if (waveDb.num_percent) {
              num = Math.ceil(Level.enemyLimit * num / 100);
              console.log("百分比数量", num);
          }
          wave.num = num;
      }
      buildWaveRoleId(wave, waveDb) {
          wave.roleIds.length = 0;
          let roleMap = db.get_role_db_map();
          for (let id of waveDb.role_ids) {
              let roleDb = roleMap[id];
              if (roleDb) {
                  wave.roleIds.push(id);
              }
              else {
                  let ids = Level.levelDb[id];
                  if (ids instanceof Array) {
                      wave.roleIds.push(Utils.randomItem(ids));
                  }
              }
          }
      }
      getWavePos(waveDb) {
          if (waveDb.pos.length >= 2) {
              let posCount = Math.floor(waveDb.pos.length / 2);
              let posIndex = Utils.random(0, posCount - 1);
              this.tempPoint.x = waveDb.pos[posIndex * 2];
              this.tempPoint.y = waveDb.pos[posIndex * 2 + 1];
          }
          else {
              let pos = Utils.randomItem(Level.tileMapBorn);
              this.tempPoint.x = pos.x;
              this.tempPoint.y = pos.y;
          }
          return this.tempPoint;
      }
      getWaveRoleId(wave) {
          let roleId;
          if (wave.roleIds.length) {
              roleId = Utils.randomItem(wave.roleIds);
          }
          else {
              roleId = Utils.randomItem(Level.allRoleIds);
          }
          return roleId;
      }
  }

  class Level {
      static load() {
          this.loadLevel(mgrGame.mapId, mgrGame.levelId);
      }
      static loadLevel(mapId, lvId) {
          this.mapDb = db.get_map_db(mapId);
          this.levelId = lvId;
          this.levelDb = this.getCfgByLevel(lvId);
          this.enemyLimit = Formula.rushEnemyLimit(lvId);
          console.log("冲塔小怪数量", this.enemyLimit);
          let rushId = Utils.rollItem(this.levelDb.rush_ids, lvId - 1);
          let idleId = Utils.rollItem(this.levelDb.idle_ids, lvId - 1);
          console.log("冲塔配置", rushId);
          console.log("放置配置", idleId);
          this.rushWaveId = rushId;
          this.idleWaveId = idleId;
      }
      static getMapLevel() {
          return db.get_level_db_map()[mgrGame.mapId];
      }
      static getCfgByLevel(level) {
          let level_db = this.getMapLevel();
          let data = null;
          for (let data of level_db) {
              if (level <= data.level) {
                  return data;
              }
          }
          return data || level_db[level_db.length - 1];
      }
      static canGetTowerRushReward() {
          return mgrGame.getItemCount(1009) > 0;
      }
      static calcTowerRushReward(level) {
          let rewardArr = db.get_tower_rush_reward_map();
          let data = null;
          for (let data of rewardArr) {
              if (level <= data.level) {
                  return data;
              }
          }
          return data || rewardArr[rewardArr.length - 1];
      }
      static notEnoughEmptyByRewardIds(scale = 1) {
          let rewardDb = this.calcTowerRushReward(mgrGame.levelId);
          if (rewardDb) {
              return mgrHolyItem.notEnoughEmptyByRewardIds(rewardDb.reward_ids, scale);
          }
          return false;
      }
      static getTowerTushRewardDaily(scale = 1) {
          let rewardDb = this.calcTowerRushReward(mgrGame.levelId);
          if (rewardDb && mgrGame.subItem(1009, 1, 55)) {
              BaseFacade.mItem.setItem(1009, 0);
              this.getRewardByItemIds(rewardDb.reward_ids, 22);
              Global.sendMsg(MSG.REFRESH_RED_POINT);
          }
      }
      static getTowerTushRewardDailyAD() {
          let rewardDb = this.calcTowerRushReward(mgrGame.levelId);
          if (rewardDb && mgrGame.subItem(1009, 1, 55)) {
              BaseFacade.mItem.setItem(1009, 0);
              this.getRewardByItemIds(rewardDb.reward_ids, 22);
              this.getRewardByItemIds(rewardDb.reward_ids, 22);
              Global.sendMsg(MSG.REFRESH_RED_POINT);
          }
      }
      static calcSecretDailyReward(level) {
          let rewardArr = db.get_secret_daily_reward_map();
          let data = null;
          for (let data of rewardArr) {
              if (level <= data.level) {
                  return data;
              }
          }
          return data || rewardArr[rewardArr.length - 1];
      }
      static getSecretDailyReward(scale = 1) {
          let rewardDb = this.calcSecretDailyReward(mgrSecret.layerId);
          if (rewardDb) {
              if (mgrHolyItem.notEnoughEmptyByRewardIds(rewardDb.reward_ids, scale)) {
                  return;
              }
          }
          if (rewardDb && !mgrSecret.dailyReward) {
              mgrSecret.dailyReward = true;
              let dropData = [];
              let reward_ids = rewardDb.reward_ids;
              for (let i = 0; i < reward_ids.length; i += 2) {
                  let itemId = reward_ids[i];
                  let count = reward_ids[i + 1] * scale;
                  if (itemId && count) {
                      mgrGame.addItem(itemId, count, 22, false, dropData);
                  }
              }
              this.showItemGet(dropData);
          }
      }
      static parseEnemy(enemyConfig) {
          let frames = enemyConfig["frames"];
          let totalConfig = {};
          for (let filename in frames) {
              let enemyName;
              let animName;
              let animIndex;
              let indexI = filename.lastIndexOf("-");
              let indexN = filename.indexOf("_");
              enemyName = filename.substring(0, indexI);
              animName = filename.substring(indexI + 1, indexN);
              animIndex = Number(filename.substring(indexN + 1, filename.indexOf(".png")));
              let data = totalConfig[enemyName];
              if (!data) {
                  data = {};
                  totalConfig[enemyName] = data;
              }
              if (!data[animName]) {
                  data[animName] = [];
              }
              data[animName].push({ file: filename, id: animIndex });
          }
          for (let k in totalConfig) {
              let v = totalConfig[k];
              for (let kk in v) {
                  let frames = v[kk];
                  frames.sort(this.sortEnemyFrame);
              }
              this.enemyNameList.push(k);
          }
          this.enemyConfig = totalConfig;
      }
      static sortEnemyFrame(a, b) {
          return a.id - b.id;
      }
      static parseConfig() {
          let roleMap = db.get_role_db_map();
          for (let key in roleMap) {
              let roleDb = roleMap[key];
              this.allRoleIds.push(roleDb.id);
          }
      }
      static parseTileMap(json) {
          let layers = json.layers;
          for (let layer of layers) {
              switch (layer.name) {
                  case "barrier": {
                      this.tileMapData = layer;
                      break;
                  }
                  case "path": {
                      for (let object of layer.objects) {
                          if (object.polygon) {
                              let path = [];
                              for (let p of object.polygon) {
                                  let x = Math.floor((object.x + p.x) / json.tilewidth);
                                  let y = Math.floor((object.y + p.y) / json.tileheight);
                                  path.push(new Laya.Point(x, y));
                              }
                              this.tileMapPath.push(path);
                              let pathR = [];
                              for (let i = path.length - 1; i >= 0; i--) {
                                  let p = path[i];
                                  pathR.push(new Laya.Point(p.x, p.y));
                              }
                              this.tileMapPath.push(pathR);
                          }
                      }
                      break;
                  }
                  case "born": {
                      let data = layer.data;
                      for (let x = 0; x < json.width; x++) {
                          for (let y = 0; y < json.height; y++) {
                              if (data[x + y * json.width]) {
                                  this.tileMapBorn.push(new Laya.Point(x, y));
                              }
                          }
                      }
                      break;
                  }
                  case "alpha": {
                      this.tileMapAlpha = layer;
                      break;
                  }
              }
          }
          Global.sendMsg(MSG.MAP_TILE_DATA_LOAD);
      }
      static isTileMapBarrier(x, y) {
          if (this.tileMapData)
              return this.tileMapData.data[x + y * this.tileMapData.width] || 0;
          else
              return 0;
      }
      static isTileMapAlpha(x, y) {
          if (this.tileMapAlpha)
              return this.tileMapAlpha.data[x + y * this.tileMapAlpha.width] || 0;
          else
              return 0;
      }
      static convertGridPosToRealPos(x, y, rand = true) {
          if (rand) {
              this.tempPos.x = x * this.tileW + Utils.random(0, this.tileW);
              this.tempPos.y = y * this.tileH + Utils.random(0, this.tileH);
          }
          else {
              this.tempPos.x = x * this.tileW + this.tileW / 2;
              this.tempPos.y = y * this.tileH + this.tileH / 2;
          }
          return this.tempPos;
      }
      static convertGridPosToRealPosX(x) {
          return x * this.tileW + this.tileW / 2;
      }
      static convertGridPosToRealPosY(y) {
          return y * this.tileH + this.tileH / 2;
          ;
      }
      static debugTextOnUI(text) {
          if (this.labelDebug) {
              this.labelDebug.text = text;
          }
      }
      static buildAttrArray(len) {
          let arr = [];
          arr.length = len;
          for (let i = 0; i < len; i++) {
              arr[i] = 0;
          }
          return arr;
      }
      static copyAttrArray(attrSrc, attrTar) {
          for (let i = 0; i < attrSrc.length && i < attrTar.length; i++) {
              attrTar[i] = attrSrc[i];
          }
      }
      static resetAttrArray(arr, len) {
          arr.length = len;
          for (let i = 0; i < len; i++) {
              arr[i] = 0;
          }
          return arr;
      }
      static clearAttrArray(arr, len) {
          for (let i = 0; i < len; i++) {
              arr[i] = 0;
          }
          return arr;
      }
      static stopTouchEvent(node) {
          node.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
      }
      static onMouseDown(e) {
          e && e.stopPropagation && e.stopPropagation();
      }
      static calcEnemyAttr(roleDb, attr, layer) {
          attr[BASE_ATTR.HP] = Math.round(Formula.enemyHP(null, layer) * roleDb.hp);
          attr[BASE_ATTR.AD] = Math.round(Formula.enemyATK(null, layer) * roleDb.atk);
          attr[BASE_ATTR.AP] = attr[BASE_ATTR.AD];
          attr[BASE_ATTR.ATK_SPEED] = roleDb.atk_speed;
          let HP_UP_ENEMY = StageAttr.getAttr(STAGE_ATTR.HP_UP_ENEMY);
          if (HP_UP_ENEMY > 0) {
              attr[BASE_ATTR.HP] += Math.round(attr[BASE_ATTR.HP] * HP_UP_ENEMY);
          }
      }
      static calcBossAttr(roleDb, attr, layer) {
          attr[BASE_ATTR.HP] = Math.round(Formula.bossHP(null, layer) * roleDb.hp);
          attr[BASE_ATTR.AD] = Math.round(Formula.bossATK(null, layer) * roleDb.atk);
          attr[BASE_ATTR.AP] = attr[BASE_ATTR.AD];
          attr[BASE_ATTR.AP] = attr[BASE_ATTR.AD];
          attr[BASE_ATTR.ATK_SPEED] = roleDb.atk_speed;
          let HP_UP_BOSS = StageAttr.getAttr(STAGE_ATTR.HP_UP_BOSS);
          if (HP_UP_BOSS > 0) {
              attr[BASE_ATTR.HP] += Math.round(attr[BASE_ATTR.HP] * HP_UP_BOSS);
          }
      }
      static getAttrName(index) {
          let attrDb = db.get_attr_base_map()[index];
          if (attrDb)
              return attrDb.name;
          else
              return BASE_ATTR[index];
      }
      static printAttr(attr, tag = "") {
      }
      static previewByDropId(dropId, dropData, limit = 0) {
          let dropDb = db.get_drop_db(dropId);
          if (dropDb) {
              dropData = dropData || [];
              let listItems = HolyItemMaker.previewHolyItemByDropDb(dropDb, limit);
              for (let item of listItems) {
                  dropData.push({ itemId: 0, quality: item.getQuality(), icon: item.getIcon(), count: 1 });
              }
              return dropData;
          }
      }
      static dropItemByDropId(dropId, show = true, dropData, ignoreSize = true) {
          let dropDb = db.get_drop_db(dropId);
          if (dropDb) {
              dropData = dropData || [];
              let listTower = TowerMaker.dropByDropDb(dropDb);
              for (let tower of listTower) {
                  mgrTower.addTowerByAmount(tower.towerDb, tower.count, 46, false, dropData);
              }
              let listItems = HolyItemMaker.dropHolyItemByDropDb(dropDb);
              for (let item of listItems) {
                  mgrHolyItem.addHolyItem(item, null, ignoreSize);
                  dropData.push({ type: DROP_TYPE.HOLY_ITEM, data: item });
              }
              if (dropDb.drop_coin.length >= 2) {
                  let coin = Utils.random(dropDb.drop_coin[0], dropDb.drop_coin[1]);
                  mgrGame.addItem(1001, coin, 46, false);
                  let itemInfo = {
                      itemId: 1001,
                      count: coin
                  };
                  dropData.push({ type: DROP_TYPE.ITEM, data: itemInfo });
              }
              if (dropDb.drop_items.length >= 2) {
                  let drop_items = dropDb.drop_items;
                  for (let i = 0; i < drop_items.length; i += 2) {
                      let itemId = drop_items[i];
                      let amount = drop_items[i + 1];
                      if (itemId && amount) {
                          mgrGame.addItem(itemId, amount, 46, false);
                          let itemInfo = {
                              itemId: itemId,
                              count: amount
                          };
                          dropData.push({ type: DROP_TYPE.ITEM, data: itemInfo });
                      }
                  }
              }
              if (show) {
                  this.showItemGet(dropData);
              }
              return dropData;
          }
      }
      static dropCustomItemByDropId(itemId, dropId, show = true, dropData, ignoreSize = true, callback = null) {
          let dropDb = db.get_drop_custom_db(dropId);
          if (dropDb) {
              dropData = dropData || [];
              switch (dropDb.cmd) {
                  case "select_item":
                  case "select_hero":
                      {
                          Director.openPanel("PanelItemSelect", { itemId: itemId, dropDb: dropDb, callback: callback });
                          break;
                      }
                  case "random_red_item":
                      {
                          let holyItem = HolyItemMaker.buildHolyItemByOption({ itemDb: HolyItemMaker.makeHolyItemClassRandom(), quality: EQUIP_QUALITY.RED, wordQuality: [4, 3, 3, 3] });
                          mgrHolyItem.addHolyItem(holyItem, dropData);
                          if (callback)
                              callback();
                          break;
                      }
                  case "random_red_box":
                      {
                          let itemDb = HolyItemMaker.makeHolyItemClassRandom();
                          let itemDbSub = HolyItemMaker.makeHolyItemClassRandom(itemDb.id);
                          let holyItem = HolyItemMaker.buildHolyItemByOption({ quality: EQUIP_QUALITY.RED, itemDb: itemDb, itemDbSub: itemDbSub });
                          mgrHolyItem.addHolyItem(holyItem, dropData);
                          if (callback)
                              callback();
                          break;
                      }
                  case "random_orange_item":
                      {
                          let holyItem = HolyItemMaker.buildHolyItemByOption({ itemDb: HolyItemMaker.makeHolyItemClassRandom(), quality: EQUIP_QUALITY.ORANGE, wordQuality: [3, 3, 3, 3] });
                          mgrHolyItem.addHolyItem(holyItem, dropData);
                          if (callback)
                              callback();
                          break;
                      }
                  case "build_orange_item":
                      {
                          Director.openPanel("PanelHolyItemBuilder", { callback: callback });
                          break;
                      }
                  case "build_super_item":
                      {
                          Director.openPanel("PanelHolyItemBuilderBox", { callback: callback });
                          break;
                      }
              }
              if (show) {
                  this.showItemGet(dropData);
              }
              return dropData;
          }
      }
      static getRewardByDropDataList(dropData) {
          for (let data of dropData) {
              this.getRewardByDropData(data);
          }
      }
      static getRewardByDropData(data) {
          switch (data.type) {
              case DROP_TYPE.TOWER:
                  let towerInfo = data.data;
                  mgrTower.addTowerByAmount(towerInfo.towerDb, towerInfo.count, 46, false);
                  break;
              case DROP_TYPE.HOLY_ITEM:
                  let holyItem = data.data;
                  mgrHolyItem.addHolyItem(holyItem);
                  break;
              case DROP_TYPE.ITEM:
                  let itemInfo = data.data;
                  mgrGame.addItem(itemInfo.itemId, itemInfo.count, 46, false);
                  break;
          }
      }
      static buildItemByDropId(dropId, dropData) {
          let dropDb = db.get_drop_db(dropId);
          if (dropDb) {
              dropData = dropData || [];
              let listItems = HolyItemMaker.dropHolyItemByDropDb(dropDb, this.optionHolyitemDrop);
              for (let item of listItems) {
                  dropData.push(item);
              }
              return dropData;
          }
      }
      static buildItemByDropIdAndTime(dropId, time = 1) {
          let dropData = [];
          for (let i = 0; i < time; i++) {
              this.buildItemByDropId(dropId, dropData);
          }
          dropData.sort(this.sortHolyItemByQuality);
          return dropData;
      }
      static sortHolyItemByQuality(a, b) {
          return b.qualityDb.quality - a.qualityDb.quality;
      }
      static quality2color(id) {
          return "";
      }
      static showItemGet(dropData) {
          if (dropData && dropData.length) {
              Director.openPanel("PanelItemGet", { items: dropData });
              for (let item of dropData) {
                  if (item.type == DROP_TYPE.TOWER) {
                      let data = item.data;
                      mgrTower.showTowerNew(data.towerDb.id, data.count, false);
                  }
                  else if (item.type == DROP_TYPE.ITEM) {
                      let data = item.data;
                      let itemDb = db.get_item_db(data.itemId);
                      if (itemDb && itemDb.type == 4) {
                          let towerDb = mgrTower.findTowerDbByItemId(itemDb.id);
                          if (towerDb) {
                              mgrTower.showTowerNew(towerDb.id, data.count, false);
                          }
                      }
                  }
              }
          }
      }
      static showFlyMoney(pos, count) {
          this.stage.showFlyMoney(pos, count);
      }
      static packSkillData(data, skillDb) {
          LogicConfig.resetSkillData(data);
          data.skillId = skillDb.id;
          data.template = skillDb.template;
          data.timeCast = skillDb.cast_time;
          data.timeCD = skillDb.cd_time;
          data.skillDb = skillDb;
          data.count = skillDb.atk_count;
          data.ground = skillDb.groud;
          data.limit = skillDb.target_limit;
          data.delayRebound = skillDb.delay_rebound;
          data.searchInAttack = skillDb.search_in_attack;
          data.limitRebound = skillDb.rebound_limit;
          data.ranage = skillDb.range;
          data.camp = skillDb.camp;
          data.isSuper = skillDb.is_super;
      }
      static getRewardBySummonDb(summonDb, dropData) {
          let rewardId = summonDb.reward_id;
          this.dropItemByDropId(rewardId, false, dropData);
      }
      static getTaskRewardPreview(id, index, data) {
          let dropData = { type: DROP_TYPE.ITEM };
          let map = db.get_task_reward_db_map()[id];
          if (!map)
              return dropData;
          let item = map[index - 1];
          if (item) {
              dropData.data = { itemId: item.item_id, count: 0 };
          }
          return dropData;
      }
      static getTaskReward(id, index, data, dropData) {
          let item = db.get_task_reward_db(id, index - 1);
          if (item) {
              if (item.item_id == 1001) {
                  let countCount = Math.round(Utils.randomRange(item.num[0], item.num[1]) * mgrGame.getEnemyCoin());
                  mgrGame.addItem(item.item_id, countCount, 50, false, dropData);
              }
              else {
                  let countCount = Utils.random(item.num[0], item.num[1]);
                  mgrGame.addItem(item.item_id, countCount, 50, false, dropData);
              }
          }
          return dropData;
      }
      static isMustBest() {
          let summonBestCount = mgrGame.getItemCount(1023);
          let summonBestLimit = db.game_cnf.summon_best_limit;
          if (summonBestLimit && summonBestCount >= summonBestLimit) {
              return false;
          }
          let summonCount = mgrGame.getItemCount(1022) + 1;
          let summonMaxxx = db.game_cnf.summon_best_count;
          if (summonCount && (summonCount >= summonMaxxx)) {
              return true;
          }
          return false;
      }
      static summonCard(type, dropData) {
          let summnDb = null;
          if (this.isMustBest()) {
              BaseFacade.mItem.setItem(1022, 0);
              summnDb = db.get_summon_card_db(db.game_cnf.summon_best_id);
              mgrGame.addItem(1023, 1, 48, false);
          }
          if (!summnDb) {
              let listItem = [];
              let dataMap = db.get_summon_card_db_map();
              for (let k in dataMap) {
                  let data = db.get_summon_card_db(k);
                  if (type != null) {
                      if (data.type == type) {
                          listItem.push(data);
                      }
                  }
                  else {
                      listItem.push(data);
                  }
              }
              summnDb = StageTool.calcWeightItem(listItem);
          }
          this.getRewardBySummonDb(summnDb, dropData);
          mgrGame.addItem(1022, 1, 48, false);
          mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER);
      }
      static summonCard1() {
          let dropData = [];
          if (mgrGame.getItemCount(3004) == 0) {
              let towerDb = db.get_tower_db(db.game_cnf.summon_first_id);
              if (towerDb) {
                  mgrTower.addTowerByAmount(towerDb, 1, 48, false, dropData);
                  mgrGame.addItem(3004, 1, 48, false);
                  mgrGame.addItem(1022, 1, 48, false);
              }
              else {
                  this.summonCard(null, dropData);
              }
          }
          else {
              this.summonCard(null, dropData);
          }
          for (let data of dropData) {
              if (data.type == DROP_TYPE.TOWER) {
                  let tower = data.data;
                  if (tower) {
                      switch (mgrTower.getTowerQualityByDB(tower.towerDb)) {
                          case EQUIP_QUALITY.GREEN:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_0);
                              break;
                          case EQUIP_QUALITY.BLUE:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_1);
                              break;
                          case EQUIP_QUALITY.PURPLE:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_2);
                              break;
                          case EQUIP_QUALITY.ORANGE:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_3);
                              break;
                      }
                  }
              }
          }
          return dropData;
      }
      static sunnomCard5() {
          let dropData = [];
          this.summonCard(0, dropData);
          this.summonCard(null, dropData);
          this.summonCard(null, dropData);
          this.summonCard(null, dropData);
          this.summonCard(null, dropData);
          for (let data of dropData) {
              if (data.type == DROP_TYPE.TOWER) {
                  let tower = data.data;
                  if (tower) {
                      switch (mgrTower.getTowerQualityByDB(tower.towerDb)) {
                          case EQUIP_QUALITY.GREEN:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_0);
                              break;
                          case EQUIP_QUALITY.BLUE:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_1);
                              break;
                          case EQUIP_QUALITY.PURPLE:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_2);
                              break;
                          case EQUIP_QUALITY.ORANGE:
                              mgrTask.doEvent(db.TASK_EVENT_ID.SUMMON_TOWER_QUALITY_3);
                              break;
                      }
                  }
              }
          }
          return dropData;
      }
      static getStatisIdIdle() {
          let idx = this.levelId;
          if (idx > 999)
              idx = 999;
          return this.mapDb.statis_point + idx;
      }
      static getStatisIdEndness() {
          let idx = this.levelId;
          if (idx > 999)
              idx = 999;
          return this.mapDb.statis_point + idx;
      }
      static onIdleBegin() {
      }
      static onIdleEnd() {
      }
      static onEndessBegin() {
          let statisId = this.getStatisIdEndness();
          console.log("打点: 无尽开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static clearStage() {
          ResEnemyManager.clearAll();
      }
      static onEndnessEnd(win, force = false) {
          StageGameStatis.stop(WaveMode.TOWER_ENDNESS, mgrGame.levelId);
          let statisId = this.getStatisIdEndness();
          console.log("打点: 无尽结束", statisId, win);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
          if (win) {
              mgrTask.setEvent(db.TASK_EVENT_ID.PASS_TOWER_RUSH, mgrGame.levelId);
              mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_TOWER_RUSH);
              mgrGame.levelId++;
              Level.load();
              this.delayOpenRushEndPanel("PanelGameWin", { mode: WaveMode.TOWER_ENDNESS });
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force, mode: WaveMode.TOWER_ENDNESS });
          }
      }
      static delayOpenRushEndPanel(panel, context) {
          Laya.timer.once(1000, this, this.openPanel, [panel, context]);
      }
      static openPanel(panel, context) {
          Director.openPanelWithSingleton(panel, context);
      }
      static onStoryRushBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: 主线故事开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onStoryRushEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.TOWER_MAIN_STORY, config.id + "-" + config.lv);
          if (win) {
              let count = mgrGame.getLevelStoryAward(config.index);
              mgrGame.addLevelStoryAward(config.index);
              mgrTask.setEvent(db.TASK_EVENT_ID.PASS_MAIN_STORY, mgrGame.getLevelStoryStep());
              if (count == 0) {
                  let dropData = [];
                  let first_reward_ids = config.first_reward_ids;
                  for (let i = 0; i < first_reward_ids.length; i += 2) {
                      let itemId = first_reward_ids[i];
                      let count = first_reward_ids[i + 1];
                      if (itemId && count) {
                          mgrGame.addItem(itemId, count, 22, false, dropData);
                      }
                  }
                  this.showWinReward(dropData, WaveMode.TOWER_MAIN_STORY, config);
              }
              else {
                  this.delayOpenRushEndPanel("PanelGameWin", { mode: WaveMode.TOWER_MAIN_STORY });
              }
              mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_MAIN_STORY);
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: 主线故事结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static getStoryRushMoreReward(config) {
          if (!config)
              return;
          let dropData = [];
          let first_reward_ids = config.first_reward_ids;
          for (let i = 0; i < first_reward_ids.length; i += 2) {
              let itemId = first_reward_ids[i];
              let count = first_reward_ids[i + 1];
              if (itemId && count) {
                  mgrGame.addItem(itemId, count, 20, false, dropData);
              }
          }
          this.showItemGet(dropData);
      }
      static onChallengeRushBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: BOSS挑战开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onChallengeRushEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.TOWER_CHALLENGE, config.id);
          if (win) {
              let dropData = [];
              let first_reward_ids = config.reward_ids;
              for (let i = 0; i < first_reward_ids.length; i += 2) {
                  let itemId = first_reward_ids[i];
                  let count = first_reward_ids[i + 1];
                  if (itemId && count) {
                      mgrGame.addItem(itemId, count, 22, false, dropData);
                  }
              }
              this.showWinReward(dropData, WaveMode.TOWER_CHALLENGE);
              mgrMonster.onMonsterChallengeSucces(config);
              mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_BOSS);
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: BOSS挑战结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static showWinReward(dropData, mode, config = null) {
          if (dropData && dropData.length)
              this.delayOpenRushEndPanel("PanelGameWinReward", { items: dropData, mode: mode, config: config });
          else
              this.delayOpenRushEndPanel("PanelGameWin", { mode: WaveMode.TOWER_MAIN_STORY });
      }
      static updateRedPoint4Button(button, value, name = "red") {
          let red = button.getChild(name);
          if (red) {
              red.visible = value;
          }
      }
      static isFirstGuide() {
          return !mgrGuide.isGuideCompletById("main", 26);
      }
      static isCollectUnlcok(data) {
          return mgrGame.getItemCount(data.item_id) > 0;
      }
      static findEnemyModelDbByItemId(itemId) {
          let roleDbMap = db.get_role_model_db_map();
          for (let k in roleDbMap) {
              let roleDb = roleDbMap[k];
              if (roleDb.item_id == itemId) {
                  return roleDb;
              }
          }
          return null;
      }
      static findHolyitemDbItemId(itemId) {
          let dataMap = db.get_holy_item_db_map();
          for (let k in dataMap) {
              let itemDb = dataMap[k];
              if (itemDb.item_id == itemId) {
                  return itemDb;
              }
          }
          return null;
      }
      static isDropInterruptById(dropId) {
          let dropDb = db.get_drop_custom_db(dropId);
          if (dropDb) {
              switch (dropDb.cmd) {
                  case "select_item":
                  case "select_hero":
                  case "build_orange_item":
                  case "build_super_item":
                      return true;
              }
          }
          return false;
      }
      static getRewardByItemIds(reward_ids, reason, scale = 1, callback) {
          if (reward_ids) {
              let dropData = [];
              let countCustom = 0;
              let customItemId = 0;
              let customItemCt = 0;
              for (let i = 0; i < reward_ids.length; i += 2) {
                  let itemId = reward_ids[i];
                  let count = reward_ids[i + 1] * scale;
                  if (itemId && count) {
                      let itemDb = db.get_item_db(itemId);
                      if (itemDb && itemDb.type == 6) {
                          if (this.isDropInterruptById(itemDb.dropId)) {
                              countCustom += count;
                              customItemId = itemId;
                              customItemCt = count;
                          }
                      }
                  }
              }
              if (countCustom >= 2) {
                  console.error("定制物品一次只能出现一个", reward_ids);
                  return;
              }
              else if (countCustom == 1) {
                  if (customItemId && customItemCt) {
                      mgrGame.addItem(customItemId, customItemCt, reason, false, dropData, () => {
                          for (let i = 0; i < reward_ids.length; i += 2) {
                              let itemId = reward_ids[i];
                              let count = reward_ids[i + 1] * scale;
                              if (itemId && itemId != customItemId && count) {
                                  mgrGame.addItem(itemId, count, reason, false, dropData);
                              }
                          }
                          this.showItemGet(dropData);
                          if (callback)
                              callback();
                      });
                  }
              }
              else {
                  for (let i = 0; i < reward_ids.length; i += 2) {
                      let itemId = reward_ids[i];
                      let count = reward_ids[i + 1] * scale;
                      if (itemId && count) {
                          mgrGame.addItem(itemId, count, reason, false, dropData);
                      }
                  }
                  this.showItemGet(dropData);
                  if (callback)
                      callback();
              }
          }
      }
      static onFbCoinBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: 金币副本开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onFbCoinEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.FB_COIN, config.name + "\n" + config.desc);
          if (win) {
              mgrGame.subItem(1011, 1, 57);
              mgrFB.addFBCoinPassCount(config.id);
              let dropData = [];
              let first_reward_ids = config.reward_ids;
              for (let i = 0; i < first_reward_ids.length; i += 2) {
                  let itemId = first_reward_ids[i];
                  let count = first_reward_ids[i + 1];
                  if (itemId && count) {
                      mgrGame.addItem(itemId, count, 22, false, dropData);
                  }
              }
              this.showWinReward(dropData, WaveMode.FB_COIN);
              mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_FB_COIN);
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: 金币副本结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static onFbItemBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: 圣物副本开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onFbItemEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.FB_ITEM, config.name + "\n" + config.desc);
          if (win) {
              mgrGame.subItem(1011, 1, 57);
              mgrFB.addFBItemPassCount(config.id);
              let dropData = [];
              let dropId = config.drop_id[mgrTime.getCurrentWeek() % config.drop_id.length];
              Level.dropItemByDropId(dropId, false, dropData, true);
              this.showWinReward(dropData, WaveMode.FB_ITEM);
              mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_FB_ITEM);
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: 圣物副本结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static onSecretBegin(config) {
          mgrSecret.selectId = config.id;
          let statisId = config.statis_point;
          console.log("打点: 秘境开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onSecretEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.SECRET, config.name + "\n");
          if (win) {
              mgrGame.subItem(1013, 1, 60);
              if (config.id == mgrSecret.layerId) {
                  let lvNext = mgrSecret.layerId + 1;
                  let lvMaxx = mgrSecret.getMaxLv();
                  if (lvNext > lvMaxx) {
                      lvNext = lvMaxx;
                  }
                  mgrSecret.layerId = lvNext;
                  mgrSecret.selectId = mgrSecret.layerId;
              }
              mgrSecret.addPassCount(config.id);
              let dropData = [];
              let isFirst = mgrSecret.getPassCount(config.id) == 1;
              if (isFirst) {
                  let reward_ids = config.first_reward_ids;
                  for (let i = 0; i < reward_ids.length; i += 2) {
                      let itemId = reward_ids[i];
                      let count = reward_ids[i + 1];
                      if (itemId && count) {
                          mgrGame.addItem(itemId, count, 60, false, dropData);
                      }
                  }
              }
              else {
                  let reward_ids = config.drop_id;
                  for (let i = 0; i < reward_ids.length; i += 2) {
                      let itemId = reward_ids[i];
                      let count = reward_ids[i + 1];
                      if (itemId && count) {
                          mgrGame.addItem(itemId, count, 60, false, dropData);
                      }
                  }
              }
              this.showWinReward(dropData, WaveMode.SECRET);
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: 秘境结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static onFinalWarBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: 歼灭战开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onFinalWarEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.FINAL_WAR, config.name + "\n");
          if (win) {
              let itemCount = Formula.rewardFinalWar(mgrFinalWar.getFinalWarLevel(config.id), config.reward_scale);
              mgrFinalWar.addFinalWarLevel(config.id);
              let dropData = [];
              mgrGame.addItem(config.item_id, itemCount, 66, false, dropData);
              this.showWinReward(dropData, WaveMode.FINAL_WAR);
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force, mode: WaveMode.FINAL_WAR });
          }
          GameStatistics.statisCommonEvent(config.statis_lv_max, mgrFinalWar.getFinalWarMaxLv(config.id));
          let statisId = config.statis_point;
          console.log("打点: 歼灭战结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static onDailyDamageBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: 茶叶蛋开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onDailyDamageEnd(win, config, force = false) {
          StageGameStatis.stop(WaveMode.DAILY_DAMAGE, config.name_pre + "\n" + config.name);
          if (win) {
              this.showDailyDamageResult();
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: 茶叶蛋结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
      }
      static showDailyDamageResult() {
          this.delayOpenRushEndPanel("PanelDamageResult");
      }
      static onNewyearFBBegin(config) {
          let statisId = config.statis_point;
          console.log("打点: 驱逐年兽开始", statisId);
          mgrStatis.statisOnStageStart(statisId);
      }
      static onNewyearFBEnd(win, config, force = false) {
          mgrNewyear.markDamage(StageGameStatis.getDamageAll());
          StageGameStatis.stop(WaveMode.NEWYEAR, "驱逐年兽\n");
          if (win) {
              this.showNewyearDamageResult();
          }
          else {
              this.delayOpenRushEndPanel("PanelGameLose", { force: force });
          }
          let statisId = config.statis_point;
          console.log("打点: 驱逐年兽结束", statisId);
          mgrStatis.statisOnStageEnd(statisId, win ? 1 : 0);
          mgrTask.doEvent(db.TASK_EVENT_ID.NEWYEAR_BEAT_NIAN);
      }
      static showNewyearDamageResult() {
          this.delayOpenRushEndPanel("PanelNewyearGameResult");
      }
  }
  Level.enemyLimit = 0;
  Level.grayFilter = [(new Laya.ColorFilter).gray()];
  Level.globalAttr = [];
  Level.enemyNameList = [];
  Level.allRoleIds = [];
  Level.tileMapPath = [];
  Level.tileMapBorn = [];
  Level.gridW = 48;
  Level.gridH = 64;
  Level.tileW = 32;
  Level.tileH = 32;
  Level.tempPos = { x: 0, y: 0, width: 0, height: 0, isTemp: true };
  Level.optionHolyitemDrop = { dropCount: 1 };

  class mgrGain extends Manager {
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
              this.saveRecord();
          }
          for (let id in this.data.id2time) {
              let maxxTime = this.calcMaxxTime(id);
              let leftTime = this.getLeftTime(id);
              if (leftTime > maxxTime) {
                  let fixxTime = leftTime - maxxTime;
                  this.setEndTime(id, this.getEndTime(id) - fixxTime);
                  this.saveRecord();
              }
          }
          console.log("mgrGain.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static getUseTime(id) {
          return this.data.id2count[id] || 0;
      }
      static setUseTime(id, value) {
          this.data.id2count[id] = value;
          this.saveRecord();
      }
      static getEndTime(id) {
          return this.data.id2time[id] || 0;
      }
      static setEndTime(id, value) {
          this.data.id2time[id] = value;
          this.saveRecord();
      }
      static getLeftTime(id) {
          let curtTime = this.curtTime;
          let lastTime = this.getEndTime(id);
          let leftTime = lastTime - curtTime;
          if (leftTime < 0)
              leftTime = 0;
          return leftTime;
      }
      static getMagicDb(id) {
          return db.get_magic_db(id);
      }
      static get curtTime() {
          return mgrTime.curtTime();
      }
      static calcMaxxTime(id) {
          let magicDb = this.getMagicDb(id);
          let count = this.getUseTime(id);
          let timeMax = 0;
          for (let i = 0; i < count; i++) {
              timeMax += (magicDb.time + i * magicDb.time_add);
          }
          return timeMax;
      }
      static getMagicTime(id) {
          let magicDb = this.getMagicDb(id);
          if (magicDb) {
              return magicDb.time + this.getUseTime(id) * magicDb.time_add;
          }
          return 0;
      }
      static getMagicTimeNext(id) {
          let magicDb = this.getMagicDb(id);
          if (magicDb) {
              return magicDb.time + (this.getUseTime(id) + 1) * magicDb.time_add;
          }
          return 0;
      }
      static isMagicRunning(id) {
          return this.getLeftTime(id) > 0;
      }
      static startMagic(id) {
          this.setEndTime(id, this.curtTime + this.getLeftTime(id) + this.getMagicTime(id));
          this.setUseTime(id, this.getUseTime(id) + 1);
          Global.sendMsg(MSG.GAME_GAIN_BEGIN, id);
      }
      static addMagicTime(id) {
          let curEndTime = this.data.id2time[id];
          if (curEndTime) {
              this.setEndTime(id, curEndTime + this.getMagicTime(id));
              this.setUseTime(id, this.getUseTime(id) + 1);
              Global.sendMsg(MSG.GAME_GAIN_BEGIN, id);
          }
          else {
              this.startMagic(id);
          }
      }
      static calcAttrAdd() {
          let attr_add = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          Level.printAttr(attr_add, "附魔属性");
          return attr_add;
      }
  }
  mgrGain.RECORD_KEY = "game166_magic_v1.0";
  mgrGain.dataDefault = {
      id2count: {},
      id2time: {},
  };

  class mgrKV extends Manager {
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = {};
          }
          console.log("mgrKV.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static setKV(key, value) {
          this.data[key] = value;
          this.saveRecord();
          return value;
      }
      static getKV(key, def = 0) {
          return this.data[key] || def;
      }
      static addKV(key, add) {
          return this.setKV(key, this.getKV(key) + add);
      }
  }
  mgrKV.RECORD_KEY = "game166_kv_v1.0";

  class mgrSign extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDailySwitchActive.bind(this),
              [MSG.MGR_TIME_UPDATE]: this.onMgrTimeUpdate.bind(this),
          });
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrSign.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onDailySwitchActive() {
          this.calcCurtDay();
      }
      static onMgrTimeUpdate() {
          if (this.nextdayTime == 0) {
              this.resetNextDayTime();
          }
      }
      static markSigned(day) {
          this.data.day2reward[day] = true;
          this.saveRecord();
      }
      static isSigned(day) {
          return this.data.day2reward[day];
      }
      static getInitTime() {
          return this.data.time;
      }
      static setInitTime(time) {
          this.data.time = time;
          this.saveRecord();
      }
      static getCurtTime() {
          return Math.floor(mgrTime.serverTime / 1000);
      }
      static calcNeedFixCount() {
          let count = 0;
          let day = this.day;
          let signDataMap = db.get_sign_db_map();
          for (let datas of signDataMap) {
              for (let data of datas) {
                  if (data.day < day && !this.isSigned(data.day)) {
                      count++;
                  }
              }
          }
          return count;
      }
      static calcCurtDay() {
          let curtTime = this.getCurtTime();
          let initTime = this.getInitTime();
          if (initTime == 0) {
              let date = new Date(curtTime * 1000);
              let y = date.getFullYear();
              let m = date.getMonth() + 1;
              let d = date.getDate();
              curtTime = Math.floor(new Date(y + "/" + m + "/" + d).getTime() / 1000);
              initTime = curtTime;
              this.setInitTime(initTime);
          }
          let curtDay = Math.floor((curtTime - initTime) / (3600 * 24));
          return curtDay + 1;
      }
      static findSignDbByDay(day) {
          let signDataMap = db.get_sign_db_map();
          for (let datas of signDataMap) {
              for (let data of datas) {
                  if (data.day == day) {
                      return data;
                  }
              }
          }
          return null;
      }
      static canFix(day) {
          if (!this.isSigned(day) && day < this.day) {
              return true;
          }
          return false;
      }
      static canSign(day) {
          if (!mgrTime.isReady()) {
              return false;
          }
          let signDb = this.findSignDbByDay(day);
          if (signDb && day <= this.day && !this.isSigned(day)) {
              return true;
          }
          return false;
      }
      static get day() {
          return this.calcCurtDay();
      }
      static showUI() {
          if (Global.isGuiding)
              return;
          if (this.canSign(this.day)) {
              Director.openPanel("PanelSign");
          }
      }
      static sign(day, scale = 1, force = false) {
          if (force || this.canSign(day)) {
              this.markSigned(day);
              let signDb = this.findSignDbByDay(day);
              if (signDb) {
                  this.getReward(signDb, scale);
                  Global.sendMsg(MSG.SIGN_UDPATE);
                  return true;
              }
          }
          return false;
      }
      static getReward(signDb, scale = 1) {
          mgrGame.addItem(signDb.item_id, signDb.item_num * scale, 23);
      }
      static get nextdayTime() {
          return this.data.nextdayTime;
      }
      static set nextdayTime(v) {
          this.data.nextdayTime = v;
          this.saveRecord();
      }
      static get nextdayIndx() {
          return this.data.nextdayIndx;
      }
      static set nextdayIndx(v) {
          this.data.nextdayIndx = v;
          this.saveRecord();
      }
      static get nextdayIndxReward() {
          return this.data.nextdayIndxReward;
      }
      static set nextdayIndxReward(v) {
          this.data.nextdayIndxReward = v;
          this.saveRecord();
      }
      static resetNextDayTime() {
          this.nextdayTime = mgrTime.curtTimeMS();
      }
      static canGetNextDayReward(data) {
          data = data || this.getNextDayRewardDB();
          if (data && mgrTime.isReady()) {
              return this.calcNextDayLeftTime() == 0;
          }
          return false;
      }
      static calcNextDayLeftTime() {
          let data = this.getNextDayRewardDB();
          if (!data)
              return 0;
          let lastDate = mgrTime.getBeijingTime(this.nextdayTime);
          let curtDate = mgrTime.getBeijingTime(mgrTime.curtTimeMS());
          let lastDayNum = mgrTime.getDateNum(lastDate);
          let curtDayNum = mgrTime.getDateNum(curtDate);
          if (lastDayNum != curtDayNum)
              return 0;
          let hour = curtDate.getHours();
          let minute = curtDate.getMinutes();
          let second = curtDate.getSeconds();
          let hourSet = data.hour;
          let leftTime = hourSet * 3600 - hour * 3600 - minute * 60 - second;
          if (leftTime < 0)
              leftTime = 0;
          return leftTime;
      }
      static getNextDayRewardDB() {
          return db.get_next_day_reward_map()[this.nextdayIndx];
      }
      static isNextDayRewardValid() {
          return this.getNextDayRewardDB() != null;
      }
      static getNextDayReward() {
          let data = this.getNextDayRewardDB();
          if (!this.canGetNextDayReward(data))
              return;
          if (mgrHolyItem.notEnoughEmptyByRewardIds(data.reward_ids))
              return;
          Level.getRewardByItemIds(data.reward_ids, 30, 1, () => {
              this.nextdayIndxReward = data.id - 1;
              this.nextdayIndx = data.id;
              this.resetNextDayTime();
              Global.sendMsg(MSG.NEXT_DAY_REWARD);
          });
      }
  }
  mgrSign.RECORD_KEY = "game166_sign_v1.0";
  mgrSign.dataDefault = {
      time: 0,
      day2reward: {},
      nextdayTime: 0,
      nextdayIndx: 0,
      nextdayIndxReward: -1,
  };
  mgrSign.dataShowAdStatis = {};

  class mgrGame extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
              [MSG.TIME_OFFLINE_TIME]: this.onTimeOfflineTime.bind(this),
              [BASE_MSG.SDK_CHECK_DEBUG_WHITE_USER_RESULT]: this.onSdkCheckDebugWhiteUserResult.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e && e.advName) {
                      let advDb = db.get_adv_db(e.advName);
                      if (advDb && advDb.advType == "video") {
                          this.onADVideoSuccess(e);
                      }
                  }
              },
          });
      }
      static onStart() {
          mgrSdk.getQqGroupNum();
          mgrSdk.checkDebugWhiteUserResult();
          if (Level.isFirstGuide()) {
              BaseFacade.mItem.setItem(4011, 0);
              mgrGuide.resetRecord();
              mgrTower.resetRecord();
          }
          CopHelper.onGamteStart();
      }
      static onDifferentDay() {
          this.loginDay++;
          BaseFacade.mItem.setItem(1005, 1);
          BaseFacade.mItem.setItem(1008, 2);
          BaseFacade.mItem.setItem(1009, 1);
          BaseFacade.mItem.setItem(3001, 0);
          mgrKV.setKV("FIRST_LOGIN", 0);
      }
      static onTimeOfflineTime(second) {
          this.boxRewardTime += second;
      }
      static onSdkCheckDebugWhiteUserResult(data) {
          if (data) {
              this.isWhiteUser = data.isWhiteUser;
          }
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          this.loadTryToPlayRewards();
          if (!this.data) {
              this.data = this.dataDefault;
              this.data.version = this.LASTEST_VERSION;
              this.saveRecord();
          }
          else {
              if (this.data.version == null)
                  this.data.version = 0;
              this.checkRecord(this.data, this.dataDefault);
          }
          if (Laya.Browser.onPC)
              this.loadStageConfig();
          StageConfig.enableGameEffect = this.enableGameEffect;
          StageConfig.towerTargetSearchType = this.towerTargetSearchType;
          console.log("mgrGame.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static get version() {
          return this.data.version;
      }
      static isNewBie() {
          return this.version >= this.LASTEST_VERSION;
      }
      static setKeyValue(key1, key2, value, checkMax = false) {
          let curtValue = this.getKeyValue(key1, key2);
          if (checkMax) {
              if (value > curtValue)
                  this.data[key1][key2] = value;
          }
          else {
              this.data[key1][key2] = value;
          }
          this.saveRecord();
      }
      static getKeyValue(key1, key2, defaultValue = 0) {
          let value = this.data[key1][key2];
          if (value == null) {
              return defaultValue;
          }
          else {
              return value;
          }
      }
      static set mapId(mapId) {
          this.data.mapId = mapId;
          this.saveRecord();
      }
      static get mapId() {
          return this.data.mapId;
      }
      static set levelId(value) {
          this.data.mapLv[this.mapId] = value;
          this.saveRecord();
      }
      static get levelId() {
          return this.getMapLv(this.mapId);
      }
      static getMapLv(mapId) {
          return this.data.mapLv[mapId] || 1;
      }
      static setMapLv(mapId, num) {
          this.data.mapLv[mapId] = num;
      }
      static getItemCount(itemId) {
          return BaseFacade.mItem.getItemCount(itemId);
          ;
      }
      static moneyBarKeep() {
          this.ui_item_coin_num = mgrGame.getItemCount(1001);
          this.ui_item_diamond_num = mgrGame.getItemCount(1000);
      }
      static clearMoneyBarKeep() {
          this.ui_item_coin_num = 0;
          this.ui_item_diamond_num = 0;
      }
      static getItemCoin() {
          if (this.ui_item_coin_num) {
              let temp = this.ui_item_coin_num;
              return temp;
          }
          else {
              return this.getItemCount(1001);
          }
      }
      static getItemDiamond() {
          if (this.ui_item_diamond_num) {
              let temp = this.ui_item_diamond_num;
              return temp;
          }
          else {
              return this.getItemCount(1000);
          }
      }
      static noticeItemNotEnough(itemId, itemCount) {
          switch (itemId) {
              case 1000:
                  mgrTip.alertPrompt("钻石不足，是否跳转到祈愿界面？", null, () => {
                      Director.openPanelWithSingleton("PanelPray", { page: 2 });
                  });
                  break;
              case 1011:
                  if (mgrAdv.checkActive(db.ADV_DB_ADVNAME.shop_ad)) {
                      mgrTip.alertPrompt(mgrGame.getItemName(itemId) + "不足，是否跳转到商店界面？", null, () => {
                          Director.openPanelWithSingleton("PanelShop");
                      });
                  }
                  else {
                      mgrTip.showMsgTip(mgrGame.getItemName(itemId) + "不足" + itemCount);
                  }
                  break;
              default:
                  mgrTip.showMsgTip(mgrGame.getItemName(itemId) + "不足" + itemCount);
                  break;
          }
      }
      static checkItem(itemId, itemCoUnt, show = true) {
          let enough = this.getItemCount(itemId) >= itemCoUnt;
          if (show && !enough) {
              this.noticeItemNotEnough(itemId, itemCoUnt);
          }
          return enough;
      }
      static subItem(itemId, itemCoUnt, reason) {
          let success = BaseFacade.mItem.subItem(itemId, itemCoUnt, reason);
          if (!success) {
              this.noticeItemNotEnough(itemId, itemCoUnt);
          }
          return success;
      }
      static subItems(item_ids, reason) {
          if (!item_ids)
              return false;
          for (let i = 0; i < item_ids.length; i += 2) {
              let itemId = item_ids[i];
              let itemCt = item_ids[i + 1];
              if (itemId && itemCt && !this.checkItem(itemId, itemCt)) {
                  return false;
              }
          }
          for (let i = 0; i < item_ids.length; i += 2) {
              let itemId = item_ids[i];
              let itemCt = item_ids[i + 1];
              if (itemId && itemCt) {
                  this.subItem(itemId, itemCt, reason);
              }
          }
          return true;
      }
      static addItem(itemId, itemCoUnt, reason, show = true, dropData = null, callback = null) {
          if (!itemId || !itemCoUnt)
              return;
          let itemDb = db.get_item_db_map()[itemId];
          if (!itemDb)
              return;
          if (reason != 21) {
              let itemGetMax = db.get_item_get_max_map()[itemId];
              if (itemGetMax && itemCoUnt >= itemGetMax.max_count) {
                  this.markPirate();
              }
          }
          switch (itemDb.type) {
              case 3:
                  {
                      if (show) {
                          dropData = dropData || [];
                      }
                      for (let i = 0; i < itemCoUnt; i++) {
                          Level.dropItemByDropId(itemDb.dropId, false, dropData);
                      }
                      if (show) {
                          Level.showItemGet(dropData);
                      }
                  }
                  break;
              case 4:
                  {
                      mgrTower.addTowerByItemId(itemId, itemCoUnt, reason);
                      if (show) {
                          let towerDb = mgrTower.findTowerDbByItemId(itemId);
                          if (towerDb) {
                              mgrTower.showTowerNew(towerDb.id, itemCoUnt);
                          }
                      }
                      if (dropData) {
                          dropData.push({ type: DROP_TYPE.ITEM, data: { itemId: itemId, count: itemCoUnt } });
                      }
                  }
                  break;
              case 6:
                  {
                      if (show) {
                          dropData = dropData || [];
                      }
                      if (itemCoUnt == 1) {
                          Level.dropCustomItemByDropId(itemId, itemDb.dropId, false, dropData, true, callback);
                      }
                      else {
                          for (let i = 0; i < itemCoUnt; i++) {
                              Level.dropCustomItemByDropId(itemId, itemDb.dropId, false, dropData, true);
                          }
                          if (callback)
                              callback();
                      }
                      if (show) {
                          Level.showItemGet(dropData);
                      }
                  }
                  break;
              default:
                  {
                      BaseFacade.mItem.addItem(itemId, itemCoUnt, reason);
                      if (show) {
                          let item = { itemId: itemId, count: itemCoUnt };
                          Director.openPanel("PanelItemGet", { items: [{ type: DROP_TYPE.ITEM, data: item }] });
                      }
                      if (dropData) {
                          dropData.push({ type: DROP_TYPE.ITEM, data: { itemId: itemId, count: itemCoUnt } });
                      }
                  }
                  break;
          }
          if (callback && itemDb.type != 6) {
              callback();
          }
      }
      static showMoneyGet(from, to, itemId, reward, real = false, reason = 21) {
          Director.openPanel("PanelMoney", { from: from, to: to, itemId: itemId, numAdd: reward, real: real, reason: reason });
      }
      static showEnergyGet(from, to, icon, msg) {
          Director.openPanel("PanelMoney", { from: from, to: to, icon: icon, msg: msg });
      }
      static getRewardByItemCount(rewardName, itemId, reason, bGive = true) {
          let countTime = BaseFacade.mItem.getItemCount(itemId);
          return this.getRewardByTime(rewardName, countTime, reason, bGive);
      }
      static getRewardByTime(rewardName, countTime, reason, bGive = true) {
          let shareReward = db.get_reward_db_map()[rewardName];
          if (!shareReward || countTime <= 0)
              return;
          let rewardDb = null;
          if (countTime >= 1 && countTime <= shareReward.length) {
              rewardDb = shareReward[countTime - 1];
          }
          else if (countTime > shareReward.length) {
              let item = shareReward[shareReward.length - 1];
              if (item && item.loop) {
                  rewardDb = item;
              }
          }
          if (!rewardDb) {
              return;
          }
          if (bGive) {
              let item_num = rewardDb.item_num;
              if (rewardDb.item_num_min && rewardDb.item_num_max) {
                  item_num = Utils.random(rewardDb.item_num_min, rewardDb.item_num_max);
              }
              this.rewardItem(rewardDb.item_id, item_num, reason);
          }
          return rewardDb;
      }
      static statisVideoShowByButton(obj, advName, updateButtonState = false) {
          CopHelper.updateAdvButtonState(obj, advName);
          if (obj.visible && obj.internalVisible) {
              this.statisVideoShow(advName);
              return true;
          }
          else {
              return false;
          }
      }
      static statisVideoShow(advName) {
          mgrAdv.statisVideoShow(advName);
      }
      static onADVideoSuccess(e) {
          this.countADVideoSuc += 0;
          // this.countADVideoSuc += 1;
          // if (!e["free"]) {
          //     if (db.cop_db.open_police && this.timeDispatchAdv) {
          //         let passTime = Timer.time - this.timeDispatchAdv;
          //         if (passTime <= 3) {
          //             Director.openPanelWithSingleton("PanelWarning");
          //         }
          //     }
          // }
      }
      static isADVideoFree() {
          return true;
          // if (db.cop_db.num_ad_video_free > 0) {
          //     let countADVideoSuc = this.countADVideoSuc;
          //     if (countADVideoSuc % db.cop_db.num_ad_video_free == 0) {
          //         return true;
          //     }
          // }
          // return false;
      }
      static dispatchAdv(advName, params = null, ignoreCheck = false, showLoading = false) {
          this.timeDispatchAdv = Timer.time;
          let data = { advName: advName, params: params };
          data["free"] = true;
          Advertisement.videop=this,
          Advertisement.videoAdverV(()=>{
              console.log("视频激励方法");
              Global.sendMsg(BASE_MSG.ADV_SHOW_SUC, data);
          });
          // if (this.isADVideoFree()) {
          //     Director.openPanelWithSingleton("PanelADFree", {
          //         funcEnsure: () => {
          //             let data = { advName: advName, params: params };
          //             data["free"] = true;
          //             Global.sendMsg(BASE_MSG.ADV_SHOW_SUC, data);
          //         },
          //     });
          // }
          // else {
          //     mgrAdv.dispatchAdv(advName, params, ignoreCheck, showLoading);
          //     if (GameGlobal.isDebug) {
          //         let data = { advName: advName, params: params };
          //         Global.sendMsg(BASE_MSG.ADV_SHOW_SUC, data);
          //     }
          // }
      }
      static shareVideo(userData = "", videoTag = "") {
          mgrSdk.shareVideo(userData, videoTag);
          if (GameGlobal.isDebug) {
              Global.sendMsg(BASE_MSG.SHARE_VIDEO_RESULT, {
                  msg: BASE_MSG.SHARE_VIDEO_RESULT,
                  userData: userData,
                  bSuccessful: true
              });
          }
      }
      static share(userData = "") {
          mgrSdk.share(userData);
          if (GameGlobal.isDebug) {
              Global.sendMsg(BASE_MSG.SDK_SHARE_SUC, {
                  msg: BASE_MSG.SHARE_VIDEO_RESULT,
                  userData: userData,
                  bSuccessful: true
              });
          }
      }
      static setDialogOpenTime(key, curtTime) {
          this.data.dialogOpenTime[key] = curtTime;
      }
      static getDialogOpenTime(key) {
          return this.data.dialogOpenTime[key] || 0;
      }
      static beginDialogCD(key, cd) {
          this.setDialogOpenTime(key, mgrTime.curtTime() + cd);
      }
      static isDialogCDing(key) {
          return this.getDialogOpenTime(key) > mgrTime.curtTime();
      }
      static rewardItem(id, reward, reason, from, to) {
          mgrGame.addItem(id, reward, reason, true);
      }
      static getItemName(itemId) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb) {
              return itemDb.name;
          }
          else {
              return "";
          }
      }
      static getItemIcon(itemId) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb) {
              return itemDb.icon;
          }
          else {
              return "";
          }
      }
      static getItemIconBig(itemId) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb) {
              return itemDb.bigIcon;
          }
          else {
              return "";
          }
      }
      static getItemType(itemId) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb) {
              return itemDb.type;
          }
          else {
              return -1;
          }
      }
      static isTryToPlayReward(index) {
          for (let i = 0; i < this.tryToPlayRewards.length; ++i) {
              if (this.tryToPlayRewards[i].index == index) {
                  if (this.tryToPlayRewards[i].isReward) {
                      return true;
                  }
                  else {
                      return false;
                  }
              }
          }
          return false;
      }
      static setTryToPlayRewards(index) {
          for (let i = 0; i < this.tryToPlayRewards.length; ++i) {
              if (this.tryToPlayRewards[i].index == index) {
                  if (this.tryToPlayRewards[i].isReward) {
                      this.tryToPlayRewards[i].isReward = true;
                      this.saveTryToPlayRewards();
                      return;
                  }
              }
          }
          this.tryToPlayRewards.push({ index: index, isReward: true });
          this.saveTryToPlayRewards();
      }
      static saveTryToPlayRewards() {
          FileRecord.setData("tryToPlayRewards", this.tryToPlayRewards);
      }
      static loadTryToPlayRewards() {
          this.tryToPlayRewards = FileRecord.getData("tryToPlayRewards") || [];
      }
      static set vibrateEnable(value) {
          this.data.bVibrate = value;
          this.saveRecord();
      }
      static get vibrateEnable() {
          return this.data.bVibrate;
      }
      static set dmgFontEnable(value) {
          this.data.bDamageFont = value;
          this.saveRecord();
      }
      static get dmgFontEnable() {
          return this.data.bDamageFont;
      }
      static set enableGameEffect(value) {
          this.data.bEffect = value;
          this.saveRecord();
      }
      static get enableGameEffect() {
          return this.data.bEffect;
      }
      static set towerTargetSearchType(value) {
          this.data.searchType = value;
          this.saveRecord();
      }
      static get towerTargetSearchType() {
          return this.data.searchType;
      }
      static set rushAutoNext(value) {
          this.data.bRushAutoNext = value;
          this.saveRecord();
      }
      static get rushAutoNext() {
          return this.data.bRushAutoNext;
      }
      static set rushFailNext(value) {
          this.data.bRushFailNext = value;
          this.saveRecord();
      }
      static get rushFailNext() {
          return this.data.bRushFailNext;
      }
      static set gameScaleNum(value) {
          this.data.bGameScaleNum = value;
          this.saveRecord();
      }
      static get gameScaleNum() {
          return this.data.bGameScaleNum;
      }
      static calcGameScaleNum() {
          if (this.levelId >= db.game_cnf.level_game_scale_3) {
              return 3;
          }
          else {
              return 2;
          }
      }
      static set videoRecordEnable(value) {
          this.data.bVideoRecord = value;
          this.saveRecord();
      }
      static get videoRecordEnable() {
          return this.data.bVideoRecord;
      }
      static get vNotice() {
          return this.data.versionNotice;
      }
      static set vNotice(version) {
          this.data.versionNotice = version;
          this.saveRecord();
      }
      static get countADVideoSuc() {
          return this.data.countADVideoSuc;
      }
      static set countADVideoSuc(v) {
          this.data.countADVideoSuc = v;
          this.saveRecord();
      }
      static get boxRewardTime() {
          return this.data.boxRewardTime;
      }
      static set boxRewardTime(v) {
          this.data.boxRewardTime = v;
      }
      static get boxRewardId() {
          return this.data.boxRewardId;
      }
      static set boxRewardId(v) {
          this.data.boxRewardId = v;
          this.saveRecord();
      }
      static get icebreak() {
          return this.data.icebreak;
      }
      static set icebreak(v) {
          this.data.icebreak = v;
          this.saveRecord();
      }
      static get timeUploadRecord() {
          return this.data.timeUploadRecord;
      }
      static set timeUploadRecord(v) {
          this.data.timeUploadRecord = v;
          this.saveRecord();
      }
      static showIceBreakUI() {
          if (!this.icebreak && mgrTower.getMainTowerLv() >= db.game_cnf.icebreak_tower_lv) {
              Director.openPanelWithSingleton("PanelIceBreak");
          }
      }
      static showFirstLoginUI(guideEnd = false) {
          if (Global.isGuiding)
              return;
          if (!mgrKV.getKV("FIRST_LOGIN", 0)) {
              mgrKV.setKV("FIRST_LOGIN", 1);
              this.onFirstLogin(guideEnd);
          }
      }
      static showRushFailUI() {
          if (Global.isGuiding)
              return;
          if (mgrTower.getMainTowerLv() > db.game_cnf.grow_newbie_level)
              return;
          if (this.loginDay > db.game_cnf.grow_alert_day)
              return;
          if (!this.isDialogCDing("PanelGrow")) {
              this.beginDialogCD("PanelGrow", db.game_cnf.grow_alert_cd * 3600);
              Director.openPanelWithSingleton("PanelGrowPop");
          }
      }
      static onFirstLogin(guideEnd = false) {
          if (guideEnd)
              CopHelper.showDialog("PanelBoxReward");
          if (mgrNative.isHtml5Platform()) {
              Director.openPanelWithSingleton("PanelNotice");
          }
          if (mgrSign.isNextDayRewardValid()) {
              CopHelper.showDialog("PanelNextDayReward");
          }
      }
      static getIceBreakReward(towerId) {
          let towerDb = db.get_tower_db(towerId);
          if (!this.icebreak && towerDb) {
              let dropData = [];
              mgrTower.addTower(towerDb, 59, false, dropData);
              Level.showItemGet(dropData);
              this.icebreak = true;
          }
      }
      static getBoxRewardDb() {
          return db.get_newbee_box_reward_map()[this.boxRewardId];
      }
      static tryGetBoxReward() {
          let rewardDb = this.getBoxRewardDb();
          if (rewardDb) {
              if (this.boxRewardTime >= rewardDb.time * 60) {
                  this.boxRewardTime = 0;
                  this.boxRewardId += 1;
                  mgrGame.addItem(rewardDb.item_id, rewardDb.item_num, 58);
                  return true;
              }
          }
          return false;
      }
      static vibrate() {
          if (this.vibrateEnable)
              mgrSdk.vibrate();
      }
      static onFpsTimerLoop() {
          this.fpsCount++;
          let now = Laya.Browser.now();
          if (now - this.fpsLastTime < 1000) {
              return;
          }
          this.fps = Math.round((this.fpsCount * 1000) / (now - this.fpsLastTime));
          console.log("fps", this.fps);
          this.fpsCount = 0;
          this.fpsLastTime = now;
      }
      static saveStageConfig() {
          FileRecord.setData("game166.stageconfig", StageConfig);
          console.log("保存StageConfig");
      }
      static loadStageConfig() {
          let config = FileRecord.getData("game166.stageconfig");
          if (config) {
              for (let k in config) {
                  StageConfig[k] = config[k];
              }
          }
      }
      static clearStageConfig() {
          FileRecord.setData("game166.stageconfig", null);
          console.log("清理StageConfig");
      }
      static getLevelStoryAward(index) {
          return this.data.levelStoryAward[index] || 0;
      }
      static setLevelStoryAward(index, count) {
          if (index > this.data.levelStoryStep) {
              this.data.levelStoryStep = index;
          }
          this.data.levelStoryAward[index] = count;
          this.saveRecord();
      }
      static addLevelStoryAward(index, add = 1) {
          this.setLevelStoryAward(index, this.getLevelStoryAward(index) + add);
      }
      static getLevelStoryStep() {
          return this.data.levelStoryStep;
      }
      static getUnlockStepByGetWayId(id) {
          let wayDb = db.get_grow_item_getway(id);
          if (wayDb) {
              return wayDb.unlock_index;
          }
          else {
              return 0;
          }
      }
      static isUnlockByGetWayId(id, showTip = false) {
          let step = this.getUnlockStepByGetWayId(id);
          let unlock = this.getLevelStoryStep() >= step;
          if (showTip && !unlock) {
              this.calcNextUnlockInfo();
          }
          return unlock;
      }
      static isFBUnlock(showTip = false) {
          return this.isUnlockByGetWayId("15", showTip);
      }
      static isSecretUnlock(showTip = false) {
          return this.isUnlockByGetWayId("10", showTip);
      }
      static isFinalWarUnlock(showTip = false) {
          return this.isUnlockByGetWayId("13", showTip);
      }
      static isSmelterUnlock(showTip = false) {
          return this.isUnlockByGetWayId("17", showTip);
      }
      static isDailyDamageUnlock(showTip = false) {
          return this.isUnlockByGetWayId("16", showTip);
      }
      static isAllEquipUnlock(showTip = false) {
          return this.isUnlockByGetWayId("18", showTip);
      }
      static isExploreUnlock(showTip = false) {
          return this.isUnlockByGetWayId("12", showTip);
      }
      static findStoryDbByIndex(index) {
          let map = db.get_main_story_level_map();
          for (let k in map) {
              let arr = map[k];
              for (let cfg of arr) {
                  if (cfg.index == index) {
                      return cfg;
                  }
              }
          }
      }
      static calcNextUnlockInfo() {
          let step = this.getLevelStoryStep();
          let mapData = db.get_grow_item_getway_map();
          let nextStep = Number.MAX_VALUE;
          for (let k in mapData) {
              let wayDb = mapData[k];
              let index = wayDb.unlock_index;
              if (!wayDb.not_show_unlock && index && index > step) {
                  if (index < nextStep) {
                      nextStep = index;
                  }
              }
          }
          Director.openPanelWithSingleton("PanelIntroUnlock", { unlock: false, step: nextStep });
      }
      static calcStepUnlockInfo(step) {
          let mapData = db.get_grow_item_getway_map();
          let listData = [];
          for (let k in mapData) {
              let wayDb = mapData[k];
              if (!wayDb.not_show_unlock && wayDb.unlock_index && wayDb.unlock_index == step) {
                  listData.push(wayDb);
              }
          }
          return listData;
      }
      static showUnlockInfo() {
          if (Global.isGuiding)
              return false;
          let step = this.getLevelStoryStep();
          let infos = this.calcStepUnlockInfo(step);
          if (infos.length) {
              Director.openPanelWithSingleton("PanelIntroUnlock", { unlock: true, step: step });
              return true;
          }
          return false;
      }
      static sortGetWayDb(a, b) {
          return a.unlock_index - b.unlock_index;
      }
      static getEnemyCoin() {
          let value = Formula.enemyCoin(this.levelId);
          if (mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1)) {
              value *= 2;
          }
          return value;
      }
      static getEnemyCoinByLevel(level) {
          let value = Formula.enemyCoin(level);
          if (mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1)) {
              value *= 2;
          }
          return value;
      }
      static getMainStoryDesc() {
          let step = mgrGame.getLevelStoryStep() + 1;
          let desc = "敬请期待";
          let dataMap = db.get_main_story_map_map();
          for (let k in dataMap) {
              let map = dataMap[k];
              let listStep = db.get_main_story_level_map()[map.id];
              for (let level of listStep) {
                  if (level.index == step) {
                      desc = map.id + "-" + level.lv;
                      break;
                  }
              }
          }
          return desc;
      }
      static isIntroShow(panel) {
          return this.data.introShow[panel];
      }
      static markIntroShow(panel) {
          this.data.introShow[panel] = true;
          this.saveRecord();
      }
      static tryOpenPanelIntro(panel, msg = "") {
          if (!this.isIntroShow(panel)) {
              if (CopHelper.showDialog(panel, { msg: msg })) {
                  this.markIntroShow(panel);
                  return true;
              }
              else if (msg) {
                  Global.sendMsg(MSG.GUIDE_MSG_TRIGGER, msg);
              }
          }
          return false;
      }
      static tryOpenPanelIntroNoCOP(panel, msg = "") {
          if (!this.isIntroShow(panel)) {
              Director.openPanelWithSingleton(panel, { msg: msg });
              this.markIntroShow(panel);
              return true;
          }
          return false;
      }
      static openPirateUI() {
          if (db.cop_db.open_police) {
              Director.openPanelWithSingleton("PanelPirate");
          }
      }
      static markPirate() {
          if (!db.cop_db.open_police)
              return;
          this.data.flagPirate = true;
          if (this.timePirateWait <= 0) {
              this.timePirateWait = Utils.random(15, 60);
          }
          this.saveRecord();
      }
      static get isPirate() {
          if (!db.cop_db.open_police)
              return false;
          return this.data.flagPirate || this.warnCount >= 3;
      }
      static updatePirate() {
          if (db.cop_db.open_police && this.isPirate) {
              if (this.timePirateWait > 0) {
                  this.timePirateWait--;
                  if (this.timePirateWait <= 0) {
                      this.openPirateUI();
                  }
              }
          }
      }
      static set warnCount(value) {
          this.data.warnCount = value;
          this.saveRecord();
      }
      static get warnCount() {
          return this.data.warnCount;
      }
      static set loginDay(value) {
          this.data.loginDay = value;
          this.saveRecord();
      }
      static get loginDay() {
          return this.data.loginDay;
      }
      static get autoSummonCard() {
          return this.data.autoSummonCard;
      }
      static set autoSummonCard(v) {
          this.data.autoSummonCard = v;
          this.saveRecord();
      }
  }
  mgrGame.RECORD_KEY = "game166_data_v1.0";
  mgrGame.fps = 0;
  mgrGame.fpsCount = 0;
  mgrGame.fpsLastTime = 0;
  mgrGame.bLockLevel = false;
  mgrGame.LASTEST_VERSION = 2;
  mgrGame.dataDefault = {
      mapId: "1",
      mapLv: {},
      dialogOpenTime: {},
      bVibrate: true,
      bVideoRecord: true,
      levelStoryStep: 0,
      levelStoryAward: {},
      levelChallengeAward: {},
      introShow: {},
      bDamageFont: true,
      bEffect: true,
      bRushAutoNext: true,
      bGameScaleNum: 1,
      bRushFailNext: false,
      searchType: TOWER_TARGET_SEARCH_TYPE.NEAREST_LOCK,
      versionNotice: 0,
      countADVideoSuc: 0,
      flagPirate: false,
      warnCount: 0,
      boxRewardTime: 0,
      boxRewardId: 0,
      icebreak: false,
      timeUploadRecord: 0,
      loginDay: 0,
      autoSummonCard: false,
  };
  mgrGame.isWhiteUser = false;
  mgrGame.ui_item_coin_num = null;
  mgrGame.ui_item_diamond_num = null;
  mgrGame.timeDispatchAdv = 0;
  mgrGame.tryToPlayRewards = [];
  mgrGame.timePirateWait = 0;

  class CustomAEPrice extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://alltower_equip/CustomAEPrice";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_cur: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_enough: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemId, need) {
          if (itemId && need) {
              let curt = mgrGame.getItemCount(itemId);
              this.label_cur.text = curt.toString();
              this.label_max.text = "/" + need;
              this.loader_icon.url = mgrGame.getItemIcon(itemId);
              this.ctrl_enough.selectedIndex = curt >= need ? 0 : 1;
          }
      }
  }

  class mgrNetwork extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [BASE_MSG.SDK_CHECK_NETWORK_RESULT]: this.onMsgSdkCheckNetworkResult.bind(this),
          });
      }
      static onMsgSdkCheckNetworkResult(data) {
          if (data.code == 1) {
              if (this.funcWaitToCall) {
                  this.funcWaitToCall();
                  FileRecord.sendCloudRecord(null, true);
              }
          }
          else {
              if (this.funcWaitToCall) {
                  this.showNetworkError();
              }
          }
          this.cancelCall();
      }
      static isBusying() {
          return this.funcWaitToCall != null;
      }
      static cancelCall() {
          Laya.timer.clear(this, this.onCallByNetworkTimeOut);
          Director.hideWait();
          this.funcWaitToCall = null;
      }
      static callByNetwork(func) {
          if (!db.cop_db.network_check_point || Global.isGuiding) {
              if (func)
                  func();
              return;
          }
          let curtTime = Timer.time;
          if (this.checkTimeOut(curtTime)) {
              this.cancelCall();
          }
          if (this.isBusying())
              return false;
          this.funcWaitToCall = func;
          this.timeWaitToCall = curtTime + this.TIME_OUT_4_CALL;
          Laya.timer.clear(this, this.onCallByNetworkTimeOut);
          Laya.timer.once(this.TIME_OUT_4_CALL * 1000, this, this.onCallByNetworkTimeOut);
          Director.showWait();
          mgrSdk.checkNetwork();
          return true;
      }
      static onCallByNetworkTimeOut() {
          if (this.funcWaitToCall) {
              this.showNetworkError();
              this.cancelCall();
          }
      }
      static checkTimeOut(curtTime) {
          if (this.timeWaitToCall)
              return curtTime >= this.timeWaitToCall;
          else
              return true;
      }
      static showNetworkError() {
          GameStatistics.statisCommonEvent(1100);
          Director.openPanelWithSingleton("PanelDialogTip", { title: "提示", desc: "请确保网络连接正常，稍后重试！", confirmText: "确定" });
      }
  }
  mgrNetwork.funcWaitToCall = null;
  mgrNetwork.timeWaitToCall = 0;
  mgrNetwork.TIME_OUT_4_CALL = 5;

  class CustomAEWordItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://alltower_equip/CustomAEWordItem";
          this.exportNodeNames = {
              cc_label_flag: "fgui.GBasicTextField",
              cc_label_word: "fgui.GBasicTextField",
              cc_button_lock: "fgui.GButton",
              cc_ctrl_lock: "fgui.Controller",
              cc_ctrl_quality: "fgui.Controller",
              cc_button_active: "fgui.GButton",
              cc_label_unlock: "fgui.GBasicTextField",
              cc_label_active_price: "fgui.GBasicTextField",
              cc_loader_active_price: "fgui.GLoader",
              cc_ctrl_word_state: "fgui.Controller",
              cc_ctrl_active: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(id, attr, data) {
          this.equipId = id;
          this.wordAttr = attr;
          this.wordData = data;
          if (data) {
              if (data.eq < this.ctrl_quality.pageCount)
                  this.ctrl_quality.selectedIndex = data.eq;
              this.ctrl_word_state.selectedIndex = 2;
              let wordDb = db.get_all_equip_word(data.id - 1);
              if (wordDb) {
                  let v = (wordDb[data.eq] || 0) * wordDb.u_factor;
                  this.label_word.text = wordDb.name + " +" + v + wordDb.u_unit;
              }
              this.button_lock.selected = data.lk ? true : false;
          }
          else {
              let condition = attr.condition_finalwar;
              let id = condition[0];
              let lv = condition[1];
              if (id && lv) {
                  let maxLv = mgrFinalWar.getFinalWarMaxLv(id);
                  if (maxLv >= lv) {
                      this.ctrl_word_state.selectedIndex = 1;
                  }
                  else {
                      this.ctrl_word_state.selectedIndex = 0;
                  }
                  let finalWarDb = db.get_finalwar_db(id - 1);
                  if (finalWarDb) {
                      this.label_unlock.text = "通关" + finalWarDb.name + lv + "解锁";
                  }
                  this.loader_active_price.url = mgrGame.getItemIcon(attr.ulock_item_id);
                  this.label_active_price.text = attr.ulock_item_num.toString();
              }
              else {
                  this.ctrl_word_state.selectedIndex = 0;
              }
          }
      }
      on_click_button_lock() {
          if (this.wordData) {
              this.wordData.lk = this.button_lock.selected;
              mgrAllEquip.saveRecord();
              Global.sendMsg(MSG.AE_EQUIP_WORD_LOCK);
          }
      }
      on_click_button_active() {
          if (this.wordAttr && !this.wordData) {
              mgrNetwork.callByNetwork(() => {
                  mgrAllEquip.wordActive(this.equipId, this.wordAttr);
              });
          }
      }
  }

  class CustomTowerEquipItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://alltower_equip/CustomTowerEquipItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_item_state: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          if (data.open) {
              this.label_name.text = data.name;
              this.loader_icon.url = data.icon;
              if (mgrAllEquip.idActive == data.id) {
                  this.item_state.selectedIndex = 3;
              }
              else {
                  this.item_state.selectedIndex = mgrAllEquip.getEquipLv(data.id) > 0 ? 2 : 1;
              }
          }
          else {
              this.item_state.selectedIndex = 0;
          }
      }
      set select(b) {
      }
  }

  class PanelAllEquipInfo extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "熔岩武具详情";
          this.sourceName = "ui://alltower_equip/PanelAllEquipInfo";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bMask = false;
          this.needWashEffect = {};
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_com_base: "fgui.GComponent",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_name: "fgui.GBasicTextField",
              cc_loader_icon: "fgui.GLoader",
              cc_node_effect: "fgui.GLoader",
              cc_com_info: "fgui.GComponent",
              cc_label_success: "fgui.GBasicTextField",
              cc_label_level: "fgui.GBasicTextField",
              cc_button_use: "fgui.GButton",
              cc_button_wash: "fgui.GButton",
              cc_button_lvup: "fgui.GButton",
              cc_list_word: "fgui.GList",
              cc_ctrl_level_max: "fgui.Controller",
              cc_com_unlock: "fgui.GComponent",
              cc_button_unlock: "fgui.GButton",
              cc_unlock_price_1: "CustomAEPrice",
              cc_unlock_price_2: "CustomAEPrice",
              cc_item_bar: "CustomBarItem",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.aequipDb = this.context;
          this.item_bar.setItemId(1016);
          this.initEvent();
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.closeAction);
          this.listWord = new ListView(this.list_word, this, this.parseWordItem, this.renderWordItem);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onAwake() {
          this.createScene3DEffect(99);
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.AE_EQUIP_WORD_ACTIVE]: this.onEquipWordActive.bind(this),
              [MSG.AE_EQUIP_LVUP_SUCC]: this.onEquipLvupSucc.bind(this),
              [MSG.AE_EQUIP_LVUP_FAIL]: this.onEquipLvupFail.bind(this),
              [MSG.AE_EQUIP_WORD_LOCK]: this.onEquipWordLock.bind(this),
              [MSG.AE_EQUIP_WASH_SUCC]: this.onEquipWashSucc.bind(this),
          });
      }
      onEquipWordActive() {
          this.listWord.refresh();
      }
      onEquipLvupSucc() {
          this.createEffectLvup();
          this.refreshLevelInfo();
      }
      onEquipLvupFail() {
          this.refreshLevelInfo();
      }
      onEquipWordLock() {
          this.refreshWashInfo();
      }
      onEquipWashSucc() {
          if (!this.aequipDb)
              return;
          let listData = this.listWord.getListData();
          for (let data of listData) {
              let word = mgrAllEquip.getEquipAttrWord(this.aequipDb.id, data.id - 1);
              if (word && !word.lk) {
                  this.needWashEffect[data.id] = true;
              }
          }
          this.listWord.refresh();
      }
      createEffectLvup() {
          let scene3d = this.scene3DEffect;
          let camera = this.cameraEffect;
          if (scene3d && camera) {
              let effectId = "166_ui_bk_qh_02";
              let effect = EffectFactory.create(effectId, scene3d);
              effect.followFguiNode(camera, this.node_effect, true);
          }
      }
      createEffectWordWash(node) {
          let scene3d = this.scene3DEffect;
          let camera = this.cameraEffect;
          if (scene3d && camera) {
              let effectId = "166_ui_xilian_glow";
              let effect = EffectFactory.create(effectId, scene3d);
              effect.followFguiNode(camera, node, true, node.width / 2, node.height / 2);
          }
      }
      parseWordItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.25, 0.05);
      }
      renderWordItem(content, data) {
          content.data = data;
          let word = mgrAllEquip.getEquipAttrWord(this.aequipDb.id, data.id - 1);
          content.view.refresh(this.aequipDb.id, data, word);
          if (this.needWashEffect[data.id]) {
              this.needWashEffect[data.id] = false;
              this.createEffectWordWash(content.view);
          }
      }
      refreshListWord() {
          let list = db.get_all_equip_attr_map();
          this.listWord.setListData(list);
      }
      refreshLevelInfo() {
          let aequipDb = this.aequipDb;
          if (aequipDb) {
              let id = aequipDb.id;
              let level = mgrAllEquip.getEquipLv(id);
              let lvShow = level - 1;
              if (lvShow) {
                  this.label_level.text = "+" + lvShow;
              }
              else {
                  this.label_level.text = "";
              }
              this.label_desc.text = Utils.sprintfOrder(aequipDb.desc, aequipDb.desc_order, mgrAllEquip.getEquipValueUI(id, 0), mgrAllEquip.getEquipValueUI(id, 1), mgrAllEquip.getEquipValueUI(id, 2));
              let lvupDbCurt = db.get_all_equip_level_map()[level - 1];
              let lvupDbNext = db.get_all_equip_level_map()[level];
              if (lvupDbCurt && lvupDbNext) {
                  this.button_lvup.icon = mgrGame.getItemIcon(lvupDbCurt.item_id);
                  this.button_lvup.title = lvupDbCurt.item_num.toString();
                  this.label_success.text = mgrAllEquip.getLvupProb(id, lvupDbCurt) + "%";
                  this.ctrl_level_max.selectedIndex = 0;
              }
              else {
                  this.ctrl_level_max.selectedIndex = 1;
              }
          }
      }
      refreshWashInfo() {
          let aequipDb = this.aequipDb;
          if (aequipDb) {
              let count = mgrAllEquip.getWordLockCount(aequipDb.id);
              let washDb = db.get_all_equip_wash(count);
              if (washDb) {
                  this.button_wash.icon = mgrGame.getItemIcon(washDb.item_id);
                  this.button_wash.title = washDb.item_num.toString();
              }
          }
      }
      refresh() {
          let aequipDb = this.aequipDb;
          if (aequipDb) {
              this.label_name.text = aequipDb.name;
              this.loader_icon.url = aequipDb.icon;
              if (mgrAllEquip.isEquipUnlock(aequipDb.id)) {
                  this.ctrl_page.selectedIndex = 2;
                  this.refreshListWord();
                  this.refreshLevelInfo();
                  this.refreshWashInfo();
              }
              else {
                  this.label_desc.text = aequipDb.desc_lock;
                  this.ctrl_page.selectedIndex = 1;
                  let itemId1 = aequipDb.unlock_items[0];
                  let itemNm1 = aequipDb.unlock_items[1] || 0;
                  this.button_unlock.icon = mgrGame.getItemIcon(itemId1);
                  this.button_unlock.title = itemNm1 + " 解锁";
                  this.unlock_price_1.refresh(aequipDb.unlock_items[2], aequipDb.unlock_items[3]);
                  this.unlock_price_2.refresh(aequipDb.unlock_items[4], aequipDb.unlock_items[5]);
              }
          }
      }
      closeAction() {
          if (this.ctrl_page.selectedIndex == 1) {
              this.closeWithTransition("out_unlock");
          }
          else {
              this.closeWithTransition("out_detail");
          }
      }
      on_click_button_use() {
          let aequipDb = this.aequipDb;
          if (aequipDb) {
              mgrAllEquip.activeEquip(aequipDb);
              this.closeAction();
          }
      }
      on_click_button_wash() {
          let aequipDb = this.aequipDb;
          if (aequipDb) {
              let count = mgrAllEquip.getWordUnlockCount(aequipDb.id);
              if (count <= 0) {
                  mgrTip.showMsgTip("无可洗炼词条，请解锁后重试");
                  return;
              }
              mgrNetwork.callByNetwork(() => {
                  mgrAllEquip.washEquip(aequipDb);
              });
          }
      }
      on_click_button_lvup() {
          let aequipDb = this.aequipDb;
          if (aequipDb) {
              mgrNetwork.callByNetwork(() => {
                  mgrAllEquip.lvupEquip(aequipDb);
              });
          }
      }
      on_click_button_unlock() {
          if (this.aequipDb) {
              let id = this.aequipDb.id;
              if (!mgrAllEquip.isEquipUnlock(id)) {
                  mgrNetwork.callByNetwork(() => {
                      if (mgrAllEquip.unlockEquip(this.aequipDb)) {
                          this.refresh();
                      }
                  });
              }
          }
      }
  }

  class PanelAllTowerEquip extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "熔岩武具";
          this.sourceName = "ui://alltower_equip/PanelAllTowerEquip";
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_equip: "fgui.GList",
          };
      }
      buildUi() {
          this.listView = new ListView(this.list_equip, this, this.parseEquipItem, this.renderEquipItem);
          this.listView.setOnClickItem(this, this.onClickEquipItem);
          this.refreshList();
          this.initEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.AE_EQUIP_UNLOCK]: this.onAEEquipUnlock.bind(this),
              [MSG.AE_EQUIP_ACTIVE]: this.onAEEquipActive.bind(this),
          });
      }
      onAEEquipUnlock() {
          this.listView.refresh();
      }
      onAEEquipActive() {
          this.listView.refresh();
      }
      parseEquipItem(content, view, index) {
          content.view = view;
          if (index < 3) {
              FguiHelper.playIdleAndIn(view, index, 0.2, 0.05);
          }
          else if (index < 6) {
              FguiHelper.playIdleAndIn(view, index - 3, 0.3, 0.05);
          }
          else {
              FguiHelper.playIdleAndIn(view, index - 6, 0.4, 0.05);
          }
      }
      renderEquipItem(content, data) {
          content.data = data;
          content.view.refresh(data);
          content.view.select = (data.id == mgrAllEquip.idActive);
      }
      onClickEquipItem(content) {
          if (content.data.open) {
              Director.openPanelWithSingleton("PanelAllEquipInfo", content.data);
          }
      }
      refreshList() {
          let dataMap = db.get_all_tower_equip_map();
          let listData = [];
          for (let k in dataMap) {
              listData.push(dataMap[k]);
          }
          listData.sort(this.sortAllTowerEquip);
          this.listView.setListData(listData);
      }
      sortAllTowerEquip(a, b) {
          return a.index - b.index;
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class CustomCommItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomCommItem";
          this.exportNodeNames = {
              cc_normal: "CustomItem",
              cc_holyitem: "CustomHolyItem",
              cc_ctrl_item: "fgui.Controller",
              cc_trans_in: "fgui.Transition",
              cc_trans_in02: "fgui.Transition",
              cc_trans_idle: "fgui.Transition",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(dropData) {
          let data = dropData.data;
          if (data instanceof HolyItem) {
              this.ctrl_item.setSelectedIndex(1);
              this.holyitem.refresh(data);
          }
          else if (data) {
              this.ctrl_item.setSelectedIndex(2);
              this.normal.refresh(data);
          }
      }
      refreshItemInfo(data) {
          this.ctrl_item.setSelectedIndex(2);
          this.normal.refresh(data);
      }
      playTransIn(delay = 0, handler = null) {
          this.trans_idle.play();
          this.trans_in.play(handler, null, delay);
      }
  }

  class CustomItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomItem";
          this.itemCount = 0;
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_amount: "fgui.GBasicTextField",
              cc_label_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickItem);
      }
      dispose() {
          super.dispose();
      }
      setOnClickCallback(callback) {
          this.funcOnClick = callback;
      }
      onClickItem() {
          if (this.funcOnClick) {
              if (this.funcOnClick()) {
                  return;
              }
          }
          if (this.itemDb) {
              Director.openPanelWithSingleton("PanelItemInfo", { itemDb: this.itemDb, count: this.itemCount, point: this.localToGlobal(this.width * 0.5, this.height * 0.5) });
          }
      }
      refresh(item) {
          if (item.itemId) {
              this.refreshById(item.itemId, item.count);
          }
          else {
              this.itemDb = null;
              this.loader_icon.url = item.icon;
              let count = item.count;
              if (count <= 0) {
                  this.label_amount.visible = false;
              }
              else {
                  this.label_amount.visible = true;
              }
              this.label_amount.text = "x" + count;
              if (item.quality < this.ctrl_quality.pageCount)
                  this.ctrl_quality.selectedIndex = item.quality || 0;
          }
      }
      refreshById(itemId, count = 1, showZero = false) {
          let itemDb = db.get_item_db(itemId);
          if (itemDb) {
              this.loader_icon.url = null;
              this.loader_icon.url = itemDb.icon;
              if (itemDb.icon) {
                  this.label_name.visible = false;
              }
              else {
                  this.label_name.visible = true;
                  this.label_name.text = itemDb.name;
              }
              if (itemDb.name_icon) {
                  this.label_name.visible = true;
                  this.label_name.text = itemDb.name_icon;
                  this.label_amount.visible = false;
              }
              else {
                  if (!showZero && count <= 0) {
                      this.label_amount.visible = false;
                  }
                  else {
                      this.label_amount.visible = true;
                  }
                  this.label_amount.text = "x" + count;
              }
              if (itemDb.quality < this.ctrl_quality.pageCount)
                  this.ctrl_quality.selectedIndex = itemDb.quality;
          }
          this.itemDb = itemDb;
          this.itemCount = count;
      }
  }

  class CustomSkillDetail extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomSkillDetail";
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_skill_normal: "fgui.GButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_desc_sub: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_list_word: "fgui.GList",
          };
      }
      onCreate() {
          this.listWord = new ListView(this.list_word, this, this.parseWordItem, this.renderWordItem);
          this.loader_bg.onClick(this, this.onClickSkillDetail);
      }
      dispose() {
          super.dispose();
      }
      parseWordItem(content, object) {
          content.name = object.getChild("name").asTextField;
          content.desc = object.getChild("desc").asTextField;
      }
      renderWordItem(content, data) {
          let arr = data.split("-");
          content.name.text = arr[0] || "";
          content.desc.text = arr[1] || "";
      }
      refresh(skillId) {
          let skillDb = db.get_skill_db(skillId);
          if (skillDb) {
              this.label_name.text = skillDb.name;
              this.label_desc.text = skillDb.desc;
              this.label_desc_sub.text = skillDb.desc_mini;
              this.listWord.setListData(skillDb.words);
              this.skill_normal.icon = skillDb.icon;
          }
      }
      onClickSkillDetail() {
          Global.sendMsg(MSG.SHOW_TOWER_SKILL_DETAIL);
      }
      on_click_skill_normal() {
      }
  }

  class CustomGuideDialogLeft extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomGuideDialogLeft";
          this.curtStep = 0;
          this.maxxStep = 0;
          this.strDialog = "";
          this.exportNodeNames = {
              cc_loader_role: "fgui.GLoader",
              cc_loader_bg: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_dialog: "fgui.GBasicTextField",
          };
      }
      onCreate() {
          this.initTimer();
          this.label_dialog.text = "";
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(100, this, this.onUpdateTimer);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdateTimer);
      }
      onUpdateTimer() {
          if (this.curtStep <= this.maxxStep) {
              this.showDialog(this.strDialog.substring(0, this.curtStep));
              this.curtStep++;
          }
      }
      show(name, dialog, role, now = false, flip = 1) {
          this.label_name.text = name;
          this.loader_role.url = role;
          this.loader_bg.url = "res/guide/guide_dialog_bg.png";
          this.strDialog = dialog;
          flip = flip || 1;
          this.loader_role.scaleX = flip * Math.abs(this.loader_role.scaleX);
          if (now) {
              this.showNow();
          }
          else {
              this.curtStep = 0;
              this.maxxStep = dialog.length;
          }
      }
      isShowing() {
          return this.curtStep < this.maxxStep;
      }
      showNow() {
          this.curtStep = this.maxxStep;
          this.showDialog(this.strDialog);
      }
      showDialog(dialog) {
          this.label_dialog.text = dialog;
      }
  }

  class CustomGuideDialogRight extends CustomGuideDialogLeft {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomGuideDialogRight";
          this.exportNodeNames = {
              cc_loader_role: "fgui.GLoader",
              cc_loader_bg: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_dialog: "fgui.GBasicTextField",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomAttrHolyItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomAttrHolyItem";
          this.exportNodeNames = {
              cc_list_attr: "fgui.GList",
          };
      }
      onCreate() {
          this.listAttr = new ListView(this.list_attr, this, this.parseAttrItem, this.renderAttrItem);
      }
      dispose() {
          super.dispose();
      }
      parseAttrItem(content, object) {
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          let perfect = object.getChild("perfect");
          if (perfect) {
              content.perfect = perfect.asTextField;
          }
          content.quality = object.getController("quality");
      }
      renderAttrItem(content, data) {
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
              let v = data.v.toFixed(1);
              let attrDb = db.get_holy_item_attr_base_map()[data.k];
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.value.text = "+" + v + "%";
                  }
                  else {
                      content.value.text = "+" + v;
                  }
              }
              else {
                  content.value.text = "+" + v + "%";
              }
              content.quality.selectedIndex = data.q || 0;
          }
          if (content.perfect) {
              let wordDb = mgrSmelter.findWordDb(data.k);
              if (wordDb) {
                  let values = wordDb["v" + (data.q + 1)] || [];
                  let max = values[1] || 0;
                  content.perfect.text = "(" + Math.floor(data.v_base / max * 100) + "%)";
              }
          }
      }
      refresh(attr) {
          this.listAttr.setListData(attr);
      }
  }

  class CustomAttrHolyItem2 extends CustomAttrHolyItem {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomAttrHolyItem2";
          this.exportNodeNames = {
              cc_list_attr: "fgui.GList",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomAttrHolyItem3 extends CustomAttrHolyItem {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomAttrHolyItem3";
          this.exportNodeNames = {
              cc_list_attr: "fgui.GList",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomHolyItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHolyItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_loader_head: "fgui.GLoader",
              cc_label_level: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_level: "fgui.Controller",
              cc_ctrl_preset: "fgui.Controller",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickItem);
      }
      dispose() {
          super.dispose();
      }
      onClickItem() {
          if (this.selectData) {
              Director.openPanelWithSingleton("PanelHolyitemInfo", { item: this.selectData, point: this.localToGlobal(this.width * 0.5, this.height * 0.5) });
          }
      }
      refresh(data, showHead = true) {
          this.selectData = data;
          this.label_level.text = "+" + data.level;
          this.loader_icon.url = data.getIcon();
          if (data.data) {
              this.ctrl_quality.selectedIndex = data.data.quality;
              if (data.data.lv >= 1) {
                  this.ctrl_level.selectedIndex = 1;
              }
              else {
                  this.ctrl_level.selectedIndex = 0;
              }
          }
          if (showHead && data.isEquiped()) {
              this.loader_head.url = data.getHead();
              this.loader_head.visible = true;
          }
          else {
              this.loader_head.visible = false;
          }
          this.ctrl_preset.selectedIndex = data.isPreset() ? 1 : 0;
      }
  }

  class CustomHolyItemDesc extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHolyItemDesc";
          this.exportNodeNames = {
              cc_list_word_desc: "fgui.GList",
          };
      }
      onCreate() {
          this.listDesc = new ListView(this.list_word_desc, this, this.parseWordItem, this.renderWordItem);
      }
      dispose() {
          super.dispose();
      }
      refresh(holyItem) {
          let listData = holyItem.getDescList();
          this.listDesc.setListData(listData);
      }
      parseWordItem(content, view) {
          content.view = view;
      }
      renderWordItem(content, data) {
          content.data = data;
          content.view.refresh(data.key, data.desc);
      }
  }

  class CustomHolyitemDescItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHolyitemDescItem";
          this.exportNodeNames = {
              cc_label_word_desc: "fgui.GBasicTextField",
              cc_label_word_key: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(key, desc) {
          switch (key) {
              case 0:
                  this.label_word_key.text = "";
                  this.label_word_desc.text = desc;
                  break;
              case 1:
                  this.label_word_key.text = "【主】";
                  this.label_word_desc.text = "        " + desc;
                  break;
              case 2:
                  this.label_word_key.text = "【副】";
                  this.label_word_desc.text = "        " + desc;
                  break;
          }
      }
  }

  class CustomHolyItemInfoBag extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHolyItemInfoBag";
          this.exportNodeNames = {
              cc_loader_tower_head: "fgui.GLoader",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_label_item_level: "fgui.GBasicTextField",
              cc_com_item: "CustomHolyItem",
              cc_label_item_desc: "CustomHolyItemDesc",
              cc_com_attr: "CustomAttrHolyItem3",
              cc_button_lock: "fgui.GButton",
              cc_button_item_lvup: "fgui.GButton",
              cc_button_item_sell: "fgui.GButton",
              cc_ctrl_equip_by_tower: "fgui.Controller",
              cc_ctrl_title_quality: "fgui.Controller",
          };
      }
      onCreate() {
          this.initEvent();
          this.com_item.touchable = false;
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
      }
      onHolyItemFeed() {
      }
      refresh(item) {
          let holyitem = item.holyitem;
          if (holyitem) {
              this.label_item_name.text = holyitem.getName();
              this.label_item_level.text = holyitem.getLevelDesc();
              this.label_item_desc.refresh(holyitem);
              this.com_item.refresh(holyitem, false);
              this.com_attr.refresh(holyitem.attr);
              this.ctrl_title_quality.selectedIndex = holyitem.qualityDb.quality;
              this.button_lock.selected = holyitem.lock;
              let isEquiped = holyitem.isEquiped();
              this.ctrl_equip_by_tower.selectedIndex = isEquiped ? 1 : 0;
              this.button_item_sell.title = mgrHolyItem.getHolyItemSellPrice(holyitem).toString();
              this.loader_tower_head.url = holyitem.getHead();
          }
          this.selectItem = item;
      }
      hideButton() {
          this.button_item_lvup.visible = false;
          this.button_item_sell.visible = false;
      }
      on_click_button_lock() {
          if (this.selectItem) {
              this.selectItem.holyitem.lock = this.button_lock.selected;
          }
      }
      on_click_button_item_lvup() {
          if (this.selectItem) {
              Global.sendMsg(MSG.HOLY_ITEM_BAG_LVUP_OPEN);
          }
      }
      on_click_button_item_sell() {
          if (this.selectItem) {
              mgrHolyItem.sellHolyItem(this.selectItem.holyitem, true);
          }
      }
  }

  class CustomHolyItemInfoBagEx extends CustomHolyItemInfoBag {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHolyItemInfoBagEx";
          this.exportNodeNames = {
              cc_loader_tower_head: "fgui.GLoader",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_label_item_level: "fgui.GBasicTextField",
              cc_com_item: "CustomHolyItem",
              cc_label_item_desc: "CustomHolyItemDesc",
              cc_com_attr: "CustomAttrHolyItem3",
              cc_button_lock: "fgui.GButton",
              cc_button_item_lvup: "fgui.GButton",
              cc_button_item_sell: "fgui.GButton",
              cc_button_item_equip: "fgui.GButton",
              cc_ctrl_equip_by_tower: "fgui.Controller",
              cc_ctrl_title_quality: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      setOnClickEquipCallback(funcEquip) {
          this.funcOnClickButtonEquip = funcEquip;
      }
      on_click_button_lock() {
          super.on_click_button_lock();
      }
      on_click_button_item_lvup() {
          super.on_click_button_item_lvup();
      }
      on_click_button_item_sell() {
          super.on_click_button_item_sell();
      }
      on_click_button_item_equip() {
          if (this.funcOnClickButtonEquip)
              this.funcOnClickButtonEquip(this.button_item_equip);
      }
  }

  class CustomBarItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomBarItem";
          this.itemId = 0;
          this.exportNodeNames = {
              cc_button_item: "fgui.GButton",
          };
      }
      onCreate() {
          this.initEvent();
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.refresh.bind(this),
          });
      }
      setItemId(itemId) {
          this.itemId = itemId;
          this.button_item.icon = mgrGame.getItemIcon(itemId);
          this.refresh();
      }
      refresh() {
          if (this.itemId) {
              this.button_item.title = mgrGame.getItemCount(this.itemId).toString();
          }
      }
      on_click_button_item() {
      }
  }

  class CustomBarStone extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomBarStone";
          this.exportNodeNames = {
              cc_button_stone: "fgui.GButton",
          };
      }
      onCreate() {
          this.initEvent();
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.refresh.bind(this),
          });
      }
      refresh() {
          this.button_stone.title = mgrGame.getItemCount(1014).toString();
      }
      on_click_button_stone() {
      }
  }

  class CustomBarTicket extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "货币栏_副本门票";
          this.sourceName = "ui://base/CustomBarTicket";
          this.exportNodeNames = {
              cc_button_ticket: "fgui.GButton",
          };
      }
      onCreate() {
          this.initEvent();
          this.refresh();
          CopHelper.updateAdvButtonState(this.button_ticket, db.ADV_DB_ADVNAME.shop_ad);
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          this.button_ticket.title = mgrGame.getItemCount(1011).toString();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.refresh.bind(this),
          });
      }
      on_click_button_ticket() {
          Director.openPanelWithSingleton("PanelShop");
      }
  }

  class CustomMoneyPop extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomMoneyPop";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_num: "fgui.GBasicTextField",
              cc_trans_play: "fgui.Transition",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      show(num) {
          this.label_num.text = "+" + num;
          this.trans_play.play(Laya.Handler.create(this, this.recover));
      }
      recover() {
          this.removeFromParent();
          this.displayObject.removeSelf();
          FguiHelper.putItem(this.sourceName, this);
      }
      static create() {
          let item = FguiHelper.getItem("ui://game/CustomMoneyPop");
          return item;
      }
  }

  class CustomDropItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomDropItem";
          this.timePass = 0;
          this.timeStay = 0;
          this.uid = 0;
          this.exportNodeNames = {
              cc_item: "fgui.GComponent",
              cc_loader_glow: "fgui.GLoader",
              cc_loader_icon: "fgui.GLoader",
              cc_label_time: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
              cc_trans_in: "fgui.Transition",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickItem);
          Global.registerListeners(this, {
              [MSG.DROP_BOX_PICK_UP_AD]: this.onDropBoxPickUpAD.bind(this),
          });
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      onClickItem() {
          if (this.dropDb) {
              if (this.dropDb.type == 1) {
                  mgrNetwork.callByNetwork(() => {
                      this.pickup();
                  });
              }
              else {
                  this.pickup();
              }
          }
      }
      recover() {
          if (this.destroyed)
              return;
          this.removeTimer();
          if (this.link) {
              this.link.removeFromList();
              this.link = null;
          }
          this.removeFromParent();
          this.displayObject.removeSelf();
          FguiHelper.putItem("ui://base/CustomDropItem", this);
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdate);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdate);
      }
      onUpdate() {
          if (this.destroyed)
              return;
          this.timePass += 1;
          let leftTime = this.timeStay - this.timePass;
          if (leftTime <= 0) {
              this.removeTimer();
              this.disappear();
          }
          else {
              if (!this.label_time.isDisposed)
                  this.label_time.text = Utils.dateFormat(leftTime, "i:s");
          }
      }
      onDropBoxPickUpAD(uid) {
          if (this.uid == uid) {
              this.recover();
          }
      }
      setIcon(url) {
          this.loader_icon.url = url;
      }
      flyTo(time, x, y) {
          Laya.Tween.to(this.displayObject, { x: x, y: y }, time, null, Laya.Handler.create(this, this.recover));
      }
      pickup() {
          let dropDb = this.dropDb;
          if (dropDb) {
              switch (dropDb.type) {
                  case 0:
                      {
                          let itemId = dropDb.coin_id;
                          let count = Math.round(Utils.randomRange(dropDb.coin_value[0], dropDb.coin_value[1]) * mgrGame.getEnemyCoin());
                          if (count) {
                              mgrGame.addItem(itemId, count, 46, false);
                              mgrTask.doEvent(db.TASK_EVENT_ID.PICKUP_COIN);
                              mgrSound.playSound("item_get");
                              let popMoney = CustomMoneyPop.create();
                              if (popMoney) {
                                  this.displayObject.parent.addChild(popMoney.displayObject);
                                  popMoney.show(count);
                                  popMoney.displayObject.pivotX = popMoney.width * popMoney.pivotX;
                                  popMoney.displayObject.pivotY = popMoney.height * popMoney.pivotY;
                                  popMoney.displayObject.x = this.displayObject.x;
                                  popMoney.displayObject.y = this.displayObject.y - 50;
                                  Level.showFlyMoney(popMoney.displayObject, dropDb.effect_count);
                              }
                          }
                          break;
                      }
                  case 1:
                      {
                          if (mgrHolyItem.notEnoughEmpty(6))
                              return;
                          let param = dropDb.param;
                          let listDrop = [];
                          let itemId = dropDb.coin_id;
                          let coin_value = dropDb.coin_value;
                          let count = Utils.random(coin_value[0], coin_value[1]);
                          if (count) {
                              mgrGame.addItem(itemId, count, 46, false);
                              listDrop.push({ type: DROP_TYPE.ITEM, data: { itemId: itemId, count: count } });
                          }
                          let countPiece = Utils.random(dropDb.piece[0], dropDb.piece[1]);
                          if (countPiece) {
                              mgrGame.addItem(1006, countPiece, 46, false);
                              listDrop.push({ type: DROP_TYPE.ITEM, data: { itemId: 1006, count: countPiece } });
                          }
                          let listHolyItems = Level.buildItemByDropIdAndTime(Level.levelDb.drop_id, param[0]);
                          for (let i = 0; i < param[1]; i++) {
                              let item = listHolyItems[i];
                              if (item) {
                                  listDrop.push({ type: DROP_TYPE.HOLY_ITEM, data: item });
                                  mgrHolyItem.addHolyItem(item);
                              }
                          }
                          Level.showItemGet(listDrop);
                          mgrTask.doEvent(db.TASK_EVENT_ID.PICKUP_BOX);
                          break;
                      }
                  case 2:
                      {
                          Director.openPanelWithSingleton("PanelDropBoxAD", { dropDb: this.dropDb, uid: this.uid });
                          return;
                      }
              }
          }
          this.recover();
      }
      disappear() {
          this.trans_out.play(Laya.Handler.create(this, this.recover));
      }
      buildUid() {
          return CustomDropItem.autoIncreaseId++;
      }
      buildDropData() {
          this.uid = this.buildUid();
          let listDrop = db.get_enemy_drop_db_map();
          this.dropDb = StageTool.calcWeightItem(listDrop);
          this.loader_icon.url = this.dropDb.icon;
          this.ctrl_quality.selectedIndex = this.dropDb.quality;
          cc$1.tween(this.item).then(cc$1.jumpTo(0.3, 0, 0, Utils.random(30, 60), 1)).start();
          this.timePass = 0;
          this.timeStay = Utils.random(db.game_cnf.drop_item_time[0], db.game_cnf.drop_item_time[1]);
          this.initTimer();
      }
      buildDropDataByType(type = 2) {
          this.uid = this.buildUid();
          let listDrop = db.get_enemy_drop_db_map();
          let listData = [];
          for (let item of listDrop) {
              if (item.type == type) {
                  listData.push(item);
              }
          }
          this.dropDb = StageTool.calcWeightItem(listData);
          this.loader_icon.url = this.dropDb.icon;
          this.ctrl_quality.selectedIndex = this.dropDb.quality;
          cc$1.tween(this.item).then(cc$1.jumpTo(0.3, 0, 0, Utils.random(30, 60), 1)).start();
          this.timePass = 0;
          this.timeStay = Utils.random(db.game_cnf.drop_item_time[0], db.game_cnf.drop_item_time[1]);
          this.initTimer();
      }
      static create() {
          let item = FguiHelper.getItem("ui://base/CustomDropItem");
          return item;
      }
  }
  CustomDropItem.autoIncreaseId = 1;

  class CustomDropItemFly extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomDropItemFly";
          this.exportNodeNames = {
              cc_loader_glow: "fgui.GLoader",
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_coin: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      recover() {
          Laya.timer.clearAll(this);
          this.removeFromParent();
          this.displayObject.removeSelf();
          FguiHelper.putItem("ui://base/CustomDropItemFly", this);
      }
      refresh(url, quality) {
          if (quality >= 0 && quality < this.ctrl_quality.pageCount) {
              this.ctrl_quality.selectedIndex = quality;
              this.ctrl_coin.selectedIndex = 0;
          }
          else {
              this.ctrl_coin.selectedIndex = 1;
          }
          this.loader_icon.url = url;
      }
      static create() {
          let item = FguiHelper.getItem("ui://base/CustomDropItemFly");
          item.touchable = false;
          return item;
      }
  }

  class CustomH5ADDToDesk extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomH5ADDToDesk";
          this.exportNodeNames = {
              cc_button_addtodesk: "fgui.GButton",
          };
      }
      onCreate() {
          Global.registerListeners(this, {
              [BASE_MSG.SDK_INSTALL_SHORTCUT_SUC]: this.onSDKInstallShortcutSuc.bind(this),
          });
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onSDKInstallShortcutSuc() {
          this.refresh();
      }
      refresh() {
          CopHelper.updateButtonVisible(this, db.cop_db.isSupportInstallShortcut && !mgrSdk.isShortcutInstalled());
      }
      on_click_button_addtodesk() {
          mgrSdk.installShortcut();
      }
  }

  class CustomHolyItemIntro extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHolyItemIntro";
          this.exportNodeNames = {
              cc_label_item_desc: "CustomHolyItemDesc",
              cc_com_item: "CustomHolyItem",
              cc_com_attr: "CustomAttrHolyItem",
              cc_button_lock: "fgui.GButton",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_label_item_level: "fgui.GBasicTextField",
              cc_ctrl_title_quality: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(holyitem) {
          if (holyitem) {
              this.label_item_name.text = holyitem.getName();
              this.label_item_level.text = holyitem.getLevelDesc();
              this.label_item_desc.refresh(holyitem);
              this.com_item.refresh(holyitem, false);
              this.com_attr.refresh(holyitem.attr);
              this.ctrl_title_quality.selectedIndex = holyitem.qualityDb.quality;
              this.button_lock.selected = holyitem.lock;
          }
          this.selectItem = holyitem;
      }
      on_click_button_lock() {
          if (this.selectItem) {
              this.selectItem.lock = this.button_lock.selected;
          }
      }
  }

  class CustomHpBar extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHpBar";
          this.exportNodeNames = {
              cc_progress_bar: "fgui.GProgressBar",
              cc_progress_boss: "fgui.GProgressBar",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      onCreate() {
          this.labelHp = this.progress_boss.getChild("text").asLabel;
          this.progressBar2Enemy = this.progress_bar.getChild("bar2").asProgress;
          this.progressBar2Boss = this.progress_boss.getChild("bar2").asProgress;
          this.touchable = false;
      }
      dispose() {
          super.dispose();
      }
      updateProgress(cur, max) {
          let value = cur / max * 100;
          switch (this.ctrl_type.selectedIndex) {
              case 0:
                  this.progress_bar.value = value;
                  this.progressBar2Enemy.tweenValue(value, 0.4);
                  break;
              case 1:
                  this.progress_boss.value = value;
                  this.progressBar2Boss.tweenValue(value, 0.4);
                  if (this.labelHp)
                      this.labelHp.text = StageTool.formatHP(cur);
                  break;
          }
      }
      switchType(index) {
          if (index < this.ctrl_type.pageCount)
              this.ctrl_type.selectedIndex = index;
      }
  }

  class CustomHpBarTower extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHpBarTower";
          this.exportNodeNames = {
              cc_progress_hp_bar2: "fgui.GProgressBar",
              cc_progress_hp_bar1: "fgui.GProgressBar",
              cc_progress_mp_bar: "fgui.GProgressBar",
              cc_guide_tip: "CustomGuideTip",
              cc_label_hp: "fgui.GBasicTextField",
              cc_label_lv: "fgui.GBasicTextField",
          };
      }
      onCreate() {
          this.touchable = false;
      }
      dispose() {
          super.dispose();
      }
      updateTowerLv(lv) {
          this.label_lv.text = lv.toString();
      }
      updateProgress(cur, max) {
          let value = cur / max * 100;
          this.progress_hp_bar1.value = value;
          this.progress_hp_bar2.tweenValue(value, 0.4);
          this.label_hp.text = StageTool.formatHP(cur);
      }
      updateRedPoint(towerId, haveHolyItemCanEquip) {
          Level.updateRedPoint4Button(this, mgrTower.haveRedPoint(towerId, haveHolyItemCanEquip));
      }
      hideRedPoint() {
          Level.updateRedPoint4Button(this, false);
      }
      initGuideTip(towerId) {
          this.guide_tip.setTowerId(towerId);
      }
      updateProgressMP(cur, max) {
          let value = cur / max * 100;
          this.progress_mp_bar.value = value;
      }
      updateCrossbowProgress(cur, max) {
      }
  }

  class CustomHpBarTowerMain extends CustomHpBarTower {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomHpBarTowerMain";
          this.exportNodeNames = {
              cc_progress_hp_bar2: "fgui.GProgressBar",
              cc_progress_hp_bar1: "fgui.GProgressBar",
              cc_progress_mp_bar: "fgui.GProgressBar",
              cc_progress_crossbow: "fgui.GProgressBar",
              cc_guide_tip: "CustomGuideTip",
              cc_label_hp: "fgui.GBasicTextField",
              cc_label_lv: "fgui.GBasicTextField",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
      updateCrossbowProgress(cur, max) {
          let value = cur / max * 100;
          this.progress_crossbow.value = value;
      }
  }

  class CustomItemInfo extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomItemInfo";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_num: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_num: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemDb, count) {
          this.loader_icon.url = itemDb.icon;
          this.label_name.text = itemDb.name;
          this.label_desc.text = itemDb.desc;
          this.label_num.text = Utils.numberFormat(count, 1);
          if (itemDb.type == 4) {
              this.ctrl_num.selectedIndex = 1;
          }
          else {
              this.ctrl_num.selectedIndex = count > 0 ? 0 : 1;
          }
          this.ctrl_quality.selectedIndex = itemDb.quality;
      }
  }

  class CustomLayerFit extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomLayerFit";
          this.exportNodeNames = {};
      }
      fit() {
          this.relations.clearAll();
          this.relations.add(this.parent, fgui.RelationType.Bottom_Bottom);
          this.relations.add(this.parent, fgui.RelationType.Center_Center);
          FguiHelper.makeFullScreenFitTop(this);
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomMoney extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomMoney";
          this.coin = 0;
          this.exportNodeNames = {};
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      recover() {
          this.removeFromParent();
          Laya.Pool.recover(this.sourceName, this);
      }
      static create() {
          let url = "ui://base/CustomMoney";
          let item = Laya.Pool.getItem(url);
          if (!item) {
              item = fgui.UIPackage.createObjectFromURL(url);
          }
          return item;
      }
      takeCoin(coin) {
          this.coin = coin;
      }
      flyTo(time, x, y) {
          Laya.Tween.to(this, { x: x, y: y, scaleX: 1, scaleY: 1 }, time, Laya.Ease.linearIn, Laya.Handler.create(this, this.onFlyEnd));
      }
      onFlyEnd() {
          if (this.coin) {
              mgrGame.addItem(1001, this.coin, 22, false);
              this.coin = 0;
          }
          this.recover();
      }
  }

  class CustomMoneyBar extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "货币栏";
          this.sourceName = "ui://base/CustomMoneyBar";
          this.exportNodeNames = {
              cc_button_coin: "fgui.GButton",
              cc_button_diamond: "fgui.GButton",
          };
      }
      onCreate() {
          this.loader_coin = this.button_coin.getChild("icon").asLoader;
          this.loader_diamond = this.button_diamond.getChild("icon").asLoader;
          this.initEvent();
          this.refresh();
          this.onClick(this, this.onClickMoneyBar);
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          this.button_coin.title = StageTool.formatCoin(mgrGame.getItemCoin());
          this.button_diamond.title = StageTool.formatDiamond(mgrGame.getItemDiamond());
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.refresh.bind(this),
              [MSG.GAME_SYNC_MONEY_BAR]: this.refresh.bind(this),
          });
      }
      hideDiamondAdd() {
          this.button_diamond.touchable = false;
          let add = this.button_diamond.getChild("add");
          if (add) {
              add.visible = false;
          }
      }
      onClickMoneyBar() {
      }
      getIconCoin() {
          return this.loader_coin;
      }
      getDiamondCoin() {
          return this.loader_diamond;
      }
      on_click_button_coin() {
      }
      on_click_button_diamond() {
          Director.openPanelWithSingleton("PanelPray", { page: 2 });
      }
  }

  class CustomNodeEffect extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomNodeEffect";
          this.exportNodeNames = {};
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      loadEffect() {
          let effectName = this.data;
          if (effectName) {
              let data = Director.getScene3DLayer(1);
              if (data) {
                  let effect = EffectFactory.create(effectName, data.scene3d);
                  if (effect) {
                      effect.followFguiNode(data.camera, this);
                      return effect;
                  }
              }
          }
      }
  }

  class CustomTowerHead extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/CustomTowerHead";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_quality: "fgui.Controller",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickItem);
      }
      dispose() {
          super.dispose();
      }
      onClickItem(e) {
          if (this.towerDb) {
              e.stopPropagation();
              Director.openPanelWithSingleton("PanelCollectDetailTower", { towerDb: this.towerDb, collectDb: mgrTower.findCollectDbByItemId(this.towerDb.item_id) });
          }
      }
      refresh(towerDb) {
          this.towerDb = towerDb;
          this.loader_icon.url = towerDb.icon_small;
          this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
      }
  }

  class PanelDialog extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/PanelDialog";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_dialog: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
              cc_button_cancel: "fgui.GButton",
          };
      }
      buildUi() {
          this.label_title.text = this.context.title || "提示";
          this.label_dialog.text = this.context.desc || "";
          this.button_ensure.title = this.context.confirmText || "确定";
          this.button_cancel.title = this.context.cancelText || "取消";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_ensure() {
          if (this.context.confirm)
              this.context.confirm();
          this.close();
      }
      on_click_button_cancel() {
          if (this.context.cancel)
              this.context.cancel();
          this.close();
      }
      on_click_button_close() {
          if (this.context.cancel)
              this.context.cancel();
          this.close();
      }
  }

  class PanelDialogCD extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/PanelDialogCD";
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.timeLeft = 30;
          this.descPostfix = "";
          this.exportNodeNames = {
              cc_label_dialog: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
          };
      }
      buildUi() {
          this.timeLeft = this.context.cd || 30;
          this.descPostfix = this.context.postfix || "";
          this.initTimer();
          this.refresh();
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      updatePerSecond() {
          this.timeLeft--;
          this.refresh();
          if (this.timeLeft <= 0) {
              this.onTimeCDEnd();
          }
      }
      refresh() {
          this.label_dialog.text = this.timeLeft + this.descPostfix;
      }
      onTimeCDEnd() {
          Global.sendMsg(this.context.msg || "");
          this.close();
      }
      on_click_button_ensure() {
          this.close();
      }
  }

  class PanelDialogTip extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/PanelDialogTip";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_dialog: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
          };
      }
      buildUi() {
          this.label_title.text = this.context.title || "提示";
          this.label_dialog.text = this.context.desc || "";
          if (this.context.confirmText)
              this.button_ensure.title = this.context.confirmText;
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_ensure() {
          this.close();
      }
  }

  class PanelHolyitemInfo extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物详情";
          this.sourceName = "ui://base/PanelHolyitemInfo";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_back: "fgui.GComponent",
              cc_com_info: "CustomHolyItemIntro",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.item = this.context.item;
          this.com_info.refresh(this.item);
          let point = this.context.point;
          if (point) {
              let halfW = UIRoot.canvasWidth / 2;
              let halfH = UIRoot.canvasHeight / 2;
              let x = point.x;
              let y = point.y;
              if (x <= halfW && y <= halfH) {
                  this.com_info.setPivot(0, 0, true);
              }
              else if (x > halfW && y <= halfH) {
                  this.com_info.setPivot(1, 0, true);
              }
              else if (x <= halfW && y > halfH) {
                  this.com_info.setPivot(0, 1, true);
              }
              else if (x > halfW && y > halfH) {
                  this.com_info.setPivot(1, 1, true);
              }
              this.com_info.x = point.x;
              this.com_info.y = point.y;
          }
          this.layer_back.onClick(this, this.onClickBackground);
      }
      dispose() {
          super.dispose();
      }
      onClickBackground() {
          this.closeWithTransition();
      }
  }

  class PanelItemInfo extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "物品信息";
          this.sourceName = "ui://base/PanelItemInfo";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.itemCount = 0;
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_back: "fgui.GComponent",
              cc_com_info: "CustomItemInfo",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.itemDb = this.context.itemDb;
          let count = mgrGame.getItemCount(this.itemDb.id);
          this.com_info.refresh(this.itemDb, count);
          let point = this.context.point;
          if (point) {
              let halfW = UIRoot.canvasWidth / 2;
              let halfH = UIRoot.canvasHeight / 2;
              let x = point.x;
              let y = point.y;
              if (x <= halfW && y <= halfH) {
                  this.com_info.setPivot(0, 0, true);
              }
              else if (x > halfW && y <= halfH) {
                  this.com_info.setPivot(1, 0, true);
              }
              else if (x <= halfW && y > halfH) {
                  this.com_info.setPivot(0, 1, true);
              }
              else if (x > halfW && y > halfH) {
                  this.com_info.setPivot(1, 1, true);
              }
              this.com_info.x = point.x;
              this.com_info.y = point.y;
          }
          this.layer_back.onClick(this, this.onClickBackground);
      }
      dispose() {
          super.dispose();
      }
      onClickBackground() {
          this.closeWithTransition();
      }
  }

  class PanelMoney extends PanelBase {
      constructor() {
          super(...arguments);
          this.panelStyle = 0;
          this.panelLayer = 6;
          this.bMask = false;
          this.sourceName = "ui://base/PanelMoney";
          this.msg = MSG.GAME_SYNC_MONEY_BAR;
          this.exportNodeNames = {
              cc_money_bar: "CustomMoneyBar",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.resNode.touchable = false;
          this.itemId = this.context.itemId || 1001;
          let itemCount = this.context.numAdd || 0;
          this.msg = this.context.msg || MSG.GAME_SYNC_MONEY_BAR;
          let urlIcon;
          if (this.context.icon) {
              urlIcon = this.context.icon;
          }
          else {
              urlIcon = mgrGame.getItemIcon(this.itemId);
          }
          if (this.context.from) {
              this.pointFrom = this.context.from;
          }
          if (this.context.to) {
              this.pointTo = this.context.to;
          }
          else {
              switch (this.itemId) {
                  case 1001:
                      this.pointTo = this.money_bar.getIconCoin().localToGlobal();
                      break;
                  case 1000:
                      this.pointTo = this.money_bar.getDiamondCoin().localToGlobal();
                      break;
                  default:
                      this.pointTo = new Laya.Point(-100, -100);
                      break;
              }
          }
          this.listMoney = [];
          for (let i = 1; i <= 10; i++) {
              let child = this.resNode.getChild(i.toString());
              if (child) {
                  if (i <= itemCount) {
                      child.visible = true;
                      let icon = child.asCom.getChild("icon").asLoader;
                      if (urlIcon) {
                          icon.url = urlIcon;
                      }
                      this.listMoney.push(child);
                  }
                  else {
                      child.visible = false;
                  }
              }
              else {
                  break;
              }
          }
          this.flyAllMoney();
          Laya.timer.once(700, this, this.destroySelf);
          this.showMoneyAdd(this.context.numAdd || 0);
      }
      getNum() {
          return this.context.numAdd || 0;
      }
      showMoneyAdd(num) {
      }
      flyAllMoney() {
          for (let money of this.listMoney) {
              this.flyMoneyToAround(money);
          }
      }
      flyMoneyToAround(money) {
          let r = 150;
          let x = money.x;
          let y = money.y;
          if (this.pointFrom) {
              x = this.pointFrom.x;
              y = this.pointFrom.y;
              money.x = x;
              money.y = y;
          }
          x += Utils.random(-r, r);
          y += Utils.random(-r, r);
          Laya.Tween.to(money, { x: x, y: y }, 300, null, Laya.Handler.create(this, this.flyMoneyToFianl, [money]));
      }
      flyMoneyToFianl(money) {
          Laya.Tween.to(money, { x: this.pointTo.x, y: this.pointTo.y }, 300, null);
      }
      dispose() {
          super.dispose();
      }
      destroySelf() {
          this.close();
          mgrGame.clearMoneyBarKeep();
          Global.sendMsg(this.msg);
          if (this.itemId && this.context.real) {
              mgrGame.addItem(this.itemId, this.getNum(), this.context.reason, false);
          }
      }
  }

  class PanelSkillInfo extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "技能详情";
          this.sourceName = "ui://base/PanelSkillInfo";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_back: "fgui.GComponent",
              cc_com_skill: "CustomSkillDetail",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.layer_back.onClick(this, this.onClickBackground);
          let skillId = this.context;
          this.com_skill.refresh(skillId);
      }
      dispose() {
          super.dispose();
      }
      onClickBackground() {
          this.closeWithTransition();
      }
  }

  class PanelStoryDialog extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://base/PanelStoryDialog";
          this.panelLayer = 4;
          this.panelStyle = 1;
          this.exportNodeNames = {
              cc_dialog_r: "CustomGuideDialogRight",
              cc_dialog_l: "CustomGuideDialogLeft",
              cc_ctrl_right: "fgui.Controller",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          let dialogId = this.context.dialogId || "1";
          let dialogDb = db.get_story_dialog_db(dialogId);
          if (dialogDb) {
              this.showDialog(dialogDb);
          }
          this.resNode.onClick(this, this.onClickBackgound);
          Global.sendMsg(MSG.GAME_PAUSE);
      }
      dispose() {
          Global.sendMsg(MSG.GAME_RESUME);
          super.dispose();
      }
      onClickBackgound() {
          let comDialog = this.dialog_l;
          if (this.ctrl_right.selectedIndex) {
              comDialog = this.dialog_r;
          }
          if (comDialog.isShowing()) {
              comDialog.showNow();
              return;
          }
          this.nextDialog();
      }
      nextDialog() {
          if (this.curtDialog) {
              let nextDialog = db.get_story_dialog_db_map()[this.curtDialog.next_id];
              if (nextDialog) {
                  this.showDialog(nextDialog);
                  return;
              }
          }
          this.close();
      }
      showDialog(data) {
          this.curtDialog = data;
          this.ctrl_right.selectedIndex = data.is_right ? 1 : 0;
          if (data.is_right) {
              this.dialog_r.show(data.name, data.dialog, data.icon_role, false, data.flip);
          }
          else {
              this.dialog_l.show(data.name, data.dialog, data.icon_role, false, data.flip);
          }
      }
  }

  let max_size = 4;
  let start_y = -150;
  let delta_y = -70;
  let offset_y = -88;
  class ViewTipItem extends ViewBase {
      constructor() {
          super();
          this.sourceName = "ui://base/ViewTipItem";
          this.m_isDone = true;
          this.m_text = "";
          this.m_count = 0;
          this.exportNodeNames = {
              cc_animNode: "fgui.GComponent",
              cc_textLabel: "fgui.GBasicTextField",
          };
          this.create();
      }
      static init() {
          if (!this.centerNode) {
              this.centerNode = new fgui.GComponent();
              let layer = Director.getLayer(8);
              layer.addChild(this.centerNode);
              this.centerNode.setXY(UIRoot.canvasCenterX, UIRoot.canvasCenterY);
              let msgHandler = new MsgHandler();
              msgHandler.registerListeners({
                  [BASE_MSG.UI_SHOW_TIP]: this.onMsgUiShowTip.bind(this),
              });
              msgHandler.startProcMsg();
          }
      }
      static onMsgUiShowTip(text) {
          this.playItem(text + "");
      }
      static playItem(text) {
          for (let i = 0; i < this.itemList.length; i++) {
              const _item = this.itemList[i];
              if (!_item.isDone) {
                  if (_item.equals(text)) {
                      _item.keepAnim();
                      return;
                  }
              }
          }
          let item;
          if (this.itemList.length >= max_size) {
              item = this.itemList.pop();
          }
          else {
              item = new ViewTipItem();
              this.centerNode.addChild(item);
          }
          this.itemList.unshift(item);
          item.setText(text);
          item.play();
          for (let i = 0; i < this.itemList.length; i++) {
              const _item = this.itemList[i];
              if (_item.isDone) {
                  break;
              }
              _item.y = start_y + i * delta_y;
          }
      }
      onCreate() {
          this.normalTween = cc$1.tween(this.animNode).parallel(cc$1.tween().to(0.2, { y: offset_y }), cc$1.tween().to(0.15, cc$1.PROP.ALPHA1)).delay(2).to(0.2, cc$1.PROP.ALPHA0).call(this.onActionFinish.bind(this));
      }
      dispose() {
          super.dispose();
      }
      setText(text) {
          this.textLabel.text = text;
          this.m_text = text;
      }
      equals(text) {
          return this.m_text === text;
      }
      get isDone() {
          return this.m_isDone;
      }
      play() {
          if (!this.m_isDone) {
              this.normalTween.stop();
              this.keepTween && this.keepTween.stop();
          }
          this.m_isDone = false;
          this.visible = true;
          this.resetNode();
          this.normalTween.start();
      }
      resetNode() {
          this.animNode.setXY(0, 0);
          this.animNode.alpha = 0;
      }
      keepAnim() {
          this.normalTween.stop();
          this.animNode.alpha = 1;
          this.animNode.y = offset_y;
          this.animNode.setScale(0, 0);
          if (this.keepTween) {
              this.keepTween.stop();
          }
          else {
              this.keepTween = cc$1.tween(this.animNode).to(0.2, cc$1.PROP.SCALE1, cc$1.OPTION.BACK_OUT).delay(2).to(0.2, cc$1.PROP.ALPHA0).call(this.onActionFinish.bind(this));
          }
          this.keepTween.start();
          this.textLabel.text = this.m_text;
      }
      onActionFinish() {
          this.visible = false;
          this.m_isDone = true;
          this.m_text = "";
          this.m_count = 0;
      }
  }
  ViewTipItem.itemList = [];

  class CustomBoxrewardItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://boxreward/CustomBoxrewardItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_ctrl_reward: "fgui.Controller",
              cc_ctrl_select: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.item.refreshById(data.item_id, data.item_num);
          let index = data.id - 1;
          this.ctrl_reward.selectedIndex = index < mgrGame.boxRewardId ? 1 : 0;
          this.ctrl_select.selectedIndex = index == mgrGame.boxRewardId ? 1 : 0;
      }
  }

  class PanelBoxReward extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "宝箱奖励";
          this.sourceName = "ui://boxreward/PanelBoxReward";
          this.bAutoRemovePackage = true;
          this.listItem = [];
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_left: "fgui.GBasicTextField",
              cc_progress_left: "fgui.GProgressBar",
              cc_button_reward: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_item_1: "CustomBoxrewardItem",
              cc_item_2: "CustomBoxrewardItem",
              cc_item_3: "CustomBoxrewardItem",
              cc_item_4: "CustomBoxrewardItem",
              cc_ctrl_box: "fgui.Controller",
          };
      }
      buildUi() {
          this.initListItem();
          this.refreshItemList();
          this.initTimer();
          this.initEvent();
          this.refresh();
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.unlock_newbie_reward_box) {
                      this.watchAdSuccess();
                  }
              },
          });
      }
      watchAdSuccess() {
          if (mgrGame.tryGetBoxReward()) {
              this.refresh();
              this.refreshItemList();
          }
      }
      initListItem() {
          this.listItem.push(this.item_1);
          this.listItem.push(this.item_2);
          this.listItem.push(this.item_3);
          this.listItem.push(this.item_4);
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      updatePerSecond() {
          this.refresh();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data) {
          content.view.refresh(data);
      }
      refreshItemList() {
          let listData = db.get_newbee_box_reward_map();
          for (let i = 0; i < this.listItem.length; i++) {
              let view = this.listItem[i];
              let index = i - 2;
              let rewardId = mgrGame.boxRewardId + index;
              let rewardDt = listData[rewardId];
              if (!rewardDt) {
                  view.visible = false;
              }
              else {
                  view.visible = true;
                  view.refresh(rewardDt);
              }
          }
      }
      refresh() {
          let reward = mgrGame.getBoxRewardDb();
          if (reward) {
              let maxxTime = reward.time * 60;
              let curtTime = mgrGame.boxRewardTime;
              if (curtTime > maxxTime)
                  curtTime = maxxTime;
              let leftTime = maxxTime - curtTime;
              if (leftTime > 0) {
                  this.label_left.text = Utils.cdTimeFormat(leftTime);
                  this.ctrl_box.selectedIndex = 0;
                  this.progress_left.value = curtTime / maxxTime * 100;
              }
              else {
                  this.progress_left.value = 100;
                  this.label_left.text = "";
                  if (reward.ad) {
                      this.ctrl_box.selectedIndex = 2;
                  }
                  else {
                      this.ctrl_box.selectedIndex = 1;
                  }
              }
          }
          else {
              this.closeWithTransition();
          }
      }
      tryGetReward() {
          if (mgrHolyItem.notEnoughEmpty(4))
              return;
          mgrNetwork.callByNetwork(() => {
              let rewardDb = mgrGame.getBoxRewardDb();
              if (rewardDb && rewardDb.ad) {
                  if (mgrGame.boxRewardTime >= rewardDb.time * 60) {
                      mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.unlock_newbie_reward_box);
                      return;
                  }
              }
              if (mgrGame.tryGetBoxReward()) {
                  this.refresh();
                  this.refreshItemList();
              }
          });
      }
      on_click_button_reward() {
          this.tryGetReward();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_ad() {
          this.tryGetReward();
      }
  }

  class CustomSummonProb extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://card/CustomSummonProb";
          this.exportNodeNames = {
              cc_button_prob: "fgui.GButton",
              cc_ctrl_prob: "fgui.Controller",
          };
      }
      onCreate() {
          for (let i = 0; i < db.game_cnf.summon_card_prob.length; i++) {
              let desc = db.game_cnf.summon_card_prob[i];
              let child = this.getChild("item_" + i);
              if (child && desc) {
                  let textArr = desc.split("_");
                  let name = child.getChild("name");
                  if (name instanceof fgui.GTextField) {
                      name.text = textArr[0] || "";
                      name.color = child.color;
                  }
                  child.text = textArr[1] || "";
              }
          }
      }
      dispose() {
          super.dispose();
      }
      show() {
          this.ctrl_prob.selectedIndex = 1;
      }
      hide() {
          this.ctrl_prob.selectedIndex = 0;
      }
      on_click_button_prob() {
      }
  }

  class CustomSummon extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://card/CustomSummon";
          this.itemCountTotal = 0;
          this.itemCountOpen = 0;
          this.exportNodeNames = {
              cc_item1: "CustomSummonCard",
              cc_item2: "CustomSummonCard",
              cc_item3: "CustomSummonCard",
              cc_item5: "CustomSummonCard",
              cc_item4: "CustomSummonCard",
              cc_ctrl_num: "fgui.Controller",
              cc_trans_summon: "fgui.Transition",
              cc_trans_summon05: "fgui.Transition",
          };
      }
      onCreate() {
          this.listCard = [];
          this.listCard.push(this.item1);
          this.listCard.push(this.item2);
          this.listCard.push(this.item3);
          this.listCard.push(this.item4);
          this.listCard.push(this.item5);
          this.handlerCardOpenEnd = Laya.Handler.create(this, this.onCardOpenEnd, null, false);
      }
      dispose() {
          super.dispose();
      }
      clearEffect() {
          for (let card of this.listCard) {
              card.destroyOpenEffect();
              card.destroyItemEffect();
          }
      }
      refresh(listData, again) {
          if (listData.length > 1) {
              this.ctrl_num.selectedIndex = 1;
          }
          else {
              this.ctrl_num.selectedIndex = 0;
          }
          this.itemCountTotal = listData.length;
          this.itemCountOpen = 0;
          for (let i = 0; i < this.listCard.length; i++) {
              let card = this.listCard[i];
              let data = listData[i];
              if (card && data) {
                  card.refresh(data, this.handlerCardOpenEnd);
              }
              if (card) {
                  card.touchable = false;
              }
          }
          let handler = Laya.Handler.create(this, this.onTransSummonEnd);
          if (again) {
              this.trans_summon05.play(handler);
          }
          else {
              this.trans_summon.play(handler);
          }
      }
      onTransSummonEnd() {
          if (mgrGame.autoSummonCard) {
              for (let i = 0; i < this.listCard.length; i++) {
                  let card = this.listCard[i];
                  if (card) {
                      card.touchable = true;
                      card.onClickCard();
                  }
              }
          }
          else {
              for (let i = 0; i < this.listCard.length; i++) {
                  let card = this.listCard[i];
                  if (card) {
                      card.playBackFlow(i);
                      card.touchable = true;
                  }
              }
          }
      }
      onCardOpenEnd() {
          this.itemCountOpen++;
          if (this.itemCountOpen >= this.itemCountTotal) {
              Global.sendMsg(MSG.SUMMON_ALL_CARD_OPEN);
          }
      }
  }

  class CustomSummonCard extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://card/CustomSummonCard";
          this.isPlay = false;
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_node_effect: "fgui.GLoader",
              cc_item: "CustomSummonItem",
              cc_progress_star: "fgui.GProgressBar",
              cc_label_card_name: "fgui.GBasicTextField",
              cc_ctrl_card_quality: "fgui.Controller",
              cc_ctrl_type: "fgui.Controller",
              cc_ctrl_clas: "fgui.Controller",
              cc_ctrl_new: "fgui.Controller",
              cc_trans_gold: "fgui.Transition",
              cc_trans_normal: "fgui.Transition",
              cc_trans_super: "fgui.Transition",
              cc_trans_back: "fgui.Transition",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickCard);
          this.handlerPlayEnd = Laya.Handler.create(this, this.onCardOpenTransEnd, null, false);
      }
      dispose() {
          super.dispose();
      }
      onClickCard() {
          if (this.isPlay)
              return;
          this.isPlay = true;
          if (this.dropData) {
              let data = this.dropData;
              let duration = 0;
              let quality = 0;
              switch (data.type) {
                  case DROP_TYPE.TOWER:
                      let towerInfo = data.data;
                      quality = towerInfo.towerDb.default_quality;
                      if (towerInfo.convert) {
                          this.refreshCardCovert(towerInfo.convert);
                      }
                      else {
                          this.refreshCardNew(mgrTower.isTowerShow(towerInfo.towerDb.id) ? 0 : 1);
                      }
                      break;
                  case DROP_TYPE.HOLY_ITEM:
                      let holyItem = data.data;
                      quality = holyItem.getQuality();
                      break;
              }
              switch (quality) {
                  case EQUIP_QUALITY.ORANGE:
                      duration = this.playGold();
                      break;
                  case EQUIP_QUALITY.PURPLE:
                      duration = this.playSuper();
                      break;
                  default:
                      duration = this.playNormal();
                      break;
              }
              Laya.timer.once(duration * 0.5, this, () => {
                  if (data.type == DROP_TYPE.HOLY_ITEM)
                      this.createItemEffect();
                  this.createOpenEffect();
              });
          }
      }
      playNormal() {
          this.stopBackFlow();
          this.trans_normal.play(this.handlerPlayEnd);
          return this.trans_normal._totalDuration * 600;
      }
      playSuper() {
          this.stopBackFlow();
          this.trans_super.play(this.handlerPlayEnd);
          return this.trans_super._totalDuration * 700;
      }
      playGold() {
          this.stopBackFlow();
          this.trans_gold.play(this.handlerPlayEnd);
          return this.trans_gold._totalDuration * 600;
      }
      stopBackFlow() {
          this.trans_back.stop();
      }
      playBackFlow(index) {
          this.trans_back.play(null, -1, index * 0.1);
      }
      onCardOpenTransEnd() {
          this.item.touchable = true;
          if (this.dropData) {
              let data = this.dropData;
              switch (data.type) {
                  case DROP_TYPE.TOWER:
                      let towerInfo = data.data;
                      mgrTower.showTowerNew(towerInfo.towerDb.id, 1, false);
                      break;
              }
          }
          if (this.handlerOpenEnd) {
              this.handlerOpenEnd.run();
          }
      }
      createOpenEffect() {
          this.destroyOpenEffect();
          let effectName = null;
          switch (this.ctrl_card_quality.selectedIndex) {
              case EQUIP_QUALITY.ORANGE:
                  effectName = "166_ui_once_chouka_gold";
                  break;
              case EQUIP_QUALITY.PURPLE:
                  effectName = "166_ui_once_chouka_purple";
                  break;
              case EQUIP_QUALITY.BLUE:
                  effectName = "166_ui_once_chouka_blue";
                  break;
              case EQUIP_QUALITY.GREEN:
                  effectName = "166_ui_once_chouka_green";
                  break;
          }
          if (effectName) {
              let data = Director.getScene3DLayer(3);
              let effect = EffectFactory.create(effectName, data.scene3d);
              effect.followFguiNode(data.camera, this.node_effect);
              this.effectOpen = effect;
          }
      }
      destroyOpenEffect() {
          if (this.effectOpen) {
              this.effectOpen.clear();
              this.effectOpen = null;
          }
          if (this.effectLoop) {
              this.effectLoop.clear();
              this.effectLoop = null;
          }
      }
      createItemEffect() {
          this.destroyItemEffect();
          let effectName = null;
          switch (this.ctrl_card_quality.selectedIndex) {
              case EQUIP_QUALITY.ORANGE:
                  effectName = "166_ui_loop_bk_glod_01";
                  break;
              case EQUIP_QUALITY.PURPLE:
                  effectName = "166_ui_loop_bk_purple_01";
                  break;
              case EQUIP_QUALITY.BLUE:
                  effectName = "166_ui_loop_bk_blue_01";
                  break;
          }
          if (effectName) {
              let data = Director.getScene3DLayer(3);
              let effect = EffectFactory.create(effectName, data.scene3d);
              effect.followFguiNode(data.camera, this.item);
              this.effectItem = effect;
          }
      }
      destroyItemEffect() {
          if (this.effectItem) {
              this.effectItem.clear();
              this.effectItem = null;
          }
      }
      refreshCardNew(index) {
          if (index < this.ctrl_new.pageCount)
              this.ctrl_new.selectedIndex = index;
      }
      refreshCardCovert(iteminfo) {
          this.ctrl_new.selectedIndex = 2;
          this.ctrl_card_quality.selectedIndex = iteminfo.quality || 0;
          this.item.refreshItemInfo(iteminfo);
      }
      refreshCard(data) {
          this.isPlay = false;
          let towerDb = data.towerDb;
          this.loader_icon.url = towerDb.icon_summon;
          this.label_card_name.text = towerDb.name;
          this.ctrl_card_quality.selectedIndex = towerDb.default_quality;
          this.ctrl_type.selectedIndex = towerDb.type;
          this.progress_star.value = 0;
          mgrTower.refreshStarLvupBar(this.progress_star, towerDb.id, true);
      }
      refresh(data, handlerOpenEnd) {
          this.isPlay = false;
          this.dropData = data;
          this.handlerOpenEnd = handlerOpenEnd;
          this.item.touchable = false;
          this.refreshCardNew(0);
          switch (data.type) {
              case DROP_TYPE.TOWER:
                  this.ctrl_clas.selectedIndex = 0;
                  this.refreshCard(data.data);
                  break;
              case DROP_TYPE.HOLY_ITEM:
                  let holyItem = data.data;
                  this.label_card_name.text = holyItem.getName();
                  this.ctrl_clas.selectedIndex = 1;
                  this.ctrl_card_quality.selectedIndex = holyItem.qualityDb.quality;
                  this.item.refresh(data);
                  break;
              case DROP_TYPE.ITEM:
                  this.ctrl_clas.selectedIndex = 1;
                  let iteminfo = data.data;
                  this.label_card_name.text = mgrGame.getItemName(iteminfo.itemId);
                  this.ctrl_card_quality.selectedIndex = iteminfo.quality || 0;
                  this.item.refresh(data);
                  break;
          }
      }
  }

  class CustomSummonItem extends CustomCommItem {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://card/CustomSummonItem";
          this.exportNodeNames = {
              cc_normal: "CustomSummonItemSub",
              cc_holyitem: "CustomHolyItem",
              cc_ctrl_item: "fgui.Controller",
              cc_trans_in: "fgui.Transition",
              cc_trans_in02: "fgui.Transition",
              cc_trans_idle: "fgui.Transition",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomSummonItemSub extends CustomItem {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://card/CustomSummonItemSub";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_amount: "fgui.GBasicTextField",
              cc_label_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelSummon extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "召唤";
          this.sourceName = "ui://card/PanelSummon";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_node_spine: "fgui.GLoader",
              cc_loader_summon5_icon: "fgui.GLoader",
              cc_loader_summon1_icon: "fgui.GLoader",
              cc_summon: "CustomSummon",
              cc_money_bar: "CustomMoneyBar",
              cc_button_summon: "fgui.GButton",
              cc_button_summon5: "fgui.GButton",
              cc_com_summon_prob: "CustomSummonProb",
              cc_button_auto_summon: "fgui.GButton",
              cc_com_count: "fgui.GComponent",
              cc_label_left_count: "fgui.GBasicTextField",
              cc_label_summon5_cost: "fgui.GBasicTextField",
              cc_label_summon1_cost: "fgui.GBasicTextField",
              cc_ctrl_free: "fgui.Controller",
              cc_ctrl_summon: "fgui.Controller",
              cc_ctrl_count: "fgui.Controller",
          };
      }
      buildUi() {
          this.initEvent();
          this.refresh();
          this.loadSpine();
          mgrGame.tryOpenPanelIntro("PanelIntroSummon");
      }
      dispose() {
          this.unloadSpine();
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.SUMMON_ALL_CARD_OPEN]: this.onAllCardOpen.bind(this),
              [BASE_MSG.ITEM_CHANGE]: this.refresh.bind(this),
          });
      }
      loadSpine() {
          this.spine = Spine.create("chouka");
          this.spine.playAnimation("come", false, () => {
              this.spine.playAnimation("idle");
          });
          this.node_spine.displayObject.addChild(this.spine);
          let data = Director.getScene3DLayer(3);
          if (data) {
              let effect = EffectFactory.create("166_ui_loop_chouka_01", data.scene3d);
              effect.followFguiNode(data.camera, this.node_spine);
          }
      }
      unloadSpine() {
          if (this.spine) {
              this.spine.destroyAndClear();
              this.spine = null;
          }
      }
      refresh() {
          this.button_auto_summon.selected = mgrGame.autoSummonCard;
          this.label_summon1_cost.text = db.game_cnf.summon_price_1.toString();
          this.label_summon5_cost.text = db.game_cnf.summon_price_5.toString();
          if (mgrGame.getItemDiamond() < db.game_cnf.summon_price_1) {
              this.label_summon1_cost.color = "#FF0000";
          }
          else {
              this.label_summon1_cost.color = "#FFFFFF";
          }
          if (mgrGame.getItemDiamond() < db.game_cnf.summon_price_5) {
              this.label_summon5_cost.color = "#FF0000";
          }
          else {
              this.label_summon5_cost.color = "#FFFFFF";
          }
          if (mgrGame.getItemCount(1005)) {
              this.ctrl_free.selectedIndex = 1;
              Level.updateRedPoint4Button(this.button_summon, true);
          }
          else {
              this.ctrl_free.selectedIndex = 0;
              Level.updateRedPoint4Button(this.button_summon, false);
          }
          let summonBestCount = mgrGame.getItemCount(1023);
          let summonBestLimit = db.game_cnf.summon_best_limit;
          if (summonBestLimit == 0 || summonBestCount < summonBestLimit) {
              this.label_left_count.text = "(" + mgrGame.getItemCount(1022) + "/" + db.game_cnf.summon_best_count + ")";
              this.ctrl_count.selectedIndex = 1;
          }
          else {
              this.ctrl_count.selectedIndex = 0;
          }
      }
      onAllCardOpen() {
          this.ctrl_summon.selectedIndex = 3;
      }
      refreshDrop() {
          this.com_summon_prob.hide();
          this.summon.clearEffect();
          if (this.ctrl_summon.selectedIndex == 3) {
              this.ctrl_summon.selectedIndex = 1;
              this.spine.playAnimation("again_chouka", false, this.onSpineOpenEndAgain.bind(this));
          }
          else {
              this.ctrl_summon.selectedIndex = 1;
              this.spine.playAnimation("chouka", false, this.onSpineOpenEnd.bind(this));
          }
      }
      onSpineOpenEndAgain() {
          this.spine.playAnimation("again_idle", true);
          this.ctrl_summon.selectedIndex = 2;
          if (this.dropData) {
              this.summon.refresh(this.dropData, true);
              this.refresh();
          }
      }
      onSpineOpenEnd() {
          this.spine.playAnimation("again_idle", true);
          this.ctrl_summon.selectedIndex = 2;
          if (this.dropData) {
              this.summon.refresh(this.dropData, false);
              this.refresh();
          }
      }
      summon1() {
          this.dropData = Level.summonCard1();
          this.refreshDrop();
      }
      summon5() {
          this.dropData = Level.sunnomCard5();
          this.refreshDrop();
      }
      isSummoning() {
          return this.ctrl_summon.selectedIndex == 1 || this.ctrl_summon.selectedIndex == 2;
      }
      summon1WithCost() {
          if (this.ctrl_free.selectedIndex) {
              if (mgrGame.subItem(1005, 1, 48)) {
                  this.summon1();
                  Global.sendMsg(MSG.REFRESH_RED_POINT);
                  return true;
              }
          }
          else {
              if (mgrGame.subItem(1000, db.game_cnf.summon_price_1, 48)) {
                  this.summon1();
                  return true;
              }
          }
          return false;
      }
      summon5WithCost() {
          if (mgrGame.subItem(1000, db.game_cnf.summon_price_5, 48)) {
              this.summon5();
              return true;
          }
          return false;
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_summon() {
          if (mgrHolyItem.notEnoughEmpty(1))
              return;
          if (this.isSummoning())
              return;
          mgrNetwork.callByNetwork(() => {
              this.summon1WithCost();
          });
      }
      on_click_button_summon5() {
          if (mgrHolyItem.notEnoughEmpty(5))
              return;
          if (this.isSummoning())
              return;
          mgrNetwork.callByNetwork(() => {
              this.summon5WithCost();
          });
      }
      on_click_button_auto_summon() {
          mgrGame.autoSummonCard = this.button_auto_summon.selected;
      }
  }

  class CustomChallengeItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://challenge/CustomChallengeItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_list_reward: "fgui.GList",
              cc_button_challenge: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
              cc_trans_challenge_in: "fgui.Transition",
              cc_trans_challenge_idle: "fgui.Transition",
          };
      }
      onCreate() {
          this.listReward = new ListView(this.list_reward, this, this.parsetRewardItem, this.renderRewardItem);
      }
      dispose() {
          super.dispose();
      }
      parsetRewardItem(content, object) {
          content.view = object.getChild("item");
      }
      renderRewardItem(content, data) {
          content.view.refresh(data);
      }
      refresh(challengeDb) {
          this.challengeDb = challengeDb;
          if (challengeDb) {
              let left = mgrMonster.getLeftChallengeCount(challengeDb.id);
              if (mgrMonster.isMonsterUnlock(challengeDb.id)) {
                  if (left > 0) {
                      this.ctrl_state.setSelectedIndex(1);
                  }
                  else {
                      if (left == 0 && mgrMonster.getMonsterADCount(challengeDb.id) == 0) {
                          this.ctrl_state.setSelectedIndex(2);
                      }
                      else {
                          this.ctrl_state.setSelectedIndex(3);
                      }
                  }
              }
              else {
                  this.ctrl_state.setSelectedIndex(0);
              }
              if (left < 0)
                  left = 0;
              this.label_title.text = challengeDb.name;
              this.label_desc.text = challengeDb.desc;
              this.label_left.text = left.toString();
              this.loader_icon.url = challengeDb.icon;
              let listData = [];
              let first_reward_ids = challengeDb.reward_ids;
              for (let i = 0; i < first_reward_ids.length; i += 2) {
                  listData.push({ itemId: first_reward_ids[i], count: first_reward_ids[i + 1] });
              }
              this.listReward.setListData(listData);
          }
      }
      get buttonAd() {
          return this.button_ad;
      }
      playTransIn(delay = 0) {
          this.trans_challenge_idle.play();
          this.trans_challenge_in.play(null, 1, delay);
      }
      on_click_button_challenge() {
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          mgrMonster.challengeMonster(this.challengeDb.id);
      }
      on_click_button_ad() {
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.boss_ex, this.challengeDb.id);
          });
      }
  }

  class CustomButton extends fgui.GButton {
      constructor() {
          super(...arguments);
          this.destroyed = false;
      }
      constructFromResource() {
          super.constructFromResource();
          this.bindObject(this);
          this.onCreate();
      }
      bindObject(object) {
          ExportViewTool.bindViewToObject(this, object);
          return this;
      }
      dispose() {
          super.dispose();
      }
      onCreate() { }
  }

  class CustomTaskChapter extends CustomButton {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://challenge/CustomTaskChapter";
          this.exportNodeNames = {
              cc_com_shadow: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_lable_chapter: "fgui.GBasicTextField",
              cc_ctrl_unlock: "fgui.Controller",
              cc_trans_in: "fgui.Transition",
              cc_trans_idle: "fgui.Transition",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data, unlock) {
          this.lable_chapter.text = data.title;
          if (unlock)
              this.loader_icon.icon = data.icon;
          else
              this.loader_icon.icon = data.icon_shadow;
          this.touchable = unlock;
      }
      playTransIn(delay = 0) {
          this.trans_idle.play();
          this.trans_in.play(null, 1, delay);
      }
  }

  var TASK_STEP;
  (function (TASK_STEP) {
      TASK_STEP[TASK_STEP["LOCK_NORMAL"] = 0] = "LOCK_NORMAL";
      TASK_STEP[TASK_STEP["LOCK_BOSS"] = 1] = "LOCK_BOSS";
      TASK_STEP[TASK_STEP["UNLOCK_NORMAL"] = 2] = "UNLOCK_NORMAL";
      TASK_STEP[TASK_STEP["UNLOCK_BOSS"] = 3] = "UNLOCK_BOSS";
      TASK_STEP[TASK_STEP["PASS_NORMAL"] = 4] = "PASS_NORMAL";
      TASK_STEP[TASK_STEP["PASS_BOSS"] = 5] = "PASS_BOSS";
  })(TASK_STEP || (TASK_STEP = {}));
  class CustomTaskStep extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://challenge/CustomTaskStep";
          this.exportNodeNames = {
              cc_label_level: "fgui.GBasicTextField",
              cc_ctrl_level: "fgui.Controller",
              cc_ctrl_select: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          if (data) {
              this.label_level.text = data.id + "-" + data.lv;
          }
          this.levelDb = data;
          let step = mgrGame.getLevelStoryStep() + 1;
          if (data.index == step) {
              this.ctrl_level.selectedIndex = data.boss ? TASK_STEP.UNLOCK_BOSS : TASK_STEP.UNLOCK_NORMAL;
              return true;
          }
          else if (data.index < step) {
              this.ctrl_level.selectedIndex = data.boss ? TASK_STEP.PASS_BOSS : TASK_STEP.PASS_NORMAL;
              return true;
          }
          else {
              this.ctrl_level.selectedIndex = data.boss ? TASK_STEP.LOCK_BOSS : TASK_STEP.LOCK_NORMAL;
              return false;
          }
      }
      unselect() {
          this.ctrl_select.selectedIndex = 0;
      }
      select() {
          this.ctrl_select.selectedIndex = 1;
      }
  }

  class CustomChallengeBoss extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "挑战模式";
          this.sourceName = "ui://challenge/CustomChallengeBoss";
          this.isInited = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_talent: "fgui.GButton",
              cc_button_sweep: "fgui.GButton",
              cc_list_challenge: "fgui.GList",
              cc_label_challeng_desc: "fgui.GBasicTextField",
          };
      }
      onCreate() {
          this.isInited = false;
          this.layer_full.makeFullScreen();
      }
      init() {
          if (this.isInited)
              return;
          this.listChallenge = new ListView(this.list_challenge, this, this.parseChallengeItem, this.renderChallengeItem);
          this.label_challeng_desc.text = db.game_cnf.challenge_desc;
          this.refreshList();
          this.refreshButton();
          this.refreshRedPoint();
          this.isInited = true;
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.boss_ex) {
                      let monsterId = e.params;
                      mgrMonster.addMonsterADCount(monsterId);
                      this.listChallenge.refresh();
                  }
                  else if (e.advName == db.ADV_DB_ADVNAME.boss_sweep) {
                      this.onBossSweepSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_sweep, db.ADV_DB_ADVNAME.boss_sweep);
      }
      refreshButton() {
          this.button_sweep.visible = mgrMonster.getSweepCount() > 0;
      }
      dispose() {
          super.dispose();
      }
      parseChallengeItem(content, object, index) {
          content.view = object;
          if (index < 3) {
              object.playTransIn(0.3 + index * 0.05);
          }
      }
      renderChallengeItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
          if (!content.showAD && mgrGame.statisVideoShowByButton(content.view.buttonAd, db.ADV_DB_ADVNAME.boss_ex)) {
              content.showAD = true;
          }
      }
      refreshList() {
          let listData = [];
          let dataMap = db.get_challenge_level_map();
          for (let k in dataMap) {
              listData.push(dataMap[k]);
          }
          this.listChallenge.setListData(listData);
      }
      onBossSweepSuccess() {
          mgrMonster.getBossSweepReward();
          this.listChallenge.refresh();
          this.refreshButton();
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_talent, mgrTalent.haveRedPoint());
      }
      on_click_button_talent() {
          Director.openPanel("PanelTalent");
      }
      on_click_button_sweep() {
          let count = mgrMonster.getSweepCount();
          if (mgrHolyItem.notEnoughEmpty(8 * count))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.boss_sweep);
          });
      }
  }

  class CustomChallengeMain extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "主线挑战";
          this.sourceName = "ui://challenge/CustomChallengeMain";
          this.isInited = false;
          this.selcectChapterIndex = 0;
          this.lastSelectItem = null;
          this.exportNodeNames = {
              cc_list_chapter: "fgui.GList",
              cc_label_task_name: "fgui.GBasicTextField",
              cc_label_task_desc: "fgui.GBasicTextField",
              cc_map: "fgui.GComponent",
              cc_com_reward: "fgui.GComponent",
              cc_list_first_reward: "fgui.GList",
              cc_label_step_name: "fgui.GBasicTextField",
              cc_ctrl_first: "fgui.Controller",
              cc_button_challenge: "fgui.GButton",
              cc_ctrl_step: "fgui.Controller",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      onCreate() {
          this.isInited = false;
      }
      init() {
          if (this.isInited)
              return;
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onSelectChange);
          this.listFirstReward = new ListView(this.list_first_reward, this, this.parseRewardItem, this.renderRewardItem);
          this.listChaper = new ListView(this.list_chapter, this, this.parseChaperItem, this.renderChaperItem);
          this.refreshChapter();
          this.isInited = true;
      }
      dispose() {
          super.dispose();
      }
      refreshChapter() {
          let listData = [];
          this.ctrl_page.clearPages();
          let step = mgrGame.getLevelStoryStep();
          let dataMap = db.get_main_story_map_map();
          let selectIndex = -1;
          let index = 0;
          for (let k in dataMap) {
              let map = dataMap[k];
              listData.push(map);
              this.ctrl_page.addPage(k);
              let listStep = db.get_main_story_level_map()[map.id];
              let lastStep = listStep[listStep.length - 1];
              if (selectIndex < 0 && lastStep && step < lastStep.index) {
                  selectIndex = index;
              }
              index++;
          }
          if (selectIndex < 0)
              selectIndex = this.ctrl_page.pageCount - 1;
          this.selcectChapterIndex = selectIndex;
          this.listChaper.setListData(listData);
          this.listChaper.scrollToView(selectIndex);
          this.ctrl_page.selectedIndex = selectIndex;
      }
      parseChaperItem(content, object, index) {
          content.view = object;
          if (index < 5) {
              object.playTransIn(0.3 + index * 0.2);
          }
      }
      renderChaperItem(content, data, index) {
          content.data = data;
          content.view.refresh(data, index <= this.selcectChapterIndex);
      }
      onSelectChange() {
          this.refreshSelectChapter();
      }
      getSelectStoryMap() {
          return this.listChaper.getItemData(this.ctrl_page.selectedIndex);
      }
      refreshSelectChapter() {
          let data = this.getSelectStoryMap();
          if (data) {
              this.label_task_name.text = data.name;
              this.label_task_desc.text = data.desc;
              let map = fgui.UIPackage.createObjectFromURL(data.map);
              if (map) {
                  for (let i = 0; i < this.map.numChildren; i++) {
                      this.map.removeChildAt(i);
                  }
                  this.map.addChild(map);
                  this.parsetMap(map.asCom);
              }
          }
      }
      parseRewardItem(content, object) {
          content.view = object;
      }
      renderRewardItem(content, item) {
          content.data = item;
          content.view.refresh(item);
      }
      refreshFirstReward(data) {
          this.ctrl_step.selectedIndex = 1;
          if (mgrGame.getLevelStoryAward(data.index) != 0) {
              this.ctrl_first.selectedIndex = 1;
              let listData = [];
              Level.previewByDropId(data.drop_id, listData, 4);
              this.listFirstReward.setListData(listData);
          }
          else {
              this.ctrl_first.selectedIndex = 0;
              let listData = [];
              let first_reward_ids = data.first_reward_ids;
              for (let i = 0; i < first_reward_ids.length; i += 2) {
                  listData.push({ itemId: first_reward_ids[i], count: first_reward_ids[i + 1] });
              }
              this.listFirstReward.setListData(listData);
          }
          this.label_step_name.text = data.name;
      }
      parsetMap(map) {
          this.listUIStep = [];
          let mapData = this.getSelectStoryMap();
          if (!mapData)
              return;
          let listStep = db.get_main_story_level_map()[mapData.id];
          let index = 0;
          let selectStep = null;
          let isAnyStepUnlock = false;
          for (let i = 0; i < map.numChildren; i++) {
              let child = map.getChildAt(i);
              if (child instanceof CustomTaskStep) {
                  this.listUIStep.push(child);
                  if (listStep) {
                      let data = listStep[index++];
                      if (child.refresh(data)) {
                          isAnyStepUnlock = true;
                      }
                      child.onClick(this, this.onClickTaskStep, [child]);
                      if (!selectStep && mgrGame.getLevelStoryAward(data.index) == 0) {
                          selectStep = child;
                      }
                  }
              }
              else if (child instanceof fgui.GLoader) {
                  child.url = child.data;
              }
          }
          this.button_challenge.visible = isAnyStepUnlock;
          if (this.listUIStep.length)
              this.selectTaskStep(selectStep || this.listUIStep[0]);
      }
      onClickTaskStep(view) {
          this.selectTaskStep(view);
      }
      selectTaskStep(view) {
          let step = mgrGame.getLevelStoryStep() + 1;
          if (view.levelDb.index > step) {
              return;
          }
          if (view.levelDb) {
              this.refreshFirstReward(view.levelDb);
          }
          if (this.lastSelectItem) {
              this.lastSelectItem.unselect();
          }
          view.select();
          this.lastSelectItem = view;
      }
      on_click_button_challenge() {
          if (this.lastSelectItem && this.lastSelectItem.levelDb) {
              if (mgrHolyItem.notEnoughEmpty(8))
                  return;
              Global.sendMsg(MSG.CHALLENGE_STORY_BEGIN, this.lastSelectItem.levelDb);
          }
      }
  }

  class PanelChallenge extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "主线挑战/挑战模式";
          this.sourceName = "ui://challenge/PanelChallenge";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_main: "CustomChallengeMain",
              cc_challenge: "CustomChallengeBoss",
              cc_button_mode_main: "fgui.GButton",
              cc_button_mode_challenge: "fgui.GButton",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      buildUi() {
          this.initEvent();
          this.ctrl_type.selectedIndex = this.context.index == 1 ? 1 : 0;
          this.ctrl_type.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.onStateChange();
          this.refreshRedPoint();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.CHALLENGE_BOSS_BEGIN]: this.onChallengeBegin.bind(this),
              [MSG.CHALLENGE_STORY_BEGIN]: this.onMainStoryBegin.bind(this),
              [BASE_MSG.ITEM_CHANGE]: this.onItemChange.bind(this),
          });
      }
      onChallengeBegin() {
          this.closeWithTransition();
      }
      onMainStoryBegin() {
          this.closeWithTransition();
      }
      onItemChange() {
          this.refreshRedPoint();
          this.challenge.refreshRedPoint();
      }
      refreshRedPoint() {
      }
      onStateChange() {
          switch (this.ctrl_type.selectedIndex) {
              case 0:
                  this.main.init();
                  mgrGame.tryOpenPanelIntro("PanelIntroStory");
                  break;
              case 1:
                  this.challenge.init();
                  mgrGame.tryOpenPanelIntro("PanelIntroBoss");
                  break;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_mode_main() {
      }
      on_click_button_mode_challenge() {
      }
  }

  class PanelLocalBanner extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/PanelLocalBanner";
          this.bMask = false;
          this.panelLayer = 7;
          this.panelStyle = 0;
          this.isSystemPanel = true;
          this.exportNodeNames = {
              cc_btnClick: "fgui.GButton",
              cc_buttonPanel: "fgui.GButton",
              cc_buttonFull: "fgui.GButton",
              cc_button_close: "fgui.GButton",
              cc_advTitle: "fgui.GBasicTextField",
              cc_advDesc: "fgui.GBasicTextField",
              cc_advSource: "fgui.GBasicTextField",
              cc_advIcon: "fgui.GLoader",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.visibleView = false;
          this.parseContext(this.context);
          if (GameGlobal.isDebug) {
              this.fillIcon({ url: "", title: "标题测试", desc: "描述测试", targetTitle: "目标标题测试", adSource: "" });
          }
          else {
              this.fillIcon(this.context.nativeData);
          }
          Global.registerListeners(this, {
              [BASE_MSG.NATIVE_ADV_LOADED]: this.onMsgNativeAdvLoaded.bind(this),
              [BASE_MSG.ADV_CLICK_SUC]: this.onMsgAdvClickSuc.bind(this),
              [BASE_MSG.ADV_CLOSE_NATIVE_BANNER]: this.onMsgCloseBanner.bind(this),
              [MSG.BANNER_CLICK_AD]: this.onMsgBannerClickAD.bind(this),
          });
          CopHelper.updateAreaMode(this, db.cop_db.native_insert_mode);
          console.log("O_O banner 开启");
      }
      dispose() {
          super.dispose();
          console.log("O_O banner 关闭");
      }
      set visibleView(value) {
          if (this.resNode)
              this.resNode.visible = value;
      }
      parseContext(context) {
          if (!context)
              return;
          let userData = context.userData;
          if (!userData)
              return;
          this.userData = userData;
          this.advName = userData.advName;
      }
      closePanelOnly() {
          super.close();
          mgrAdv.closeNativeAdv(this.advName, false);
      }
      close(bManualClose) {
          super.close();
          mgrAdv.closeAdv(this.advName);
          mgrAdv.closeNativeAdv(this.advName, bManualClose);
          Global.sendMsg(MSG.BANNER_HIDE);
      }
      onMsgNativeAdvLoaded(data) {
          if (data.userData.advName == this.advName) {
              this.userData = data.userData;
              this.fillIcon(data.nativeData);
          }
      }
      onMsgAdvClickSuc(data) {
          if (data.advName == this.advName) {
              Timer.callLater(0.01, () => {
                  this.close(false);
              });
          }
      }
      onMsgCloseBanner(e) {
          this.closePanelOnly();
      }
      hide() {
          super.hide();
          this.visibleView = false;
      }
      onMsgBannerClickAD() {
          this.on_click_btnClick();
      }
      fillIcon(nativeData) {
          if (!nativeData)
              return;
          this.visibleView = true;
          this.advIcon.visible = true;
          this.advIcon.url = nativeData.url;
          this.advTitle.text = nativeData.title;
          this.advDesc.text = nativeData.desc;
          if (this.advDesc.text.length > 40) {
              this.advDesc.fontSize = Math.floor(this.advDesc.fontSize * 40 / this.advDesc.text.length);
          }
          let count = this.advTitle.width / nativeData.title.length;
          if (nativeData.title.length > 13) {
              this.advTitle.fontSize = Math.floor(count);
          }
          this.btnClick.text = nativeData.targetTitle;
          if (nativeData.adSource && nativeData.adSource != "") {
              this.advSource.text = nativeData.adSource || "";
              this.advSource.visible = true;
          }
          else {
              this.advSource.visible = false;
          }
          console.log("PanelLocalBanner fill native icon");
          Global.sendMsg(MSG.BANNER_SHOW);
      }
      clickBanner() {
          this.on_click_btnClick();
      }
      on_click_button_close() {
          this.close(true);
      }
      on_click_btnClick() {
          mgrAdv.onNativeAdvClick(this.advName, this.userData);
      }
      on_click_buttonFull() {
          this.on_click_btnClick();
      }
      on_click_buttonPanel() {
          this.on_click_btnClick();
      }
  }

  class PanelLocalInterstitial extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/PanelLocalInterstitial";
          this.panelLayer = 7;
          this.panelStyle = 0;
          this.isSystemPanel = true;
          this.exportNodeNames = {
              cc_advTitle: "fgui.GBasicTextField",
              cc_advDesc: "fgui.GBasicTextField",
              cc_advSource: "fgui.GBasicTextField",
              cc_advIcon: "fgui.GLoader",
              cc_buttonFull: "fgui.GButton",
              cc_buttonPanel: "fgui.GButton",
              cc_button_close: "fgui.GButton",
              cc_btnClick: "fgui.GButton",
          };
      }
      buildUi() {
          this.visibleView = false;
          this.parseContext(this.context);
          if (GameGlobal.isDebug) {
              this.fillIcon({ url: "", title: "标题测试", desc: "描述测试", targetTitle: "目标标题测试", adSource: "" });
          }
          else {
              this.fillIcon(this.context.nativeData);
          }
          Global.registerListeners(this, {
              [BASE_MSG.NATIVE_ADV_LOADED]: this.onMsgNativeAdvLoaded.bind(this),
              [BASE_MSG.ADV_CLICK_SUC]: this.onMsgAdvClickSuc.bind(this),
          });
          CopHelper.updateAreaMode(this, db.cop_db.native_insert_mode);
      }
      parseContext(context) {
          if (!context)
              return;
          let userData = context.userData;
          if (!userData)
              return;
          this.userData = userData;
          this.advName = userData.advName;
      }
      dispose() {
          super.dispose();
      }
      set visibleView(value) {
          if (this.resNode)
              this.resNode.visible = value;
      }
      hide() {
          super.hide();
          this.visibleView = false;
      }
      onMsgNativeAdvLoaded(data) {
          if (data.userData.advName == this.advName) {
              this.userData = data.userData;
              this.fillIcon(data.nativeData);
          }
      }
      onMsgAdvClickSuc(data) {
          console.log("--- > msg onMsgAdvClickSuc");
          if (data.advName == this.advName) {
              Timer.callLater(0.05, () => {
                  this.close();
              });
          }
      }
      fillIcon(nativeData) {
          if (!nativeData)
              return;
          this.visibleView = true;
          this.advIcon.visible = true;
          let url = nativeData.url.replace(".short.webp", "");
          this.advIcon.url = url;
          this.advTitle.text = nativeData.title;
          this.advDesc.text = nativeData.desc;
          if (nativeData.adSource && nativeData.adSource != "") {
              this.advSource.text = nativeData.adSource || "";
              this.advSource.visible = true;
          }
          else {
              this.advSource.visible = false;
          }
          console.log("PanelLocalInterstitial fill native icon");
      }
      on_click_button_close() {
          this.close();
      }
      on_click_btnClick() {
          mgrAdv.onNativeAdvClick(this.advName, this.userData);
      }
      on_click_buttonFull() {
          this.on_click_btnClick();
      }
      on_click_buttonPanel() {
          this.on_click_btnClick();
      }
  }

  class PanelMoreGameOppo extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/PanelMoreGameOppo";
          this.exportNodeNames = {
              cc_list: "fgui.GList",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelMoreGameOppoDown extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/PanelMoreGameOppoDown";
          this.exportNodeNames = {};
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelTryToPlay extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/PanelTryToPlay";
          this.exportNodeNames = {
              cc_button_close: "fgui.GButton",
              cc_list: "fgui.GList",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
      }
  }

  class ViewBannerOtherGame extends ViewBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/ViewBannerOtherGame";
          this.exportNodeNames = {
              cc_banner: "fgui.GComponent",
              cc_list_game: "fgui.GList",
          };
      }
      onCreate() {
          this.listView = new ListView(this.list_game, this, this.parseExpertItem, this.renderExpertItem);
          mgrSdk.openJump("list");
          Global.registerListeners(this, {
              [BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
          });
          if (this.context.offsety)
              this.banner.y += this.context.offsety;
      }
      dispose() {
          super.dispose();
      }
      onMsgOpenJumpResult(e) {
          if (e.type == "list") {
              if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
                  this.visible = false;
                  return;
              }
              else {
                  this.visible = true;
              }
              let datas = e.jumpInfo;
              this.datas = datas;
              this.listView.setListData(this.datas);
              if (this.datas && this.datas.length >= 6) {
                  let tween = cc$1.tween();
                  for (let i = 0; i < this.datas.length - 5; i++) {
                      tween.delay(2).call(() => {
                          this.listView.scrollToView(i, true, true);
                      });
                  }
                  for (let i = this.datas.length - 6; i >= 0; i--) {
                      tween.delay(2).call(() => {
                          this.listView.scrollToView(i, true, true);
                      });
                  }
                  cc$1.tween(this)
                      .repeatForever(tween)
                      .start();
              }
          }
      }
      parseExpertItem(content, object) {
          content.icon = object.getChild("cc_loaderIcon").asLoader;
          content.button = object.getChild("cc_btn_go").asButton;
          content.button.onClick(this, this.onClickExpert, [content]);
      }
      renderExpertItem(content, data) {
          content.icon.url = data.url;
          content.index = data.index;
      }
      onClickExpert(content) {
          console.log("onClickExpert==========");
          mgrSdk.jumpOtherGame(content.index, "list");
      }
  }

  class ViewBannerOtherGameVertical extends ViewBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://channel/ViewBannerOtherGameVertical";
          this.exportNodeNames = {
              cc_list_game: "fgui.GList",
          };
      }
      onCreate() {
          this.listView = new ListView(this.list_game, this, this.parseExpertItem, this.renderExpertItem);
          mgrSdk.openJump("list");
          Global.registerListeners(this, {
              [BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      onMsgOpenJumpResult(e) {
          if (e.type == "list") {
              if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
                  this.visible = false;
                  return;
              }
              else {
                  this.visible = true;
              }
              let datas = e.jumpInfo;
              this.datas = datas;
              this.listView.setListData(this.datas);
              if (this.datas && this.datas.length >= 6) {
                  let tween = cc$1.tween();
                  for (let i = 0; i < this.datas.length - 5; i++) {
                      tween.delay(2).call(() => {
                          this.listView.scrollToView(i, true, true);
                      });
                  }
                  for (let i = this.datas.length - 6; i >= 0; i--) {
                      tween.delay(2).call(() => {
                          this.listView.scrollToView(i, true, true);
                      });
                  }
                  cc$1.tween(this)
                      .repeatForever(tween)
                      .start();
              }
          }
      }
      parseExpertItem(content, object) {
          content.icon = object.getChild("cc_loaderIcon").asLoader;
          content.button = object.getChild("cc_btn_go").asButton;
          content.button.onClick(this, this.onClickExpert, [content]);
      }
      renderExpertItem(content, data) {
          content.icon.url = data.url;
          content.index = data.index;
      }
      onClickExpert(content) {
          console.log("onClickExpert==========");
          mgrSdk.jumpOtherGame(content.index, "list");
      }
  }

  class CustomCollectEnemy extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://collect/CustomCollectEnemy";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_boss: "fgui.Controller",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.loader_icon.url = data.url;
          this.ctrl_unlock.selectedIndex = Level.isCollectUnlcok(data) ? 1 : 0;
          this.ctrl_boss.selectedIndex = data.isBoss ? 1 : 0;
      }
      click(data) {
          Director.openPanel("PanelCollectDetailEnemy", { collectDb: data });
      }
  }

  class CustomCollectHolyitem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://collect/CustomCollectHolyitem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.loader_icon.url = data.url;
          this.ctrl_unlock.selectedIndex = Level.isCollectUnlcok(data) ? 1 : 0;
      }
      click(data) {
          Director.openPanel("PanelCollectDetailItem", { collectDb: data });
      }
  }

  class mgrCollect extends Manager {
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
              this.saveRecord();
          }
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static isRewarded(itemId) {
          return this.data.id2reward[itemId];
      }
      static markReward(itemId) {
          this.data.id2reward[itemId] = true;
      }
      static canReward(collectDb) {
          return collectDb && mgrGame.getItemCount(collectDb.item_id) && !this.isRewarded(collectDb.item_id);
      }
      static tryGetReward(collectDb) {
          if (this.canReward(collectDb)) {
              this.markReward(collectDb.item_id);
              let itemId = collectDb.reward_item_id;
              let itemCn = collectDb.reward_item_count;
              if (itemId && itemCn) {
                  mgrGame.addItem(itemId, itemCn, 54);
              }
              Global.sendMsg(MSG.REFRESH_RED_POINT);
              return true;
          }
          return false;
      }
      static isAnyCollectCanRewardByType(type) {
          let collectArr = db.get_collect_db_map()[type];
          if (collectArr) {
              for (let collectDb of collectArr) {
                  if (this.canReward(collectDb)) {
                      return true;
                  }
              }
          }
          return false;
      }
      static isAnyCollectCanReward() {
          return this.isAnyCollectCanRewardByType("tower");
      }
      static showDetailByTowerId(towerId) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              Director.openPanelWithSingleton("PanelCollectDetailTower", { towerDb: towerDb, collectDb: mgrTower.findCollectDbByItemId(towerDb.item_id) });
          }
      }
  }
  mgrCollect.RECORD_KEY = "game166_collect_v1.0";
  mgrCollect.dataDefault = {
      id2reward: {},
  };

  class CustomCollectTower extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://collect/CustomCollectTower";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.loader_icon.url = data.url;
          this.ctrl_unlock.selectedIndex = Level.isCollectUnlcok(data) ? 1 : 0;
          let towerDb = mgrTower.findTowerDbByItemId(data.item_id);
          if (towerDb)
              this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
          StageTool.updateRedPoint4Button(this, mgrCollect.canReward(data));
      }
      click(data) {
          let towerDb = mgrTower.findTowerDbByItemId(data.item_id);
          if (towerDb) {
              Director.openPanel("PanelCollectDetailTower", { towerDb: towerDb, collectDb: data });
          }
      }
  }

  class PanelCollect extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "图鉴界面";
          this.sourceName = "ui://collect/PanelCollect";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_tower: "fgui.GButton",
              cc_button_enemy: "fgui.GButton",
              cc_button_holyitem: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_label_unlock: "fgui.GBasicTextField",
              cc_list_tower: "fgui.GList",
              cc_list_enemy: "fgui.GList",
              cc_list_holyitem: "fgui.GList",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.listTower = new ListView(this.list_tower, this, this.parseTowerItem, this.renderTowerItem);
          this.listEnemy = new ListView(this.list_enemy, this, this.parseEnemyItem, this.renderEnemyItem);
          this.listHolyitem = new ListView(this.list_holyitem, this, this.parseHolyItem, this.renderHolyItem);
          this.listTower.setOnClickItem(this, this.onClickTower);
          this.listEnemy.setOnClickItem(this, this.onClickEnemy);
          this.listHolyitem.setOnClickItem(this, this.onClickItem);
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onPageChange);
          this.onPageChange();
          this.initEvent();
          this.refreshButton();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.REFRESH_RED_POINT]: this.onRefreshRedPoint.bind(this),
          });
      }
      onRefreshRedPoint() {
          this.refreshButton();
          this.listTower.refresh();
      }
      refreshButton() {
          StageTool.updateRedPoint4Button(this.button_tower, mgrCollect.isAnyCollectCanRewardByType("tower"));
      }
      onPageChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.refreshListTower();
                  break;
              case 1:
                  this.refreshListEnemy();
                  break;
              case 2:
                  this.refreshListItem();
                  break;
          }
      }
      refreshListTower() {
          let listData = db.get_collect_db_map()["tower"];
          if (listData)
              this.listTower.setListData(listData);
          let countUnlcok = 0;
          let countTotal = 0;
          for (let data of listData) {
              if (data.item_id && mgrGame.getItemCount(data.item_id))
                  countUnlcok++;
              countTotal++;
          }
          this.label_unlock.text = "解锁箭塔" + countUnlcok + "/" + countTotal;
      }
      refreshListEnemy() {
          let listData = db.get_collect_db_map()["enemy"];
          if (listData)
              this.listEnemy.setListData(listData);
          let countUnlcok = 0;
          let countTotal = 0;
          for (let data of listData) {
              if (data.item_id && mgrGame.getItemCount(data.item_id))
                  countUnlcok++;
              countTotal++;
          }
          this.label_unlock.text = "解锁怪物" + countUnlcok + "/" + countTotal;
      }
      refreshListItem() {
          let listData = db.get_collect_db_map()["holyitem"];
          if (listData)
              this.listHolyitem.setListData(listData);
          let countUnlcok = 0;
          let countTotal = 0;
          for (let data of listData) {
              if (data.item_id && mgrGame.getItemCount(data.item_id))
                  countUnlcok++;
              countTotal++;
          }
          this.label_unlock.text = "解锁圣物" + countUnlcok + "/" + countTotal;
      }
      parseTowerItem(content, view) {
          content.view = view;
      }
      renderTowerItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickTower(content) {
          content.view.click(content.data);
      }
      parseEnemyItem(content, view) {
          content.view = view;
      }
      renderEnemyItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickEnemy(content) {
          content.view.click(content.data);
      }
      parseHolyItem(content, view) {
          content.view = view;
      }
      renderHolyItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickItem(content) {
          content.view.click(content.data);
      }
      on_click_button_tower() {
      }
      on_click_button_enemy() {
      }
      on_click_button_holyitem() {
      }
      on_click_button_close() {
          this.close();
      }
  }

  const ST_READ_HEAD = 1;
  const ST_READ_DATA = 2;
  class SeasionWS extends Laya.EventDispatcher {
      constructor() {
          super();
          this.instanceId = 0;
          this.uuid = null;
          this.revDataBuffer = "";
          this.socket = null;
          this.readState = ST_READ_HEAD;
          this.head = {};
          this.instanceId = 0;
          this.uuid = null;
          this.revDataBuffer = "";
          this.socket = null;
          this.readState = ST_READ_HEAD;
          this.head = {};
      }
      setUuid(uuid) {
          this.uuid = uuid;
      }
      setSocket(socket) {
          this.socket = socket;
          this.socket.onopen = () => {
              this.event('open');
          };
          this.socket.onclose = () => {
              this.event("close");
          };
          this.socket.onerror = (errEvent) => {
              this.event("error");
          };
          this.socket.onmessage = (msgEvent) => {
              this.revDataBuffer += msgEvent.data;
              if (this.readState == ST_READ_HEAD) {
                  let rep = /({.+?})/;
                  let result = rep.exec(this.revDataBuffer);
                  if (!!result) {
                      let headStr = result.shift();
                      this.revDataBuffer = this.revDataBuffer.replace(headStr, "");
                      this.head = JSON.parse(headStr);
                      this.readState = ST_READ_DATA;
                  }
              }
              if (this.readState == ST_READ_DATA) {
                  if (this.revDataBuffer.length >= this.head.dataLength) {
                      let dataStr = this.revDataBuffer.slice(0, this.revDataBuffer.length);
                      try {
                          let data = JSON.parse(dataStr);
                          this.event("data", data);
                      }
                      catch (error) {
                          console.error("ST_READ_DATA error:", error);
                      }
                      this.revDataBuffer = this.revDataBuffer.replace(dataStr, "");
                      this.readState = ST_READ_HEAD;
                  }
              }
          };
      }
      write(data) {
          let content = JSON.stringify(data);
          let head = {
              dataLength: content.length,
          };
          this.socket.send(JSON.stringify(head) + content);
      }
      close() {
          this.socket.close();
      }
  }

  class NetworkWS {
      static newSeasion(ip, port) {
          return;
          let address = 'ws://' + ip + ':' + port.toString();
          console.log("连接地址:", address);
          let client = new WebSocket(address);
          let seasionWs = new SeasionWS();
          seasionWs.setSocket(client);
          return seasionWs;
      }
  }

  class GameRemoteRouter {
      constructor(seasion) {
          this.__seasion = null;
          this.__registedRouter = null;
          this.seasion = seasion;
          if (!this.seasion) {
              console.error("没有设置seasion");
              return;
          }
          this.seasion.on('data', this, (data) => {
              this.__router(data);
          });
      }
      static get bLinking() {
          return this._bLinking;
      }
      static create() {
          if (this._instance)
              return;
          if (this._bLinking)
              return;
          this._bLinking = true;
          let session = NetworkWS.newSeasion(`127.0.0.1`, 8082);
          session.on("open", this, () => {
              Timer.callLater(1, () => {
                  Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "链接存档服务器成功!可以存档！");
              });
              this._instance = new GameRemoteRouter(session);
              this._bLinking = false;
          });
          session.on("error", this, () => {
              console.log("链接存档服务器失败!");
              this._bLinking = false;
          });
      }
      static get instance() {
          if (!this._instance) {
              this.create();
          }
          return this._instance;
      }
      get seasion() {
          return this.__seasion;
      }
      set seasion(value) {
          this.__seasion = value;
      }
      sendMsgToServer(reqData) {
          this.seasion.write(reqData);
      }
      registerRouter(route, callback) {
          if (!!route && !!callback) {
              this.__registedRouter[route] = callback;
          }
      }
      __router(data) {
          if (!data)
              return;
          if (!data.route)
              return;
          if (!this.__registedRouter[data.route])
              return;
          let router = this.__registedRouter[data.route];
          router(data.data);
      }
  }
  GameRemoteRouter._bLinking = false;

  class PointHelper {
      static loadPointConfig(data) {
          if (!data)
              return;
          this.jsonPointConfig = data;
          console.log("加载Point配置", this.jsonPointConfig);
      }
      static getPointConfig(id) {
          return this.jsonPointConfig[id];
      }
      static setPointConfig(id, data) {
          return this.jsonPointConfig[id] = data;
      }
      static getSpinePoint(id, index) {
          let data = this.getPointConfig(id);
          if (data) {
              return data.points[index];
          }
          else {
              return null;
          }
      }
      static loadConfig(resolve) {
          Laya.loader.load(this.pathConfig, Laya.Handler.create(this, this.onConfigLoad, [resolve]), null, Laya.Loader.JSON);
      }
      static onConfigLoad(resolve) {
          let jsonData = Laya.loader.getRes(this.pathConfig);
          if (jsonData)
              this.loadPointConfig(jsonData);
          if (resolve)
              resolve();
      }
      static saveConifg() {
          if (!GameRemoteRouter.instance) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存Point配置!");
              let data = this.jsonPointConfig || {};
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: this.pathConfig,
                      data: data,
                  },
              });
          }
      }
  }
  PointHelper.pathConfig = "res/cfg/spine_cofing.json";
  PointHelper.jsonPointConfig = {};

  class AnimationEx extends Laya.Animation {
  }

  class AnimationHelper {
      static init() {
          GameRemoteRouter.instance;
      }
      static loadAnimationConfig(data) {
          if (!data)
              return;
          this.jsonAnimationConfig = data;
          console.log("加载Animation配置", this.jsonAnimationConfig);
      }
      static getAnimationConfig(id) {
          return this.jsonAnimationConfig[id];
      }
      static setAnimationConfig(id, data) {
          return this.jsonAnimationConfig[id] = data;
      }
      static updateAnimtionConfig(id, x, y) {
          let cfg = this.getAnimationConfig(id);
          if (cfg) {
              cfg.x = x;
              cfg.y = y;
          }
          else {
              this.setAnimationConfig(id, { x: x, y: y });
          }
      }
      static loadConfig(resolve) {
          Laya.loader.load(this.pathConfig, Laya.Handler.create(this, this.onConfigLoad, [resolve]), null, Laya.Loader.JSON);
      }
      static onConfigLoad(resolve) {
          let jsonData = Laya.loader.getRes(this.pathConfig);
          if (jsonData)
              this.loadAnimationConfig(jsonData);
          if (resolve)
              resolve();
      }
      static saveConifg() {
          if (!GameRemoteRouter.instance) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存Animaion配置!");
              let data = this.jsonAnimationConfig || {};
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: this.pathConfig,
                      data: data,
                  },
              });
          }
      }
  }
  AnimationHelper.pathConfig = "res/cfg/animation_cofing.json";
  AnimationHelper.jsonAnimationConfig = {};

  class EnemySkinMover extends Laya.Script {
      constructor() {
          super(...arguments);
          this.isRunning = true;
          this.funcEaseMove = Laya.Ease.linearIn;
          this.moveToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, pass: 0, running: false, delay: 0, v0: 0, gravity: 1800, jump: false };
      }
      onAwake() {
          this.node = this.owner;
      }
      onUpdate() {
          if (this.isRunning)
              this.updateMoveTo(GameConst.FrameDeltaTime);
      }
      updateMoveTo(dt) {
          let moveToData = this.moveToData;
          if (!moveToData.running)
              return;
          moveToData.pass += dt;
          let timePass = moveToData.pass;
          let timeMaxx = moveToData.time;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          this.node.x = this.funcEaseMove(timePass, moveToData.x, moveToData.dx, timeMaxx);
          this.node.y = this.funcEaseMove(timePass, moveToData.y, moveToData.dy, timeMaxx);
          this.node.zOrder = this.node.y;
          if (timePass >= timeMaxx) {
              moveToData.running = false;
              moveToData.jump = false;
          }
      }
      moveTo(time, x, y) {
          if (this.moveToData.jump)
              return;
          this.moveToData.pass = 0;
          this.moveToData.time = time;
          this.moveToData.x = this.node.x;
          this.moveToData.y = this.node.y;
          let dx = x - this.node.x;
          let dy = y - this.node.y;
          this.moveToData.dx = dx;
          this.moveToData.dy = dy;
          this.moveToData.jump = false;
          this.moveToData.running = true;
      }
      jumpTo(time, x, y) {
          this.moveToData.pass = 0;
          this.moveToData.time = time;
          this.moveToData.x = this.node.x;
          this.moveToData.y = this.node.y;
          let dx = x - this.node.x;
          let dy = y - this.node.y;
          this.moveToData.dx = dx;
          this.moveToData.dy = dy;
          this.moveToData.jump = true;
          this.moveToData.running = true;
          this.moveToData.v0 = -this.moveToData.gravity * time / 2;
      }
      reset() {
          this.moveToData.running = false;
      }
  }

  class NodeFollower extends Laya.Script {
      onAwake() {
          this.node = this.owner;
      }
      onUpdate() {
          let target = this.target;
          if (target && !target.destroyed) {
              this.node.x = target.x + this.offsetx;
              this.node.y = target.y + this.offsety;
          }
      }
      setTarget(target, offsetx = 0, offsety = 0) {
          this.target = target;
          this.offsetx = offsetx;
          this.offsety = offsety;
      }
  }

  class ObjectSkin extends Laya.Sprite {
      constructor() {
          super(...arguments);
          this.collisionOffsetX = 0;
          this.collisionOffsetY = 0;
          this.collisionRadius = 20;
          this.uid = 0;
          this.buffId2Effect = {};
          this.recovered = false;
          this.bInvalid = false;
          this.canMove = true;
      }
      ;
      buildUid() {
          ObjectSkin.autoIncreaseUid++;
          this.uid = ObjectSkin.autoIncreaseUid;
      }
      loadHpBar(x = 0, y = 0, type = 0, url = null) {
          if (this.hpBar)
              return;
          let hpBar = FguiHelper.getItem("ui://base/CustomHpBar");
          hpBar.switchType(type);
          let object = hpBar.displayObject;
          object.pivotX = object.width / 2;
          Level.stage.layerGameUI.addChild(object);
          let follower = object.getComponent(NodeFollower);
          if (!follower) {
              follower = object.addComponent(NodeFollower);
          }
          follower.setTarget(this, x, y);
          hpBar.visible = false;
          this.hpBar = hpBar;
      }
      resetHpBar(cur, max) {
          if (this.hpBar) {
              this.hpBar.updateProgress(cur, max);
              this.hpBar.visible = false;
          }
      }
      updateHpBar(cur, max) {
          if (this.hpBar) {
              this.hpBar.updateProgress(cur, max);
              this.hpBar.visible = cur < max;
          }
      }
      removeHpBar() {
          if (this.hpBar) {
              this.hpBar.removeFromParent();
              this.hpBar.displayObject.removeSelf();
              FguiHelper.putItem("ui://base/CustomHpBar", this.hpBar);
              this.hpBar = null;
          }
      }
      hideHpBar() {
          if (this.hpBar) {
              this.hpBar.visible = false;
          }
      }
      clearBuffEffectNode(id) {
          let node = this.buffId2Effect[id];
          if (node) {
              node.onTimeEnd();
              this.buffId2Effect[id] = null;
          }
      }
      clearAllBuffEffectNode() {
          for (let k in this.buffId2Effect) {
              let effect = this.buffId2Effect[k];
              if (effect) {
                  effect.onTimeEnd();
              }
          }
          this.buffId2Effect = {};
      }
      setBuffEffectNode(id, effect) {
          this.clearBuffEffectNode(id);
          this.buffId2Effect[id] = effect;
      }
      onMoveSpeedChange(scale) {
      }
      onBuffStart(object, buffId, data) {
          let buff = db.get_buff_db(buffId);
          if (StageConfig.enableGameEffect && buff) {
              if (buff.gray) {
              }
              let effect = EffectFactory.createByTypeAndHeight(buff.effect, this, null, null, -this.height);
              if (effect) {
                  this.setBuffEffectNode(buffId, effect);
              }
          }
          this.onMoveSpeedChange(object.getSpeedScale());
      }
      onBuffExec(object, buffId, data) {
      }
      onBuffEnd(object, buffId, data) {
          this.clearBuffEffectNode(buffId);
          this.onMoveSpeedChange(object.getSpeedScale());
      }
      get invalid() {
          return this.bInvalid || this.recovered || this.destroyed;
      }
      onDestroy() {
          this.clearAllBuffEffectNode();
          this.removeHpBar();
      }
      updateNoMove(noMove) {
          let canMove = noMove == 0;
          if (this.canMove != canMove) {
              this.onCanMoveChange(canMove);
          }
          this.canMove = canMove;
      }
      updateNoAttack(noAttack) {
      }
      onCanMoveChange(canMove) {
      }
      getShootPoint(indexShooter, indexPoint, convert = true) {
      }
      playTransIn() {
          this.alpha = 0;
          Laya.Tween.to(this, { alpha: 1 }, 300);
      }
      onRecover() {
      }
      static create(clas) {
          let item = LogicPool.getItem(clas);
          item.buildUid();
          item.recovered = false;
          item.bInvalid = false;
          return item;
      }
      recover() {
          if (this.recovered)
              return;
          this.recovered = true;
          this.onRecover();
          this.clearAllBuffEffectNode();
          this.removeHpBar();
          this.removeSelf();
          LogicPool.putItem(this);
      }
  }
  ObjectSkin.autoIncreaseUid = 0;

  let PLAY_RATE = 1000 / 30;
  class EnemySkin extends ObjectSkin {
      constructor() {
          super(...arguments);
          this.offset = new Laya.Point;
          this.skinHeight = 0;
          this.targetPos = new Laya.Point;
          this._tempPoint = new Laya.Point;
          this.skinTransformId = 0;
      }
      onAwake() {
          this.mover = this.addComponent(EnemySkinMover);
      }
      onRecover() {
          this.removeCrazyUI();
          super.onRecover();
      }
      loadSkin(roleDb, modelDb, loadHpBar = true) {
          let animName = modelDb.anim;
          let prefabUrl = modelDb.res;
          if (!this.nodeSkin) {
              this.createSkin();
          }
          this.animName = animName;
          this.modelDb = modelDb;
          if (roleDb) {
              if (loadHpBar) {
                  this.loadHpBar(0, -roleDb.height, roleDb.boss ? 1 : 0);
              }
              this.loadCrazyUI(0, -roleDb.height);
              this.updateCollision(roleDb);
          }
          AtlasHelper.loadAtlas(prefabUrl, this.onAtlasLoad.bind(this));
          return this.animation;
      }
      updateCollision(roleDb) {
          this.collisionRadius = roleDb.height / 2 * roleDb.scale;
          this.collisionOffsetY = -this.collisionRadius;
          if (StageConfig.showCollisionArea) {
              let graphics = this.graphics;
              graphics.clear();
              graphics.drawCircle(this.collisionOffsetX, this.collisionOffsetY, this.collisionRadius, "#ff000055");
          }
      }
      loadCrazyUI(x = 0, y = 0) {
          if (this.uiCrazy)
              return;
          let uiCrazy = FguiHelper.getItem("ui://game/CustomBossCrazy");
          if (!uiCrazy)
              return;
          let object = uiCrazy.displayObject;
          object.pivotX = object.width / 2;
          Level.stage.layerGameUI.addChild(object);
          let follower = object.getComponent(NodeFollower);
          if (!follower) {
              follower = object.addComponent(NodeFollower);
          }
          follower.setTarget(this, x, y);
          uiCrazy.visible = false;
          this.uiCrazy = uiCrazy;
      }
      showCrazyLayer(layer) {
          if (this.uiCrazy)
              this.uiCrazy.showCrazyLayer(layer);
      }
      removeCrazyUI() {
          if (this.uiCrazy) {
              this.uiCrazy.removeFromParent();
              this.uiCrazy.displayObject.removeSelf();
              FguiHelper.putItem("ui://game/CustomBossCrazy", this.uiCrazy);
              this.uiCrazy = null;
          }
      }
      onAtlasLoad() {
          if (this.modelDb && this.modelDb.action_in) {
              this.playTransIn();
          }
          else {
              this.playMove();
          }
      }
      createSkin() {
          this.clearSkin();
          let skin = new Laya.Sprite;
          let animation = new AnimationEx;
          this.addChild(skin);
          skin.addChild(animation);
          this.animation = animation;
          this.nodeSkin = skin;
      }
      clearSkin() {
          if (this.nodeSkin) {
              this.nodeSkin.destroy();
              this.nodeSkin = null;
          }
      }
      playTransIn() {
          if (this.modelDb && this.modelDb.action_in) {
              this.play(0, false, this.animName + "_" + this.modelDb.action_in);
          }
          else {
              super.playTransIn();
          }
      }
      play(from, loop, name) {
          this.animation.play(from, loop, name);
          let cfg = AnimationHelper.getAnimationConfig(name);
          if (cfg) {
              this.animation.x = cfg.x;
              this.animation.y = cfg.y;
          }
          else {
              this.animation.x = 0;
              this.animation.y = 0;
          }
      }
      onCanMoveChange(canMove) {
          if (this.animation) {
              if (canMove) {
                  this.animation.interval = PLAY_RATE;
              }
              else {
                  this.animation.interval = Number.MAX_VALUE;
              }
          }
      }
      playMove() {
          if (this.animation) {
              this.animation.interval = PLAY_RATE;
              this.play(0, true, this.animName + "_" + this.modelDb.action_move);
          }
      }
      playAttack(time, action = "atk", attackTimeLine = 1.0) {
          if (this.animation) {
              this.play(0, false, this.animName + "_" + action);
              if (this.animation.frames) {
                  let frameLen = this.animation.frames.length * attackTimeLine;
                  let interval = time * 1000 / frameLen;
                  this.animation.interval = interval;
              }
          }
      }
      playFakeDead() {
          if (this.animation) {
              this.animation.interval = PLAY_RATE;
              this.play(0, false, this.animName + "_" + this.modelDb.action_die);
          }
          this.bInvalid = true;
      }
      playRevive() {
          this.bInvalid = false;
      }
      playDead() {
          if (this.animation) {
              this.animation.interval = PLAY_RATE;
              this.play(0, false, this.animName + "_" + this.modelDb.action_die);
              Laya.Tween.to(this, { alpha: 0 }, 500, null, null, 500);
              Laya.timer.once(1000, this, () => {
                  this.recover();
              });
          }
          if (this.modelDb.effect_dead) {
              EffectFactory.createByType(this.modelDb.effect_dead, EffectFactory.layerFront, this);
          }
      }
      playHurt() {
          if (this.colorFilter) {
              this.colorFilter.adjustBrightness(100);
              this.colorFilter.adjustBrightness(100);
              Laya.timer.once(120, this, () => {
                  this.colorFilter.reset();
              });
          }
      }
      initSkin(target) {
          let cx = Level.gridW / 2;
          let dx = cx - target.gx;
          let scale = target.roleDb.scale;
          this.nodeSkin.scale(scale, scale);
          if (!this.modelDb.no_flip) {
              if (dx > 0) {
                  this.nodeSkin.scaleX = -scale;
              }
              else if (dx < 0) {
                  this.nodeSkin.scaleX = scale;
              }
          }
          let halfTw = Level.tileW / 2;
          let halfTh = Level.tileH / 2;
          this.offset.x = Utils.random(-halfTw, halfTh);
          this.offset.y = Utils.random(-halfTh, halfTh);
          let pos = Level.convertGridPosToRealPos(target.mx, target.my, false);
          this.x = pos.x + this.offset.x;
          this.y = pos.y + this.offset.y;
          this.zOrder = this.y;
          this.targetPos.reset();
          this.skinHeight = target.roleDb.height;
          this.resetHpBar(target.getAttr(BASE_ATTR.HP), target.getAttrMax(BASE_ATTR.HP));
          if (this.mover)
              this.mover.reset();
      }
      getFlip() {
          if (this.nodeSkin)
              return this.nodeSkin.scaleX;
          else
              return 1;
      }
      flip(target, dx) {
          if (this.modelDb.no_flip)
              return;
          let scale = target.roleDb.scale;
          if (dx > 0) {
              this.nodeSkin.scaleX = -scale;
          }
          else if (dx < 0) {
              this.nodeSkin.scaleX = scale;
          }
      }
      updatePosition(target, dt, dx, dy, mx, my) {
          if (!target.targetId) {
              this.flip(target, dx);
          }
          this.moveTo(dt, mx, my);
      }
      setXY(x, y) {
          this.x = x;
          this.y = y;
      }
      jumpTo(time, x, y, msg) {
          let pos = Level.convertGridPosToRealPos(x, y, false);
          let tx = pos.x + this.offset.x;
          let ty = pos.y + this.offset.y;
          cc$1.tween(this).then(cc$1.jumpTo(time, tx, ty, 100, 1)).start();
          this.zOrder = ty;
      }
      moveTo(dt, mx, my) {
          let pos = Level.convertGridPosToRealPos(mx, my, false);
          let tx = pos.x + this.offset.x;
          let ty = pos.y + this.offset.y;
          this.mover.moveTo(dt, tx, ty);
      }
      lookAtTarget(caster, target) {
          let dx = target.mx - caster.mx;
          this.flip(caster, dx);
      }
      getShootPoint(index, indexPoint, convert = true) {
          let point = PointHelper.getSpinePoint(this.modelDb.id, indexPoint);
          if (point) {
              this._tempPoint.x = point.x;
              this._tempPoint.y = point.y;
          }
          else {
              this._tempPoint.x = 0;
              this._tempPoint.y = 0;
          }
          if (convert) {
              this.nodeSkin.localToGlobal(this._tempPoint);
              this.parent.globalToLocal(this._tempPoint);
          }
          return this._tempPoint;
      }
      getShootOffset(index = 0) {
          this._tempPoint.x = 0;
          this._tempPoint.y = 0;
          return this._tempPoint;
      }
      getHitPoint(index, offset = 0.5) {
          this._tempPoint.x = this.x;
          this._tempPoint.y = this.y - this.skinHeight * offset;
          return this._tempPoint;
      }
      getHitOffset(index, offset = 0.5) {
          this._tempPoint.x = 0;
          this._tempPoint.y = -this.skinHeight * offset;
          return this._tempPoint;
      }
      get width() {
          return 0;
      }
      get height() {
          return this.skinHeight;
      }
      onMoveSpeedChange(scale) {
          if (this.animation) {
              this.animation.interval = PLAY_RATE / scale;
          }
      }
      onSkinTranform(id) {
          this.skinTransformId = id;
      }
  }
  EnemySkin.poolkey = "EnemySkin";

  class EnemySkinSpine extends EnemySkin {
      loadSkin(roleDb, modelDb, loadHpBar = true) {
          this.modelDb = modelDb;
          this.createSpine(modelDb.res);
          if (roleDb) {
              if (loadHpBar) {
                  this.loadHpBar(0, -roleDb.height, roleDb.boss ? 1 : 0);
              }
              this.loadCrazyUI(0, -roleDb.height);
              this.updateCollision(roleDb);
          }
          if (this.modelDb && this.modelDb.action_in) {
              this.playTransIn();
          }
          else {
              this.playMove();
          }
          return this.animation;
      }
      createSpine(res) {
          this.clearSpine();
          let skin = Spine.create(res);
          this.addChild(skin);
          this.spine = skin;
          this.nodeSkin = skin;
      }
      clearSpine() {
          if (this.spine) {
              this.spine.destroy();
              this.spine = null;
          }
      }
      removeSelf() {
          this.clearSpine();
          return super.removeSelf();
      }
      onCanMoveChange(canMove) {
          if (this.spine) {
              if (canMove) {
                  this.spine.playbackRate = 1;
                  this.mover.isRunning = true;
              }
              else {
                  this.spine.playbackRate = 0;
                  this.mover.isRunning = false;
              }
          }
      }
      get move() {
          if (this.skinTransformId)
              return this.modelDb.transform_move;
          else
              return this.modelDb.action_move;
      }
      get die() {
          if (this.skinTransformId)
              return this.modelDb.transform_die;
          else
              return this.modelDb.action_die;
      }
      playTransIn() {
          if (this.modelDb && this.modelDb.action_in) {
              this.play(0, false, this.modelDb.action_in);
          }
          else {
              super.playTransIn();
          }
      }
      play(from, loop, name, callback) {
          this.actionName = name;
          this.actionLoop = loop;
          if (this.spine)
              this.spine.playAnimation(name, loop, callback);
      }
      playMove() {
          if (this.spine) {
              this.spine.playbackRate = 1;
              this.play(0, true, this.move);
          }
      }
      playAttack(time, action = "atk", attackTimeLine = 1.0) {
          if (this.spine) {
              if (time > 0) {
                  if (attackTimeLine > 0) {
                      time = time / attackTimeLine;
                  }
                  let timeAnim = this.spine.getAnimTime(action);
                  let playRate = timeAnim / time;
                  this.spine.playbackRate = playRate;
              }
              else {
                  this.spine.playbackRate = 1 * StageConfig.gameTimeScale;
              }
              this.play(0, false, action);
          }
      }
      playFakeDead() {
          if (this.spine) {
              this.spine.playbackRate = 1;
              this.play(0, false, this.die);
          }
          this.bInvalid = true;
      }
      playDead() {
          this.hideHpBar();
          if (this.spine) {
              this.spine.playbackRate = 1;
              Laya.Tween.to(this, { alpha: 0 }, 500, null, null, 500);
              this.play(0, false, this.die, () => {
                  this.recover();
              });
          }
          if (this.modelDb.effect_dead) {
              EffectFactory.createByType(this.modelDb.effect_dead, EffectFactory.layerFront, this);
          }
      }
      onMoveSpeedChange(scale) {
          if (this.spine) {
              this.spine.playbackRate = scale;
          }
      }
      onSkinTranform(id) {
          this.skinTransformId = id;
      }
      refreshAction() {
      }
      getShootPoint(indexShooter, indexPoint, convert = true) {
          let point = PointHelper.getSpinePoint(this.spine.spineId, indexPoint);
          if (point) {
              this._tempPoint.x = point.x;
              this._tempPoint.y = point.y;
          }
          else {
              this._tempPoint.x = 0;
              this._tempPoint.y = 0;
          }
          if (convert) {
              this.spine.localToGlobal(this._tempPoint);
              this.parent.globalToLocal(this._tempPoint);
          }
          return this._tempPoint;
      }
      getShootOffset(index = 0) {
          let point = PointHelper.getSpinePoint(this.spine.spineId, index);
          if (point) {
              this._tempPoint.x = point.x;
              this._tempPoint.y = point.y;
          }
          else {
              this._tempPoint.x = 0;
              this._tempPoint.y = 0;
          }
          return this._tempPoint;
      }
  }
  EnemySkinSpine.poolkey = "EnemySkinSpine";

  class PanelCollectDetailEnemy extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "图鉴_怪物详情";
          this.sourceName = "ui://collect_detail/PanelCollectDetailEnemy";
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_skill_name: "fgui.GBasicTextField",
              cc_label_skill_desc: "fgui.GBasicTextField",
              cc_com_stage: "fgui.GComponent",
          };
      }
      buildUi() {
          this.collectDb = this.context.collectDb;
          let modelDb = Level.findEnemyModelDbByItemId(this.collectDb.item_id);
          if (modelDb) {
              this.label_name.text = this.collectDb.name;
              this.label_desc.text = this.collectDb.desc;
              this.label_skill_name.text = this.collectDb.desc1;
              this.label_skill_desc.text = this.collectDb.desc2;
              let skin;
              if (modelDb.spine) {
                  skin = new EnemySkinSpine();
              }
              else {
                  skin = new EnemySkin();
              }
              skin.loadSkin(null, modelDb);
              this.skin = skin;
              this.com_stage.displayObject.addChild(skin);
          }
      }
      dispose() {
          if (this.skin) {
              this.skin.destroy();
              this.skin = null;
          }
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelCollectDetailItem extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "图鉴_圣物详情";
          this.sourceName = "ui://collect_detail/PanelCollectDetailItem";
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_from: "fgui.GBasicTextField",
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_quality: "fgui.Controller",
          };
      }
      buildUi() {
          this.collectDb = this.context.collectDb;
          this.itemDb = Level.findHolyitemDbItemId(this.collectDb.item_id);
          if (this.itemDb) {
              this.loader_icon.url = this.itemDb.icon;
              this.label_name.text = this.itemDb.name;
              this.label_desc.text = this.collectDb.desc;
              this.label_from.text = this.collectDb.desc1;
          }
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class TowerImageHelper {
      static loadTowerImageConfig(data) {
          if (!data)
              return;
          this.towerImageConfig = data;
          console.log("加载tower_image", this.towerImageConfig);
      }
      static registLoader(root, controller, event = true) {
          let loaders = [];
          for (let i = 0; i < root.numChildren; i++) {
              let child = root.getChildAt(i);
              if (child instanceof fgui.GLoader) {
                  loaders.push(child);
              }
          }
          this.refreshLoader(loaders);
          if (event && controller)
              controller.on(fgui.Events.STATE_CHANGED, this, this.refreshLoader, [loaders]);
      }
      static refreshLoader(loaders) {
          for (let loader of loaders) {
              let url = loader.url;
              if (url) {
                  if (url.startsWith("ui://"))
                      loader.url = this.getTowerImage(loader.url);
                  else {
                      loader.url = "";
                      loader.url = url;
                  }
              }
              else {
                  loader.url = "";
              }
          }
      }
      static getTowerImage(id) {
          return this.towerImageConfig.id2image[id] || "";
      }
      static getTowerImageByQuality(url, qualityIdx) {
          let urls = [];
          let config = this.towerImageConfig.tower2image[url];
          if (config) {
              let def = config.default;
              if (def) {
                  for (let url of def) {
                      if (url)
                          urls.push(url);
                  }
              }
              let qualityUrls = config.quality[qualityIdx];
              if (qualityUrls) {
                  for (let url of qualityUrls) {
                      if (url)
                          urls.push(url);
                  }
              }
          }
          return urls;
      }
      static loadConfig(resolve) {
          Laya.loader.load(this.pathConfig, Laya.Handler.create(this, this.onConfigLoad, [resolve]), null, Laya.Loader.JSON);
      }
      static onConfigLoad(resolve) {
          let jsonData = Laya.loader.getRes(this.pathConfig);
          if (jsonData)
              this.loadTowerImageConfig(jsonData);
          if (resolve)
              resolve();
      }
  }
  TowerImageHelper.pathConfig = "res/cfg/tower_image.json";
  TowerImageHelper.towerImageConfig = {};

  class ResTower {
      constructor(towerId) {
          this.init(towerId);
      }
      init(towerId) {
          console.log("-------------------------------------ResTower-------------------------------------", towerId);
          this.towerId = towerId;
          this.towerDb = db.get_tower_db(towerId);
          this.res_tower = [];
          this.res_fgui_package = {};
          this.res_effect = {};
          if (this.towerDb.main) {
              this.parseSkillDb(db.get_skill_db_map()[mgrTower.getMainSkillId()]);
              this.parseSkillDb(db.get_skill_db_map()[mgrTower.getMainSuperId()]);
          }
          else {
              this.parseSkillDb(db.get_skill_db_map()[this.towerDb.skill_id]);
              this.parseSkillDb(db.get_skill_db_map()[this.towerDb.super_skill_id]);
          }
      }
      addEffectRes(url) {
          if (url) {
              if (url.startsWith("ui://")) {
                  let pkgReg = /ui:\/\/(\S+)\//img;
                  let result = pkgReg.exec(url);
                  if (result) {
                      let pkgName = result[1];
                      if (!this.res_fgui_package[pkgName]) {
                          this.res_fgui_package[pkgName] = true;
                          console.log("ResTower.addEffectRes fgui", this.towerId, pkgName);
                      }
                  }
              }
              else {
                  if (!this.res_effect[url]) {
                      this.res_effect[url] = true;
                      console.log("ResTower.addEffectRes", this.towerId, url);
                  }
              }
          }
      }
      addEffectDb(effectId) {
          if (effectId) {
              let effectDb = db.get_effect_db_map()[effectId];
              if (effectDb) {
                  switch (effectDb.type) {
                      case "2d":
                      case "fgui":
                          this.addEffectRes(effectDb.model);
                          break;
                      default:
                          let modelDb = db.get_model_db_map()[effectDb.model];
                          if (modelDb) {
                              this.addEffectRes(modelDb.resPath);
                          }
                          else {
                              this.addEffectRes(effectDb.model);
                          }
                          break;
                  }
              }
          }
      }
      addEffectDbArr(effectIds) {
          for (let effectId of effectIds) {
              this.addEffectDb(effectId);
          }
      }
      parseSkillDb(skillDb) {
          if (!skillDb)
              return;
          this.addEffectDb(skillDb.effect_cast);
          this.addEffectDb(skillDb.effect_shoot);
          this.addEffectDbArr(skillDb.effect_lock);
          this.addEffectDb(skillDb.effect_hurt);
          this.addEffectDb(skillDb.effect_hit);
          this.parseBulletDb(db.get_bullet_db_map()[skillDb.bullet_id]);
          this.parseBuffDb(db.get_buff_db_map()[skillDb.buff_caster_id]);
          this.parseBuffDb(db.get_buff_db_map()[skillDb.buff_target_id]);
      }
      parseBulletDb(bulletDb) {
          if (!bulletDb)
              return;
          this.addEffectDb(bulletDb.effect_lock);
          this.addEffectDb(bulletDb.effect_shoot);
          this.addEffectDb(bulletDb.effect_hit);
          this.addEffectDb(bulletDb.effect_bullet);
      }
      parseBuffDb(buffDb) {
          if (!buffDb)
              return;
          switch (buffDb.template) {
              case "Trap":
              case "Skill":
                  this.parseSkillDb(db.get_skill_db_map()[buffDb.param[0]]);
                  break;
          }
          this.addEffectDb(buffDb.effect);
      }
      clearPackageRes(pkg) {
          if (pkg) {
              let cnt = pkg._items.length;
              for (let j = 0; j < cnt; j++) {
                  let pi = pkg._items[j];
                  if (pi.type == fgui.PackageItemType.Atlas) {
                      let url = pi.file;
                      console.log("ResTower.clearPackageRes", url);
                      Laya.Loader.clearRes(url);
                  }
              }
          }
      }
      removePackage(pkgName) {
          console.log("ResTower.removePackage", this.towerId, pkgName);
          let pkg = fgui.UIPackage.getByName(pkgName);
          if (pkg) {
              this.clearPackageRes(pkg);
              fgui.UIPackage.removePackage(pkgName);
          }
      }
      release() {
          for (let url of this.res_tower) {
              Laya.loader.clearRes(url);
              console.log("ResTower.release", this.towerId, url);
          }
          for (let pkgName in this.res_fgui_package) {
              this.removePackage(pkgName);
          }
          for (let url in this.res_effect) {
              Laya.loader.clearRes(url);
              console.log("ResTower.release", this.towerId, url);
          }
          if (this.res_spine) {
              Spine.clear(this.res_spine);
              console.log("ResTower.release", this.towerId, this.res_spine);
          }
          this.res_tower = null;
          this.res_effect = null;
          this.res_fgui_package = null;
          this.res_spine = null;
      }
      setSpine(spineId) {
          let spineDb = db.get_spine_db(spineId);
          this.res_spine = spineDb.resPath;
          console.log("ResTower.setSpine", this.towerId, spineDb.resPath);
      }
  }

  class ResTowerManager {
      static getTowerRes(towerId) {
          let res = this.resTowerAll[towerId];
          if (res == null) {
              res = new ResTower(towerId);
              this.resTowerAll[towerId] = res;
          }
          return res;
      }
      static clearAll() {
      }
      static onTowerAdd(towerId) {
          console.log("塔资源.添加", towerId);
          this.getTowerRes(towerId);
      }
      static onTowerRem(towerId) {
          console.log("塔资源.删除", towerId);
          let res = this.getTowerRes(towerId);
          if (res) {
              res.release();
              delete this.resTowerAll[towerId];
          }
      }
  }
  ResTowerManager.resTowerAll = {};

  var SHOOTER_STATE;
  (function (SHOOTER_STATE) {
      SHOOTER_STATE[SHOOTER_STATE["IDLE"] = 1] = "IDLE";
      SHOOTER_STATE[SHOOTER_STATE["THINK"] = 2] = "THINK";
      SHOOTER_STATE[SHOOTER_STATE["MOVE"] = 3] = "MOVE";
      SHOOTER_STATE[SHOOTER_STATE["CAST"] = 4] = "CAST";
      SHOOTER_STATE[SHOOTER_STATE["ATTACK"] = 5] = "ATTACK";
      SHOOTER_STATE[SHOOTER_STATE["KEEP"] = 6] = "KEEP";
      SHOOTER_STATE[SHOOTER_STATE["DEAD"] = 7] = "DEAD";
  })(SHOOTER_STATE || (SHOOTER_STATE = {}));
  class TowerShooter extends Laya.Script {
      constructor() {
          super(...arguments);
          this.init_x = 0;
          this.move_r = 50;
          this.timeInAttack = 0;
          this.keepInAttack = false;
          this.shootPoint = new Laya.Point;
          this.factorFlip = 1;
          this.timeInState = 0;
          this.waitInState = 1;
      }
      onAwake() {
          this.spine = this.owner;
          this.state = new StateMachine();
          this.state.registerState(SHOOTER_STATE.IDLE, "Idle", this);
          this.state.registerState(SHOOTER_STATE.THINK, "Think", this);
          this.state.registerState(SHOOTER_STATE.MOVE, "Move", this);
          this.state.registerState(SHOOTER_STATE.CAST, "Cast", this);
          this.state.registerState(SHOOTER_STATE.ATTACK, "Attack", this);
          this.state.registerState(SHOOTER_STATE.KEEP, "Keep", this);
          this.state.registerState(SHOOTER_STATE.DEAD, "Dead", this);
          this.state.setState(SHOOTER_STATE.THINK);
          this.init_x = this.spine.x;
          let move_r = this.spine.parent.width / 2;
          if (move_r > 0)
              this.move_r = move_r;
          this.spine.x = this.getRandomPosX();
      }
      onUpdate() {
          this.state.update(GameConst.FrameDeltaTime);
      }
      cast(time, anim, keepInAttack = false) {
          this.timeInAttack = time;
          this.nameInAttack = anim;
          this.keepInAttack = keepInAttack;
          this.state.setState(SHOOTER_STATE.CAST);
      }
      playIdle() {
          this.spine.playbackRate = 1;
          this.spine.playAnimation("idle", true);
      }
      playMove() {
          this.spine.playbackRate = 1;
          this.spine.playAnimation("move", true);
      }
      playDead() {
          this.state.setState(SHOOTER_STATE.DEAD, true);
          this.spine.playbackRate = 0;
      }
      endAttack() {
          if (this.keepInAttack) {
              if (this.bullet) {
                  this.bullet.onBulletEnd();
                  this.bullet = null;
              }
              this.state.setState(SHOOTER_STATE.ATTACK);
          }
      }
      getRandomPosX() {
          return Utils.random(this.init_x - this.move_r, this.init_x + this.move_r);
      }
      getShootPoint(parent, index, convert = true) {
          let point = PointHelper.getSpinePoint(this.spine.spineId, index);
          if (point) {
              this.shootPoint.x = point.x;
              this.shootPoint.y = point.y;
          }
          else {
              this.shootPoint.x = 0;
              this.shootPoint.y = -120;
          }
          if (convert) {
              this.spine.localToGlobal(this.shootPoint);
              parent.globalToLocal(this.shootPoint);
          }
          return this.shootPoint;
      }
      setFlip(flip) {
          this.spine.scaleX = flip * this.factorFlip;
      }
      getFlip() {
          return this.spine.scaleX;
      }
      lookAtTarget(caster, target) {
          let dx = target.mx - caster.mx;
          if (dx > 0) {
              this.setFlip(1);
          }
          else if (dx < 0) {
              this.setFlip(-1);
          }
      }
      setBullet(bullet) {
          this.bullet = bullet;
      }
      enterIdle() {
          this.timeInState = 0;
          this.playIdle();
      }
      execIdle(t) {
          this.timeInState += t;
          if (this.timeInState >= 5) {
              this.state.setState(SHOOTER_STATE.THINK);
          }
      }
      enterThink() {
          this.timeInState = 0;
          this.waitInState = Utils.random(1, 3);
          this.playIdle();
      }
      execThink(t) {
          this.timeInState += t;
          if (this.timeInState >= this.waitInState) {
              this.state.setState(SHOOTER_STATE.MOVE);
          }
      }
      enterMove() {
          this.timeInState = 0;
          let spine = this.spine;
          let tx = this.getRandomPosX();
          let dx = tx - spine.x;
          if (dx > 0) {
              this.setFlip(1);
          }
          else if (dx < 0) {
              this.setFlip(-1);
          }
          let time = Math.abs(dx) / 0.1;
          this.waitInState = time / 1000;
          Laya.Tween.to(spine, { x: tx }, time);
          this.playMove();
      }
      execMove(t) {
          this.timeInState += t;
          if (this.timeInState >= this.waitInState) {
              this.state.setState(SHOOTER_STATE.THINK);
          }
      }
      enterCast() {
          this.timeInState = 0;
          this.waitInState = this.timeInAttack;
          let animName = this.nameInAttack + "01";
          if (this.waitInState > 0) {
              let timeAnim = this.spine.getAnimTime(animName);
              let playRate = timeAnim / this.waitInState;
              this.spine.playbackRate = playRate;
          }
          else {
              this.spine.playbackRate = 1;
          }
          this.spine.playAnimation(animName, false);
      }
      execCast(t) {
          this.timeInState += t;
          if (this.timeInState >= this.waitInState) {
              if (!this.keepInAttack) {
                  this.state.setState(SHOOTER_STATE.ATTACK);
              }
              else {
                  this.state.setState(SHOOTER_STATE.KEEP);
              }
          }
      }
      enterAttack() {
          this.timeInState = 0;
          let animName = this.nameInAttack + "02";
          this.waitInState = this.spine.getAnimTime(animName);
          this.spine.playAnimation(animName, false);
      }
      execAttack(t) {
          this.timeInState += t;
          if (this.timeInState >= this.waitInState) {
              this.state.setState(SHOOTER_STATE.IDLE);
          }
      }
      enterKeep() {
          let animName = this.nameInAttack + "02";
          this.spine.playAnimation(animName, true);
      }
  }

  class TowerSkin extends ObjectSkin {
      constructor() {
          super(...arguments);
          this.shooter = [];
          this._tempPoint = new Laya.Point;
          this.grayFilter = [(new Laya.ColorFilter).gray()];
      }
      loadSkin(towerDb, onUI = false) {
          let skin = this.createTowerSkin(towerDb.res);
          this.addChild(skin.displayObject);
          this.skin = skin;
          if (onUI) {
              skin.setScale(towerDb.scale_ui, towerDb.scale_ui);
          }
          else {
              skin.setScale(towerDb.scale, towerDb.scale);
          }
          this.refreshQuality(towerDb.id);
          if (towerDb.main) {
              this.loadHpBar(0, towerDb.hp_height, 0, "ui://base/CustomHpBarTowerMain");
          }
          else {
              this.loadHpBar(0, towerDb.hp_height);
          }
          return skin;
      }
      loadHpBar(x = 0, y = 0, type = 0, url = "ui://base/CustomHpBarTower") {
          if (this.hpBar)
              return;
          let hpBar = FguiHelper.getItem(url);
          let object = hpBar.displayObject;
          object.pivotX = object.width / 2;
          Level.stage.layerGameUI.addChild(object);
          object.zOrder = 100;
          let follower = object.getComponent(NodeFollower);
          if (!follower) {
              follower = object.addComponent(NodeFollower);
          }
          if (this.hpPoint) {
              follower.setTarget(this, 0, (-this.skin.height + this.hpPoint.y) * this.skin.scaleY);
          }
          else {
              follower.setTarget(this, x, y);
          }
          hpBar.visible = true;
          this.hpBar = hpBar;
      }
      refreshHpBarPosition() {
          if (this.hpBar) {
              let object = this.hpBar.displayObject;
              let follower = object.getComponent(NodeFollower);
              if (follower && this.hpPoint) {
                  follower.setTarget(this, 0, (-this.skin.height + this.hpPoint.y) * this.skin.scaleY);
              }
          }
      }
      resetHpBar(cur, max) {
          if (this.hpBar) {
              this.hpBar.updateProgress(cur, max);
          }
      }
      updateHpBar(cur, max) {
          if (this.hpBar) {
              this.hpBar.updateProgress(cur, max);
          }
      }
      updateHpBarLv(lv) {
          if (this.hpBar) {
              this.hpBar.updateTowerLv(lv);
          }
      }
      updateMpBar(cur, max) {
          if (this.hpBar) {
              this.hpBar.updateProgressMP(cur, max);
          }
      }
      updateCrossbowProgress(cur, max) {
          if (this.hpBar) {
              this.hpBar.updateCrossbowProgress(cur, max);
          }
      }
      removeHpBar() {
          if (this.hpBar) {
              this.hpBar.removeFromParent();
              this.hpBar.displayObject.removeSelf();
              FguiHelper.putItem(this.hpBar.sourceName, this.hpBar);
              this.hpBar = null;
          }
      }
      createTowerSkin(url) {
          let sprite = fgui.UIPackage.createObjectFromURL(url).asCom;
          this.ctrlQuality = sprite.getController("quality");
          this.hpPoint = sprite.getChild("hp").displayObject;
          TowerImageHelper.registLoader(sprite, this.ctrlQuality);
          return sprite;
      }
      loadSkinByStar(towerDb, onUI = false, star = 0) {
          let skin = this.createTowerSkin(towerDb.res);
          this.addChild(skin.displayObject);
          this.skin = skin;
          if (onUI) {
              skin.setScale(towerDb.scale_ui, towerDb.scale_ui);
          }
          else {
              skin.setScale(towerDb.scale, towerDb.scale);
          }
          this.ctrlQuality.selectedIndex = star;
          this.loadHpBar(0, 30);
          return skin;
      }
      loadSpine(name = "ta_01", index = 0) {
          let spine = Spine.create(name);
          spine.playAnimation("idle");
          let stage = this.skin.getChild("stage" + (index + 1)).asCom;
          if (stage) {
              spine.x = stage.width * 0.5;
              stage.displayObject.addChild(spine);
          }
          else {
              this.skin.displayObject.addChild(spine);
          }
          return spine;
      }
      addShooter(name, factorFlip) {
          if (!name)
              return;
          let spine = this.loadSpine(name, this.shooter.length);
          let shooter = spine.addComponent(TowerShooter);
          this.shooter.push(shooter);
          shooter.factorFlip = factorFlip;
      }
      clearShooter() {
          for (let shooter of this.shooter) {
              shooter.spine.destroy();
          }
          this.shooter = [];
      }
      getShooter(index = 0) {
          return this.shooter[index];
      }
      syncShooter(tower) {
          for (let i = this.shooter.length; i < tower.comAttackers.length; i++) {
              let skillDb = tower.skillDb;
              if (skillDb)
                  this.addShooter(skillDb.spine, skillDb.spine_flip);
          }
          ResTowerManager.getTowerRes(tower.towerDb.id).setSpine(tower.skillDb.spine);
      }
      syncShooterByDB(towerDb, star = 0) {
          for (let i = this.shooter.length; i < mgrTower.getTowerAttackNum(towerDb.id, star); i++) {
              let skillDb;
              if (towerDb.main) {
                  skillDb = db.get_skill_db_map()[mgrTower.getMainSkillId()];
              }
              else {
                  skillDb = db.get_skill_db_map()[towerDb.skill_id];
              }
              if (skillDb)
                  this.addShooter(skillDb.spine, skillDb.spine_flip);
          }
      }
      initSkin(tower, updateRedPoint = true) {
          let towerW = tower.towerDb.size[0];
          let towerH = tower.towerDb.size[1];
          this.x = (tower.gx + towerW / 2) * Level.tileW;
          this.y = (tower.gy + towerH / 2) * Level.tileH;
          this.zOrder = this.y;
          this.towerDb = tower.towerDb;
          this.refreshQuality(this.towerDb.id);
          this.resetHpBar(tower.getAttr(BASE_ATTR.HP), tower.getAttrMax(BASE_ATTR.HP));
          if (updateRedPoint)
              this.updateRedPoint(null);
          else
              this.hideRedPoint();
          this.initGuideTip();
      }
      refreshQuality(id) {
          this.ctrlQuality.selectedIndex = mgrTower.getTowerStar(id);
          this.refreshHpBarPosition();
      }
      refreshSkill(tower) {
          if (tower.towerDb.main) {
              for (let shooter of this.shooter) {
                  shooter.owner.destroy();
              }
              this.shooter.length = 0;
              this.syncShooter(tower);
          }
      }
      refreshSkillByDB(towerDb, reset = false, star = 0) {
          if (towerDb.main) {
              if (reset) {
                  for (let shooter of this.shooter) {
                      shooter.owner.destroy();
                  }
                  this.shooter.length = 0;
              }
              this.syncShooterByDB(towerDb, star);
          }
      }
      getHitPoint(index, offset = 0.5, random = false) {
          if (random) {
              let halfW = 20;
              let halfH = 20;
              this._tempPoint.x = this.x + Utils.random(-halfW, halfW);
              this._tempPoint.y = this.y - this.skin.height * this.skin.scaleY * offset + Utils.random(-halfH, halfH);
          }
          else {
              this._tempPoint.x = this.x;
              this._tempPoint.y = this.y - this.skin.height * this.skin.scaleY * offset;
          }
          return this._tempPoint;
      }
      getHitOffset(index, offset = 0.5) {
          this._tempPoint.x = 0;
          this._tempPoint.y = -this.skin.height * this.skin.scaleY * offset;
          return this._tempPoint;
      }
      get width() {
          return 0;
      }
      get height() {
          return this.skin.height * this.skin.scaleY;
      }
      getShootPoint(indexShooter, indexPoint, convert = true) {
          let shooter = this.getShooter(indexShooter);
          if (shooter) {
              return shooter.getShootPoint(this.parent, indexPoint, convert);
          }
          else {
              if (convert) {
                  this._tempPoint.x = this.skin.x;
                  this._tempPoint.y = this.skin.y;
              }
              else {
                  this._tempPoint.x = 0;
                  this._tempPoint.y = 0;
              }
              return this._tempPoint;
          }
      }
      updateRedPoint(haveHolyItemCanEquip) {
          if (this.hpBar && this.towerDb) {
              this.hpBar.updateRedPoint(this.towerDb.id, haveHolyItemCanEquip);
          }
      }
      hideRedPoint() {
          if (this.hpBar) {
              this.hpBar.hideRedPoint();
          }
      }
      initGuideTip() {
          if (this.hpBar && this.towerDb) {
              this.hpBar.initGuideTip(this.towerDb.id);
          }
      }
      playDead() {
          this.removeHpBar();
          for (let shooter of this.shooter) {
              shooter.playDead();
              shooter.spine.filters = this.grayFilter;
          }
          if (this.skin) {
              this.skin.grayed = true;
          }
          this.bInvalid = true;
      }
      recover() {
          this.clearShooter();
          if (this.skin) {
              this.skin.grayed = false;
          }
          super.recover();
      }
  }
  TowerSkin.poolkey = "TowerSkin";

  class PanelCollectDetailTower extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "图鉴_塔详情";
          this.sourceName = "ui://collect_detail/PanelCollectDetailTower";
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_skill1: "fgui.GBasicTextField",
              cc_label_skill2: "fgui.GBasicTextField",
              cc_loader_item1: "fgui.GLoader",
              cc_loader_item2: "fgui.GLoader",
              cc_loader_item3: "fgui.GLoader",
              cc_loader_item4: "fgui.GLoader",
              cc_com_stage: "fgui.GComponent",
              cc_com_skill1: "fgui.GComponent",
              cc_com_skill2: "fgui.GComponent",
              cc_button_reward: "fgui.GButton",
              cc_list_tip: "fgui.GList",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      buildUi() {
          this.towerDb = this.context.towerDb;
          this.collectDb = this.context.collectDb;
          this.listTip = new ListView(this.list_tip, this, this.parseTipItem, this.renderTipItem);
          this.refresh();
      }
      dispose() {
          if (this.skin) {
              this.skin.destroy();
              this.skin = null;
          }
          super.dispose();
      }
      parseTipItem(content, object) {
          content.icon = object.getChild("icon").asImage;
          content.title = object.getChild("title").asTextField;
      }
      renderTipItem(content, data) {
          content.title.text = data.tip;
          if (data.color)
              content.icon.color = data.color;
      }
      refreshTipList() {
          let towerDb = this.towerDb;
          if (!towerDb)
              return;
          let listData = [];
          let tips = towerDb.tip_collect.split("/");
          for (let i = 0; i < tips.length; i++) {
              listData.push({ tip: tips[i], color: towerDb.tip_color[i] });
          }
          this.listTip.setListData(listData);
      }
      refresh() {
          let towerDb = this.towerDb;
          if (!towerDb)
              return;
          let skin = new TowerSkin();
          skin.loadSkin(towerDb, true);
          this.skin = skin;
          this.com_stage.displayObject.addChild(skin);
          if (this.towerDb.main) {
              this.skin.refreshSkillByDB(this.towerDb);
          }
          else {
              this.skin.syncShooterByDB(this.towerDb);
          }
          this.label_name.text = towerDb.name;
          this.label_desc.text = towerDb.desc;
          let skillDb1 = db.get_skill_db(mgrTower.getTowerSkillId(towerDb.id));
          let skillDb2 = db.get_skill_db(mgrTower.getTowerSuperId(towerDb.id));
          this.com_skill1.icon = skillDb1.icon;
          this.com_skill2.icon = skillDb2.icon;
          this.label_skill1.text = skillDb1.desc;
          this.label_skill2.text = skillDb2.desc;
          this.refreshTipList();
          this.loader_item1.url = this.getHolyItemIcon(towerDb.holyitem_ids[0] || "1");
          this.loader_item2.url = this.getHolyItemIcon(towerDb.holyitem_ids[1] || "1");
          this.loader_item3.url = this.getHolyItemIcon(towerDb.holyitem_ids[2] || "1");
          this.loader_item4.url = this.getHolyItemIcon(towerDb.holyitem_ids[3] || "1");
          this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
          let collectDb = this.collectDb;
          if (collectDb) {
              this.button_reward.title = collectDb.reward_item_count.toString();
              this.button_reward.icon = mgrGame.getItemIcon(collectDb.reward_item_id);
              if (mgrGame.getItemCount(collectDb.item_id)) {
                  if (mgrCollect.isRewarded(collectDb.item_id)) {
                      this.ctrl_reward.selectedIndex = 2;
                  }
                  else {
                      this.ctrl_reward.selectedIndex = 1;
                  }
              }
              else {
                  this.ctrl_reward.selectedIndex = 0;
              }
          }
          else {
              this.ctrl_reward.selectedIndex = 2;
          }
      }
      getHolyItemIcon(id) {
          let data = db.get_holy_item_db(id);
          if (data)
              return data.icon;
          else
              return "";
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_reward() {
          if (mgrCollect.tryGetReward(this.collectDb)) {
              this.refresh();
          }
      }
  }

  class CustomDailyDamageDesc extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://dailydamage/CustomDailyDamageDesc";
          this.exportNodeNames = {
              cc_label_name: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_ctrl_style: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.label_name.text = data.name;
          this.label_desc.text = data.desc;
          if (data.style < this.ctrl_style.pageCount)
              this.ctrl_style.selectedIndex = data.style;
      }
  }

  class CustomDailyDmageHistoryItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://dailydamage/CustomDailyDmageHistoryItem";
          this.exportNodeNames = {
              cc_label_name: "fgui.GBasicTextField",
              cc_label_damage: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.label_name.text = data.name;
          this.label_damage.text = StageTool.formatDailyDamage(mgrDailyDamage.getDamageHistory(data.id));
      }
  }

  class SceneBase {
  }

  class LogicSkillManager extends LogicTicker {
      constructor(world) {
          super();
          this.funcSkillTemplate = {};
          this.funcBuffTemplate = {};
          this.world = world;
          this.linkActions = new LinkList();
      }
      tick() {
          let head = this.linkActions.head;
          while (head) {
              let action = head.data;
              head = head.next;
              if (action) {
                  action.tick();
              }
          }
      }
      addAction(action) {
          let item = this.linkActions.append(action);
          action.listItem = item;
      }
      registSkillTempate(template, data) {
          this.funcSkillTemplate[template] = data;
          return this;
      }
      registSkillTempates(skills) {
          for (let template of skills) {
              this.registSkillTempate(template.name, template);
          }
          return this;
      }
      setSkillPackFunc(callback) {
          this.funcPackSkill = callback;
      }
      packSkillData(skillData, skillId) {
          if (this.funcPackSkill) {
              this.funcPackSkill(skillData, skillId);
          }
      }
      useSkill(caster, target, skillData, index = 0, count = 0) {
          this.execSkill(skillData.template, caster, target, skillData, index, count);
      }
      findTarget2Cast(template, caster, target, skillData = null, index = 0) {
          let config = this.funcSkillTemplate[template];
          if (config && config.find) {
              return LogicTool.safeCall(config.find, template, caster, target, skillData, index);
          }
          else {
              return target;
          }
      }
      findTargets(caster, target, skillData, index = 0, count = 0) {
          let template = skillData.template;
          let config = this.funcSkillTemplate[template];
          if (config && config.multi) {
              let targets = LogicTool.safeCall(config.multi, template, caster, target, skillData, index);
              if (targets) {
                  return targets;
              }
          }
          else {
              return [target];
          }
      }
      findTarget2Exec(caster, target, skillData, index = 0, count = 0) {
          let targets = this.findTargets(caster, target, skillData, index);
          if (targets) {
              for (let obj of targets) {
                  this.useSkill(caster, obj, skillData, index, count);
              }
          }
      }
      execSkill(template, caster, target, skillData = null, index = 0, count = 0) {
          let config = this.funcSkillTemplate[template];
          if (config) {
              LogicTool.safeCall(config.exec, template, caster, target, skillData, index, count);
          }
      }
      hitSkill(casterId, targetId, template, skillData, count) {
          let config = this.funcSkillTemplate[template];
          if (config) {
              LogicTool.safeCall(config.hit, casterId, targetId, template, skillData, count);
          }
      }
      registBuffTempate(template, funcStart, funcRestart, funcExec, funcEnd, funcCalc, funcExecAndClear) {
          console.log("注册BUFF模板", template);
          this.funcBuffTemplate[template] = {
              start: funcStart,
              restart: funcRestart,
              exec: funcExec,
              end: funcEnd,
              calc: funcCalc,
              execAndClear: funcExecAndClear,
          };
          return this;
      }
      registBuffTempates(buffs) {
          for (let template of buffs) {
              this.registBuffTempate(template.name, template.start, template.restart, template.exec, template.end, template.calc, template.execAndClear);
          }
          return this;
      }
      buffStart(template, caster, target, buff, param) {
          let config = this.funcBuffTemplate[template];
          if (config) {
              LogicTool.safeCall(config.start, caster, target, buff, param);
          }
      }
      buffRestart(template, caster, target, buff, param) {
          let config = this.funcBuffTemplate[template];
          if (config) {
              LogicTool.safeCall(config.restart, caster, target, buff, param);
          }
      }
      buffExec(template, target, buff) {
          let config = this.funcBuffTemplate[template];
          if (config) {
              LogicTool.safeCall(config.exec, target, buff);
          }
      }
      buffCalc(template, target, buff) {
          let config = this.funcBuffTemplate[template];
          if (config) {
              LogicTool.safeCall(config.calc, target, buff);
          }
      }
      buffEnd(template, target, buff) {
          let config = this.funcBuffTemplate[template];
          if (config) {
              LogicTool.safeCall(config.end, target, buff);
          }
      }
      buffExecAndClear(template, target, buff, skillDb) {
          let config = this.funcBuffTemplate[template];
          if (config) {
              if (config.execAndClear) {
                  LogicTool.safeCall(config.execAndClear, target, buff, skillDb);
                  return true;
              }
          }
          return false;
      }
  }

  var TRAP_STATE;
  (function (TRAP_STATE) {
      TRAP_STATE[TRAP_STATE["IDLE"] = 1] = "IDLE";
      TRAP_STATE[TRAP_STATE["BEGIN"] = 2] = "BEGIN";
      TRAP_STATE[TRAP_STATE["ATTACK"] = 3] = "ATTACK";
      TRAP_STATE[TRAP_STATE["CDING"] = 4] = "CDING";
      TRAP_STATE[TRAP_STATE["END"] = 5] = "END";
  })(TRAP_STATE || (TRAP_STATE = {}));
  class LogicTrap extends LogicObject {
      constructor() {
          super(...arguments);
          this.timeInState = 0;
          this.timeWtstate = 0;
          this.dataTrap = { time: 0, delay: 0, countExe: 0, countMax: 0, interval: 0 };
      }
      onCreate() {
          this.state = new StateMachine();
          this.state.registerState(TRAP_STATE.IDLE, "Idle", this);
          this.state.registerState(TRAP_STATE.BEGIN, "Begin", this);
          this.state.registerState(TRAP_STATE.ATTACK, "Attack", this);
          this.state.registerState(TRAP_STATE.CDING, "Cding", this);
          this.state.registerState(TRAP_STATE.END, "End", this);
          this.state.setState(TRAP_STATE.IDLE);
      }
      onUpdate(t) {
          this.state.update(t);
      }
      destroy() {
          this.world.remUnit(this);
      }
      start(caster, delay, time, interval) {
          this.tid = caster.tid;
          if (interval <= 0)
              return;
          this.dataTrap.delay = delay;
          this.dataTrap.time = time;
          this.dataTrap.countExe = 0;
          this.dataTrap.countMax = time / interval;
          this.dataTrap.interval = interval;
          this.state.setState(TRAP_STATE.BEGIN);
      }
      execSkill(caster) {
      }
      enterBegin() {
          this.timeInState = 0;
          this.timeWtstate = this.dataTrap.delay;
      }
      execBegin(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              this.state.setState(TRAP_STATE.ATTACK);
          }
      }
      enterAttack() {
          this.dataTrap.countExe++;
          this.execSkill(this);
          if (this.dataTrap.countExe >= this.dataTrap.countMax) {
              this.state.setState(TRAP_STATE.END);
          }
          else {
              this.state.setState(TRAP_STATE.CDING);
          }
      }
      enterCding() {
          this.timeInState = 0;
          this.timeWtstate = this.dataTrap.interval;
      }
      execCding(t) {
          this.timeInState += t;
          if (this.timeInState >= this.timeWtstate) {
              this.state.setState(TRAP_STATE.ATTACK);
          }
      }
      enterEnd() {
          this.destroy();
      }
  }
  LogicTrap.poolkey = "LogicTrap";

  class LogicEnemyVirtual extends LogicObject {
      constructor() {
          super(...arguments);
          this.virtual = true;
      }
      execSkill(caster, data) {
          this.dispose();
      }
      execSkillWithDamage(caster, damage, data) {
          this.dispose();
      }
      dispose() {
          this.world.remUnit(this);
      }
      addBuffById(caster, buffId) {
          if (buffId) {
              let buffDb = db.get_buff_db(buffId);
              if (buffDb) {
                  this.addBuff(caster, buffDb.id, buffDb.template, buffDb.time, buffDb.delay, buffDb.count);
              }
          }
      }
  }
  LogicEnemyVirtual.poolkey = "LogicEnemyVirtual";

  class LogicWorld {
      getMap() {
          return this.map;
      }
      getObjectMgr() {
          return this.objectMgr;
      }
      getSkillMgr() {
          return this.skillMgr;
      }
      getTickMgr() {
          return this.tickMgr;
      }
      init(gridW = 40, gridH = 40) {
          this.map = new LogicMap(this);
          this.map.initGrid(gridW, gridH);
          this.tickMgr = new LogicTickManager(this);
          this.objectMgr = new LogicObjectManager(this);
          this.skillMgr = new LogicSkillManager(this);
          this.tickMgr.addTicker(this.objectMgr);
          this.tickMgr.addTicker(this.skillMgr);
          this.buildings = new LinkList();
          return this;
      }
      tickTime(dt) {
          this.tickMgr.tickTime(dt);
      }
      setOnUnitCreateListener(callback) {
          this.callbackOnUnitCreate = callback;
      }
      setOnUnitRemoveListener(callback) {
          this.callbackOnUnitRemove = callback;
      }
      setOnBulletCreateListener(callback) {
          this.callbackOnBulletCreate = callback;
      }
      setOnEffectHitCreateListener(callback) {
          this.callbackOnEffectHitCreate = callback;
      }
      eventEffectHitCreate(caster, target, skillId, count, flipX = 1) {
          LogicTool.safeCall(this.callbackOnEffectHitCreate, caster, target, skillId, count, flipX);
      }
      eventBulletCreate(...arg) {
          LogicTool.safeCall(this.callbackOnBulletCreate, ...arg);
      }
      eventBuffRemove(...arg) {
      }
      addUnit(unit, x, y, ...arg) {
          unit.create(this);
          this.map.moveObjectTo(unit, x, y);
          LogicTool.safeCall(this.callbackOnUnitCreate, unit, x, y, ...arg);
      }
      remUnit(unit, reason) {
          if (unit.removed)
              return;
          this.objectMgr.remObject(unit);
          this.map.remObject(unit);
          LogicTool.safeCall(this.callbackOnUnitRemove, unit, reason);
          unit.remove();
      }
      remAllUnit(camp, reason) {
          let head = this.objectMgr.getLinkHead();
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object && (!camp || object.camp == camp)) {
                  if (object instanceof LogicBuilding) {
                      this.remBuilding(object, reason);
                  }
                  else {
                      this.remUnit(object, reason);
                  }
              }
          }
      }
      remAllTrap(reason) {
          let head = this.objectMgr.getLinkHead();
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object) {
                  if (object instanceof LogicTrap) {
                      this.remUnit(object, reason);
                  }
              }
          }
      }
      clearAllEnemyById(tid, reason) {
          let head = this.objectMgr.getLinkHead();
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object instanceof LogicEnemy) {
                  if (object.tid == tid) {
                      this.remUnit(object, reason);
                  }
              }
          }
      }
      clearAllEnemyBuff(exceptIds) {
          let head = this.objectMgr.getLinkHead();
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object) {
                  if (object instanceof LogicEnemy) {
                      object.clearAllBuff(exceptIds);
                  }
              }
          }
      }
      findEnemyByRoleId(tid) {
          let head = this.objectMgr.getLinkHead();
          while (head) {
              let object = head.getData();
              head = head.next;
              if (object) {
                  if (object instanceof LogicEnemy) {
                      if (object.tid == tid) {
                          return object;
                      }
                  }
              }
          }
      }
      addEnemy(clas, x, y, roleId, layer) {
          let unit = LogicObject.create(clas, roleId, layer);
          unit.camp = LogicCamp.ENEMY;
          this.addUnit(unit, x, y);
          return unit;
      }
      addVirtual(x, y, roleId, layer) {
          let unit = LogicObject.create(LogicEnemyVirtual, roleId, layer);
          unit.camp = LogicCamp.VIRTUAL;
          this.addUnit(unit, x, y);
          return unit;
      }
      addTrap(clas, x, y, skillId) {
          let unit = LogicObject.create(clas, skillId);
          unit.camp = LogicCamp.NONE;
          this.addUnit(unit, x, y);
          return unit;
      }
      setOnBuildingCreateListener(callback) {
          this.callbackOnBuildingCreate = callback;
      }
      setOnBuildingMoveListener(callback) {
          this.callbackOnBuildingMove = callback;
      }
      setOnBuildingRemoveListener(callback) {
          this.callbackOnBuildingRemove = callback;
      }
      addBuilding(clas, x, y, tid, shape = [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }]) {
          let building = new clas(tid);
          building.create(this);
          building.camp = LogicCamp.FRIEND;
          building.setShape(shape);
          this.map.moveBuildingTo(building, x, y, building.shape);
          LogicTool.safeCall(this.callbackOnBuildingCreate, building, x, y);
          this.buildings.append(building);
          return building;
      }
      moveBuilding(building, x, y) {
          let ox = building.gx;
          let oy = building.gy;
          this.map.moveBuildingTo(building, x, y, building.shape);
          LogicTool.safeCall(this.callbackOnBuildingMove, building, x, y, ox, oy);
          return building;
      }
      addBuildingShage(x, y, shape = [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }]) {
          for (let data of shape) {
              this.map.addFlag(x + data.x, y + data.y, MAP_FLAG.BUILDING);
          }
      }
      remBuilding(building, reason) {
          if (building.removed)
              return;
          let item = this.buildings.find(building);
          if (item) {
              item.removeFromList();
          }
          this.objectMgr.remObject(building);
          this.map.remBuilding(building, building.shape);
          LogicTool.safeCall(this.callbackOnBuildingRemove, building, reason);
          building.remove();
      }
      findBuildingNearest(gx, gy) {
          let head = this.buildings.head;
          let disanceMax = Number.MAX_VALUE;
          let nearBuilding = null;
          while (head) {
              let data = head.data;
              head = head.next;
              if (data) {
                  let dx = data.gx - gx;
                  let dy = data.gy - gy;
                  let distanceSq = dx * dx + dy * dy;
                  if (distanceSq < disanceMax) {
                      disanceMax = distanceSq;
                      nearBuilding = data;
                  }
              }
          }
          return nearBuilding;
      }
      destroyView() {
          var head = this.objectMgr.getLinkHead();
          while (head) {
              let unit = head.data;
              head = head.next;
              if (unit) {
                  if (unit instanceof LogicTower) {
                      LogicTool.safeCall(this.callbackOnBuildingRemove, unit, null, true);
                  }
                  else {
                      LogicTool.safeCall(this.callbackOnUnitRemove, unit, null, true);
                  }
              }
          }
      }
      restoreView() {
          var head = this.objectMgr.getLinkHead();
          while (head) {
              let unit = head.data;
              head = head.next;
              if (unit) {
                  if (unit instanceof LogicTower) {
                      LogicTool.safeCall(this.callbackOnBuildingCreate, unit, unit.mx, unit.my, true);
                  }
                  else {
                      LogicTool.safeCall(this.callbackOnUnitCreate, unit, unit.mx, unit.my, true);
                  }
              }
          }
      }
  }

  class StateMachine2D extends Laya.Script {
      constructor() {
          super();
          this.isRunning = false;
          this.stateCurt = 0;
          this.stateNext = 0;
          this.state2name = {};
          this.funcEnter = {};
          this.funcExecute = {};
          this.funcExit = {};
          this.funcExecuteCurt = StateMachine2D.FuncEmpty;
          this.state2relation = {};
          this.state2nextstate = {};
          this.caller = this;
      }
      onUpdate() {
          if (this.isRunning)
              this.update(GameConst.FrameDeltaTime);
      }
      update(dt) {
          this.updateLogic(dt);
      }
      updateLogic(dt) {
          this.funcExecuteCurt(dt);
          if (this.stateNext) {
              this.callFunc(this.funcExit[this.stateCurt], dt);
              this.stateLast = this.stateCurt;
              this.stateCurt = this.stateNext;
              this.stateNext = 0;
              this.funcExecuteCurt = this.funcExecute[this.stateCurt];
              this.callFunc(this.funcEnter[this.stateCurt], dt);
          }
      }
      static FuncEmpty() { }
      ;
      registerState(state, stateName, caller, funcEnter, funcExecute, funcExit) {
          this.state2name[state] = stateName;
          if (caller)
              this.caller = caller;
          if (funcEnter) {
              this.funcEnter[state] = funcEnter;
          }
          else {
              this.funcEnter[state] = this.caller["enter" + stateName];
          }
          if (funcExecute) {
              this.funcExecute[state] = funcExecute.bind(this.caller);
          }
          else {
              this.funcExecute[state] = (this.caller["exec" + stateName] || StateMachine2D.FuncEmpty).bind(this.caller);
          }
          if (funcExit) {
              this.funcExit[state] = funcExit;
          }
          else {
              this.funcExit[state] = this.caller["exit" + stateName];
          }
      }
      registerRelation(state, toStates, nextState) {
          if (nextState) {
              this.state2nextstate[state] = nextState;
          }
          var relation = this.state2relation[state];
          if (!relation) {
              relation = {};
          }
          var len = toStates.length;
          for (var i = 0; i < len; i++) {
              relation[toStates[i]] = true;
          }
          this.state2relation[state] = relation;
      }
      resetMachine() {
          this.stateCurt = 0;
          this.stateNext = 0;
      }
      setCurrentState(state) {
          this.callFunc(this.funcExit[this.stateCurt]);
          this.callFunc(this.funcEnter[state]);
          this.stateCurt = state;
          this.stateNext = 0;
          this.funcExecuteCurt = this.funcExecute[this.stateCurt] || StateMachine2D.FuncEmpty;
      }
      exitState(force) {
          var stateNext = this.state2nextstate[this.stateCurt];
          if (stateNext) {
              this.setState(stateNext, force);
          }
          else {
              this.setState(this.stateLast, force);
          }
      }
      setNextStateByName(name) {
          this.setNextState(this.name2state[name], false);
      }
      setState(state, force) {
          let result = this.setNextState(state, force);
          if (!result) {
          }
          else {
          }
      }
      setStateNoReEnter(state, force) {
          if (!force && this.stateCurt == state)
              return false;
          this.setState(state, force);
          return true;
      }
      getState() {
          return this.stateCurt;
      }
      getLastState() {
          return this.stateLast;
      }
      getNextState(state) {
          return this.state2nextstate[state];
      }
      getStateName(state) {
          return this.state2name[state];
      }
      checkRelation(fromState, toState) {
          var relation = this.state2relation[fromState];
          if (relation) {
              let friend = relation[toState];
              if (!friend) {
                  return false;
              }
          }
          return true;
      }
      setNextState(state, force) {
          if (!force && (this.stateCurt == state || this.stateNext == state))
              return true;
          if (this.stateNext && !force) {
              if (!this.checkRelation(this.stateNext, state)) {
                  return false;
              }
          }
          else {
              if (this.stateCurt && !force) {
                  if (!this.checkRelation(this.stateCurt, state)) {
                      return false;
                  }
              }
          }
          this.stateNext = state;
          return true;
      }
      callFunc(func, dt) {
          if (func) {
              func.call(this.caller, dt);
          }
      }
  }

  class StageBase2D extends StateMachine2D {
      constructor() {
          super(...arguments);
          this.screenOffsetX = 0;
          this.screenOffsetY = 0;
      }
      onAwake() {
          this.scene = this.owner;
          this.fitScreen();
      }
      fitScreen() {
          this.screenOffsetX = (UIRoot.canvasWidth - this.scene.width) / 2;
          this.screenOffsetY = (UIRoot.canvasHeight - this.scene.height) / 2;
          this.scene.x += this.screenOffsetX;
          this.scene.y += this.screenOffsetY;
      }
  }

  class Tower extends LogicTower {
      constructor() {
          super(...arguments);
          this.timepassHpRecover = 0;
          this.timemaxxHpRecover = 3;
          this.dataFuncCD = {};
          this._tempPoint = new Laya.Point;
          this.passTimer = 0;
          this.maxxTimer = 1;
      }
      onCreate() {
          super.onCreate();
          this.attrCur = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          this.attrStd = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          this.attrScl = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          this.loadTowerById(this.tid);
          this.syncAttacker();
      }
      onUpdate(t) {
          super.onUpdate(t);
          this.updateMpRecover(t);
          this.updateHpRecover(t);
          this.updateTimer(t);
      }
      onRemove() {
          super.onRemove();
          this.unbindSkin();
      }
      takeoff() {
          if (this.slotId) {
              let towerId = mgrTower.getSlotTower(this.slotId - 1);
              mgrTower.equipTower(this.slotId - 1, null);
              this.world.remBuilding(this);
              Global.sendMsg(MSG.TOWER_TAKEOFF, { slotId: this.slotId, towerId: towerId });
          }
      }
      updateMpRecover(t) {
          if (StageAttr.noAttr(STAGE_ATTR.SILENCE)) {
              let recover = this.getEnergyRecover();
              this.addEnergy(t * recover);
          }
          if (this.skin) {
              this.skin.updateMpBar(this.getAttr(BASE_ATTR.MP), this.getAttrMax(BASE_ATTR.MP));
          }
      }
      updateHpRecover(t) {
          this.timepassHpRecover += t;
          if (this.timepassHpRecover >= this.timemaxxHpRecover) {
              this.timepassHpRecover = 0;
              let SK_HP_RECOVER = this.attrCur[BASE_ATTR.SK_HP_RECOVER];
              if (SK_HP_RECOVER > 0) {
                  let hurtHP = this.attrStd[BASE_ATTR.HP] - this.attrCur[BASE_ATTR.HP];
                  if (hurtHP > 0) {
                      let add = Math.round(hurtHP * SK_HP_RECOVER);
                      let dd = DamageCalculation.damageData;
                      dd.damage = add;
                      this.cure(dd);
                      DamageCalculation.holyDebug("再生");
                  }
              }
          }
      }
      searchTargets() {
          let selectUids = {};
          let enemyList = this.findObjectsByRangeAndCampId(LogicCamp.ENEMY, selectUids);
          if (StageConfig.towerTargetSearchType == TOWER_TARGET_SEARCH_TYPE.HP_LESS) {
              enemyList.sort(this.sortByHP);
          }
          let friendList = this.findObjectsByRangeAndCampId(LogicCamp.FRIEND, selectUids);
          let objectList;
          if (this.getSkillCampID() == LogicCamp.ENEMY) {
              objectList = enemyList;
          }
          else {
              objectList = friendList;
          }
          this.updateHalo(enemyList, friendList);
          return objectList;
      }
      sortByHP(a, b) {
          return a.getAttr(BASE_ATTR.HP) - b.getAttr(BASE_ATTR.HP);
      }
      updateHalo(enemyList, friendList) {
          DamageCalculation.calcHalo(this, enemyList, friendList);
      }
      syncAttacker() {
          if (this.skillDb) {
              for (let i = this.comAttackers.length; i < mgrTower.getTowerAttackNum(this.towerDb.id); i++) {
                  this.addAttacker();
              }
          }
      }
      calcBuffBySkillCaster(caster, skillId, skillData) {
          let skillDb = skillData.skillDb;
          if (skillDb && skillDb.buff_caster_id) {
              this.addBuffByProb(caster, skillDb.buff_caster_id, skillDb.buff_caster_prob);
          }
      }
      calcBuffBySkillTarget(caster, skillId, skillData) {
          let skillDb = skillData.skillDb;
          if (skillDb && skillDb.buff_target_id) {
              this.addBuffByProb(caster, skillDb.buff_target_id, skillDb.buff_target_prob);
          }
      }
      addBuffByProb(caster, buffId, prob) {
          let r = Utils.random(0, 99);
          if (r < prob) {
              this.addBuffById(caster, buffId);
          }
      }
      calcDamage(caster, data, dmgData) {
          return DamageCalculation.calcDamageByEnemy(caster, this, data, dmgData);
      }
      execSkill(caster, skillData) {
          let data = skillData.skillDb;
          let damge = this.calcDamage(caster, skillData);
          if (data.damage_add_by_count > 0) {
              damge.damage = Math.ceil(damge.damage * (skillData.count * data.damage_add_by_count));
          }
          if (data.blood) {
              damge.blood = Math.ceil(damge.damage * data.blood);
          }
          this.execSkillWithDamage(caster, damge, skillData);
          if (caster && damge.blood) {
              damge.damage = damge.blood;
              caster.cure(damge);
          }
      }
      execSkillWithDamage(caster, damageData, skillData) {
          let data = skillData.skillDb;
          switch (data.cmd) {
              case "none":
                  break;
              case "cure":
                  this.cure(damageData);
                  break;
              case "energy":
                  this.addEnergyPercent(data.damage, true);
                  break;
              case "wudi":
                  break;
              case "kill":
                  this.killSelf(damageData);
                  break;
              default:
                  if (StageConfig.enableGameEffect && data.effect_hurt && this.skin) {
                      let halfW = this.skin.width * 0.5;
                      let halfH = this.skin.height * 0.5;
                      let offsetX = Utils.random(-halfW, halfW);
                      let offsetY = -this.skin.height * data.hit_offset + Utils.random(-20, 20);
                      EffectFactory.createByType(data.effect_hurt, EffectFactory.layerFront, this.skin, null, null, offsetX, offsetY);
                  }
                  let isShieldOnce = this.checkFlag(LogicObjectFlag.SHIELD_ONCE);
                  this.hurt(damageData);
                  let SK_HURT_DAMAGE_RECOVER_HP = this.getAttr(BASE_ATTR.SK_HURT_DAMAGE_RECOVER_HP);
                  if (SK_HURT_DAMAGE_RECOVER_HP > 0) {
                      if (DamageCalculation.calcProb(db.game_cnf.holyitem_config_35)) {
                          let addhp = Math.ceil(damageData.damage * SK_HURT_DAMAGE_RECOVER_HP);
                          this.cureByValue(addhp);
                      }
                  }
                  if (caster.camp == LogicCamp.ENEMY) {
                      let SK_HURT_HP_R_RECOVER_MP = this.getAttr(BASE_ATTR.SK_HURT_HP_R_RECOVER_MP);
                      if (SK_HURT_HP_R_RECOVER_MP > 0) {
                          let curtTime = this.world.tickMgr.time;
                          if (!this.isFuncCDing("SK_HURT_HP_R_RECOVER_MP", curtTime)) {
                              this.beginFuncCDing("SK_HURT_HP_R_RECOVER_MP", curtTime, SK_HURT_HP_R_RECOVER_MP);
                              let percent = Math.floor((1 - this.getAttrPercent(BASE_ATTR.HP)) * 100);
                              this.addEnergy(percent);
                          }
                      }
                  }
                  if (!isShieldOnce) {
                      let SK_HURT_NEXT_WUDI = this.getAttr(BASE_ATTR.SK_HURT_NEXT_WUDI);
                      if (SK_HURT_NEXT_WUDI > 0) {
                          if (DamageCalculation.calcProb(SK_HURT_NEXT_WUDI)) {
                              this.addFlag(LogicObjectFlag.SHIELD_ONCE);
                          }
                      }
                  }
                  let SK_HURT_REBOUND = this.getAttr(BASE_ATTR.SK_HURT_REBOUND);
                  if (SK_HURT_REBOUND > 0) {
                      let damage = Math.ceil(damageData.damage * SK_HURT_REBOUND);
                      damageData.damage = damage;
                      damageData.tidCaster = caster.tid;
                      caster.hurt(damageData);
                  }
                  break;
          }
      }
      cure(data) {
          let addhp = data.damage;
          this.cureByValue(addhp);
      }
      cureByValue(addhp) {
          if (addhp <= 0)
              return;
          let attrSelf = this.attrCur;
          let SHADOW = StageAttr.getAttr(STAGE_ATTR.SHADOW);
          if (SHADOW > 0) {
              addhp = Math.floor(addhp * (1 - SHADOW));
              if (addhp <= 0) {
                  return;
              }
          }
          let hpMax = this.attrStd[BASE_ATTR.HP];
          let hpLeft = attrSelf[BASE_ATTR.HP] + addhp;
          if (hpLeft > hpMax) {
              hpLeft = hpMax;
          }
          attrSelf[BASE_ATTR.HP] = hpLeft;
          this.updateHpBar();
          this.showCure(addhp);
      }
      hurt(data) {
          let damage = data.damage;
          if (this.checkFlag(LogicObjectFlag.SHIELD)) {
              data.isShield = true;
              damage = 0;
          }
          if (this.checkFlag(LogicObjectFlag.SHIELD_ONCE)) {
              this.remFlag(LogicObjectFlag.SHIELD_ONCE, true);
              data.isShield = true;
              damage = 0;
          }
          this.showDamage(data);
          if (damage > 0) {
              let attrSelf = this.attrCur;
              let dmgSuck = attrSelf[BASE_ATTR.DMG_SUCK];
              if (dmgSuck > 0) {
                  if (dmgSuck < damage) {
                      damage -= dmgSuck;
                      dmgSuck = 0;
                  }
                  else {
                      damage = 0;
                      dmgSuck -= damage;
                  }
                  attrSelf[BASE_ATTR.DMG_SUCK] = dmgSuck;
                  if (damage <= 0)
                      return;
              }
              let hpBefore = attrSelf[BASE_ATTR.HP];
              let hpLeft = hpBefore - damage;
              if (hpLeft <= 0) {
                  if (Level.stage.enemyWave.isIdleMode()) {
                      hpLeft = 1;
                  }
                  else {
                      hpLeft = 0;
                  }
              }
              attrSelf[BASE_ATTR.HP] = hpLeft;
              if (hpLeft <= 0) {
                  let SK_REVIVE = attrSelf[BASE_ATTR.SK_REVIVE];
                  if (SK_REVIVE && SK_REVIVE > 0) {
                      if (DamageCalculation.calcProb(SK_REVIVE)) {
                          hpLeft = attrSelf[BASE_ATTR.HP] = Math.round(this.attrStd[BASE_ATTR.HP] * 0.5);
                          DamageCalculation.holyDebug("神佑复生");
                      }
                  }
              }
              this.updateHpBar();
              if (hpLeft <= 0 && !this.removed) {
                  this.onDead();
              }
          }
      }
      killSelf(data) {
          let attrSelf = this.attrCur;
          data.damage = attrSelf[BASE_ATTR.HP];
          let damage = data.damage;
          this.showDamage(data);
          if (damage > 0) {
              let hpBefore = attrSelf[BASE_ATTR.HP];
              let hpLeft = hpBefore - damage;
              this.updateHpBar();
              if (hpLeft <= 0 && !this.removed) {
                  this.onDead(true);
              }
          }
      }
      onDead(force = false) {
          let isDead = true;
          if (!force) {
              let SK_DEAD_4_WUDI = this.getAttr(BASE_ATTR.SK_DEAD_4_WUDI);
              if (SK_DEAD_4_WUDI > 0) {
                  let curtTime = this.world.tickMgr.time;
                  if (!this.isFuncCDing("NO_DEAD_CD", curtTime)) {
                      this.beginFuncCDing("NO_DEAD_VALID", curtTime, SK_DEAD_4_WUDI);
                      this.beginFuncCDing("NO_DEAD_CD", curtTime, db.game_cnf.holyitem_config_43);
                  }
                  if (this.isFuncCDing("NO_DEAD_VALID", curtTime)) {
                      isDead = false;
                  }
              }
          }
          if (isDead) {
              let SK_DEAD_4_BUFF = this.getAttr(BASE_ATTR.SK_DEAD_4_BUFF);
              this.world.remBuilding(this, UNIT_REMOVE_REASON.DEAD);
              mgrTower.setTowerAttrInBattle(this.towerDb.id, null, null);
              Global.sendMsg(MSG.TOWER_DEAD);
              if (SK_DEAD_4_BUFF > 0) {
                  this.addBuffToAllTower(db.game_cnf.holyitem_config_45, SK_DEAD_4_BUFF);
              }
          }
      }
      addBuffToAllTower(buffId, SK_DEAD_4_BUFF) {
          let world = this.world;
          let head = world.buildings.head;
          while (head) {
              let data = head.data;
              head = head.next;
              if (data) {
                  data.addBuffById(data, buffId, [1 + SK_DEAD_4_BUFF]);
              }
          }
      }
      isFuncCDing(key, curtTime) {
          let timeTick = this.dataFuncCD[key] || 0;
          if (timeTick == 0) {
              timeTick = curtTime;
          }
          return curtTime < timeTick;
      }
      beginFuncCDing(key, curtTime, cd) {
          this.dataFuncCD[key] = curtTime + cd;
      }
      showCure(damage) {
          if (damage <= 0)
              return;
          if (!this.skin)
              return;
          let text = CustomDamageText.create();
          text.showRecoverHP(damage);
          Level.stage.layerGameUI.addChild(text.displayObject);
          text.x = this.skin.x;
          text.y = this.skin.y - 50;
          text.displayObject.zOrder = text.y;
      }
      showCureMP(damage) {
          if (damage <= 0)
              return;
          if (this.skin) {
              let text = CustomDamageText.create();
              Level.stage.layerGameUI.addChild(text.displayObject);
              text.x = this.skin.x;
              text.y = this.skin.y - 50;
              text.showRecoverMP(damage);
              text.displayObject.zOrder = text.y;
          }
      }
      showDamage(damage) {
          if (!mgrGame.dmgFontEnable)
              return;
          if (this.skin && (damage.damage > 0 || damage.isShield || damage.isFlee)) {
              let text = CustomDamageText.create();
              Level.stage.layerGameUI.addChild(text.displayObject);
              text.x = this.skin.x;
              text.y = this.skin.y - 50;
              text.showDamage(damage);
              text.displayObject.zOrder = text.y;
          }
      }
      bindSkin(skin) {
          this.skin = skin;
          skin.initSkin(this);
          skin.syncShooter(this);
          this.updateHpBar();
          this.updateHpBarLv();
      }
      unbindSkin() {
          if (this.skin) {
          }
          this.skin = null;
      }
      updateHpBar() {
          if (this.skin) {
              let hp = this.attrCur[BASE_ATTR.HP];
              let hpMax = this.attrStd[BASE_ATTR.HP];
              this.skin.updateHpBar(hp, hpMax);
          }
      }
      updateHpBarLv() {
          if (this.skin) {
              this.skin.updateHpBarLv(mgrTower.getTowerLv(this.towerDb.id));
          }
      }
      set range(value) {
          this.attrCur[BASE_ATTR.RANGE] = value;
      }
      get range() {
          return this.attrCur[BASE_ATTR.RANGE];
      }
      loadTowerById(id, lv = 1) {
          let towerDb = db.get_tower_db(id);
          this.towerDb = towerDb;
          if (towerDb) {
              this.refreshAttr();
              this.attrCur[BASE_ATTR.MP] = 0;
              this.refreshSkill();
              this.rangex = Math.floor(towerDb.size[0] / 2);
              this.rangey = Math.floor(towerDb.size[1] / 2);
          }
          return this;
      }
      onAttrChange() {
          this.range = this.attrCur[BASE_ATTR.RANGE];
      }
      getEnergyRecover() {
          let SK_ENERGE_NONE = this.attrCur[BASE_ATTR.SK_ENERGE_NONE];
          if (SK_ENERGE_NONE > 0) {
              return 0;
          }
          let MP_RECOVER = this.attrCur[BASE_ATTR.MP_RECOVER];
          let SK_MP_RECOVER = this.attrCur[BASE_ATTR.SK_MP_RECOVER];
          if (SK_MP_RECOVER > 0) {
              MP_RECOVER = MP_RECOVER + MP_RECOVER * SK_MP_RECOVER;
          }
          return MP_RECOVER;
      }
      getAttackSpeed() {
          let SK_ATK_SPEED_DOWN_4_DAMAGE = this.attrCur[BASE_ATTR.SK_ATK_SPEED_DOWN_4_DAMAGE];
          if (SK_ATK_SPEED_DOWN_4_DAMAGE > 0) {
              return this.attrCur[BASE_ATTR.ATK_SPEED] * StageConfig.gameTimeScale * db.game_cnf.holyitem_config_41;
          }
          else {
              return this.attrCur[BASE_ATTR.ATK_SPEED] * StageConfig.gameTimeScale;
          }
      }
      getAttackSpeedNormal() {
          return this.attrCur[BASE_ATTR.ATK_SPEED] * StageConfig.gameTimeScale;
      }
      refreshAttr() {
          let attrStd = this.attrStd;
          let attrCur = this.attrCur;
          let hurtHp = (attrStd[BASE_ATTR.HP] || 0) - (attrCur[BASE_ATTR.HP] || 0);
          let hurtMp = (attrStd[BASE_ATTR.MP] || 0) - (attrCur[BASE_ATTR.MP] || 0);
          mgrTower.calcTowerAttr(this.towerDb.id, this.attrCur);
          Level.copyAttrArray(this.attrCur, this.attrStd);
          Level.resetAttrArray(this.attrScl, this.attrScl.length);
          let leftHp = attrCur[BASE_ATTR.HP] - hurtHp;
          let leftMp = attrCur[BASE_ATTR.MP] - hurtMp;
          attrCur[BASE_ATTR.HP] = Math.max(leftHp, 1);
          attrCur[BASE_ATTR.MP] = Math.max(leftMp, 0);
          this.calcAttrByBuff();
          this.updateHpBar();
          this.updateHpBarLv();
          this.searchTargets();
          mgrTower.setTowerAttrInBattle(this.towerDb.id, attrCur, this.attrStd);
      }
      calcAttrByBuff() {
          this.calcBuffAll(StageConfig.attrNoRecover);
      }
      refreshSkill() {
          let towerDb = this.towerDb;
          if (towerDb) {
              if (towerDb.main) {
                  this.skillDb = db.get_skill_db_map()[mgrTower.getMainSkillId()];
                  this.superDb = db.get_skill_db_map()[mgrTower.getMainSuperId()];
              }
              else {
                  this.skillDb = db.get_skill_db_map()[towerDb.skill_id];
                  this.superDb = db.get_skill_db_map()[towerDb.super_skill_id];
              }
          }
          if (this.skin) {
              this.skin.refreshSkill(this);
          }
      }
      isEnergyFull() {
          return StageConfig.keepSuperSkill || this.isAttrMax(BASE_ATTR.MP);
      }
      letEnergyEmpty() {
          this.attrCur[BASE_ATTR.MP] = 0;
      }
      letEnergyFull() {
          this.attrCur[BASE_ATTR.MP] = this.attrStd[BASE_ATTR.MP];
      }
      addEnergy(add = 1, show = false) {
          this.addAttr(BASE_ATTR.MP, add);
          if (show) {
              this.showCureMP(add);
          }
      }
      addEnergyPercent(percent = 1, show = false) {
          let add = this.getAttrMax(BASE_ATTR.MP) * percent;
          this.addAttr(BASE_ATTR.MP, add);
          if (show) {
              this.showCureMP(add);
          }
      }
      getEnergyPercent() {
          return this.getAttrPercent(BASE_ATTR.MP);
      }
      getSkillCampID() {
          let skillDb = this.skillDb;
          if (!StageConfig.handSuperSkill && this.superDb && this.isEnergyFull()) {
              skillDb = this.superDb;
          }
          if (skillDb) {
              return skillDb.camp;
          }
          else {
              return LogicCamp.ENEMY;
          }
      }
      canCastSkillToTarget(target, data) {
          if (data.camp == LogicCamp.SELF) {
              return true;
          }
          else {
              return target.camp == LogicCamp.VIRTUAL || target.camp == data.camp;
          }
      }
      packSkillData(data, skillDb) {
          if (skillDb.is_super) {
              let SK_TA_03 = this.getAttr(BASE_ATTR.SK_TA_03);
              if (SK_TA_03 > 0) {
                  if (DamageCalculation.calcProb(SK_TA_03)) {
                      for (let attacker of this.comAttackers) {
                          Level.packSkillData(attacker.skillDataHand, skillDb);
                          attacker.castHand(true);
                      }
                  }
              }
          }
          else {
              let SK_TA_04 = this.getAttr(BASE_ATTR.SK_TA_04);
              if (SK_TA_04) {
                  if (DamageCalculation.calcProb(SK_TA_04)) {
                      if (this.superDb) {
                          skillDb = this.superDb;
                      }
                  }
              }
          }
          Level.packSkillData(data, skillDb);
          if (!skillDb.is_super) {
              let atkSpeed;
              if (skillDb.atk_count == 0) {
                  atkSpeed = this.getAttackSpeedNormal();
              }
              else {
                  atkSpeed = this.getAttackSpeed();
              }
              data.timeCast = skillDb.cast_time / atkSpeed;
              data.timeCD = skillDb.cd_time / atkSpeed;
          }
          else {
              data.timeCast = skillDb.cast_time / StageConfig.gameTimeScale;
              data.timeCD = skillDb.cd_time / StageConfig.gameTimeScale;
          }
      }
      prepareSkillData(data) {
          let skillDb = this.skillDb;
          let triggerSuper = false;
          if (this.superDb) {
              if (this.attrCur[BASE_ATTR.NEXT_SKILL_SUPER]) {
                  skillDb = this.superDb;
                  this.attrCur[BASE_ATTR.NEXT_SKILL_SUPER] = 0;
                  triggerSuper = true;
              }
              else {
                  if (!StageConfig.handSuperSkill && this.isEnergyFull()) {
                      skillDb = this.superDb;
                      this.letEnergyEmpty();
                  }
              }
          }
          if (skillDb) {
              this.packSkillData(data, skillDb);
              data.triggerSuper = triggerSuper;
          }
      }
      prepareSuperSkillData(data) {
          if (this.superDb && this.isEnergyFull()) {
              let skillDb = this.superDb;
              if (skillDb) {
                  this.packSkillData(data, skillDb);
              }
              this.letEnergyEmpty();
          }
      }
      isSuperSkill(skillDb) {
          if (skillDb && skillDb.is_super) {
              return true;
          }
          else {
              return false;
          }
      }
      getSuperSkillId() {
          let skillDb = this.superDb;
          if (skillDb) {
              return skillDb.id;
          }
          else {
              return "";
          }
      }
      getSuperSkillDb() {
          return this.superDb;
      }
      onSkillCast(time, index = 0, targetId = 0, skillData) {
          if (this.skin) {
              let skillDb = skillData.skillDb;
              if (skillDb.is_super) {
                  Global.sendMsg(MSG.TOWER_CAST_SUPER_SKILL, skillDb);
              }
              let shooter = this.skin.getShooter(index);
              if (shooter) {
                  let target = this.world.objectMgr.getObjectById(targetId);
                  if (target) {
                      if (skillDb.no_flip) {
                          shooter.setFlip(1);
                      }
                      else {
                          shooter.lookAtTarget(this, target);
                      }
                      if (StageConfig.enableGameEffect && skillDb.effect_lock.length) {
                          let skin = Level.stage.getUnitSkinById(targetId);
                          if (skin) {
                              let shootPoint = shooter.getShootPoint(EffectFactory.layerFront, skillDb.point_index);
                              let offsety = -skin.height * skillDb.hit_offset;
                              for (let effect of skillDb.effect_lock) {
                                  let effectDb = db.get_effect_db(effect);
                                  if (effectDb.line) {
                                      let eLock = EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
                                      let node = eLock.node;
                                      node.x = shootPoint.x;
                                      node.y = shootPoint.y;
                                  }
                                  else {
                                      EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
                                  }
                              }
                          }
                      }
                  }
                  if (skillDb.sound_cast) {
                      mgrSound.playSound(skillDb.sound_cast);
                  }
                  if (StageConfig.enableGameEffect && skillDb.effect_cast) {
                      let effectDb = db.get_effect_db_map()[skillDb.effect_cast];
                      if (effectDb) {
                          let shootPoint = shooter.getShootPoint(EffectFactory.layerFront, effectDb.point_index || skillDb.point_index);
                          let effect = EffectFactory.createByType(skillDb.effect_cast, EffectFactory.layerFront, shootPoint);
                          if (shooter.getFlip() < 0) {
                              let node = effect.node;
                              node.scaleX = -node.scaleX;
                          }
                      }
                  }
                  shooter.cast(time, skillDb.action, skillDb.keep_cast);
              }
          }
      }
      useSkillById(target, skillId, index = 0, attackCount = 0, skillData) {
          if (!skillData) {
              this.world.skillMgr.packSkillData(this.tempSkillData, skillId);
              skillData = this.tempSkillData;
          }
          if (skillData) {
              let skillDb = skillData.skillDb;
              if (skillDb && skillDb.is_super) {
                  skillData.triggerSuper = true;
              }
          }
          this.world.skillMgr.findTarget2Exec(this, target, skillData, index, attackCount);
          this.onSkillUse(target, skillData, index, attackCount);
      }
      onSkillUse(target, skillData, index, count) {
          let SK_BLOOD_4_DAMAGE = this.attrCur[BASE_ATTR.SK_BLOOD_4_DAMAGE];
          if (SK_BLOOD_4_DAMAGE > 0) {
              let dd = DamageCalculation.damageData;
              dd.damage = Math.floor(this.getAttr(BASE_ATTR.HP) * db.game_cnf.holyitem_config_46);
              this.hurt(dd);
          }
          if (this.skin) {
              let shooter = this.skin.getShooter(index);
              let skillDb = skillData.skillDb || db.get_skill_db(skillData.skillId);
              if (!shooter || !skillDb)
                  return;
              DamageCalculation.calcSkillUse(this, target, skillData, index, count);
              if (StageConfig.enableGameEffect && skillDb.effect_shoot) {
                  if (skillDb.effect_shoot_tower) {
                      EffectFactory.createByType(skillDb.effect_shoot, EffectFactory.layerFront, this.skin);
                  }
                  else {
                      let shootPoint = shooter.getShootPoint(EffectFactory.layerFront, skillDb.point_index);
                      EffectFactory.createByType(skillDb.effect_shoot, EffectFactory.layerFront, shootPoint);
                  }
              }
          }
      }
      onSkillUseEnd(skillData, index) {
          if (this.skin) {
              let shooter = this.skin.getShooter(index);
              if (shooter) {
                  shooter.endAttack();
              }
          }
      }
      onTargetDead(index) {
          if (this.skin) {
              let shooter = this.skin.getShooter(index);
              if (shooter) {
                  shooter.endAttack();
              }
          }
      }
      getShootPoint(index, point_index) {
          if (this.skin) {
              let shooter = this.skin.getShooter(index);
              if (shooter) {
                  return shooter.getShootPoint(this.skin.parent, point_index);
              }
              else {
                  let posf = Level.convertGridPosToRealPos(this.mx, this.my, false);
                  this._tempPoint.x = posf.x + 10;
                  this._tempPoint.y = posf.y - 60;
              }
          }
          else {
              let posf = Level.convertGridPosToRealPos(this.mx, this.my, false);
              this._tempPoint.x = posf.x + 10;
              this._tempPoint.y = posf.y - 60;
          }
          return this._tempPoint;
      }
      getHitPoint(index) {
          let posf = Level.convertGridPosToRealPos(this.mx, this.my, false);
          this._tempPoint.x = posf.x + 10;
          this._tempPoint.y = posf.y - 60;
          return this._tempPoint;
      }
      addBuffById(caster, buffId, param = null, time = 0) {
          let buffDb = db.get_buff_db_map()[buffId];
          if (buffDb) {
              this.addBuff(caster, buffDb.id, buffDb.template, time || buffDb.time, buffDb.delay, buffDb.count, param);
          }
      }
      buildBuffUId(caster, id) {
          if (caster instanceof Tower) {
              return caster.uid + id;
          }
          else {
              return id;
          }
      }
      sortTargets(a, b) {
          let scoreA = a.getAttrPercent(BASE_ATTR.HP);
          let scoreB = b.getAttrPercent(BASE_ATTR.HP);
          return scoreA - scoreB;
      }
      addAttacker() {
          let attacker = super.addAttacker();
          if (this.skin) {
              this.skin.syncShooter(this);
          }
          return attacker;
      }
      canMove() {
          if (this.towerDb) {
              return !this.towerDb.main;
          }
          return false;
      }
      prepareHandCastSuperSkill() {
          Global.sendMsg(MSG.TOWER_HAND_SKILL_PREPARE, this);
      }
      findIdleAttacker() {
          return Utils.randomItem(this.comAttackers);
      }
      handCastSuperSkill() {
          if (!this.isEnergyFull())
              return true;
          console.log("手动释放技能", this.superDb.id);
          mgrTask.doEvent(db.TASK_EVENT_ID.SKILL_HAND);
          if (this.superDb.no_target) {
              let attack = this.findIdleAttacker();
              attack.targetId = this.uid;
              this.prepareSuperSkillData(attack.skillDataHand);
              attack.castHand(true);
          }
          else {
              let objectList = this.findObjectsByRangeAndCampId(this.superDb.camp, null);
              if (objectList.length) {
                  let object = objectList[0];
                  let attack = this.findIdleAttacker();
                  this.prepareSuperSkillData(attack.skillDataHand);
                  attack.targetId = object.uid;
                  let targetFinal = attack.findSkillTarget(attack.skillDataHand, object);
                  if (targetFinal) {
                      attack.targetId = targetFinal.uid;
                  }
                  attack.castHand(true);
              }
              else {
                  let posList = this.world.map.findCirleByRange(this.gx, this.gy, this.range);
                  let pos = Utils.randomItem(posList);
                  let enemy;
                  if (pos) {
                      enemy = this.world.addVirtual(pos.x, pos.y, "1");
                  }
                  else {
                      enemy = this.world.addVirtual(this.gx, this.gy, "1");
                  }
                  let attack = this.findIdleAttacker();
                  attack.targetId = enemy.uid;
                  this.prepareSuperSkillData(attack.skillDataHand);
                  attack.castHand(true);
              }
          }
          return true;
      }
      execWatch(t) {
          if (StageConfig.enableTowerAttack) {
              super.execWatch(t);
          }
      }
      execAttack(t) {
          if (StageConfig.enableTowerAttack) {
              super.execAttack(t);
          }
      }
      onBuffStart(buff) {
          if (this.skin) {
              this.skin.onBuffStart(this, buff.id, buff.data);
          }
      }
      onBuffExec(buff) {
          if (this.skin) {
              this.skin.onBuffExec(this, buff.id, buff.data);
          }
      }
      onBuffEnd(buff) {
          if (this.skin) {
              this.skin.onBuffEnd(this, buff.id, buff.data);
          }
      }
      scaleAttrOverLay(index, scale) {
          let scaleAdd = (this.attrScl[index] || 0) + scale;
          let scaleFinal = 1 + scaleAdd;
          this.attrScl[index] = scaleAdd;
          this.attrCur[index] = this.attrStd[index] * scaleFinal;
          this.onAttrChange();
      }
      recoverAttr(index) {
          this.attrScl[index] = 0;
          super.recoverAttr(index);
      }
      recoverAttrAll(exceptIds) {
          for (let i = 0; i < this.attrScl.length; i++) {
              this.attrScl[i] = 0;
          }
          super.recoverAttrAll(exceptIds);
      }
      updateTimer(t) {
          this.passTimer += t;
          if (this.passTimer >= this.maxxTimer) {
              this.passTimer = 0;
              this.onUpdatePerSecond();
          }
      }
      onUpdatePerSecond() {
          let BLOOD = StageAttr.getAttr(STAGE_ATTR.BLOOD);
          if (BLOOD > 0) {
              let dd = DamageCalculation.damageData;
              dd.damage = Math.ceil(BLOOD * this.getAttrMax(BASE_ATTR.HP));
              this.hurt(dd);
          }
          let SK_HURT_SELF_4_DAMAGE = this.getAttr(BASE_ATTR.SK_HURT_SELF_4_DAMAGE);
          if (SK_HURT_SELF_4_DAMAGE > 0) {
              let damage = Math.floor(this.getAttr(BASE_ATTR.HP) * db.game_cnf.holyitem_config_40);
              let dd = DamageCalculation.damageData;
              dd.damage = damage;
              this.hurt(dd);
          }
      }
      createEffectLock(skillDb) {
          if (!skillDb)
              return;
          if (StageConfig.enableGameEffect && skillDb.effect_lock.length) {
              let skin = this.skin;
              if (skin) {
                  let offsety = -skin.height * skillDb.hit_offset;
                  for (let effect of skillDb.effect_lock) {
                      let effectDb = db.get_effect_db(effect);
                      if (effectDb.line) {
                          let eLock = EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
                      }
                      else {
                          EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
                      }
                  }
              }
          }
      }
      createEffect(effect, hit_offset = 0) {
          if (!effect)
              return;
          let skin = this.skin;
          if (skin) {
              let offsety = -skin.height * hit_offset;
              let effectDb = db.get_effect_db(effect);
              if (effectDb) {
                  EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, skin, 0, null, 0, offsety);
              }
          }
      }
  }
  Tower.poolkey = "Tower";

  class HitAreaHelper {
      static loadHitAreaConfig(data) {
          if (!data)
              return;
          this.jsonHitAreaConfig = data;
          console.log("加载HitArea配置", this.jsonHitAreaConfig);
      }
      static getHitAreaConfig(id) {
          return this.jsonHitAreaConfig[id];
      }
      static setHitAreaConfig(id, data) {
          return this.jsonHitAreaConfig[id] = data;
      }
      static getHitArea(id) {
          let data = this.getHitAreaConfig(id);
          if (data) {
              return data;
          }
          else {
              return [];
          }
      }
      static loadConfig(resolve) {
          Laya.loader.load(this.pathConfig, Laya.Handler.create(this, this.onConfigLoad, [resolve]), null, Laya.Loader.JSON);
      }
      static onConfigLoad(resolve) {
          let jsonData = Laya.loader.getRes(this.pathConfig);
          if (jsonData)
              this.loadHitAreaConfig(jsonData);
          if (resolve)
              resolve();
      }
  }
  HitAreaHelper.pathConfig = "res/cfg/hit_area_cofing.json";
  HitAreaHelper.jsonHitAreaConfig = {};

  class LogicAction extends LogicTicker {
      constructor() {
          super();
      }
      destroy() {
          if (this.listItem) {
              this.listItem.removeFromList();
              this.listItem = null;
          }
      }
  }
  LogicAction.poolkey = "LogicAction";

  class LogicActionSkill extends LogicAction {
      constructor() {
          super();
          this.skillData = {};
      }
      static create(world, time, caster, target, template, skillId, skillData) {
          let action = LogicPool.getItem(LogicActionSkill).bind(world, time, caster, target, template, skillId, skillData, 0);
          action.selectUids = {};
          action.selectUids[action.targetId] = true;
          return action;
      }
      static recover(obj) {
          LogicPool.putItem(obj);
      }
      bind(world, time, caster, target, template, skillId, skillData, execNum) {
          this.world = world;
          this.casterId = caster.uid;
          this.targetId = target.uid;
          this.template = template;
          this.skillId = skillId;
          this.copySkillData(skillData);
          this.skillData.targetX = target.gx;
          this.skillData.targetY = target.gy;
          this.timePass = 0;
          this.timeTick = time / LogicConfig.LOGIC_FRAME_ITME;
          this.tickAtOnce = true;
          this.execNum = execNum;
          return this;
      }
      copySkillData(data) {
          for (let k in data) {
              this.skillData[k] = data[k];
          }
      }
      destroy() {
          super.destroy();
          LogicActionSkill.recover(this);
      }
      rebound(caster, target) {
          let targetUse = caster.world.map.findObjectsByRange(target.gx, target.gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, caster.range, 2, true, false, this.selectUids, false, false);
          if (targetUse.length > 0) {
              caster = target;
              target = targetUse[0];
              this.targetId = target.uid;
              this.selectUids[this.targetId] = true;
              let timeUse = Skill.calcBulletFlyTime(caster, target, this.skillData.skillDb);
              this.timeTick = timeUse;
              this.world.eventBulletCreate(this.skillId, timeUse, caster, target, 0);
              this.execNum++;
              return true;
          }
          return false;
      }
      tick() {
          this.timePass++;
          if (this.delayRebound) {
              if (this.timePass >= this.delayRebound) {
                  this.delayRebound = 0;
                  this.timePass = 0;
                  let caster = this.world.objectMgr.getObjectById(this.casterId);
                  let target = this.world.objectMgr.getObjectById(this.targetId);
                  if (caster && target) {
                      if (!this.rebound(caster, target)) {
                          this.destroy();
                          return;
                      }
                  }
                  return;
              }
          }
          if (this.timePass >= this.timeTick) {
              this.world.skillMgr.hitSkill(this.casterId, this.targetId, this.template, this.skillData, 0);
              let noLimit = this.execNum < this.skillData.limitRebound;
              if (noLimit) {
                  let caster = this.world.objectMgr.getObjectById(this.casterId);
                  let target = this.world.objectMgr.getObjectById(this.targetId);
                  if (caster && target) {
                      let skillDb = this.skillData.skillDb;
                      if (DamageCalculation.calcSkillRebound(caster, target, skillDb, this.skillData)) {
                          if (this.skillData.delayRebound) {
                              this.delayRebound = this.skillData.delayRebound;
                              this.timePass = 0;
                              return;
                          }
                          else {
                              if (this.rebound(caster, target)) {
                                  return;
                              }
                          }
                      }
                  }
                  else {
                  }
              }
              else {
              }
              if (this.tickAtOnce) {
                  this.destroy();
              }
              else {
                  this.timePass = 0;
              }
          }
      }
  }
  LogicActionSkill.poolkey = "LogicActionSkill";

  class LogicActionSkillDamage extends LogicActionSkill {
      constructor() {
          super();
          this.damageData = { damage: 0, direction: new LogicPoint };
      }
      static create(world, tickCount, caster, target, template, skillId, skillData) {
          return LogicPool.getItem(LogicActionSkillDamage).bind(world, tickCount, caster, target, template, skillId, skillData, 0);
      }
      bind(world, tickCount, caster, target, template, skillId, skillData, execNum) {
          super.bind(world, tickCount, caster, target, template, skillId, skillData, execNum);
          if (caster.attrCur) {
              target.calcDamage(caster, skillData, this.damageData);
          }
          else {
              console.error("LogicActionSkillDamage: 为什么属性会为空");
          }
          this.copySkillData(skillData);
          return this;
      }
      tick() {
          this.timePass++;
          if (this.timePass >= this.timeTick) {
              let caster = this.world.objectMgr.getObjectById(this.casterId);
              let target = this.world.objectMgr.getObjectById(this.targetId);
              let skillData = this.skillData;
              if (caster && target && skillData) {
                  caster.calcBuffBySkillCaster(caster, this.skillId, skillData);
                  target.calcBuffBySkillTarget(caster, this.skillId, skillData);
                  target.execSkillWithDamage(caster, this.damageData, this.skillData);
              }
              if (this.tickAtOnce) {
                  this.destroy();
              }
              else {
                  this.timePass = 0;
              }
          }
      }
  }
  LogicActionSkillDamage.poolkey = "LogicActionSkillDamage";

  class Bullet extends Laya.Script {
      constructor() {
          super(...arguments);
          this.bulletId = "";
          this.path = [];
          this.listEffect = [];
          this.needEffectHit = true;
          this.isHitTarget = false;
          this.bIsValid = false;
          this.isRunning = false;
          this.speedRotation = 600;
          this.funcEaseMove = Laya.Ease.linearIn;
          this.funcEaseRotation = Laya.Ease.linearIn;
          this.targetTemp = { x: 0, y: 0, width: 0, height: 0 };
          this.targetDegree = 0;
          this.moveToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, pass: 0, running: false, delay: 0 };
          this.damage = 0;
          this.rotationToData = { time: 0, pass: 0, running: false, delay: 0, rotation: 0, rotation_delta: 0 };
          this.funcEaseScale = Laya.Ease.linearIn;
          this.scaleToData = { time: 0, pass: 0, running: false, delay: 0, scale: 0, scale_delta: 0 };
      }
      reset() {
          this.bIsValid = true;
          this.needEffectHit = true;
          this.isHitTarget = false;
          this.effect_hit = "";
          this.effect_hit_ex = "";
      }
      set x(value) {
          this.node.x = value;
      }
      get x() {
          return this.node.x;
      }
      set y(value) {
          this.node.y = value;
      }
      get y() {
          return this.node.y;
      }
      onAwake() {
      }
      recover() {
          if (!this.bIsValid)
              return;
          this.bIsValid = false;
          this.node.removeSelf();
          Laya.Pool.recover("Bullet_" + this.bulletDb.id, this.node);
      }
      remove() {
          this.clearEffect();
          this.recover();
      }
      getSprite2D() {
          let sprite = Laya.Pool.getItem("BulletSprite2D");
          if (!sprite) {
              sprite = new Laya.Sprite;
          }
          else {
          }
          return sprite;
      }
      putSprite2D(sprite) {
          sprite.removeSelf();
          Laya.Pool.recover("BulletSprite2D", sprite);
      }
      createEffect(effectId = "bullet02", offsetx = 0, offsety = 0, save = true) {
          if (!effectId)
              return;
          if (!this.calcCanShowEffectByFps())
              return;
          if (!StageConfig.enableGameEffect)
              return;
          let node = this.getSprite2D();
          this.node.addChild(node);
          node.x = offsetx;
          node.y = offsety;
          let data = Director.getScene3DLayer(1);
          let effect = EffectFactory.create(effectId, data.scene3d);
          effect.followNode2d(data.camera, node, this.node);
          effect.flagSave = save;
          this.listEffect.push(effect);
      }
      createEffectHit() {
          if (!this.calcCanShowEffectByFps())
              return;
          if (StageConfig.enableGameEffect && this.effect_hit && EffectFactory.layerFront) {
              let effectDb = db.get_effect_db_map()[this.effect_hit];
              if (effectDb) {
                  EffectFactory.createByTypeByDB(effectDb, EffectFactory.layerFront, this.node, null, null, 0, this.target.height * effectDb.offset);
              }
          }
      }
      deleteEffect(effectDel) {
          let listEffect = [];
          for (let effect of this.listEffect) {
              if (effect == effectDel) {
                  effect.clear();
              }
              else {
                  listEffect.push(effect);
              }
          }
          this.listEffect = listEffect;
      }
      clearEffect() {
          for (let effect of this.listEffect) {
              if (effect.node2d) {
                  this.putSprite2D(effect.node2d);
                  effect.node2d = null;
              }
              effect.clear();
              effect = null;
          }
          this.listEffect.length = 0;
      }
      loadView(url) {
          if (!url)
              return;
          LoaderHelper.createSpriteWithLoad(url, this, this.onSkinLoad);
      }
      onSkinLoad(view) {
          this.removeSkin();
          this.skin = view;
          if (this.bulletDb.lighter)
              view.blendMode = "lighter";
          this.node.addChild(view);
          this.playAnim(this.bulletDb.anim);
      }
      loadViewFgui(path) {
          let res = fgui.UIPackage.createObjectFromURL(path);
          if (res) {
              this.onResFguiLoad(res.asCom);
          }
          else {
              let pkgReg = /ui:\/\/(\S+)\//img;
              let result = pkgReg.exec(path);
              if (result) {
                  let pkgName = result[1];
                  fgui.UIPackage.loadPackage(`res/fgui/${pkgName}`, Laya.Handler.create(this, () => {
                      let res = fgui.UIPackage.createObjectFromURL(path);
                      if (res)
                          this.onResFguiLoad(res.asCom);
                  }));
                  return;
              }
          }
      }
      onResFguiLoad(view) {
          this.removeSkin();
          this.skin = view.displayObject;
          if (this.bulletDb.lighter)
              view.blendMode = "lighter";
          this.node.addChild(this.skin);
      }
      playAnim(anim) {
          if (this.animation && anim) {
              this.animation.interval = 1000 / 8;
              this.animation.play(0, true, anim);
          }
      }
      removeSkin() {
          if (this.skin) {
              this.skin.destroy();
              this.skin = null;
          }
      }
      onUpdate() {
          let t = GameConst.FrameDeltaTime * StageConfig.gameTimeScale;
          ;
          this.update(t);
          this.updateScaleTo(t);
      }
      update(t) {
          this.updateMoveTo(t);
          this.updateRotationTo(t);
      }
      updateRotation(t) {
          this.node.rotation += this.speedRotation * t;
      }
      updateMoveTo(dt) {
          let moveToData = this.moveToData;
          if (!moveToData.running)
              return;
          this.updateRotationTo(dt);
          moveToData.pass += dt;
          let timePass = moveToData.pass;
          let timeMaxx = moveToData.time;
          let timeDely = moveToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          this.node.x = this.funcEaseMove(timePass, moveToData.x, moveToData.dx, timeMaxx);
          this.node.y = this.funcEaseMove(timePass, moveToData.y, moveToData.dy, timeMaxx);
          if (timePass >= timeMaxx) {
              moveToData.running = false;
              this.onBulletEnd();
          }
      }
      updateRotationTo(dt) {
          let rotationToData = this.rotationToData;
          if (!rotationToData.running)
              return;
          rotationToData.pass += dt;
          let timePass = rotationToData.pass;
          let timeMaxx = rotationToData.time;
          let timeDely = rotationToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          this.node.rotation = this.funcEaseRotation(timePass, rotationToData.rotation, rotationToData.rotation_delta, timeMaxx);
          if (timePass >= timeMaxx) {
              rotationToData.running = false;
          }
      }
      updateMoveDegree(dt) {
          let degreeFrom = this.node.rotation;
          let degreeTo = (this.targetDegree) % 360;
          let degreeDelta = degreeTo - degreeFrom;
          if (degreeDelta > 180)
              degreeTo -= 360;
          Laya.Tween.to(this.node, { rotation: degreeTo }, 200);
      }
      globalToLocal(point) {
          return this.node.parent.globalToLocal(point, true);
      }
      copyTarget(target) {
          for (let k in target) {
              this.targetTemp[k] = target[k];
          }
          return this.targetTemp;
      }
      set setTarget(target) {
          if (target.isTemp) {
              target = this.copyTarget(target);
          }
          this.target = target;
          this.targetUID = target.uid;
      }
      getTarget() {
          return this.target;
      }
      calcScaleTo(time) {
          if (this.bulletDb.scale_time && this.bulletDb.scale.length >= 2) {
              this.scaleTo(this.bulletDb.scale_time, this.bulletDb.scale[0], this.bulletDb.scale[1]);
          }
      }
      shootTarget(time, target, handerComplete = null, directionX = null) {
          this.target = target;
          this.moveToData.pass = 0;
          this.moveToData.time = time;
          this.moveToData.x = this.node.x;
          this.moveToData.y = this.node.y;
          let dx = this.target_x - this.node.x;
          let dy = this.target_y - this.node.y;
          this.moveToData.dx = dx;
          this.moveToData.dy = dy;
          this.moveToData.running = true;
          this.moveToData.delay = 0;
          let degree = Utils.vectorToDegree(dx, dy);
          this.targetDegree = degree;
          this.handerComplete = handerComplete;
          this.onBulletStart();
          this.calcScaleTo(time);
      }
      bindCaster(caster, offsetx, offsety) {
      }
      bindSkillDb(skillDb) {
          this.skillDb = skillDb;
      }
      bind(caster, target, skillDb) {
      }
      calcCanShowEffectByFps() {
          return true;
      }
      onBulletStart() {
          let degreeFrom = this.node.rotation;
          let degreeTo = (this.targetDegree) % 360;
          let degreeDelta = degreeTo - degreeFrom;
          if (degreeDelta > 180)
              degreeTo -= 360;
          this.rotationTo(0.2, degreeTo);
      }
      updateBulletHit(pass) {
          if (!this.isHitTarget) {
              if (pass >= this.bulletDb.hit_time) {
                  this.onBulletHit();
              }
          }
      }
      onBulletHit() {
          if (this.isHitTarget)
              return;
          this.isHitTarget = true;
          if (this.skillDb && this.skillDb.sound_hit) {
              mgrSound.playSound(this.skillDb.sound_hit);
          }
          if (this.needEffectHit) {
              this.createEffectHit();
          }
      }
      onBulletEnd(isHit = true) {
          if (isHit) {
              this.onBulletHit();
          }
          if (this.handerComplete) {
              this.handerComplete.runWith(this);
          }
          this.remove();
      }
      born(root) {
          root.addChild(this.node);
          this.playShootSound();
      }
      playShootSound() {
      }
      setPos(point) {
          let parent = this.node.parent;
          point = parent.globalToLocal(point, true);
          this.node.x = point.x;
          this.node.y = point.y;
      }
      lookAt(target, offset = 0) {
          let dx = target.x - this.node.x;
          let dy = target.y - this.node.y;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree + offset;
      }
      lookAtPos(x, y, offset = 0) {
          let dx = x - this.node.x;
          let dy = y - this.node.y;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree + offset;
      }
      lookAtDegree(degree, offset = 0) {
          this.node.rotation = degree + offset;
      }
      setDamage(damage) {
          this.damage = damage;
      }
      setDegree(degree) {
          this.node.rotation = degree;
      }
      rotationTo(time, rotation, delay = 0) {
          this.rotationToData.pass = 0;
          this.rotationToData.time = time;
          this.rotationToData.delay = delay;
          this.rotationToData.rotation = this.node.rotation;
          this.rotationToData.rotation_delta = rotation - this.node.rotation;
          this.rotationToData.running = true;
      }
      updateScaleTo(dt) {
          let scaleToData = this.scaleToData;
          if (!scaleToData.running)
              return;
          scaleToData.pass += dt;
          let timePass = scaleToData.pass;
          let timeMaxx = scaleToData.time;
          let timeDely = scaleToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          let scale = this.funcEaseScale(timePass, scaleToData.scale, scaleToData.scale_delta, timeMaxx);
          this.node.scale(scale, scale);
          if (timePass >= timeMaxx) {
              scaleToData.running = false;
          }
      }
      scaleTo(time, scaleFrom, scaleTo, delay = 0) {
          this.node.scale(scaleFrom, scaleFrom);
          this.scaleToData.pass = 0;
          this.scaleToData.time = time;
          this.scaleToData.delay = delay;
          this.scaleToData.scale = scaleFrom;
          this.scaleToData.scale_delta = scaleTo - scaleFrom;
          this.scaleToData.running = true;
      }
      onBulletUpdateDegree(dx, dy, offset = 0) {
          let degree = Utils.vectorToDegree(dx, dy);
          this.setDegree(degree + offset);
      }
      isTargetValid() {
          if (this.target) {
              if (this.target.invalid) {
                  return false;
              }
              else {
                  if (this.targetUID && this.targetUID != this.target.uid) {
                      return false;
                  }
              }
              return true;
          }
          return false;
      }
      get target_x() {
          return this.target.x;
      }
      get target_y() {
          return this.target.y - this.target.height * 0.5;
      }
      set delay(value) {
      }
  }

  class BulletBezier2 extends Bullet {
      constructor() {
          super(...arguments);
          this.funcEaseBezier = Laya.Ease.linearIn;
          this.bezierData2 = { target: 0, pointFrom: new Laya.Point, pointTo: new Laya.Point, point1: new Laya.Point, point2: new Laya.Point, time: 0, pass: 0, running: false, delay: 0 };
      }
      update(t) {
          this.updateBezier2(t);
      }
      twoBezier(t, p1, p2, p3) {
          return (1 - t) * (1 - t) * p1 + 2 * t * (1 - t) * p2 + t * t * p3;
      }
      updateBezier2(dt) {
          let bezierData = this.bezierData2;
          if (!bezierData.running)
              return;
          bezierData.pass += dt;
          let timePass = bezierData.pass;
          let timeMaxx = bezierData.time;
          let timeDely = bezierData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          let t = this.funcEaseBezier(timePass, 0, 1, timeMaxx);
          let oldX = this.node.x;
          let oldY = this.node.y;
          if (this.isTargetValid()) {
              bezierData.pointTo.x = this.target_x;
              bezierData.pointTo.y = this.target_y;
          }
          this.node.x = this.twoBezier(t, bezierData.pointFrom.x, bezierData.point1.x, bezierData.pointTo.x);
          this.node.y = this.twoBezier(t, bezierData.pointFrom.y, bezierData.point1.y, bezierData.pointTo.y);
          let dx = this.node.x - oldX;
          let dy = this.node.y - oldY;
          this.onBulletUpdateDegree(dx, dy);
          if (timePass >= timeMaxx) {
              bezierData.running = false;
              this.onBulletEnd();
          }
      }
      shootTarget(time, target, handerComplete = null) {
          this.setTarget = target;
          this.bezierData2.pass = 0;
          this.bezierData2.time = time;
          this.bezierData2.pointFrom.x = this.node.x;
          this.bezierData2.pointFrom.y = this.node.y;
          this.bezierData2.pointTo.x = target.x;
          this.bezierData2.pointTo.y = target.y;
          let r = Mathf.distance(this.bezierData2.pointFrom, this.bezierData2.pointTo) * 0.5;
          let rot = Mathf.random(Math.PI * 200) / 100;
          let x = this.bezierData2.pointFrom.x + Math.cos(rot) * r;
          let y = this.bezierData2.pointFrom.y + Math.sin(rot) * r;
          this.bezierData2.point1.x = x;
          this.bezierData2.point1.y = y;
          this.bezierData2.running = true;
          this.handerComplete = handerComplete;
          this.calcScaleTo(time);
      }
  }

  class BulletFall extends Bullet {
      constructor() {
          super(...arguments);
          this.funcEaseFollow = Laya.Ease.sineIn;
          this.funcEaseAlpha = Laya.Ease.sineIn;
          this.followToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, timeAlpla: 0, pass: 0, running: false, delay: 0 };
      }
      update(t) {
          this.updateFollowTo(t);
      }
      updateFollowTo(dt) {
          let followToData = this.followToData;
          if (!followToData.running)
              return;
          followToData.pass += dt;
          let timePass = followToData.pass;
          let timeMaxx = followToData.time;
          let timeDely = followToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          this.node.x = this.funcEaseFollow(timePass, followToData.x, followToData.dx, timeMaxx);
          this.node.y = this.funcEaseFollow(timePass, followToData.y, followToData.dy, timeMaxx);
          this.node.alpha = this.funcEaseAlpha(timePass, 0, 1, followToData.timeAlpla);
          if (timePass >= timeMaxx) {
              followToData.running = false;
              this.onBulletEnd();
          }
      }
      shootTarget(time, target, handerComplete = null, directionX = null) {
          this.setTarget = target;
          if (directionX == null) {
              directionX = target.x - this.node.x;
          }
          let height = this.bulletDb.param[0] || 0;
          let degree = this.bulletDb.param[1] || 0;
          let time_offset = this.bulletDb.param[2] || 0;
          let offsety = -height;
          let offsetx = 0;
          let factor = height * Math.sin(degree * Math.PI / 180);
          if (directionX > 0) {
              offsetx = -factor;
          }
          else {
              offsetx = factor;
          }
          this.node.x = target.x + offsetx;
          this.node.y = target.y + offsety;
          let dx = target.x - this.node.x;
          let dy = target.y - this.node.y;
          this.onBulletUpdateDegree(dx, dy, -90);
          this.followToData.pass = 0;
          this.followToData.time = time + Utils.randomRange(-time_offset, time_offset);
          this.followToData.x = this.node.x;
          this.followToData.y = this.node.y;
          this.followToData.running = true;
          this.followToData.delay = 0;
          this.followToData.dx = target.x - this.node.x;
          this.followToData.dy = target.y - this.node.y;
          this.followToData.timeAlpla = this.followToData.time / 2;
          this.node.alpha = 0;
          this.handerComplete = handerComplete;
          this.calcScaleTo(time);
      }
  }

  class BulletFollow extends Bullet {
      constructor() {
          super(...arguments);
          this.funcEaseFollow = Laya.Ease.linearIn;
          this.followToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, pass: 0, running: false, delay: 0 };
      }
      update(t) {
          this.updateFollowTo(t);
      }
      updateFollowTo(dt) {
          let followToData = this.followToData;
          if (!followToData.running)
              return;
          followToData.pass += dt;
          let timePass = followToData.pass;
          let timeMaxx = followToData.time;
          let timeDely = followToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          if (this.isTargetValid()) {
              followToData.dx = this.target_x - followToData.x;
              followToData.dy = this.target_y - followToData.y;
          }
          let oldX = this.node.x;
          let oldY = this.node.y;
          this.node.x = this.funcEaseFollow(timePass, followToData.x, followToData.dx, timeMaxx);
          this.node.y = this.funcEaseFollow(timePass, followToData.y, followToData.dy, timeMaxx);
          let dx = this.node.x - oldX;
          let dy = this.node.y - oldY;
          this.onBulletUpdateDegree(dx, dy, 0);
          if (timePass >= timeMaxx) {
              followToData.running = false;
              this.onBulletEnd();
          }
      }
      shootTarget(time, target, handerComplete = null) {
          this.setTarget = target;
          this.followToData.pass = 0;
          this.followToData.time = time;
          this.followToData.x = this.node.x;
          this.followToData.y = this.node.y;
          this.followToData.running = true;
          this.followToData.delay = 0;
          this.followToData.dx = target.x - this.node.x;
          this.followToData.dy = target.y - this.node.y;
          this.handerComplete = handerComplete;
          this.calcScaleTo(time);
      }
  }

  class BulletJump extends Bullet {
      constructor() {
          super(...arguments);
          this.updateData = { time: 0, pass: 0, running: false, delay: 0 };
      }
      update(t) {
          this.updateTime(t);
      }
      updateTime(dt) {
          let updateData = this.updateData;
          if (!updateData.running)
              return;
          updateData.pass += dt;
          let timePass = updateData.pass;
          let timeMaxx = updateData.time;
          let timeDely = updateData.delay;
          if (timeDely > timePass)
              return;
          if (!this.node.visible) {
              this.node.visible = true;
          }
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          if (timePass >= timeMaxx) {
              updateData.running = false;
              this.onBulletEnd();
          }
      }
      shootTarget(time, target, handerComplete = null) {
          let time_offset = this.bulletDb.param[0] || 0;
          this.node.x = target.x;
          this.node.y = target.y;
          this.updateData.pass = 0;
          this.updateData.time = time;
          this.updateData.running = true;
          this.updateData.delay = Utils.randomRange(0, time_offset);
          this.node.visible = false;
          this.needEffectHit = false;
          this.calcScaleTo(time);
      }
  }

  class BulletLine extends Bullet {
      constructor() {
          super(...arguments);
          this.bodyOriginWidth = 0;
          this.tempPoint = new Laya.Point;
          this.funcEaseFollow = Laya.Ease.linearIn;
          this.lineData = { time: 0, pass: 0, running: false };
          this.casterOffsetX = 0;
          this.casterOffsetY = 0;
      }
      onSkinLoad(view) {
          super.onSkinLoad(view);
          this.body = view.getChildByName("body");
          this.head = view.getChildByName("head");
          this.bodyOriginWidth = this.body.width;
      }
      onResFguiLoad(view) {
          super.onResFguiLoad(view);
          let body = view.getChild("body");
          if (body) {
              this.body = body.displayObject;
          }
          else {
              this.body = view.displayObject;
          }
          let head = view.getChild("head");
          if (head) {
              this.head = head.displayObject;
              this.head.pivotX = this.head.width / 2;
          }
          this.bodyOriginWidth = this.body.width;
      }
      createEffectHit() {
          if (!this.calcCanShowEffectByFps())
              return;
          if (this.effect_hit) {
              this.tempPoint.x = this.target_x;
              this.tempPoint.y = this.target_y;
              EffectFactory.createByType(this.effect_hit, this.node.parent, this.tempPoint);
          }
      }
      update(t) {
          this.updateLineTo(t);
      }
      updateLineTo(dt) {
          let lineData = this.lineData;
          if (!lineData.running)
              return;
          lineData.pass += dt;
          let timePass = lineData.pass;
          let timeMaxx = lineData.time;
          let isEnd = false;
          if (timeMaxx && timePass > timeMaxx) {
              timePass = timeMaxx;
              isEnd = true;
          }
          this.updateBulletHit(timePass);
          if (this.isTargetValid() && this.isCasterValid()) {
              this.node.visible = true;
              this.node.x = this.caster.x + this.casterOffsetX;
              this.node.y = this.caster.y + this.casterOffsetY;
              let dx = this.target_x - this.node.x;
              let dy = this.target_y - this.node.y;
              let distance = Math.sqrt(dx * dx + dy * dy);
              if (this.head) {
                  this.head.x = distance;
              }
              if (this.body) {
                  if (this.bodyOriginWidth) {
                      this.body.scaleX = distance / this.bodyOriginWidth;
                      let degree = Utils.vectorToDegree(dx, dy);
                      this.node.rotation = degree;
                  }
              }
          }
          else {
              isEnd = true;
          }
          if (isEnd) {
              lineData.running = false;
              this.onBulletEnd();
          }
      }
      updateRotation() {
          let dx = this.target_x - this.node.x;
          let dy = this.target_y - this.node.y;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree;
      }
      shootTarget(time, target, handerComplete = null) {
          this.setTarget = target;
          if (target.isTemp) {
              time = 0.2;
          }
          this.lineData.pass = 0;
          this.lineData.time = time;
          this.lineData.running = true;
          this.handerComplete = handerComplete;
          this.node.visible = false;
          this.calcScaleTo(time);
          this.updateRotation();
      }
      isCasterValid() {
          if (this.caster) {
              if (this.caster.invalid) {
                  return false;
              }
              else {
                  return true;
              }
          }
          return false;
      }
      bindCaster(caster, offsetx, offsety) {
          this.caster = caster;
          this.casterOffsetX = offsetx;
          this.casterOffsetY = offsety;
      }
  }

  class BulletParabola extends Bullet {
      constructor() {
          super(...arguments);
          this.funcEaseParabola = Laya.Ease.linearIn;
          this.parabolaToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, pass: 0, running: false, delay: 0, target: 0, v0: 0, gravity: 1800, rotate: false, forward: false };
      }
      update(t) {
          this.upateParabolaTo(t);
      }
      shootTarget(time, target, handerComplete) {
          let parabolaToData = this.parabolaToData;
          this.setTarget = target;
          parabolaToData.pass = 0;
          parabolaToData.time = time;
          parabolaToData.x = this.node.x;
          parabolaToData.y = this.node.y;
          parabolaToData.running = true;
          parabolaToData.delay = 0;
          parabolaToData.forward = this.bulletDb.forward;
          parabolaToData.rotate = this.bulletDb.rotate != 0;
          this.speedRotation = this.bulletDb.rotate;
          parabolaToData.dx = target.x - this.node.x;
          parabolaToData.dy = target.y - this.node.y;
          parabolaToData.v0 = -parabolaToData.gravity * time / 2;
          this.calcScaleTo(time);
      }
      upateParabolaTo(dt) {
          let parabolaToData = this.parabolaToData;
          if (!parabolaToData.running)
              return;
          parabolaToData.pass += dt;
          let timePass = parabolaToData.pass;
          let timeMaxx = parabolaToData.time;
          let timeDely = parabolaToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          if (this.isTargetValid()) {
              parabolaToData.dx = this.target_x - parabolaToData.x;
              parabolaToData.dy = this.target_y - parabolaToData.y;
          }
          let t = parabolaToData.pass;
          let offsety = parabolaToData.v0 * t + parabolaToData.gravity * t * t / 2;
          let oldX = this.node.x;
          let oldY = this.node.y;
          this.node.x = this.funcEaseParabola(timePass, parabolaToData.x, parabolaToData.dx, timeMaxx);
          this.node.y = this.funcEaseParabola(timePass, parabolaToData.y, parabolaToData.dy, timeMaxx) + offsety;
          if (parabolaToData.forward) {
              let dx = this.node.x - oldX;
              let dy = this.node.y - oldY;
              this.onBulletUpdateDegree(dx, dy, 0);
          }
          else if (parabolaToData.rotate) {
              this.updateRotation(dt);
          }
          if (timePass >= timeMaxx) {
              parabolaToData.running = false;
              this.onBulletEnd();
          }
      }
  }

  var DEBUG = false;
  var DEBUG_HIT = false;
  class BulletReal extends Bullet {
      constructor() {
          super();
          this.moveDistance = 0;
          this.damageDistance = 32;
          this.damageRange = 1;
          this.direction = new Laya.Point;
          this.collisionRadius = 50;
          this.scanRadius = 1;
          this.uid2HurtTime = {};
          this.offsetQueue = [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: -1, y: 0 }, { x: 0, y: -1 }];
          this.listTarget = [];
          this.updateDamageData = { pass: 0, time: 1 };
          this.attr = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          this.skillData = {};
      }
      onAwake() {
          super.onAwake();
          this.node = this.owner;
          this.showCollisionArea();
      }
      showCollisionArea() {
          if (StageConfig.showCollisionArea) {
              let graphics = this.node.graphics;
              graphics.clear();
              graphics.drawCircle(0, 0, this.radius, "#ff000055");
          }
      }
      get radius() {
          return this.collisionRadius * this.node.scaleX;
      }
      bind(caster, target, skillDb, uid2HurtTime = null) {
          this.world = caster.world;
          this.skillDb = skillDb;
          this.uidCaster = caster.uid;
          this.tidCaster = caster.tid;
          Level.packSkillData(this.skillData, skillDb);
          Level.copyAttrArray(caster.attrCur, this.attr);
          this.resetSelectUids(uid2HurtTime);
      }
      resetSelectUids(uid2HurtTime = null) {
          this.uid2HurtTime = uid2HurtTime || {};
      }
      restMoveDistance() {
          this.moveDistance = 0;
      }
      addMoveDistance(distance) {
          this.moveDistance += Math.abs(distance);
          while (this.moveDistance >= this.damageDistance) {
              this.moveDistance -= this.damageDistance;
              this.execDamage();
          }
      }
      findCirleByRange(x, y, range) {
          let step = Math.floor(range) * 2;
          this.findTargets2Damage(this.listTarget, x, y);
          while (step > 0) {
              let offsetCurt = null;
              let halfs = step / 2;
              let fromx = x - halfs;
              let fromy = y - halfs;
              let offsetx = 0;
              let offsety = 0;
              for (let i = 0; i < this.offsetQueue.length; i++) {
                  offsetCurt = this.offsetQueue[i];
                  for (let j = 1; j <= step; j++) {
                      offsetx += offsetCurt.x;
                      offsety += offsetCurt.y;
                      let tx = fromx + offsetx;
                      let ty = fromy + offsety;
                      this.findTargets2Damage(this.listTarget, tx, ty);
                  }
              }
              step -= 2;
              if (step < 0) {
                  break;
              }
          }
      }
      execDamage() {
          let pos = Level.stage.localPos2GridPos(this.node.x, this.node.y);
          this.listTarget.length = 0;
          this.findCirleByRange(pos.x, pos.y, this.scanRadius);
          for (let i = this.listTarget.length - 1; i >= 0; i--) {
              let target = this.listTarget[i];
              if (this.onTargetHit(target)) {
                  break;
              }
          }
      }
      resetUpdateDamageTime(interval = 1) {
          this.updateDamageData.pass = interval;
          this.updateDamageData.time = interval;
      }
      updateDamageByTime(t) {
          this.updateDamageData.pass += t;
          if (this.updateDamageData.pass >= this.updateDamageData.time) {
              this.updateDamageData.pass = 0;
              this.execDamageByTime();
          }
      }
      execDamageByTime() {
          let pos = Level.stage.localPos2GridPos(this.node.x, this.node.y);
          this.listTarget.length = 0;
          this.findTargets2Damage(this.listTarget, pos.x, pos.y);
          for (let i = 0; i < this.listTarget.length; i++) {
              let target = this.listTarget[i];
              if (this.onTargetHit(target)) {
                  break;
              }
          }
      }
      findTargets2Damage(listTarget, gx, gy) {
          if (DEBUG)
              Level.stage.drawStep(gx, gy);
          let list = Level.stage.world.map.getSectionTable(gx, gy);
          if (!list)
              return;
          let head = list.head;
          while (head) {
              let target = head.data;
              head = head.next;
              if (target && target.camp == LogicCamp.ENEMY) {
                  listTarget.push(target);
              }
          }
      }
      calcDamage(target, isCrossbow = false) {
          let caster = this.world.objectMgr.getObjectById(this.uidCaster);
          if (caster) {
              return DamageCalculation.calcDamage(caster, target, this.skillData, null, isCrossbow);
          }
      }
      calcCollisionWithCircle(a, b) {
          let dx = a.x - b.x;
          let dy = a.y - b.y;
          let radiusSum = a.radius + b.radius;
          let distanceSq = dx * dx + dy * dy;
          let radiusSq = radiusSum * radiusSum;
          return distanceSq <= radiusSq;
      }
      checkCDTime() {
      }
      onTargetHit(target) {
          let curtTime = Utils.getTime();
          let lastTime = this.uid2HurtTime[target.uid] || curtTime;
          let caster = this.world.objectMgr.getObjectById(this.uidCaster);
          if (caster && curtTime >= lastTime && this.calcCollisionWithCircle(this, target)) {
              this.uid2HurtTime[target.uid] = curtTime + 200;
              if (this.skillDb) {
                  if (this.skillDb.effect_hit) {
                      this.world.eventEffectHitCreate(caster, target, this.skillDb.id, 0);
                  }
                  target.execSkillWithDamage(caster, this.calcDamage(target), this.skillData);
              }
              return true;
          }
          return false;
      }
      findHitObjects(gx, gy, skillDb) {
          if (skillDb.use_hit_area) {
              return this.world.map.findObjectsByOffset(gx, gy, HitAreaHelper.getHitArea(skillDb.id), MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, skillDb.target_limit, DEBUG_HIT);
          }
          else {
              return this.world.map.findObjectsByRange(gx, gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, skillDb.hit_range, skillDb.target_limit, true, DEBUG_HIT);
          }
      }
  }

  class BulletRealBoomerang extends BulletReal {
      constructor() {
          super(...arguments);
          this.speed = 0;
          this.aspeed = -1000 * 3.5;
          this.speedRotation = 600;
          this.distance = 0;
          this.timepass = 0;
          this.timemaxx = 1;
      }
      update(t) {
          this.timepass += t;
          this.speed += this.aspeed * t;
          let moveDistance = this.speed * t;
          this.addMoveDistance(moveDistance);
          this.node.x += this.direction.x * moveDistance;
          this.node.y += this.direction.y * moveDistance;
          this.updateRotation(t);
          if (this.timepass >= this.timemaxx) {
              this.onBulletEnd();
          }
      }
      shootTarget(time, target, handerComplete) {
          time = 1;
          this.setTarget = target;
          let dx = target.x - this.node.x;
          let dy = target.y - this.node.y;
          let speed = -this.aspeed * time / 2;
          this.speed = speed;
          this.timepass = 0;
          this.timemaxx = time;
          this.direction.x = dx;
          this.direction.y = dy;
          this.direction.normalize();
          this.speedRotation = this.bulletDb.rotate;
          this.restMoveDistance();
          this.calcScaleTo(time);
      }
  }

  class BulletRealCrossbow extends BulletReal {
      constructor() {
          super(...arguments);
          this.speed = 0;
          this.aSpeed = 0;
          this.distance = 0;
          this.timedelay = 0;
          this.timepass = 0;
          this.timemaxx = 1;
          this.hitCount = 0;
          this.penetrate = false;
          this.damageDampPercent = 0.6;
          this.isOuting = false;
          this.scanRadius = 2;
          this.outEase = Laya.Ease.linearIn;
          this.outToData = { time: 0.2, pass: 0, running: false, delay: 0 };
          this.bombSkillData = {};
      }
      onUpdate() {
          let dt = GameConst.FrameDeltaTime * StageConfig.gameTimeScale;
          if (this.isOuting) {
              this.updateOuting(dt);
          }
          else {
              this.update(dt);
          }
      }
      updateOuting(t) {
          let outToData = this.outToData;
          outToData.pass += t;
          let timePass = outToData.pass;
          let timeMaxx = outToData.time;
          this.node.alpha = this.outEase(timePass, 1, -1, timeMaxx);
          if (timePass >= timeMaxx) {
              this.onBulletEnd(false);
          }
      }
      update(t) {
          this.timepass += t;
          if (this.timedelay) {
              if (this.timepass < this.timedelay) {
                  return;
              }
              else {
                  this.timedelay = 0;
                  this.node.visible = true;
              }
          }
          else {
              if (!this.node.visible)
                  this.node.visible = true;
          }
          this.speed += this.aSpeed * t;
          let moveDistance = this.speed * t;
          this.addMoveDistance(moveDistance);
          this.node.x += this.direction.x * moveDistance;
          this.node.y += this.direction.y * moveDistance;
          if (this.timepass >= this.timemaxx) {
              this.moveOut();
          }
          this.updateScaleTo(t);
      }
      calcDamage(target) {
          let dd = super.calcDamage(target, true);
          let damageDamp = Math.pow(this.damageDampPercent, this.hitCount);
          dd.damage = Math.ceil(dd.damage * damageDamp);
          return dd;
      }
      onTargetHit(target) {
          let isHit = super.onTargetHit(target);
          if (isHit) {
              this.hitCount++;
              if (this.hitCount == 1) {
                  let caster = this.world.objectMgr.getObjectById(this.uidCaster);
                  if (caster) {
                      let TT_CROSSBOW_BOMB = caster.attrCur[BASE_ATTR.TT_CROSSBOW_BOMB];
                      if (TT_CROSSBOW_BOMB && TT_CROSSBOW_BOMB > 0) {
                          if (DamageCalculation.calcProb(TT_CROSSBOW_BOMB)) {
                              this.bomb(caster, target);
                          }
                      }
                  }
              }
              if (!this.penetrate) {
                  this.onBulletEnd();
                  return true;
              }
              else {
                  return false;
              }
          }
      }
      moveOut() {
          this.isOuting = true;
      }
      bomb(caster, target) {
          let skillDb = db.get_skill_db(db.game_cnf.crossbow_bomb_id);
          if (skillDb) {
              if (skillDb.effect_hit) {
                  this.world.eventEffectHitCreate(caster, target, skillDb.id, 0);
              }
              Level.packSkillData(this.bombSkillData, skillDb);
              this.world.skillMgr.useSkill(caster, target, this.bombSkillData);
          }
      }
      set delay(delay) {
          this.timedelay = delay;
      }
      shootTarget(time, target, handerComplete) {
          time = db.game_cnf.crossbow_time;
          let DARK = StageAttr.getAttr(STAGE_ATTR.DARK);
          if (DARK > 0) {
              time = time * (1 - DARK);
          }
          this.setTarget = target;
          let dx = target.x - this.node.x;
          let dy = target.y - this.node.y;
          this.speed = db.game_cnf.crossbow_speed;
          this.aSpeed = db.game_cnf.crossbow_aspeed;
          this.timepass = 0;
          this.timemaxx = time;
          this.direction.x = dx;
          this.direction.y = dy;
          this.direction.normalize();
          this.hitCount = 0;
          this.delay = 0;
          this.node.visible = false;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree;
          this.node.alpha = 1;
          this.isOuting = false;
          this.outToData.pass = 0;
          this.restMoveDistance();
          this.calcScaleTo(time);
      }
  }

  class BulletRealDirection extends BulletReal {
      constructor() {
          super(...arguments);
          this.speed = 0;
          this.aSpeed = 0;
          this.distance = 0;
          this.timedelay = 0;
          this.timepass = 0;
          this.timemaxx = 1;
          this.hitCount = 0;
          this.penetrate = true;
          this.isOuting = false;
          this.scanRadius = 2;
          this.outEase = Laya.Ease.linearIn;
          this.outToData = { time: 0.2, pass: 0, running: false, delay: 0 };
      }
      onUpdate() {
          let dt = GameConst.FrameDeltaTime * StageConfig.gameTimeScale;
          if (this.isOuting) {
              this.updateOuting(dt);
          }
          else {
              this.update(dt);
          }
      }
      updateOuting(t) {
          let outToData = this.outToData;
          outToData.pass += t;
          let timePass = outToData.pass;
          let timeMaxx = outToData.time;
          this.node.alpha = this.outEase(timePass, 1, -1, timeMaxx);
          if (timePass >= timeMaxx) {
              this.onBulletEnd(false);
          }
      }
      update(t) {
          this.timepass += t;
          if (this.timedelay) {
              if (this.timepass < this.timedelay) {
                  return;
              }
              else {
                  this.timedelay = 0;
                  this.node.visible = true;
              }
          }
          else {
              if (!this.node.visible)
                  this.node.visible = true;
          }
          this.speed += this.aSpeed * t;
          let moveDistance = this.speed * t;
          this.addMoveDistance(moveDistance);
          this.node.x += this.direction.x * moveDistance;
          this.node.y += this.direction.y * moveDistance;
          if (this.timepass >= this.timemaxx) {
              this.moveOut();
          }
          this.updateScaleTo(t);
      }
      calcDamage(target) {
          return super.calcDamage(target);
      }
      onTargetHit(target) {
          let isHit = super.onTargetHit(target);
          if (isHit) {
              this.hitCount++;
              if (!this.penetrate) {
                  this.onBulletEnd();
                  return true;
              }
              else {
                  return false;
              }
          }
      }
      moveOut() {
          this.isOuting = true;
      }
      set delay(delay) {
          this.timedelay = delay;
      }
      shootTarget(time, target, handerComplete) {
          time = db.game_cnf.crossbow_time;
          this.setTarget = target;
          let dx = target.x - this.node.x;
          let dy = target.y - this.node.y;
          let param = this.bulletDb.param;
          this.collisionRadius = param[0] || 1;
          this.speed = param[1] || 800;
          this.aSpeed = param[2] || 50;
          this.timepass = 0;
          this.timemaxx = time;
          this.direction.x = dx;
          this.direction.y = dy;
          this.direction.normalize();
          this.hitCount = 0;
          this.delay = 0;
          this.node.visible = false;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree;
          this.node.alpha = 1;
          this.isOuting = false;
          this.outToData.pass = 0;
          this.restMoveDistance();
          this.calcScaleTo(time);
          this.showCollisionArea();
      }
  }

  class BulletRealDirectionRange extends BulletReal {
      constructor() {
          super(...arguments);
          this.speed = 0;
          this.aSpeed = 0;
          this.distance = 0;
          this.timedelay = 0;
          this.timepass = 0;
          this.timemaxx = 1;
          this.hitCount = 0;
          this.penetrate = true;
          this.isOuting = false;
          this.scanRadius = 2;
          this.outEase = Laya.Ease.linearIn;
          this.outToData = { time: 0.2, pass: 0, running: false, delay: 0 };
      }
      onUpdate() {
          let dt = GameConst.FrameDeltaTime * StageConfig.gameTimeScale;
          if (this.isOuting) {
              this.updateOuting(dt);
          }
          else {
              this.update(dt);
          }
      }
      updateOuting(t) {
          let outToData = this.outToData;
          outToData.pass += t;
          let timePass = outToData.pass;
          let timeMaxx = outToData.time;
          this.node.alpha = this.outEase(timePass, 1, -1, timeMaxx);
          if (timePass >= timeMaxx) {
              this.onBulletEnd(false);
          }
      }
      update(t) {
          this.timepass += t;
          if (this.timedelay) {
              if (this.timepass < this.timedelay) {
                  return;
              }
              else {
                  this.timedelay = 0;
                  this.node.visible = true;
              }
          }
          else {
              if (!this.node.visible)
                  this.node.visible = true;
          }
          this.speed += this.aSpeed * t;
          let moveDistance = this.speed * t;
          this.addMoveDistance(moveDistance);
          this.node.x += this.direction.x * moveDistance;
          this.node.y += this.direction.y * moveDistance;
          if (this.timepass >= this.timemaxx) {
              this.moveOut();
          }
          this.updateScaleTo(t);
      }
      calcDamage(target) {
          return super.calcDamage(target);
      }
      onTargetHit(target) {
          let isHit = super.onTargetHit(target);
          if (isHit) {
              this.hitCount++;
              if (!this.penetrate) {
                  this.onBulletEnd();
                  return true;
              }
              else {
                  return false;
              }
          }
      }
      moveOut() {
          this.isOuting = true;
      }
      set delay(delay) {
          this.timedelay = delay;
      }
      shootTarget(time, target, handerComplete) {
          time = db.game_cnf.crossbow_time;
          this.setTarget = target;
          let dx = target.x - this.node.x;
          let dy = target.y - this.node.y;
          let param = this.bulletDb.param;
          this.collisionRadius = param[0] || 1;
          this.speed = param[1] || 800;
          this.aSpeed = param[2] || 50;
          if (this.world) {
              let caster = this.world.objectMgr.getObjectById(this.uidCaster);
              let distance = caster.getAttr(BASE_ATTR.RANGE) * Level.tileW;
              if (this.aSpeed != 0) {
                  time = (-this.speed + Math.sqrt(this.speed * this.speed + 2 * this.aSpeed * distance)) / this.aSpeed;
              }
              else {
                  time = distance / this.speed;
              }
          }
          this.timepass = 0;
          this.timemaxx = time;
          this.direction.x = dx;
          this.direction.y = dy;
          this.direction.normalize();
          this.hitCount = 0;
          this.delay = 0;
          this.node.visible = false;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree;
          this.node.alpha = 1;
          this.isOuting = false;
          this.outToData.pass = 0;
          this.restMoveDistance();
          this.calcScaleTo(time);
          this.showCollisionArea();
      }
  }

  class BulletRealDirectionSkill extends BulletReal {
      constructor() {
          super(...arguments);
          this.speed = 0;
          this.aSpeed = 0;
          this.distance = 0;
          this.timedelay = 0;
          this.timepass = 0;
          this.timemaxx = 1;
          this.hitCount = 0;
          this.isOuting = false;
          this.scanRadius = 2;
          this.outEase = Laya.Ease.linearIn;
          this.outToData = { time: 0.2, pass: 0, running: false, delay: 0 };
          this.tempSkillData = {};
      }
      onUpdate() {
          let dt = GameConst.FrameDeltaTime * StageConfig.gameTimeScale;
          if (this.isOuting) {
              this.updateOuting(dt);
          }
          else {
              this.update(dt);
          }
      }
      updateOuting(t) {
          let outToData = this.outToData;
          outToData.pass += t;
          let timePass = outToData.pass;
          let timeMaxx = outToData.time;
          this.node.alpha = this.outEase(timePass, 1, -1, timeMaxx);
          if (timePass >= timeMaxx) {
              this.onBulletEnd();
          }
      }
      update(t) {
          this.timepass += t;
          if (this.timedelay) {
              if (this.timepass < this.timedelay) {
                  return;
              }
              else {
                  this.timedelay = 0;
                  this.node.visible = true;
              }
          }
          else {
              if (!this.node.visible)
                  this.node.visible = true;
          }
          this.speed += this.aSpeed * t;
          let moveDistance = this.speed * t;
          this.addMoveDistance(moveDistance);
          this.node.x += this.direction.x * moveDistance;
          this.node.y += this.direction.y * moveDistance;
          if (this.timepass >= this.timemaxx) {
              this.moveOut();
          }
          this.updateScaleTo(t);
      }
      calcDamage(target) {
          return super.calcDamage(target);
      }
      onTargetHit(target) {
          let curtTime = Utils.getTime();
          let lastTime = this.uid2HurtTime[target.uid] || curtTime;
          let caster = this.world.objectMgr.getObjectById(this.uidCaster);
          if (caster && curtTime >= lastTime && this.calcCollisionWithCircle(this, target)) {
              this.uid2HurtTime[target.uid] = curtTime + 200;
              this.onBulletEnd();
              return true;
          }
          return false;
      }
      onBulletEnd(isHit = true) {
          if (isHit) {
              this.onBulletHit();
              if (this.world) {
                  let caster = this.world.objectMgr.getObjectById(this.uidCaster);
                  let skillDb = this.skillDb;
                  if (caster && skillDb) {
                      Level.packSkillData(this.tempSkillData, skillDb);
                      if (caster) {
                          let pos = Level.stage.localPos2GridPos(this.node.x, this.node.y);
                          let targets = Skill.findHitObjects(caster, pos.x, pos.y, skillDb);
                          for (let obj of targets) {
                              Skill.execSkill(this.world, caster, obj, skillDb.template, this.tempSkillData, skillDb);
                          }
                      }
                  }
              }
          }
          if (this.handerComplete) {
              this.handerComplete.runWith(this);
          }
          this.remove();
      }
      moveOut() {
          this.isOuting = true;
      }
      set delay(delay) {
          this.timedelay = delay;
      }
      shootTarget(time, target, handerComplete) {
          time = db.game_cnf.crossbow_time;
          this.setTarget = target;
          let dx = target.x - this.node.x;
          6;
          let dy = target.y - this.node.y;
          let param = this.bulletDb.param;
          this.collisionRadius = param[0] || 1;
          this.speed = param[1] || 800;
          this.aSpeed = param[2] || 50;
          if (this.world) {
              let caster = this.world.objectMgr.getObjectById(this.uidCaster);
              let distance = caster.getAttr(BASE_ATTR.RANGE) * Level.tileW;
              if (this.aSpeed != 0) {
                  time = (-this.speed + Math.sqrt(this.speed * this.speed + 2 * this.aSpeed * distance)) / this.aSpeed;
              }
              else {
                  time = distance / this.speed;
              }
          }
          this.timepass = 0;
          this.timemaxx = time;
          this.direction.x = dx;
          this.direction.y = dy;
          this.direction.normalize();
          this.hitCount = 0;
          this.delay = 0;
          this.node.visible = false;
          let degree = Utils.vectorToDegree(dx, dy);
          this.node.rotation = degree;
          this.node.alpha = 1;
          this.isOuting = false;
          this.outToData.pass = 0;
          this.restMoveDistance();
          this.calcScaleTo(time);
          this.showCollisionArea();
      }
  }

  var ShurikenState;
  (function (ShurikenState) {
      ShurikenState[ShurikenState["MOVE"] = 0] = "MOVE";
      ShurikenState[ShurikenState["WAIT"] = 1] = "WAIT";
      ShurikenState[ShurikenState["BACK"] = 2] = "BACK";
  })(ShurikenState || (ShurikenState = {}));
  class BulletRealShuriken extends BulletReal {
      constructor() {
          super(...arguments);
          this.speedRotation = 800;
          this.waitpass = 0;
          this.waitmaxx = 1;
          this.state = ShurikenState.MOVE;
          this.funcEaseMove = Laya.Ease.quartIn;
          this.targetDegree = 0;
          this.moveToData = { x: 0, y: 0, dx: 0, dy: 0, time: 0, pass: 0, running: false, delay: 0 };
      }
      update(t) {
          if (this.nodeView)
              this.nodeView.rotation += this.speedRotation * t;
          switch (this.state) {
              case ShurikenState.MOVE:
                  if (this.updateMoveTo(t)) {
                      this.state = ShurikenState.WAIT;
                  }
                  break;
              case ShurikenState.BACK:
                  if (this.updateMoveTo(t)) {
                      this.onBulletEnd();
                  }
                  break;
              case ShurikenState.WAIT:
                  this.waitpass += t;
                  this.updateDamageByTime(t);
                  if (this.waitpass >= this.waitmaxx) {
                      this.moveBack();
                  }
                  break;
          }
      }
      updateMoveTo(dt) {
          let moveToData = this.moveToData;
          if (!moveToData.running)
              return;
          moveToData.pass += dt;
          let timePass = moveToData.pass;
          let timeMaxx = moveToData.time;
          let timeDely = moveToData.delay;
          if (timeDely > timePass)
              return;
          timePass -= timeDely;
          if (timePass > timeMaxx)
              timePass = timeMaxx;
          let ox = this.node.x;
          let oy = this.node.y;
          let nx = this.funcEaseMove(timePass, moveToData.x, moveToData.dx, timeMaxx);
          let ny = this.funcEaseMove(timePass, moveToData.y, moveToData.dy, timeMaxx);
          this.node.x = nx;
          this.node.y = ny;
          let dx = nx - ox;
          let dy = ny - oy;
          this.addMoveDistance(Math.sqrt(dx * dx + dy * dy));
          if (timePass >= timeMaxx) {
              moveToData.running = false;
              return true;
          }
          return false;
      }
      moveBack() {
          this.moveToData.pass = 0;
          this.moveToData.x += this.moveToData.dx;
          this.moveToData.y += this.moveToData.dy;
          this.moveToData.dx = -this.moveToData.dx;
          this.moveToData.dy = -this.moveToData.dy;
          this.moveToData.running = true;
          this.state = ShurikenState.BACK;
          this.funcEaseMove = Laya.Ease.quartIn;
      }
      moveTo(time, target, handerComplete = null) {
          this.setTarget = target;
          this.moveToData.pass = 0;
          this.moveToData.time = time;
          this.moveToData.x = this.node.x;
          this.moveToData.y = this.node.y;
          let dx = this.target_x - this.node.x;
          let dy = this.target_y - this.node.y;
          this.moveToData.dx = dx;
          this.moveToData.dy = dy;
          this.moveToData.running = true;
          this.moveToData.delay = 0;
          let degree = Utils.vectorToDegree(dx, dy);
          this.targetDegree = degree;
          this.handerComplete = handerComplete;
          this.direction.x = dx;
          this.direction.y = dy;
          this.direction.normalize();
          this.funcEaseMove = Laya.Ease.quartOut;
      }
      onSkinLoad(view) {
          super.onSkinLoad(view);
          this.nodeView = view.getChildByName("view");
      }
      shootTarget(time, target, handerComplete) {
          this.setTarget = target;
          this.moveTo(time, target, handerComplete);
          this.restMoveDistance();
          let param = this.bulletDb.param;
          let interval = param[0] || 1;
          let atktime = param[1] || 5;
          let waitmaxx = interval * atktime;
          this.resetUpdateDamageTime(interval);
          this.waitpass = 0;
          this.waitmaxx = waitmaxx;
          this.state = ShurikenState.MOVE;
          this.calcScaleTo(time);
      }
      execDamageByTime() {
          let pos = Level.stage.localPos2GridPos(this.node.x, this.node.y);
          let targets = this.findHitObjects(pos.x, pos.y, this.skillDb);
          let caster = this.world.objectMgr.getObjectById(this.uidCaster);
          if (caster) {
              for (let target of targets) {
                  target.execSkillWithDamage(caster, DamageCalculation.calcDamage(caster, target, this.skillData, null), this.skillData);
              }
          }
      }
  }

  class FactoryBullet {
      static create(bulletId) {
          return this.createByBulletDb(db.get_bullet_db(bulletId));
      }
      static createByBulletDb(bulletDb) {
          let clas = Bullet;
          switch (bulletDb.template) {
              case "BulletParabola":
                  clas = BulletParabola;
                  break;
              case "BulletFollow":
                  clas = BulletFollow;
                  break;
              case "BulletBezier":
                  clas = BulletBezier2;
                  break;
              case "BulletLine":
                  clas = BulletLine;
                  break;
              case "BulletRealBoomerang":
                  clas = BulletRealBoomerang;
                  break;
              case "BulletRealShuriken":
                  clas = BulletRealShuriken;
                  break;
              case "BulletFall":
                  clas = BulletFall;
                  break;
              case "BulletJump":
                  clas = BulletJump;
                  break;
              case "BulletRealCrossbow":
                  clas = BulletRealCrossbow;
                  break;
              case "BulletRealDirection":
                  clas = BulletRealDirection;
                  break;
              case "BulletRealDirectionRange":
                  clas = BulletRealDirectionRange;
                  break;
              case "BulletRealDirectionSkill":
                  clas = BulletRealDirectionSkill;
                  break;
          }
          return this.createBulletByClas(clas, bulletDb);
      }
      static createBulletByClas(clas, bulletDb, usePool = true) {
          if (!bulletDb)
              return;
          let node;
          if (usePool) {
              node = Laya.Pool.getItem("Bullet_" + bulletDb.id);
          }
          let bullet;
          if (node) {
              bullet = node.getComponent(clas);
              bullet.node = node;
              bullet.bulletId = bulletDb.id;
              bullet.bulletDb = bulletDb;
              bullet.playAnim(bulletDb.anim);
          }
          else {
              node = new Laya.Sprite();
              bullet = node.addComponent(clas);
              bullet.node = node;
              bullet.bulletId = bulletDb.id;
              bullet.bulletDb = bulletDb;
              if (bulletDb.load_model) {
                  if (bulletDb.fgui) {
                      bullet.loadViewFgui(bulletDb.model);
                  }
                  else {
                      bullet.loadView(bulletDb.model);
                  }
              }
          }
          if (StageConfig.enableGameEffect && bulletDb.effect_bullet)
              bullet.createEffect(bulletDb.effect_bullet, 0, 0, false);
          bullet.reset();
          if (bulletDb.scale_y) {
              bullet.node.scale(bulletDb.scale[0], bulletDb.scale_y);
          }
          else {
              bullet.node.scale(bulletDb.scale[0], bulletDb.scale[0]);
          }
          bullet.effect_hit = bulletDb.effect_hit;
          let config = this.getBulletConfig(bulletDb.id);
          if (StageConfig.enableGameEffect && config instanceof Array && config.length > 0) {
              for (let data of config) {
                  bullet.createEffect(data.id, data.x, data.y);
              }
          }
          else {
          }
          return bullet;
      }
      static getBulletEffect(bulletDb) {
          let effectIds = [];
          if (!bulletDb)
              return effectIds;
          let config = this.getBulletConfig(bulletDb.id);
          if (config instanceof Array && config.length > 0) {
              for (let data of config) {
                  effectIds.push(data.id);
              }
          }
          return effectIds;
      }
      static loadBulletConfig(data) {
          if (!data)
              return;
          this.jsonBulletConfig = data;
          console.log("加载子弹配置", this.jsonBulletConfig);
      }
      static getBulletConfig(id) {
          return this.jsonBulletConfig[id];
      }
      static setBulletConfig(id, data) {
          return this.jsonBulletConfig[id] = data;
      }
      static loadConfig(resolve) {
          Laya.loader.load(this.pathConfig, Laya.Handler.create(this, this.onConfigLoad, [resolve]), null, Laya.Loader.JSON);
      }
      static onConfigLoad(resolve) {
          let jsonData = Laya.loader.getRes(this.pathConfig);
          if (jsonData)
              this.loadBulletConfig(jsonData);
          if (resolve)
              resolve();
      }
  }
  FactoryBullet.jsonBulletConfig = {};
  FactoryBullet.pathConfig = "res/cfg/bullet_cofing.json";

  class CustomCrossBow extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower/CustomCrossBow";
          this.exportNodeNames = {
              cc_tran_shoot: "fgui.Transition",
          };
      }
      onCreate() {
          TowerImageHelper.registLoader(this);
      }
      dispose() {
          super.dispose();
      }
      shoot() {
          this.tran_shoot.stop();
          this.tran_shoot.play();
      }
  }

  var Math_PI_2 = Math.PI / 180;
  class TowerMain extends Tower {
      constructor() {
          super(...arguments);
          this.crossbowEnergyCur = 0;
          this.crossbowEnergyMax = 100;
      }
      onCreate() {
          super.onCreate();
          this.initCrossbow();
      }
      onUpdate(t) {
          super.onUpdate(t);
          this.updateCrossbowEnergyRecover(t);
      }
      selectTarget(target) {
      }
      setTargets(targets) {
          this.targetIds.length = 0;
          let isFind = false;
          for (let target of targets) {
              if (target.getAttr(BASE_ATTR.HP) && this.isTargetInRange(target)) {
                  isFind = true;
                  this.targetIds.push(target.uid);
                  this.selectTarget(target);
              }
          }
          if (isFind) {
              this.tryAttack();
          }
      }
      searchTargetsBySector(rx, ry, degree) {
          let targets = this.findObjectsByRange();
          this.targetIds.length = 0;
          let isFind = false;
          for (let target of targets) {
              if (target.getAttr(BASE_ATTR.HP)) {
                  if (target.camp == LogicCamp.FRIEND || LogicTool.isPointInSector(this.gx, this.gy, rx, ry, target.gx, target.gy, degree)) {
                      isFind = true;
                      this.targetIds.push(target.uid);
                      this.selectTarget(target);
                  }
              }
          }
          if (isFind) {
              this.tryAttack();
          }
          return isFind;
      }
      tryAttack() {
      }
      bindSkin(skin) {
          super.bindSkin(skin);
          let crossbow = skin.skin.getChild("cross");
          if (crossbow instanceof CustomCrossBow) {
              this.nodeCrossbow = crossbow;
              this.nodeCrossbow.visible = true;
              let gPoint = crossbow.localToGlobal();
              crossbow.removeFromParent();
              Level.stage.layerCrossbow.addChild(crossbow.displayObject);
              crossbow.x = gPoint.x;
              crossbow.y = gPoint.y;
              crossbow.scaleX = skin.skin.scaleX;
              crossbow.scaleY = skin.skin.scaleY;
          }
      }
      unbindSkin() {
          if (this.skin && this.nodeCrossbow) {
              this.nodeCrossbow.displayObject.removeSelf();
              this.skin.skin.addChild(this.nodeCrossbow);
              this.nodeCrossbow.visible = false;
              this.nodeCrossbow = null;
          }
          super.unbindSkin();
      }
      calcCrossbowNum() {
      }
      initCrossbow() {
          this.crossbowEnergyMax = 100;
          this.crossbowEnergyCur = this.crossbowEnergyMax;
      }
      costCrossbowEnergy(cost) {
          if (this.crossbowEnergyCur >= cost) {
              this.crossbowEnergyCur -= cost;
              this.updateCrossbowProgress();
              return true;
          }
          else {
              mgrTip.showMsgTip("攻城弩能量不足!");
              return false;
          }
      }
      updateCrossbowEnergyRecover(t) {
          if (this.crossbowEnergyCur >= this.crossbowEnergyMax)
              return;
          let add = t * db.game_cnf.crossbow_energy_recover;
          this.crossbowEnergyCur += add;
          this.updateCrossbowProgress();
          if (this.crossbowEnergyCur > this.crossbowEnergyMax) {
              this.crossbowEnergyCur = this.crossbowEnergyMax;
          }
      }
      updateCrossbowProgress() {
          if (this.skin) {
              this.skin.updateCrossbowProgress(this.crossbowEnergyCur, this.crossbowEnergyMax);
          }
      }
      shootCrossbow(x, y) {
          if (this.nodeCrossbow && StageAttr.noAttr(STAGE_ATTR.DISARM)) {
              if (!this.costCrossbowEnergy(db.game_cnf.crossbow_energy_cost)) {
                  return false;
              }
              let point = this.nodeCrossbow.localToGlobal();
              let dx = x - point.x;
              let dy = y - point.y;
              let degree = Utils.vectorToDegree(dx, dy);
              this.nodeCrossbow.rotation = degree - 90;
              this.nodeCrossbow.shoot();
              let from = Level.stage.layerBullet.globalToLocal(point);
              let to = Level.stage.layerBullet.globalToLocal(new Laya.Point(x, y));
              let indexLeft = 0;
              let indexRight = 0;
              let isLeft = true;
              let bulletNum = 1;
              let bulletDegree = Math_PI_2 * db.game_cnf.crossbow_degree;
              let bulletDelay = db.game_cnf.crossbow_delay;
              let attrCaster = this.attrCur;
              let TT_CROSSBOW_ADD = attrCaster[BASE_ATTR.TT_CROSSBOW_ADD];
              if (TT_CROSSBOW_ADD && TT_CROSSBOW_ADD > 0) {
                  bulletNum += TT_CROSSBOW_ADD;
              }
              let penetrate = false;
              let damageDampPercent = 0.6;
              let TT_CROSSBOW_PEN = attrCaster[BASE_ATTR.TT_CROSSBOW_PEN];
              if (TT_CROSSBOW_PEN && TT_CROSSBOW_PEN > 0) {
                  damageDampPercent = TT_CROSSBOW_PEN;
                  penetrate = true;
              }
              let bulletNumHalf = Math.floor(bulletNum * 0.5);
              let skillDb;
              if (this.skillDb.attr_dmg == "AP") {
                  skillDb = db.get_skill_db(db.game_cnf.crossbow_skill_id_ap);
              }
              else {
                  skillDb = db.get_skill_db(db.game_cnf.crossbow_skill_id_ad);
              }
              if (skillDb.sound_shoot) {
                  mgrSound.playSound(skillDb.sound_shoot);
              }
              let bulletDb = db.get_bullet_db(skillDb.bullet_id);
              let uid2HurtTime = {};
              for (let i = 0; i < bulletNum; i++) {
                  let tx;
                  let ty;
                  let delay = 0;
                  if (i == 0) {
                      tx = to.x;
                      ty = to.y;
                      delay = bulletNumHalf;
                  }
                  else {
                      if (isLeft) {
                          indexLeft++;
                          tx = LogicTool.rotatex(to.x, to.y, -bulletDegree * indexLeft, from.x, from.y);
                          ty = LogicTool.rotatey(to.x, to.y, -bulletDegree * indexLeft, from.x, from.y);
                          delay = bulletNumHalf - indexLeft;
                      }
                      else {
                          indexRight++;
                          tx = LogicTool.rotatex(to.x, to.y, bulletDegree * indexRight, from.x, from.y);
                          ty = LogicTool.rotatey(to.x, to.y, bulletDegree * indexRight, from.x, from.y);
                          delay = bulletNumHalf + indexRight;
                      }
                      isLeft = !isLeft;
                  }
                  this._tempPoint.x = tx;
                  this._tempPoint.y = ty;
                  let bullet = this.shootCrossbowArrow(point, this._tempPoint, skillDb, bulletDb, uid2HurtTime);
                  bullet.delay = delay * bulletDelay;
                  bullet.penetrate = penetrate;
                  bullet.damageDampPercent = damageDampPercent;
              }
              return true;
          }
          return false;
      }
      shootCrossbowArrow(from, to, skillDb, bulletDb, uid2HurtTime) {
          let timeUse = 1;
          let bullet = FactoryBullet.createByBulletDb(bulletDb);
          bullet.born(Level.stage.layerBullet);
          bullet.node.x = from.x;
          bullet.node.y = from.y;
          bullet.bind(this, null, skillDb, uid2HurtTime);
          bullet.shootTarget(timeUse, { x: to.x, y: to.y, width: 1, height: 1 });
          return bullet;
      }
  }
  TowerMain.poolkey = "TowerMain";

  class EnemyFinalWar extends EnemyBoss {
      onDead() {
          if (this.roleDb && this.roleDb.dead_cmd) {
              switch (this.roleDb.dead_cmd) {
                  case "dmg_reduct_25":
                      let findTarget = this.world.findEnemyByRoleId(this.roleDb.dead_cmd_param);
                      if (findTarget) {
                          let reduct = findTarget.attrCur[BASE_ATTR.DMG_REDUCT] + 0.25;
                          if (reduct >= 1) {
                              reduct = 1;
                              findTarget.clearAllBuff(StageConfig.attrNoRecover);
                          }
                          findTarget.attrCur[BASE_ATTR.DMG_REDUCT] = reduct;
                      }
                      break;
              }
          }
          super.onDead();
      }
  }
  EnemyFinalWar.poolkey = "EnemyFinalWar";

  var Math_PI_2$1 = Math.PI / 180;
  class Skill {
      static execSkill(world, caster, target, template, skillData, skillDb) {
          let skillId = skillData.skillId;
          caster.calcBuffBySkillCaster(caster, skillId, skillData);
          if (skillDb.damage_delay) {
              world.skillMgr.addAction(LogicActionSkillDamage.create(world, skillDb.damage_delay / caster.getAttackSpeed(), caster, target, template, skillId, skillData));
          }
          else {
              target.calcBuffBySkillTarget(caster, skillId, skillData);
              target.execSkill(caster, skillData);
          }
      }
      static execSkillNoCasterBuff(world, caster, target, template, skillData, skillDb) {
          let skillId = skillData.skillId;
          if (skillDb.damage_delay) {
              world.skillMgr.addAction(LogicActionSkillDamage.create(world, skillDb.damage_delay / caster.getAttackSpeed(), caster, target, template, skillId, skillData));
          }
          else {
              target.calcBuffBySkillTarget(caster, skillId, skillData);
              target.execSkill(caster, skillData);
          }
      }
      static createBullet(world, caster, target, template, skillData, index, skillDb) {
          let skillId = skillData.skillId;
          let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
          world.eventBulletCreate(skillId, timeUse, caster, target, index);
          let action = LogicActionSkill.create(world, timeUse, caster, target, template, skillId, skillData);
          world.skillMgr.addAction(action);
      }
      static findHitObjects(caster, gx, gy, skillDb, flipX = 1) {
          if (skillDb.use_hit_area) {
              return caster.world.map.findObjectsByOffset(gx, gy, HitAreaHelper.getHitArea(skillDb.id), MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, this.getSkillHitLimit(caster, skillDb), this.DEBUG_HIT_RANGE, flipX);
          }
          else {
              return caster.world.map.findObjectsByRange(gx, gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, skillDb.hit_range, this.getSkillHitLimit(caster, skillDb), true, this.DEBUG_HIT_RANGE);
          }
      }
      static findHitFriends(caster, gx, gy, skillDb, flipX = 1) {
          if (skillDb.use_hit_area) {
              return caster.world.map.findObjectsByOffset(gx, gy, HitAreaHelper.getHitArea(skillDb.id), MAP_FLAG.BUILDING, LogicCamp.FRIEND, this.getSkillHitLimit(caster, skillDb), this.DEBUG_HIT_RANGE, flipX);
          }
          else {
              return caster.world.map.findObjectsByRange(gx, gy, MAP_FLAG.BUILDING, LogicCamp.FRIEND, skillDb.hit_range, this.getSkillHitLimit(caster, skillDb), true, this.DEBUG_HIT_RANGE);
          }
      }
      static calcBulletFlyTime(caster, target, skillDb) {
          if (skillDb.bullet_time_ignore_range) {
              return skillDb.bullet_time;
          }
          else {
              let dx = target.gx - caster.gx;
              let dy = target.gy - caster.gy;
              let distance = Math.sqrt(dx * dx + dy * dy);
              return skillDb.bullet_time + distance / skillDb.bullet_speed;
          }
      }
      static getSkillHitLimit(caster, skillDb) {
          return skillDb.hit_limit;
      }
      static getSkillTargetLimit(caster, skillDb) {
          let attrCur = caster.attrCur;
          if (!skillDb.is_super) {
              let target_add = attrCur[BASE_ATTR.TT_TARGET_ADD] || 0;
              return target_add + skillDb.target_limit;
          }
          else {
              return skillDb.target_limit;
          }
      }
      static searchMutilTargets(template, caster, target, skillData, index) {
          let world = caster.world;
          let listTargets = Skill.listTargets;
          listTargets.length = 0;
          let skillDb = skillData.skillDb;
          listTargets.push(target);
          let limit = Skill.getSkillTargetLimit(caster, skillDb) + 1;
          let targetCount = 1;
          for (let id of caster.targetIds) {
              let obj = world.objectMgr.getObjectById(id);
              if (obj && obj != target) {
                  if (targetCount < limit) {
                      listTargets.push(obj);
                      targetCount++;
                      if (targetCount >= limit) {
                          break;
                      }
                  }
              }
          }
          return listTargets;
      }
      static searchMutilTargets4Enemy(template, caster, target, skillData, index) {
          let world = caster.world;
          let listTargets = Skill.listTargets;
          listTargets.length = 0;
          let skillDb = skillData.skillDb;
          let limit = Skill.getSkillTargetLimit(caster, skillDb) + 1;
          let head = world.buildings.head;
          while (head) {
              let obj = head.data;
              head = head.next;
              if (obj) {
                  listTargets.push(obj);
                  let dx = caster.gx - obj.gx;
                  let dy = caster.gy - obj.gy;
                  obj.__distanceSqWithCaster = dx * dx + dy * dy;
              }
          }
          listTargets.sort(Skill.sortTargetWithDistance);
          if (limit < listTargets.length)
              listTargets.length = limit;
          return listTargets;
      }
      static sortTargetWithDistance(a, b) {
          let distanceA = a.__distanceSqWithCaster || 0;
          let distanceB = b.__distanceSqWithCaster || 0;
          return distanceA - distanceB;
      }
      static searchMutilTargetsRandom(template, caster, target, skillData, index) {
          let world = caster.world;
          let listTargets = Skill.listTargets;
          listTargets.length = 0;
          let skillDb = skillData.skillDb;
          let limit = Skill.getSkillTargetLimit(caster, skillDb) + 1;
          let head = world.buildings.head;
          while (head) {
              let obj = head.data;
              head = head.next;
              if (obj) {
                  listTargets.push(obj);
              }
          }
          Utils.randomSort(listTargets);
          if (limit < listTargets.length)
              listTargets.length = limit;
          return listTargets;
      }
      static regist(world) {
          let skillMgr = world.skillMgr;
          skillMgr.registSkillTempates([
              {
                  name: "BulletAttack",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      if (caster && target && skillDb) {
                          let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
                          let bulletDb = db.get_bullet_db(skillDb.bullet_id);
                          let bullet = FactoryBullet.createByBulletDb(bulletDb);
                          let posf = caster.getShootPoint(index);
                          let fx = posf.x;
                          let fy = posf.y;
                          bullet.born(Level.stage.layerBullet);
                          bullet.node.x = fx;
                          bullet.node.y = fy;
                          let targetSkin = Level.stage.getUnitSkinById(target.uid);
                          bullet.bind(caster, target, skillDb);
                          bullet.shootTarget(timeUse, targetSkin);
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                  }
              },
              {
                  name: "BulletAttackMulti",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      if (caster && target && skillDb) {
                          let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
                          let bulletDb = db.get_bullet_db(skillDb.bullet_id);
                          let posf = caster.getShootPoint(index);
                          let num = Utils.random(bulletDb.num[0], bulletDb.num[1]) || 1;
                          if (num > 0) {
                              let bulletDegree = 0;
                              if (num != 0)
                                  bulletDegree = Math_PI_2$1 * 360 / num;
                              let tox = posf.x + 200;
                              let toy = posf.y;
                              for (let i = 0; i < num; i++) {
                                  let tx;
                                  let ty;
                                  if (i == 0) {
                                      tx = tox;
                                      ty = toy;
                                  }
                                  else {
                                      tx = LogicTool.rotatex(tox, toy, bulletDegree * i, posf.x, posf.y);
                                      ty = LogicTool.rotatey(tox, toy, bulletDegree * i, posf.x, posf.y);
                                  }
                                  let bullet = FactoryBullet.createByBulletDb(bulletDb);
                                  let fx = posf.x;
                                  let fy = posf.y;
                                  bullet.born(Level.stage.layerBullet);
                                  bullet.node.x = fx;
                                  bullet.node.y = fy;
                                  bullet.bind(caster, target, skillDb);
                                  bullet.shootTarget(timeUse, { x: tx, y: ty, width: 1, height: 1 });
                                  bullet.effect_hit = skillDb.effect_hit;
                              }
                          }
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillId = skillData.skillId;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          let targets = this.findHitObjects(caster, target.gx, target.gy, skillDb);
                          for (let obj of targets) {
                              if (skillDb.effect_hit_all)
                                  world.eventEffectHitCreate(caster, obj, skillId);
                              this.execSkill(world, caster, obj, template, skillData, skillDb);
                          }
                      }
                  }
              },
              {
                  name: "MeleeAttack",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      world.eventEffectHitCreate(caster, target, skillId, count);
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "Line",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      if (count == 0) {
                          let skillDb = skillData.skillDb;
                          caster.calcBuffBySkillCaster(caster, skillDb.id, skillData);
                          this.createBullet(world, caster, target, template, skillData, index, skillDb);
                      }
                      else {
                          skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkillNoCasterBuff(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "IceLine",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      if (count == 0) {
                          let skillDb = skillData.skillDb;
                          this.createBullet(world, caster, target, template, skillData, index, skillDb);
                      }
                      else {
                          skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "BOSS16Line",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      let head = world.buildings.head;
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              if (count == 0) {
                                  this.createBullet(world, caster, data, template, skillData, index, skillDb);
                              }
                              else {
                                  skillMgr.hitSkill(caster.uid, data.uid, template, skillData, count);
                              }
                          }
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          skillData.count = count;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "MeleeAttackAreaBullet",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      world.eventBulletCreate(skillId, 1, caster, target, index);
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillId = skillData.skillId;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          if (!skillDb.effect_hit_all)
                              world.eventEffectHitCreate(caster, target, skillId, count);
                          if (skillDb.buff_first_id) {
                              target.addBuffById(caster, skillDb.buff_first_id);
                          }
                          let targets = this.findHitObjects(caster, target.gx, target.gy, skillDb);
                          for (let obj of targets) {
                              if (skillDb.effect_hit_all)
                                  world.eventEffectHitCreate(caster, obj, skillId);
                              this.execSkill(world, caster, obj, template, skillData, skillDb);
                          }
                      }
                  }
              },
              {
                  name: "MeleeAttackArea",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillId = skillData.skillId;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          if (!skillDb.effect_hit_all)
                              world.eventEffectHitCreate(caster, target, skillId, count);
                          if (skillDb.buff_first_id) {
                              target.addBuffById(caster, skillDb.buff_first_id);
                          }
                          let targets = this.findHitObjects(caster, target.gx, target.gy, skillDb);
                          for (let obj of targets) {
                              if (skillDb.effect_hit_all)
                                  world.eventEffectHitCreate(caster, obj, skillId);
                              this.execSkill(world, caster, obj, template, skillData, skillDb);
                          }
                      }
                  }
              },
              {
                  name: "MeleeAttackMulti",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                  }
              },
              {
                  name: "MeleeAttackMultiNoHit",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                  }
              },
              {
                  name: "RangeAttack",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      this.createBullet(world, caster, target, template, skillData, index, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillId = skillData.skillId;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "Boss18Skill",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      if (target) {
                          target = world.addVirtual(24, 20);
                      }
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      this.createBullet(world, caster, target, template, skillData, index, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillDb = skillData.skillDb;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                          let head = world.buildings.head;
                          while (head) {
                              let obj = head.data;
                              head = head.next;
                              if (obj) {
                                  obj.createEffect(skillDb.effect_hit_sub, skillDb.hit_offset);
                                  this.execSkill(world, caster, obj, template, skillData, skillDb);
                              }
                          }
                      }
                  }
              },
              {
                  name: "RangeAttack4Enemy",
                  multi: this.searchMutilTargets4Enemy,
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      if (skillDb && skillDb.multi_effect_lock) {
                          let targets = Skill.searchMutilTargets4Enemy(template, caster, target, skillData, index);
                          for (let obj of targets) {
                              obj.createEffectLock(skillData.skillDb);
                          }
                      }
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      this.createBullet(world, caster, target, template, skillData, index, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillId = skillData.skillId;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "RangeAttackRandom",
                  multi: this.searchMutilTargetsRandom,
                  exec: (template, caster, target, skillData, index, count) => {
                      this.createBullet(world, caster, target, template, skillData, index, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let skillId = skillData.skillId;
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "SuperSkill03",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      let targets = world.map.findObjectsByRange(caster.gx, caster.gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, caster.range, this.getSkillHitLimit(caster, skillDb), true, this.DEBUG_HIT_RANGE);
                      targets.sort(function (a, b) {
                          let scoreA = a.getSortScore();
                          let scoreB = b.getSortScore();
                          return scoreB - scoreA;
                      });
                      let targetMaxHp = targets[0];
                      if (targetMaxHp) {
                          return targetMaxHp;
                      }
                      else {
                          return target;
                      }
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      this.createBullet(world, caster, target, template, skillData, index, skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "RangeAttackMulti",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      this.createBullet(world, caster, target, template, skillData, index, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "RangeAttackArea",
                  multi: this.searchMutilTargets,
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let skillDb = skillData.skillDb;
                      let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
                      world.eventBulletCreate(skillId, timeUse, caster, target, index);
                      let action = LogicActionSkill.create(world, timeUse, caster, target, template, skillId, skillData);
                      skillMgr.addAction(action);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      if (caster) {
                          let tx = skillData.targetX;
                          let ty = skillData.targetY;
                          let skillDb = skillData.skillDb;
                          let targets = this.findHitObjects(caster, tx, ty, skillDb);
                          for (let obj of targets) {
                              this.execSkill(world, caster, obj, template, skillData, skillDb);
                          }
                      }
                  }
              },
              {
                  name: "AllTower",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let head = world.buildings.head;
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              world.eventEffectHitCreate(caster, data, skillId, count);
                              skillMgr.hitSkill(caster.uid, data.uid, template, skillData, count);
                          }
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "AllTowerAction",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let head = world.buildings.head;
                      let listTower = [];
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              listTower.push(data);
                          }
                      }
                      Utils.randomSort(listTower);
                      let countIdex = 0;
                      for (let tower of listTower) {
                          let action = LogicActionSkill.create(world, countIdex * 0.1, caster, tower, template, skillId, skillData);
                          skillMgr.addAction(action);
                          countIdex++;
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "AllTowerNoSelf",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let head = world.buildings.head;
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              if (data.uid != caster.uid) {
                                  world.eventEffectHitCreate(caster, data, skillId, count);
                                  skillMgr.hitSkill(caster.uid, data.uid, template, skillData, count);
                              }
                          }
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "AllTowerMain",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let head = world.buildings.head;
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              if (data instanceof TowerMain) {
                                  world.eventEffectHitCreate(caster, data, skillId, count);
                              }
                              skillMgr.hitSkill(caster.uid, data.uid, template, skillData, count);
                          }
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "BuffSelf",
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      skillMgr.hitSkill(caster.uid, caster.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "TowerCure",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      let targets = [];
                      let head = world.buildings.head;
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              targets.push(data);
                          }
                      }
                      targets.sort(function (a, b) {
                          return a.getAttrPercent(BASE_ATTR.HP) * 100 - b.getAttrPercent(BASE_ATTR.HP) * 100;
                      });
                      let targetMinHp = targets[0];
                      if (targetMinHp) {
                          return targetMinHp;
                      }
                      else {
                          return target;
                      }
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "TowerHpLess",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let targets = [];
                      let head = world.buildings.head;
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Tower) {
                              targets.push(data);
                          }
                      }
                      targets.sort(function (a, b) {
                          return a.getAttr(BASE_ATTR.HP) - b.getAttr(BASE_ATTR.HP);
                      });
                      let targetMinHp = targets[0];
                      if (targetMinHp) {
                          return targetMinHp;
                      }
                      else {
                          return target;
                      }
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "JumpAttack",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let skillDb = skillData.skillDb;
                      let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
                      let tx = target.gx;
                      let ty = target.gy;
                      if (target instanceof LogicTower) {
                          let p = target.findNearestBlock(caster.gx, caster.gy);
                          tx = p.x;
                          ty = p.y;
                      }
                      let dx = tx - caster.gx;
                      let dy = ty - caster.gy;
                      let ds = Math.sqrt(dx * dx + dy * dy);
                      let bx = Math.round(tx - dx / ds * 2);
                      let by = Math.round(ty - dy / ds * 2);
                      let bestPos = world.map.findBestAttackPos(bx, by, tx, ty, MAP_FLAG.BUILDING | MAP_FLAG.BARRIER);
                      if (bestPos) {
                          caster.jumpTo(timeUse, bestPos.x, bestPos.y, "jump");
                      }
                      let action2 = LogicActionSkill.create(world, timeUse, caster, target, template, skillId, skillData);
                      world.skillMgr.addAction(action2);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "Transform",
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, caster, skillData.skillId, count);
                      skillMgr.hitSkill(caster.uid, caster.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      if (caster) {
                          caster.calcBuffBySkillCaster(caster, skillData.skillId, skillData);
                      }
                  }
              },
              {
                  name: "SectorAttack",
                  multi: (template, caster, target, skillData, index) => {
                      let world = caster.world;
                      let listTargets = Skill.listTargets;
                      listTargets.length = 0;
                      let towerUids = {};
                      listTargets.push(target);
                      towerUids[target.uid] = true;
                      let param = skillData.skillDb.param;
                      let degree = param[0] / 2;
                      let range = param[1];
                      let listObjects = world.map.findObjectsBySector(caster.gx, caster.gy, target.gx, target.gy, range, degree, MAP_FLAG.BUILDING, LogicCamp.FRIEND, 0, true);
                      for (let obj of listObjects) {
                          if (!towerUids[obj.uid]) {
                              towerUids[obj.uid] = true;
                              listTargets.push(obj);
                          }
                      }
                      return listTargets;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                  }
              },
              {
                  name: "RectAttack",
                  multi: (template, caster, target, skillData, index) => {
                      let world = caster.world;
                      let listTargets = Skill.listTargets;
                      listTargets.length = 0;
                      let towerUids = {};
                      listTargets.push(target);
                      towerUids[target.uid] = true;
                      let param = skillData.skillDb.param;
                      let width = param[0];
                      let height = param[1];
                      let listObjects = world.map.findObjectsByRect(caster.gx, caster.gy, target.gx, target.gy, width, height, MAP_FLAG.BUILDING, LogicCamp.FRIEND, 0, true);
                      for (let obj of listObjects) {
                          if (!towerUids[obj.uid]) {
                              towerUids[obj.uid] = true;
                              listTargets.push(obj);
                          }
                      }
                      return listTargets;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                  }
              },
              {
                  name: "LRSkillAttack",
                  multi: (template, caster, target, skillData, index) => {
                      let listTargets = Skill.listTargets;
                      let dx = target.gx - caster.gx;
                      let flipX = dx < 0 ? 1 : -1;
                      listTargets.length = 0;
                      let towerUids = {};
                      let listObjects = this.findHitFriends(caster, caster.gx, caster.gy, skillData.skillDb, flipX);
                      for (let obj of listObjects) {
                          if (!towerUids[obj.uid]) {
                              towerUids[obj.uid] = true;
                              listTargets.push(obj);
                          }
                      }
                      world.eventEffectHitCreate(caster, target, skillData.skillId, 0, flipX);
                      return listTargets;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                  }
              },
              {
                  name: "LRSkillAttackRange",
                  multi: (template, caster, target, skillData, index) => {
                      let listTargets = Skill.listTargets;
                      let dx = target.gx - caster.gx;
                      let flipX = dx < 0 ? 1 : -1;
                      listTargets.length = 0;
                      let towerUids = {};
                      let listObjects = this.findHitFriends(caster, caster.gx, caster.gy, skillData.skillDb, flipX);
                      for (let obj of listObjects) {
                          if (!towerUids[obj.uid]) {
                              towerUids[obj.uid] = true;
                              listTargets.push(obj);
                          }
                      }
                      world.eventEffectHitCreate(caster, target, skillData.skillId, 0, flipX);
                      return listTargets;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
                      let action = LogicActionSkill.create(world, timeUse, caster, target, template, skillDb.skillId, skillData);
                      world.skillMgr.addAction(action);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "AllEnemy",
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let head = world.objectMgr.getLinkHead();
                      while (head) {
                          let data = head.data;
                          head = head.next;
                          if (data instanceof Enemy) {
                              world.eventEffectHitCreate(caster, data, skillId, count);
                              skillMgr.hitSkill(caster.uid, data.uid, template, skillData, count);
                          }
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "Boss19Skill1",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      if (target && skillDb && skillDb.param.length) {
                          let findTarget = world.findEnemyByRoleId(skillDb.param[0].toString());
                          if (findTarget) {
                              target = findTarget;
                          }
                          else {
                              target = world.addVirtual(24, 20);
                          }
                      }
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      world.eventEffectHitCreate(caster, target, skillId, count);
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                          if (target instanceof EnemyBossFinalWar) {
                              target.revive(true);
                          }
                      }
                  }
              },
              {
                  name: "Boss19Skill2",
                  exec: (template, caster, target, skillData, index, count) => {
                      skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                      }
                      let skillDb = skillData.skillDb;
                      if (skillDb) {
                          let roleId = skillDb.param[0];
                          if (roleId) {
                              for (let i = 0; i < skillDb.param.length; i += 2) {
                                  let x = skillDb.param[i + 1];
                                  let y = skillDb.param[i + 2];
                                  if (x != null && y != null) {
                                      let obj = world.addEnemy(EnemyFinalWar, x, y, roleId, caster.lv);
                                      world.eventEffectHitCreate(caster, obj, skillDb.id, count);
                                  }
                              }
                          }
                      }
                  }
              },
              {
                  name: "Boss19Skill3",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      if (target) {
                          target = world.addVirtual(caster.gx - 7, caster.gy);
                      }
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      if (skillDb) {
                          let action = LogicActionSkill.create(world, skillDb.damage_delay, caster, target, template, skillDb.skillId, skillData);
                          world.skillMgr.addAction(action);
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                      }
                      let skillDb = skillData.skillDb;
                      if (skillDb) {
                          let roleId = skillDb.param[0];
                          if (roleId) {
                              let x = target.gx;
                              let y = target.gy;
                              let obj = world.addEnemy(EnemyBossFinalWar, x, y, roleId, caster.lv);
                              world.eventEffectHitCreate(caster, obj, skillDb.id, count);
                              Global.sendMsg(MSG.WAVE_CMD_FINAL_BOSS, { roleId: roleId, uid: obj.uid });
                              if (caster instanceof EnemyBossFinalWar) {
                                  caster.showHpBar();
                                  caster.attrCur[BASE_ATTR.DMG_REDUCT] = 1;
                              }
                          }
                      }
                  }
              },
              {
                  name: "Boss19Skill4",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      if (target && skillDb && skillDb.param.length) {
                          let findTarget = world.findEnemyByRoleId(skillDb.param[0].toString());
                          if (findTarget) {
                              target = findTarget;
                          }
                          else {
                              target = world.addVirtual(24, 20);
                          }
                      }
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      if (count == 0) {
                          let skillDb = skillData.skillDb;
                          this.createBullet(world, caster, target, template, skillData, index, skillDb);
                      }
                      else {
                          skillMgr.hitSkill(caster.uid, target.uid, template, skillData, count);
                      }
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "MapPointHit",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      let x = skillDb.param[0] || 0;
                      let y = skillDb.param[1] || 0;
                      target = world.addVirtual(x, y);
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillDb = skillData.skillDb;
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      let towerUids = {};
                      let targets = this.findHitFriends(caster, target.gx, target.gy, skillDb);
                      for (let obj of targets) {
                          if (!towerUids[obj.uid]) {
                              towerUids[obj.uid] = true;
                              this.execSkill(world, caster, obj, template, skillData, skillDb);
                          }
                      }
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
              {
                  name: "MapPointHitArea",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      let x = skillDb.param[0] || 0;
                      let y = skillDb.param[1] || 0;
                      target = world.addVirtual(x, y);
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      let skillId = skillData.skillId;
                      let skillDb = skillData.skillDb;
                      let timeUse = this.calcBulletFlyTime(caster, target, skillDb);
                      world.eventBulletCreate(skillId, timeUse, caster, target, index);
                      let action = LogicActionSkill.create(world, timeUse, caster, target, template, skillId, skillData);
                      skillMgr.addAction(action);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      if (caster) {
                          let tx = skillData.targetX;
                          let ty = skillData.targetY;
                          let skillDb = skillData.skillDb;
                          let targets = this.findHitFriends(caster, tx, ty, skillDb);
                          let towerUids = {};
                          for (let obj of targets) {
                              if (!towerUids[obj.uid]) {
                                  towerUids[obj.uid] = true;
                                  this.execSkill(world, caster, obj, template, skillData, skillDb);
                              }
                          }
                      }
                  }
              },
              {
                  name: "CallBySlotIds",
                  find: (template, caster, target, skillData = null, index = 0) => {
                      let skillDb = skillData.skillDb;
                      for (let slotId of skillDb.param) {
                          let tower = Level.stage.findTowerBySlotId(slotId);
                          if (tower) {
                              target = tower;
                              break;
                          }
                      }
                      return target;
                  },
                  exec: (template, caster, target, skillData, index, count) => {
                      world.eventEffectHitCreate(caster, target, skillData.skillId, count);
                      this.execSkill(world, caster, target, template, skillData, skillData.skillDb);
                  },
                  hit: (casterId, targetId, template, skillData, count) => {
                      let caster = world.objectMgr.getObjectById(casterId);
                      let target = world.objectMgr.getObjectById(targetId);
                      if (caster && target) {
                          let skillDb = skillData.skillDb;
                          this.execSkill(world, caster, target, template, skillData, skillDb);
                      }
                  }
              },
          ]);
      }
  }
  Skill.DEBUG_HIT_RANGE = false;
  Skill.listTargets = [];

  class Trap extends LogicTrap {
      onCreate() {
          super.onCreate();
          this.attrCur = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          this.attrStd = Level.buildAttrArray(BASE_ATTR.LEN_TOWER);
          this.skillDb = db.get_skill_db(this.tid);
          this.skillData = {};
          Level.packSkillData(this.skillData, this.skillDb);
      }
      start(caster, delay, time, interval) {
          if (caster) {
              Level.copyAttrArray(caster.attrCur, this.attrCur);
              Level.copyAttrArray(caster.attrStd, this.attrStd);
          }
          super.start(caster, delay, time, interval);
      }
      execSkill(caster) {
          let data = this.skillDb;
          if (data) {
              let objects;
              let selectUids = {};
              if (data.camp == LogicCamp.FRIEND) {
                  if (data.use_hit_area) {
                      objects = this.world.map.findObjectsByOffset(this.gx, this.gy, HitAreaHelper.getHitArea(data.id), MAP_FLAG.BUILDING, LogicCamp.FRIEND, 0, Trap.debug, 1, selectUids, true);
                  }
                  else {
                      objects = this.world.map.findObjectsByRange(this.gx, this.gy, MAP_FLAG.BUILDING, LogicCamp.FRIEND, data.hit_range, 0, true, Trap.debug, selectUids, true);
                  }
              }
              else {
                  if (data.use_hit_area) {
                      objects = this.world.map.findObjectsByOffset(this.gx, this.gy, HitAreaHelper.getHitArea(data.id), MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, 0, Trap.debug, 1, selectUids, true);
                  }
                  else {
                      objects = this.world.map.findObjectsByRange(this.gx, this.gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, data.hit_range, 0, true, Trap.debug, selectUids, true);
                  }
              }
              for (let object of objects) {
                  Skill.execSkill(this.world, caster, object, data.template, this.skillData, data);
              }
          }
      }
  }
  Trap.poolkey = "Trap";
  Trap.debug = false;

  class Buff {
      static addTargetStun(target) {
          target.addFlag(LogicObjectFlag.NO_ATTACK);
          target.addFlag(LogicObjectFlag.NO_MOVE);
      }
      static remTargetStun(target) {
          target.remFlag(LogicObjectFlag.NO_ATTACK);
          target.remFlag(LogicObjectFlag.NO_MOVE);
      }
      static recoverAttrByParam(target, param) {
          if (target) {
              target.calcBuffAll(StageConfig.attrNoRecover);
          }
      }
      static regist(world) {
          let skillMgr = world.skillMgr;
          skillMgr.registBuffTempates([
              {
                  name: "Stun",
                  start: (caster, target, buff) => {
                      this.addTargetStun(target);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.remTargetStun(target);
                  }
              },
              {
                  name: "Stun4Tower1",
                  start: (caster, target, buff) => {
                      this.addTargetStun(target);
                      let SK_TA_01 = caster.getAttr(BASE_ATTR.SK_TA_01);
                      if (SK_TA_01 > 0 && DamageCalculation.calcProb(SK_TA_01)) {
                          caster.useSkillById(target, caster.getSuperSkillId());
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.remTargetStun(target);
                  }
              },
              {
                  name: "Slow",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      target.addFlag(LogicObjectFlag.SLOW);
                      target.scaleSpeed(param[0] || 0.5);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      if (target.remFlag(LogicObjectFlag.SLOW)) {
                          target.recoverSpeed();
                      }
                  }
              },
              {
                  name: "Weak",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      target.addFlag(LogicObjectFlag.SLOW);
                      target.scaleSpeed(param[0] || 0.5);
                      target.scaleAttr(BASE_ATTR.HURT_FACTOR, param[1] || 1.5);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      if (target.remFlag(LogicObjectFlag.SLOW)) {
                          target.recoverSpeed();
                      }
                      target.recoverAttr(BASE_ATTR.HURT_FACTOR);
                  }
              },
              {
                  name: "Frozen",
                  start: (caster, target, buff) => {
                      this.addTargetStun(target);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.remTargetStun(target);
                  }
              },
              {
                  name: "Damage",
                  start: (caster, target, buff, param) => {
                      buff.attr = caster.attrCur;
                      buff.tidCaster = caster.tid;
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                  },
                  exec: (target, buff) => {
                      let attrId = buff.param[0];
                      let attrVl = buff.param[1];
                      if (attrId && attrVl && buff.attr) {
                          let damage = Math.round((buff.attr[attrId] || 0) * attrVl);
                          if (damage) {
                              let data = DamageCalculation.damageData;
                              data.isAP = attrId == BASE_ATTR.AP;
                              data.damage = damage;
                              data.tidCaster = buff.tidCaster;
                              DamageCalculation.dealDamageByBuff(data, target);
                              target.hurt(data);
                          }
                      }
                  },
                  end: (target, buff) => {
                  },
                  execAndClear: (target, buff, skillDb) => {
                      let attrId = buff.param[0];
                      let attrVl = buff.param[1];
                      let leftTime = buff.maxcount - buff.curCount;
                      if (leftTime > 0 && attrId && attrVl && buff.attr) {
                          let damage = (buff.attr[attrId] || 0) * attrVl * leftTime * skillDb.damage;
                          if (damage) {
                              let data = DamageCalculation.damageData;
                              let isAp = (attrId == BASE_ATTR.AP);
                              let crit = 0;
                              let crit_dmg = buff.attr[BASE_ATTR.CRIT_DMG] || 1;
                              if (isAp) {
                                  crit = buff.attr[BASE_ATTR.SK_AP_CRIT] || 0;
                              }
                              else {
                                  crit = buff.attr[BASE_ATTR.CRIT] || 0;
                              }
                              if (DamageCalculation.calcIsCrit(crit)) {
                                  damage *= crit_dmg;
                                  data.isCrit = true;
                              }
                              data.isAP = isAp;
                              data.damage = Math.round(damage);
                              data.tidCaster = buff.tidCaster;
                              DamageCalculation.dealDamageByBuff(data, target);
                              target.hurt(data);
                          }
                      }
                      buff.removeFrom(target);
                  },
              },
              {
                  name: "DamageStep",
                  start: (caster, target, buff, param) => {
                      buff.attr = caster.attrCur;
                      buff.tidCaster = caster.tid;
                  },
                  exec: (target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      if (buffDb) {
                          let param = buffDb.param;
                          let attrId = param[0];
                          let attrVl = param[buff.curCount * 3 - 2] || 1;
                          let interval = param[buff.curCount * 3 - 1] || 0;
                          let crit = param[buff.curCount * 3] || 0;
                          buff.interval = interval;
                          if (attrId && attrVl && buff.attr) {
                              let data = DamageCalculation.calcDamageWithAttrByDamageId(buff.attr, target, attrId, attrVl, crit, null, buffDb.hp_curt_damage);
                              if (data) {
                                  DamageCalculation.dealDamageByBuff(data, target);
                                  target.hurt(data);
                              }
                          }
                      }
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "Cure",
                  start: (caster, target, buff) => {
                  },
                  exec: (target, buff) => {
                      let data = DamageCalculation.damageData;
                      data.damage = 5;
                      target.cure(data);
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "DamagePercent",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.attr = caster.attrCur;
                      buff.tidCaster = caster.tid;
                  },
                  exec: (target, buff) => {
                      let data = DamageCalculation.damageData;
                      let hp = target.getAttr(BASE_ATTR.HP);
                      let damage = hp * buff.param[0];
                      let damageLimit = buff.attr[BASE_ATTR.AD] * db.game_cnf.buff_damage_hp_limit_ad + buff.attr[BASE_ATTR.AP] * db.game_cnf.buff_damage_hp_limit_ap;
                      damage = Math.min(damage, damageLimit);
                      data.damage = Math.ceil(damage);
                      data.tidCaster = buff.tidCaster;
                      DamageCalculation.dealDamageByBuff(data, target);
                      target.hurt(data);
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "CurePercent",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                  },
                  exec: (target, buff) => {
                      let data = DamageCalculation.damageData;
                      data.damage = Math.round(target.getAttrLost(BASE_ATTR.HP) * buff.param[0]);
                      target.cure(data);
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "CurePercentMax",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                  },
                  exec: (target, buff) => {
                      let data = DamageCalculation.damageData;
                      data.damage = Math.round(target.getAttrMax(BASE_ATTR.HP) * buff.param[0]);
                      target.cure(data);
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "CurePercentRevive",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                  },
                  exec: (target, buff) => {
                      let data = DamageCalculation.damageData;
                      data.damage = Math.round(target.getAttrMax(BASE_ATTR.HP) * buff.param[0]);
                      target.cure(data);
                  },
                  end: (target, buff) => {
                      if (target instanceof EnemyBossFinalWar) {
                          target.revive(target.canDead);
                      }
                  }
              },
              {
                  name: "Wudi",
                  start: (caster, target, buff) => {
                      target.addFlag(LogicObjectFlag.SHIELD);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      target.remFlag(LogicObjectFlag.SHIELD);
                  }
              },
              {
                  name: "SuckByHP",
                  start: (caster, target, buff, param) => {
                      let factor = 0;
                      if (param) {
                          factor = param[0] || 0;
                      }
                      let suck = Math.ceil(caster.getAttrMax(BASE_ATTR.HP) * factor);
                      target.attrCur[BASE_ATTR.DMG_SUCK] = suck;
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      target.setAttr(BASE_ATTR.DMG_SUCK, 0);
                  }
              },
              {
                  name: "DamageReduct",
                  start: (caster, target, buff, param) => {
                      let buffDb = db.get_buff_db(buff.id);
                      target.setAttr(BASE_ATTR.DMG_REDUCT, buffDb.param[0] || 0);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      target.recoverAttr(BASE_ATTR.DMG_REDUCT);
                  }
              },
              {
                  name: "Trap",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      target.world.addTrap(Trap, target.gx, target.gy, buffDb.param[0].toString()).start(caster, buffDb.delay, buffDb.time, buffDb.time / buffDb.count);
                      buff.removeFrom(target);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "AtkSpeed",
                  start: (caster, target, buff) => {
                      buff.calc(target);
                  },
                  calc: (target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      target.scaleAttr(BASE_ATTR.ATK_SPEED, buffDb.param[0]);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      target.recoverAttr(BASE_ATTR.ATK_SPEED);
                  }
              },
              {
                  name: "AttrAdd",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc(target, buff) {
                      let param = buff.param;
                      if (param) {
                          for (let i = 0; i < param.length; i += 2) {
                              let k = param[i];
                              let v = param[i + 1];
                              if (k != null && v != null) {
                                  target.changeAttr(k, target.getAttr(k) + v);
                              }
                          }
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
              {
                  name: "AttrScale",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc(target, buff) {
                      let param = buff.param;
                      if (param) {
                          for (let i = 0; i < param.length; i += 2) {
                              let k = param[i];
                              let v = param[i + 1];
                              if (k != null && v != null) {
                                  target.scaleAttr(k, v);
                              }
                          }
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
              {
                  name: "AttrScaleSelf",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc(target, buff) {
                      let param = buff.param;
                      if (param) {
                          for (let i = 0; i < param.length; i += 2) {
                              let k = param[i];
                              let v = param[i + 1];
                              if (k != null && v != null) {
                                  target.scaleAttr(k, v);
                              }
                          }
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
              {
                  name: "AttrScaleOverLay",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc: (target, buff) => {
                      let param = buff.param;
                      if (param) {
                          for (let i = 0; i < param.length; i += 2) {
                              let k = param[i];
                              let v = param[i + 1];
                              if (k != null && v != null) {
                                  if (k == BASE_ATTR.CRIT) {
                                      target.changeAttr(k, target.getAttr(k) + v);
                                  }
                                  else {
                                      target.scaleAttrOverLay(k, v - 1);
                                  }
                              }
                          }
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
              {
                  name: "RangeChange",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc: (target, buff) => {
                      let param = buff.param;
                      if (param) {
                          let range = target.getAttr(BASE_ATTR.RANGE);
                          target.changeAttr(BASE_ATTR.RANGE, range + param[0]);
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
              {
                  name: "ChangeSkill",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      if (buffDb) {
                          target.changeSkill(buffDb.param_s[0], buffDb.param_s[1]);
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "Reborn",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      if (buffDb) {
                          target.rebornById(buffDb.param_s[0], buffDb.param[0] == 0);
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "Transform",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      if (buffDb) {
                          buff.param = buffDb.param;
                      }
                      buff.calc(target);
                      target.skinTransform(1);
                      target.changeSkill(buffDb.param_s[0], buffDb.param_s[1]);
                  },
                  calc: (target, buff) => {
                      let param = buff.param;
                      if (param) {
                          for (let i = 0; i < param.length; i += 2) {
                              let k = param[i];
                              let v = param[i + 1];
                              if (k != null && v != null) {
                                  target.scaleAttr(k, v);
                              }
                          }
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                      target.skinTransform(0);
                      target.changeSkill();
                  }
              },
              {
                  name: "TransformForever",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      if (buffDb) {
                          buff.param = buffDb.param;
                      }
                      buff.calc(target);
                      target.skinTransform(1);
                      target.changeSkill(buffDb.param_s[0], buffDb.param_s[1]);
                  },
                  calc: (target, buff) => {
                      let param = buff.param;
                      if (param) {
                          for (let i = 0; i < param.length; i += 2) {
                              let k = param[i];
                              let v = param[i + 1];
                              if (k != null && v != null) {
                                  target.scaleAttr(k, v);
                              }
                          }
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "AttrAttack",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc: (target, buff) => {
                      let param = buff.param;
                      if (param) {
                          let scale = (param[0] || 1) - 1;
                          target.scaleAttrOverLay(BASE_ATTR.AD, scale);
                          target.scaleAttrOverLay(BASE_ATTR.AP, scale);
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
              {
                  name: "BeatBack",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      let dx = target.mx - caster.mx;
                      let dy = target.my - caster.my;
                      let distance = Math.sqrt(dx * dx + dy * dy);
                      let step = buffDb.param[0] || 1;
                      let range = buffDb.param[1] || 5;
                      if (distance <= 1) {
                          step = range;
                      }
                      else {
                          let scale = Math.ceil(range / distance);
                          step = Math.round(step * scale);
                      }
                      target.beatBack(caster, step);
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "Skill",
                  start: (caster, target, buff) => {
                      let buffDb = db.get_buff_db(buff.id);
                      let targetUse = caster.world.map.findObjectsByRange(target.gx, target.gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, caster.range, 2);
                      if (targetUse.length > 1) {
                          target.useSkillById(targetUse[1], buffDb.param[0].toString(), 0, 0);
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "None",
                  start: (caster, target, buff) => {
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                  }
              },
              {
                  name: "DamageEx",
                  start: (caster, target, buff, param) => {
                      if (!param) {
                          let buffDb = db.get_buff_db(buff.id);
                          param = buffDb.param;
                      }
                      buff.param = param;
                      buff.calc(target);
                  },
                  calc: (target, buff) => {
                      let param = buff.param;
                      if (param) {
                          let value = target.getAttr(BASE_ATTR.DMG_EX) + (param[0] || 0);
                          target.changeAttr(BASE_ATTR.DMG_EX, value);
                      }
                  },
                  exec: (target, buff) => {
                  },
                  end: (target, buff) => {
                      this.recoverAttrByParam(target, buff.param);
                  }
              },
          ]);
      }
  }

  class EventManager {
      constructor() {
          this.dispatcher = new Laya.EventDispatcher();
      }
      static getInstance() {
          if (EventManager._instance == null) {
              EventManager._instance = new EventManager();
          }
          return EventManager._instance;
      }
      Emit(MsgName, agv) {
          this.dispatcher.event(MsgName, agv);
      }
      AddMsgListener(MsgName, caller, listener, arg) {
          this.dispatcher.on(MsgName, caller, listener, (arg == null) ? null : ([arg]));
          return this;
      }
      RemoveMsgListener(MsgName, caller, listener, arg) {
          this.dispatcher.off(MsgName, caller, listener);
          return this;
      }
  }

  class View {
      constructor() {
          this.isShowBanner = false;
          this.manager = null;
          this.isPopFromStack = false;
          this._keyFromUI = null;
          this.msgEventMap = {};
          this.type = View.TYPE_DEFAULT;
      }
      setUIManager(manager) {
          this.manager = manager;
      }
      getUIManager() {
          return this.manager;
      }
      loadUIComponent(pack, component, index) {
          this.uiRoot = fgui.UIPackage.createObject(pack, component).asCom;
          if (index != null) {
              fgui.GRoot.inst.addChildAt(this.uiRoot, index);
          }
          else {
              fgui.GRoot.inst.addChild(this.uiRoot);
          }
          this.fullScreen();
          this.parseUI();
          this.onShow();
      }
      findNode(node, path) {
          var list = path.split("/");
          for (var i = 0; i < list.length; i++) {
              let child = node.getChild(list[i]);
              if (child == null) {
                  console.log("findNode: Not found", list[i]);
                  return null;
              }
              else {
                  node = child.asCom;
              }
          }
          return node;
      }
      childPath(path) {
          return this.findNode(this.uiRoot, path);
      }
      child(name) {
          return this.uiRoot.getChild(name);
      }
      childAt(index) {
          return this.uiRoot.getChildAt(index);
      }
      buttonClose(path) {
          this.childPath(path).onClick(this, this.onClickClose);
      }
      onClickClose(e) {
          this.stopEvent(e);
          this.goBack();
      }
      buttonView(path, view, isDialog) {
          if (!isDialog)
              isDialog = false;
          this.childPath(path).onClick(this, this.onClickButtonView, [view, isDialog]);
      }
      hideChild(path) {
          let child = this.childPath(path);
          if (child) {
              child.visible = false;
          }
      }
      onClickButtonView(view, isDialog, e) {
          this.stopEvent(e);
          if (this.isPopFromStack) {
              this.remove();
              return;
          }
          if (isDialog)
              this.getUIManager().showDialogForce(view);
          else
              this.getUIManager().showView(view);
      }
      stopEvent(e) {
          e._stoped = true;
      }
      remove() {
          if (this.uiRoot) {
              this.uiRoot.dispose();
          }
          if (this.type == View.TYPE_MAIN) {
              this.getUIManager().curtMainView = null;
          }
          this.manager.onViewDel(this);
          this.onRemove();
          this.delMsgEvent();
          if (this.isShowBanner) {
          }
          if (this.isPopFromStack) {
              this.getUIManager().popViewStack();
          }
      }
      onRemove() {
      }
      loadUI(data1, data2) {
      }
      parseUI() {
      }
      setFrom(key) {
          this._keyFromUI = key;
      }
      getFrom() {
          return this._keyFromUI;
      }
      fullScreen() {
          if (this.uiRoot)
              this.uiRoot.makeFullScreen();
      }
      show() {
          if (this.uiRoot)
              this.uiRoot.visible = true;
          this.onShow();
      }
      hide() {
          if (this.uiRoot)
              this.uiRoot.visible = false;
          this.onHide();
      }
      onShow() { }
      ;
      onHide() { }
      ;
      showBanner() {
          this.isShowBanner = true;
      }
      onMsgAdBannerLoad() {
          if (this.isShowBanner) {
          }
      }
      stopTouchEvent(e) {
          e._stoped = true;
      }
      addMsgEvent(key, func) {
          if (this.msgEventMap[key])
              return;
          this.msgEventMap[key] = func;
          EventManager.getInstance().AddMsgListener(key, this, func);
      }
      delMsgEvent() {
          for (let key in this.msgEventMap) {
              let func = this.msgEventMap[key];
              if (func) {
                  EventManager.getInstance().RemoveMsgListener(key, this, func);
              }
          }
      }
      isDialog() {
          return this.type == View.TYPE_DIALOG;
      }
      close() {
          this.remove();
      }
      goBack() {
          switch (this.type) {
              case View.TYPE_MAIN:
                  if (this.prevMainName) {
                      this.manager.showView(this.prevMainName);
                  }
                  break;
              default:
                  this.remove();
                  break;
          }
      }
  }
  View.TYPE_DEFAULT = 0;
  View.TYPE_DIALOG = 1;
  View.TYPE_MAIN = 2;

  class PopViewData {
  }
  class UIManager {
      constructor() {
          this.listDataDebug = null;
          this.viewTop = null;
          this.viewBottom = null;
          this.viewStacks = null;
          this.initData();
      }
      static getInstance() {
          if (UIManager._instance == null) {
              UIManager._instance = new UIManager();
          }
          return UIManager._instance;
      }
      initData() {
          this.uiAutoId = 0;
          this.uiMap = new Map();
          this.uiClas = {};
          this.uiDialog = {};
          this.uiCondition = {};
          this.uiBanner = {};
          this.curtMainView = null;
      }
      registUIClas(name, clas, isDialog) {
          this.uiClas[name] = clas;
          this.uiDialog[name] = isDialog;
          return UIManager._instance;
      }
      isUIDialog(name) {
          return this.uiDialog[name];
      }
      registUICondition(name, func) {
          this.uiCondition[name] = func;
          return UIManager._instance;
      }
      registBanner(name) {
          this.uiBanner[name] = true;
          return UIManager._instance;
      }
      loadNativePackage(url, caller, func) {
          fgui.UIPackage.loadPackage(url, Laya.Handler.create(caller, func));
      }
      loadPackage(url, caller, func) {
          fgui.UIPackage.loadPackage(url, Laya.Handler.create(caller, func));
      }
      generateViewId() {
          return ++this.uiAutoId;
      }
      createView(key, noCheck) {
          if (!noCheck && !this.checkViewCanOpen(key))
              return null;
          var clas = this.uiClas[key];
          if (clas == null)
              console.error("UIManager.createView not found", key);
          var view = new clas();
          view.id = this.generateViewId();
          view.name = key;
          view.setUIManager(this);
          if (this.uiBanner[key]) {
              view.showBanner();
          }
          return view;
      }
      getView(id) {
          return this.uiMap[id];
      }
      openDebug() {
          this.showDebugList(this.listDataDebug);
      }
      registDebugMenu(data) {
          this.listDataDebug = data;
      }
      showDebugList(data, itemClick) {
          let view = this.showView("debug");
          if (view) {
              view.showData(data, itemClick);
          }
      }
      openEditor(target, prop, callbackSave) {
          let listData = [];
          for (let key in prop) {
              let desc = prop[key];
              listData.push({
                  name: desc,
                  owner: target,
                  ownerKey: key,
              });
          }
          this.showEditorList(listData, callbackSave);
      }
      showEditorList(data, callbackSave) {
          let view = this.showView("editor");
          if (view) {
              view.showData(data, callbackSave);
          }
      }
      closeMainView() {
          if (this.curtMainView) {
              this.curtMainView.remove();
              this.curtMainView = null;
          }
      }
      checkViewCanOpen(key) {
          let func = this.uiCondition[key];
          if (func) {
              return func();
          }
          else {
              return true;
          }
      }
      showView(key, data1, data2) {
          let view = null;
          if (this.isUIDialog(key)) {
              view = this.showDialog(key, data1, data2);
          }
          else {
              view = this.showMainView(key, data1, data2);
          }
          return view;
      }
      showMainView(key, data1, data2) {
          let prevMainName = null;
          if (this.curtMainView) {
              prevMainName = this.curtMainView.name;
              this.curtMainView.remove();
              this.curtMainView = null;
          }
          this.closeMainView();
          console.log("showMainView", key);
          var view = this.createView(key);
          if (view) {
              view.type = View.TYPE_MAIN;
              view.prevMainName = prevMainName;
              view.loadUI(data1, data2);
              this.onViewAdd(view);
              this.curtMainView = view;
          }
          return view;
      }
      showDialog(key, data1, data2) {
          console.log("showDialog", key);
          var view = this.createView(key);
          if (view) {
              view.type = View.TYPE_DIALOG;
              view.loadUI(data1, data2);
              this.onViewAdd(view);
          }
          return view;
      }
      showDialogForce(key, data1, data2) {
          console.log("showDialogForce", key);
          var view = this.createView(key, true);
          if (view) {
              view.type = View.TYPE_DIALOG;
              view.loadUI(data1, data2);
              this.onViewAdd(view);
          }
          return view;
      }
      onViewAdd(view) {
          if (this.viewBottom == null) {
              this.viewBottom = view;
          }
          if (this.viewTop) {
              this.viewTop.next = view;
              view.prev = this.viewTop;
              view.next = null;
          }
          this.viewTop = view;
          this.uiMap[view.id] = view;
      }
      onViewDel(view) {
          let prev = view.prev;
          let next = view.next;
          if (prev && next) {
              prev.next = next;
              next.prev = prev;
          }
          if (this.viewBottom == view) {
              this.viewBottom = view.next;
          }
          if (this.viewTop == view) {
              this.viewTop = view.prev;
          }
          this.uiMap[view.id] = null;
      }
      getViewRealName(view) {
          if (view.__proto__ && view.__proto__.constructor)
              return view.__proto__.constructor.name;
          else
              return view.id;
      }
      printTop2BottomView() {
          let view = this.viewTop;
          let layer = 0;
          console.log("-----------printTop2BottomView-----------");
          while (view) {
              console.log(++layer, view.id, this.getViewRealName(view));
              view = view.prev;
          }
          console.log("-----------------------------------------");
      }
      showViewQueue(keys) {
          let view = null;
          for (let i = 0; i < keys.length; i++) {
              let viewData = keys[i];
              view = this.showView(viewData.key, viewData.data1, viewData.data1);
          }
          return view;
      }
      haveStack() {
          return this.viewStacks && this.viewStacks.length > 0;
      }
      setViewStack(keys) {
          this.viewStacks = keys;
          return this;
      }
      popViewStack() {
          let view = null;
          for (let i = 0; i < this.viewStacks.length; i++) {
              let viewData = this.viewStacks.shift();
              if (viewData) {
                  console.log("pop ", viewData.key);
                  view = this.showView(viewData.key, viewData.data1, viewData.data1);
                  if (view) {
                      view.isPopFromStack = true;
                      break;
                  }
              }
          }
          return view;
      }
      putViewStack() {
      }
      hideMain() {
          if (this.curtMainView) {
              this.curtMainView.hide();
          }
      }
      showMain() {
          if (this.curtMainView) {
              this.curtMainView.show();
          }
      }
      closeAll() {
          let view = this.viewTop;
          while (view) {
              let prev = view.prev;
              view.close();
              view = prev;
          }
          this.viewTop = null;
          this.viewBottom = null;
      }
  }

  class MapBG extends Laya.Script {
      constructor() {
          super(...arguments);
          this.effectList = [];
          this.offsetx = 0;
          this.offsety = 0;
          this.scaleMin = 1;
          this.scaleStd = 0.9;
          this.scaleInt = 0.9;
      }
      onAwake() {
          this.spriteBG = this.owner;
      }
      onStart() {
      }
      set url(value) {
          this.loadImage(value);
      }
      get url() {
          if (this.spriteBG) {
              let texture = this.spriteBG.texture;
              if (texture) {
                  return texture.url;
              }
          }
          return "";
      }
      loadFguiUrl(value) {
          let object = fgui.UIPackage.createObjectFromURL(value);
          if (object) {
              this.onFguiResLoad(object);
          }
          else {
              let pkgReg = /ui:\/\/(\S+)\//img;
              let result = pkgReg.exec(value);
              if (result) {
                  let pkgName = result[1];
                  fgui.UIPackage.loadPackage(`res/fgui/${pkgName}`, Laya.Handler.create(this, () => {
                      let res = fgui.UIPackage.createObjectFromURL(value);
                      if (res) {
                          this.onFguiResLoad(res);
                      }
                  }));
                  return;
              }
          }
      }
      onFguiResLoad(object) {
          this.owner.removeChildren();
          this.owner.addChild(object.displayObject);
          this.loadEffect(object.asCom);
      }
      loadEffect(resMap) {
          this.clearEffect();
          if (resMap) {
              this.transIn = resMap.getTransition("in");
              for (let i = 0; i < resMap.numChildren; i++) {
                  let child = resMap.getChildAt(i);
                  if (child instanceof CustomNodeEffect) {
                      let effect = child.loadEffect();
                      if (effect) {
                          this.effectList.push(effect);
                      }
                  }
              }
          }
      }
      hideEffect() {
          for (let effect of this.effectList) {
              effect.hide();
          }
      }
      showEffect() {
          for (let effect of this.effectList) {
              effect.show();
          }
      }
      clearEffect() {
          for (let effect of this.effectList) {
              effect.clear();
          }
          this.effectList.length = 0;
      }
      clearImage() {
          let texture = this.spriteBG.texture;
          if (texture) {
              Laya.loader.clearRes(texture.url);
              this.spriteBG.texture = null;
          }
      }
      loadImage(url) {
          if (this.url == url)
              return;
          Laya.loader.load(url, Laya.Handler.create(this, this.onImageLoad), null, Laya.Loader.IMAGE);
      }
      onImageLoad(texture) {
          this.clearImage();
          this.spriteBG.texture = texture;
      }
      hide() {
          if (this.spriteBG) {
              this.spriteBG.visible = false;
          }
      }
      show() {
          if (this.spriteBG) {
              this.spriteBG.visible = true;
          }
      }
      loadTile(path) {
          let mapJson = Laya.loader.getRes(path);
          if (mapJson) {
              this.onTileDataLoad(mapJson);
          }
          else {
              Laya.loader.load(path, Laya.Handler.create(this, () => {
                  let mapJson = Laya.loader.getRes(path);
                  if (mapJson) {
                      this.onTileDataLoad(mapJson);
                  }
              }), null, Laya.Loader.JSON);
          }
      }
      onTileDataLoad(mapJson) {
          Level.parseTileMap(mapJson);
      }
      loadMap(urlMap, urlTile) {
          this.loadFguiUrl(urlMap);
          this.loadTile(urlTile);
      }
      loadMapById(id) {
          if (this.mapId != id) {
              this.mapId = id;
              let config = db.get_map_config(id);
              if (config) {
                  this.mapDb = config;
                  this.offsetx = Math.floor((1536 - config.width) / 2);
                  this.offsety = Math.floor((2048 - config.height) / 2);
                  this.loadMap(config.map, config.tile);
                  let scaleMin = Math.max(UIRoot.canvasWidth / config.width, UIRoot.canvasHeight / config.height);
                  this.scaleMin = scaleMin;
                  this.scaleStd = config.std_scale;
                  this.scaleInt = Math.max(scaleMin, config.int_scale);
                  mgrTower.defaultPosGid = config.tower_pos_gid;
                  return config.auto_scale;
              }
          }
          return false;
      }
      getMapTowerPosGid() {
          if (this.mapDb) {
              return this.mapDb.tower_pos_gid;
          }
          else {
              return "1";
          }
      }
      playTransIn() {
          if (this.transIn)
              this.transIn.play();
      }
  }

  class TrapSkin extends ObjectSkin {
      onAwake() {
      }
      initSkin(target, parent) {
          let pos = Level.convertGridPosToRealPos(target.gx, target.gy, false);
          this.x = pos.x;
          this.y = pos.y;
          this.zOrder = this.y;
          this.loadSkin(target.skillDb, parent);
      }
      loadSkin(skillDb, parent) {
          if (StageConfig.enableGameEffect && !this.nodeEffect && skillDb && skillDb.effect_hit) {
              this.nodeEffect = EffectFactory.createByType(skillDb.effect_hit, parent, this);
          }
      }
      recover() {
          if (this.nodeEffect) {
              this.nodeEffect.onTimeEnd();
              this.nodeEffect = null;
          }
          super.recover();
      }
  }
  TrapSkin.poolkey = "TrapSkin";

  let gridW = Level.gridW;
  let gridH = Level.gridH;
  let tileW = Level.tileW;
  let tileH = Level.tileH;
  let gridCenterX = Math.floor(gridW / 2) - 1;
  let gridCenterY = Math.floor(gridH / 2) - 1;
  let space = 4;
  var TouchMode;
  (function (TouchMode) {
      TouchMode[TouchMode["NONE"] = 0] = "NONE";
      TouchMode[TouchMode["MAP"] = 1] = "MAP";
      TouchMode[TouchMode["TOWER"] = 2] = "TOWER";
  })(TouchMode || (TouchMode = {}));
  class StageGame extends StageBase2D {
      constructor() {
          super(...arguments);
          this.uid2Enemy = [];
          this.uid2Tower = [];
          this.uid2Trap = [];
          this.towerSlots = [];
          this.scaleMax = 1.5;
          this.countEnemy = 0;
          this.enableGameView = true;
          this.dropItemCustomRunning = false;
          this.dropItemCustomTime = 0;
          this.dropItemCustomMaxx = 5;
          this.mainTowerUID = 1;
          this.touchSlotId = 0;
          this.enbaleUnlockSlot = true;
          this.count = 0;
          this.isWorldRunning = true;
          this.passTime = 0;
          this.passWait = 1;
          this.dropPoint = new Laya.Point;
          this.dropMoneyData = { x: 0, y: 0, num: 0 };
          this.lastDropTime = 0;
          this.towerCount = 0;
          this.isTouchDown = false;
          this.pointDown = new Laya.Point;
          this.pointDownReset = true;
          this.enableTouch = true;
          this.enabelMoveMap = true;
          this.lasttDistance = 0;
          this.multiDistance = 0;
          this.touchMode = TouchMode.MAP;
          this.lastX = 0;
          this.lastY = 0;
          this.lastTouchCount = 0;
          this.isMultiTouch = false;
          this.enableShootCrossbow = true;
          this.mainLastFindTargetTick = 0;
          this.tempPos = new Laya.Point;
          this.sceneMoveDistance = 0;
          this.touchMoveDistance = 0;
          this.scaleBeforeFocus = 1;
      }
      onAwake() {
          super.onAwake();
          this.changeScenePivot(this.scene.width / 2, this.scene.height / 2);
          console.log("场景高宽", this.scene.width, this.scene.height, this.scene.x, this.scene.y);
          let nodeWorld = this.scene.getChildByName("world");
          this.initData();
          this.initLayer(nodeWorld);
          EffectFactory.setLayer2D(this.layerEffectTop, this.layerEffectBottom);
          let nodeBG = this.scene.getChildByName("bg");
          let nodeMask = this.scene.getChildByName("bg_mask");
          this.range = this.scene.getChildByName("range");
          this.range.visible = false;
          this.loadTowerOption();
          this.mapBG = nodeBG.addComponent(MapBG);
          this.graphicsWorld = nodeWorld.graphics;
          console.log("中心格子", gridCenterX, gridCenterY);
          let mapW = gridW * tileW;
          let mapH = gridH * tileH;
          nodeWorld.x -= (mapW / 2);
          nodeWorld.y -= (mapH / 2);
          this.world = new LogicWorld().init(gridW, gridH);
          Skill.regist(this.world);
          Buff.regist(this.world);
          this.world.skillMgr.setSkillPackFunc((data, skillId) => {
              LogicConfig.resetSkillData(data);
              let skillDb = db.get_skill_db(skillId);
              if (skillDb) {
                  data.skillId = skillDb.id;
                  data.template = skillDb.template;
                  data.timeCast = skillDb.cast_time;
                  data.timeCD = skillDb.cd_time;
                  data.skillDb = skillDb;
                  data.count = skillDb.atk_count;
                  data.ground = skillDb.groud;
              }
          });
          this.world.setOnUnitCreateListener(this.onUnitCreate.bind(this));
          this.world.setOnUnitRemoveListener(this.onUnitRemove.bind(this));
          this.world.setOnBuildingCreateListener(this.onTowerCreate.bind(this));
          this.world.setOnBuildingMoveListener(this.onTowerMove.bind(this));
          this.world.setOnBuildingRemoveListener(this.onTowerRemove.bind(this));
          this.world.setOnBulletCreateListener(this.onBulletCreate.bind(this));
          this.world.setOnEffectHitCreateListener(this.onEffectHitCreate.bind(this));
          this.initEnemWave(nodeWorld);
          Level.stage = this;
          this.initEvent();
          this.loadMap();
          this.refreshGuide();
      }
      loadTowerOption() {
          let towerOption = fgui.UIPackage.createObjectFromURL("ui://game/CustomTowerOption");
          this.layerMenuUI.addChild(towerOption.displayObject);
          this.towerOption = towerOption;
          this.towerOption.visible = false;
      }
      initEnemWave(nodeWorld) {
          this.enemyWave = nodeWorld.addComponent(EnemyWave);
          this.enemyWave.world = this.world;
      }
      initData() {
          StageAttr.initAttr();
          mgrAllEquip.updateAttr();
      }
      initLayer(node) {
          this.layerEffectBottom = this.createLayer(node);
          this.layerTower = this.createLayer(node);
          this.layerEnermy = this.createLayer(node);
          this.layerItem = this.createLayer(node);
          this.layerBullet = this.createLayer(node);
          this.layerCrossbow = this.createLayer(node);
          this.layerEffectTop = this.createLayer(node);
          this.layerGameUI = this.createLayer(node);
          this.layerMenuUI = this.createLayer(node);
      }
      dropItemCustomBegin() {
          this.dropItemCustomRunning = true;
          this.dropItemCustomMaxx = db.game_cnf.auto_drop_item_custom_time * 60;
          this.dropItemCustomTime = Utils.getTime() + this.dropItemCustomMaxx * 1000;
      }
      dropItemCustom(unit, skin) {
          if (!mgrGame.isNewBie())
              return false;
          if (!this.dropItemCustomRunning)
              return false;
          if (this.destroyed)
              return false;
          if (this.layerItem.destroyed)
              return false;
          if (Utils.getTime() < this.dropItemCustomTime)
              return false;
          let item = CustomDropItem.create();
          if (item && !item.destroyed) {
              this.layerItem.addChild(item.displayObject);
              item.displayObject.pivotX = item.width / 2;
              item.displayObject.pivotY = item.height / 2;
              let x = 0;
              let y = 0;
              if (skin) {
                  x = skin.x;
                  y = skin.y;
              }
              else {
                  let pos = Level.convertGridPosToRealPos(unit.gx, unit.gy);
                  x = pos.x;
                  y = pos.y;
              }
              item.displayObject.x = x;
              item.displayObject.y = y;
              item.buildDropDataByType(2);
              this.dropItemCustomRunning = false;
              return true;
          }
          return false;
      }
      dropItemOnGround(unit, skin) {
          if (this.destroyed)
              return;
          if (this.layerItem.destroyed)
              return;
          let item = CustomDropItem.create();
          if (item && !item.destroyed) {
              this.layerItem.addChild(item.displayObject);
              item.displayObject.pivotX = item.width / 2;
              item.displayObject.pivotY = item.height / 2;
              let x = 0;
              let y = 0;
              if (skin) {
                  x = skin.x;
                  y = skin.y;
              }
              else {
                  let pos = Level.convertGridPosToRealPos(unit.gx, unit.gy);
                  x = pos.x;
                  y = pos.y;
              }
              item.displayObject.x = x;
              item.displayObject.y = y;
              item.buildDropData();
          }
      }
      tryPickupDropItems(gx, gy) {
      }
      createLayer(parent) {
          let layer = new Laya.Sprite;
          parent.addChild(layer);
          return layer;
      }
      loadMap() {
          this.loadMapById(Level.mapDb.map_id);
      }
      loadMapById(id) {
          if (this.mapBG.loadMapById(id)) {
              this.changeSceneScale(this.scaleMin);
          }
      }
      loadTileMapData(world) {
          world.map.clearFlagAll();
          for (let x = 0; x < gridW; x++) {
              for (let y = 0; y < gridH; y++) {
                  if (Level.isTileMapBarrier(x, y)) {
                      world.map.addFlag(x, y, MAP_FLAG.BARRIER);
                  }
                  if (Level.isTileMapAlpha(x, y)) {
                      world.map.addFlag(x, y, MAP_FLAG.ALPHA);
                  }
              }
          }
      }
      changeScenePivot(x, y) {
          let dx = x - this.scene.pivotX;
          let dy = y - this.scene.pivotY;
          this.scene.pivot(x, y);
          this.scene.x += dx * this.scene.scaleX;
          this.scene.y += dy * this.scene.scaleY;
      }
      drawGrid() {
          let lineColor = "#00aa0055";
          this.graphicsWorld.clear();
          let data = this.world.getMap().gridFlag;
          for (let w = 0; w < data.length; w++) {
              let line = data[w];
              for (let h = 0; h < line.length; h++) {
                  let value = line[h];
                  let color = "#00000000";
                  if (value & (MAP_FLAG.BUILDING | MAP_FLAG.BARRIER)) {
                      color = "#aa0000aa";
                  }
                  else if (value & MAP_FLAG.ALPHA) {
                      color = "#33ccffaa";
                  }
                  else if (value & MAP_FLAG.UNIT_DEST) {
                      color = "#aa0000aa";
                  }
                  else if (value & MAP_FLAG.UNIT_MOVING) {
                      color = "#0000aaaa";
                  }
                  else if (value & MAP_FLAG.UNIT_STAND) {
                      color = "#aa0000aa";
                  }
                  this.graphicsWorld.drawRect(tileW * w, tileH * h, tileW, tileH, color, lineColor);
              }
          }
          console.log("O_O 刷新格子");
      }
      drawStep(x, y, color = "#0000ff55") {
          this.graphicsWorld.drawRect(tileW * x, tileH * y, tileW, tileH, color, "#00aa0055");
      }
      drawPath(points) {
          for (let point of points) {
              this.graphicsWorld.drawRect(tileW * point.x, tileH * point.y, tileW, tileH, "#abcdefaa", "#00aa0055");
          }
      }
      drawGridPos() {
          let data = this.world.getMap().gridFlag;
          for (let w = 0; w < data.length; w++) {
              let line = data[w];
              for (let h = 0; h < line.length; h++) {
                  this.graphicsWorld.strokeText(w + "," + h, tileW * (w + 0.5), tileH * h, "10px Arial", "#ffffff", 1, "center");
              }
          }
      }
      onStart() {
          this.loadTowerGround();
          this.loadTowers();
          this.focusSceneInit();
          mgrSound.playMusic("sBg");
          if (Level.isFirstGuide()) {
              this.enemyWave.openModeGuide();
              this.world.remAllUnit(LogicCamp.ENEMY);
              this.countEnemy = 0;
              this.hideTowerOption();
          }
      }
      get towerPosGid() {
          return mgrTower.defaultPosGid;
      }
      loadTowers() {
          this.clearTowerSkin();
          mgrTower.checkTowerPosAndFix();
          let towerPos = db.get_tower_pos_map()[this.towerPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              let id = mgrTower.getSlotTower(pos.id - 1);
              if (id) {
                  this.loadTowerByIdAndSlotId(id, pos.id);
              }
          }
          this.refreshTowerSlot();
      }
      loadTowerByIdAndSlotId(towerId, slotId) {
          let pos = db.get_tower_pos(this.towerPosGid, slotId - 1);
          if (pos) {
              let tower = this.loadTowerByIdAndGrid(towerId, pos.x, pos.y);
              if (tower) {
                  tower.slotId = pos.id;
                  if (tower.towerDb.main) {
                      this.mainTowerUID = tower.uid;
                      this.mainTower = tower;
                  }
              }
          }
      }
      loadTowerByIdAndGrid(towerId, gx, gy) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              let shape = [];
              let towerW = towerDb.size[0];
              let towerH = towerDb.size[1];
              let offsetx = Math.floor(towerW / 4);
              for (let i = 0; i < towerW; i++) {
                  for (let j = 0; j < towerH; j++) {
                      shape.push({ x: i, y: j });
                  }
              }
              ResTowerManager.onTowerAdd(towerId);
              if (towerDb.main)
                  return this.world.addBuilding(TowerMain, gx - offsetx, gy, towerId, shape);
              else
                  return this.world.addBuilding(Tower, gx - offsetx, gy, towerId, shape);
          }
      }
      loadTowerGround() {
          let towerPos = db.get_tower_pos_map()[this.towerPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              if (!pos.no_move) {
                  this.loadTowerSlot(pos, pos.size[0], pos.size[1]);
              }
          }
          this.refreshTowerSlot();
      }
      createTowerEmpty() {
          return fgui.UIPackage.createObjectFromURL(this.mapBG.mapDb.url_tower_bottom).asCom;
      }
      loadTowerSlot(pos, sw = 3, sh = 2) {
          let towerEmpty = this.createTowerEmpty();
          this.layerTower.addChild(towerEmpty.displayObject);
          let id = pos.id;
          let gx = pos.x;
          let gy = pos.y;
          towerEmpty.x = (pos.x + sw / 2) * Level.tileW;
          towerEmpty.y = (pos.y + sh / 2) * Level.tileH;
          towerEmpty.sortingOrder = towerEmpty.y;
          let touchArea = towerEmpty.getChild("touch");
          touchArea.on(Laya.Event.MOUSE_DOWN, this, this.onTowerDown, [{ gx: gx, gy: gy, slotId: id }]);
          touchArea.on(Laya.Event.MOUSE_MOVE, this, this.onTowerTouchMove);
          touchArea.on(Laya.Event.MOUSE_UP, this, this.onTowerUp, [{ gx: gx, gy: gy, slotId: id }]);
          let ad;
          let buttonAd = towerEmpty.getChild("button_ad");
          if (buttonAd) {
              buttonAd.onClick(this, this.onClickTowerEmptyButtnAD, [pos]);
              let showAd = this.isTowerSlotShowAD(pos);
              ad = towerEmpty.getController("ad");
              ad.selectedIndex = showAd ? 0 : 1;
              mgrGame.statisVideoShowByButton(buttonAd, db.ADV_DB_ADVNAME.map_unlock_tower_slot);
          }
          let rect = new Laya.Rectangle(towerEmpty.x - towerEmpty.width * towerEmpty.pivotX, towerEmpty.y - towerEmpty.height * towerEmpty.pivotY, towerEmpty.width, towerEmpty.height);
          let state = towerEmpty.getController("state");
          this.towerSlots.push({ id: id, gx: gx, gy: gy, pos: pos, node: towerEmpty, rect: rect, state: state, ad: ad });
          TowerImageHelper.registLoader(towerEmpty, state);
          let shape = [];
          let towerW = sw;
          let towerH = sh;
          for (let i = 0; i < towerW; i++) {
              for (let j = 0; j < towerH; j++) {
                  shape.push({ x: i, y: j });
              }
          }
          this.world.addBuildingShage(gx, gy, shape);
          return towerEmpty;
      }
      onClickTowerEmptyButtnAD(pos) {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.map_unlock_tower_slot, pos);
      }
      watchAdSuccess4UnlockTowerEmpty(slot) {
          mgrTower.tryUnlockSlot(slot.id - 1, true);
      }
      onTowerSlotUnlock(slotId) {
          let slot = this.findTowerSlotById(slotId);
          if (slot) {
              let effect = EffectFactory.create("tower_deploy", EffectFactory.scene3d);
              effect.followFguiNode(EffectFactory.camera, slot.node, true, 0, -50);
          }
          this.refreshTowerSlot();
      }
      refreshTowerSlot() {
          for (let slot of this.towerSlots) {
              this.refreshTowerSlotSingle(slot);
          }
      }
      isTowerSlotUnlcok(id) {
          return mgrTower.isTowerSlotUnlcok(id);
      }
      isTowerSlotShowAD(pos) {
          return !Global.isGuiding && db.cop_db.tower_slot_show_ad && this.enemyWave.isIdleMode() && pos.buttn_ad;
      }
      refreshTowerSlotSingle(slot) {
          if (!slot)
              return;
          if (this.isTowerSlotUnlcok(slot.id - 1)) {
              if (mgrTower.getSlotTower(slot.id - 1)) {
                  slot.state.selectedIndex = 2;
              }
              else {
                  slot.state.selectedIndex = 1;
              }
          }
          else {
              slot.state.selectedIndex = 0;
              if (slot.ad) {
                  let showAd = this.isTowerSlotShowAD(slot.pos);
                  slot.ad.selectedIndex = showAd ? 0 : 1;
              }
          }
      }
      findTowerById(id) {
          let head = this.world.buildings.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower) {
                  if (tower.towerDb.id == id) {
                      return tower;
                  }
              }
          }
          return null;
      }
      findTowerSlotById(id) {
          for (let slot of this.towerSlots) {
              if (slot.id == id) {
                  return slot;
              }
          }
      }
      findTowerSlotUnlock() {
          for (let slot of this.towerSlots) {
              if (slot.state.selectedIndex == 1) {
                  return slot;
              }
          }
      }
      findTowerSlotByPos(x, y) {
          this.tempPos.x = x;
          this.tempPos.y = y;
          let local = this.layerTower.globalToLocal(this.tempPos);
          for (let slot of this.towerSlots) {
              if (slot.rect.contains(local.x, local.y)) {
                  console.log("O_O  找到孔", slot.gx, slot.gy);
                  return slot;
              }
          }
      }
      findTowerSlotByGrid(gx, gy) {
          for (let slot of this.towerSlots) {
              if (slot.gx == gx && slot.gy == gy) {
                  console.log("O_O  找到孔", slot.gx, slot.gy);
                  return slot;
              }
          }
      }
      onTowerDown(data, e) {
          if (!this.enableTouch)
              return;
          let gx = data.gx;
          let gy = data.gy;
          this.touchDownTower = this.findTowerByGrid(gx, gy);
          console.log("O_O onTowerDown", gx, gy, this.touchDownTower);
          this.onTouchDown(e);
      }
      onTowerTouchMove(e) {
          this.onTouchMove(e);
      }
      onTowerUp(data, e) {
          if (StageConfig.enableEnemyTouchRemove) {
              let tower = this.findTowerByGrid(data.gx, data.gy);
              if (tower) {
                  tower.takeoff();
                  tower = null;
              }
          }
          if (!this.enableTouch)
              return;
          if (!this.enemyWave.isTowerRushMode() && !this.isMultiTouch) {
              let gx = data.gx;
              let gy = data.gy;
              this.touchUpSlot = this.findTowerSlotByGrid(gx, gy);
              this.touchUpTower = this.findTowerByGrid(gx, gy);
              console.log("O_O onTowerUp", gx, gy, this.touchUpTower);
              this.touchSlotId = data.slotId;
              if (!this.touchDownTower && !this.touchUpTower && !this.isSceneMoved()) {
                  if (this.touchUpSlot) {
                      if (!this.isTowerSlotUnlcok(this.touchUpSlot.id - 1)) {
                          this.showSlotUnlock(this.touchUpSlot.pos);
                      }
                      else {
                          this.showTowerDeloy(this.touchUpSlot.node);
                      }
                  }
              }
              else {
                  if (this.touchUpTower && this.touchDownTower == this.touchUpTower && !this.isSceneMoved()) {
                      this.showTowerOption(this.uid2Tower[this.touchUpTower.uid], this.touchUpTower);
                  }
              }
          }
          this.onTouchUp(e);
      }
      showTowerDeloy(node) {
          if (!this.enemyWave.isTowerRushMode()) {
              Director.openPanel("PanelDeploy");
              this.focusSceneDeployIn(node.x, node.y);
          }
      }
      hideTowerRange() {
          this.range.visible = false;
      }
      showTowerRange(node, tower) {
          this.range.x = node.x;
          this.range.y = node.y;
          this.range.visible = true;
          let rangelen = 0;
          if (tower) {
              rangelen = tower.attrCur[BASE_ATTR.RANGE] * tileW - tileW * 0.5;
          }
          let scale = rangelen / 256;
          this.range.scale(scale, scale);
      }
      showTowerOption(node, tower) {
          if (!this.enbaleUnlockSlot)
              return;
          if (node) {
              if (this.towerOption.tower != tower || !this.range.visible) {
                  if (!this.range.visible) {
                      this.focusSceneDeployIn(node.x, node.y);
                  }
                  this.showTowerRange(node, tower);
                  this.towerOption.visible = true;
                  this.towerOption.x = node.x;
                  this.towerOption.y = node.y;
                  this.towerOption.bindTower(tower, this.enemyWave.isTowerRushMode());
                  Global.sendMsg(MSG.TOWER_OPTION_SHOW);
              }
              else {
                  this.hideTowerOption();
              }
          }
      }
      hideTowerOption(deploy = false) {
          if (Level.isFirstGuide())
              return;
          if (!this.range.visible)
              return;
          if (!deploy)
              this.focusSceneDeployOut();
          this.range.visible = false;
          this.towerOption.visible = false;
          this.towerOption.bindTower(null);
      }
      showTowerInfo(tower) {
          let skin = this.uid2Tower[tower.uid];
          if (skin) {
              this.range.x = skin.x;
              this.range.y = skin.y;
              this.range.visible = true;
              let rangelen = tower.towerDb.range * tileW;
              let scale = rangelen / 256;
              this.range.scale(scale, scale);
              this.towerOption.visible = true;
              this.towerOption.x = skin.x;
              this.towerOption.y = skin.y;
          }
          let listMenu = [
              {
                  name: tower.towerDb.name + "等级:" + mgrTower.getTowerLv(tower.towerDb.id),
              },
              {
                  name: "升级",
                  callback: (view) => {
                      view.remove();
                      mgrTower.addTowerLv(tower.towerDb.id, 10);
                  }
              },
              {
                  name: "取消",
                  callback: (view) => {
                      view.remove();
                  }
              },
          ];
          this.showDebug(listMenu);
      }
      showSlotUnlock(slot) {
          if (!this.enbaleUnlockSlot)
              return;
          if (Level.isFirstGuide()) {
              if (mgrTower.calcSlotUnlockCount() == 0) {
                  mgrTower.tryUnlockSlot(slot.id - 1, true);
              }
          }
          else {
              Director.openPanelWithSingleton("PanelTowerSlotUnlock", slot);
          }
      }
      showSlotDeploy(slot) {
          let towerMap = db.get_tower_db_map();
          let listMenu = [];
          for (let key in towerMap) {
              let towerDb = towerMap[key];
              listMenu.push({
                  name: "创建" + towerDb.name,
                  towerDb: towerDb,
              });
          }
          this.showDebug(listMenu, (view, data) => {
              view.remove();
              let towerDb = data.towerDb;
              this.loadTowerByIdAndSlotId(towerDb.id, slot.id);
              mgrTower.equipTower(slot.id - 1, towerDb.id);
          });
      }
      showDebug(...arg) {
          fgui.UIPackage.loadPackage("res/fgui/test", Laya.Handler.create(this, () => {
              UIManager.getInstance().showDebugList(arg[0], arg[1]);
          }));
      }
      findTowerByPos(x, y) {
          this.tempPos.x = x;
          this.tempPos.y = y;
          let local = this.layerTower.globalToLocal(this.tempPos);
          for (let uid in this.uid2Tower) {
              let tower = this.uid2Tower[uid];
              if (tower) {
                  let skin = tower.skin;
                  let rect = new Laya.Rectangle(tower.x - skin.width * skin.pivotX, tower.y - skin.height * skin.pivotY, skin.width, skin.height);
                  if (rect.contains(local.x, local.y)) {
                      console.log("O_O  找到塔", tower.towerDb.name);
                      return tower;
                  }
              }
          }
      }
      findTowerByGrid(gx, gy) {
          let list = this.world.map.getSectionTable(gx, gy);
          let find = null;
          let head = list.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower instanceof Tower) {
                  find = tower;
                  break;
              }
          }
          return find;
      }
      findTowerBySlotId(slotId) {
          let list = this.world.buildings;
          let find = null;
          let head = list.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower instanceof Tower) {
                  if (tower.slotId == slotId) {
                      find = tower;
                      break;
                  }
              }
          }
          return find;
      }
      isTowerDeadBySlotIds(slotIds) {
          let isAllDead = true;
          let list = this.world.buildings;
          let head = list.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower instanceof Tower) {
                  if (slotIds[tower.slotId]) {
                      isAllDead = false;
                      break;
                  }
              }
          }
          return isAllDead;
      }
      findTowerCanMove(gx, gy) {
          let tower = this.findTowerByGrid(gx, gy);
          if (tower && tower.canMove()) {
              return tower;
          }
          else {
              return null;
          }
      }
      findEnemyByRange(gx, gy, range) {
          return this.world.map.findObjectsByRange(gx, gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, range, 0, true, false);
      }
      findTowerAny() {
          for (let uid in this.uid2Tower) {
              let tower = this.uid2Tower[uid];
              if (tower) {
                  return tower;
              }
          }
      }
      findEnemyAny() {
          for (let uid in this.uid2Enemy) {
              let enemy = this.uid2Enemy[uid];
              if (enemy) {
                  return enemy;
              }
          }
          return null;
      }
      onUpdate() {
          if (this.isWorldRunning) {
              let t = GameConst.updateFrameDeltaTime() * StageConfig.gameTimeScale;
              this.updateSecond(t);
              this.world.tickTime(t);
              this.enemyWave.updateLogic(t);
              StageGameStatis.udpate(t);
          }
      }
      updateSecond(t) {
          this.passTime += t;
          if (this.passTime >= this.passWait) {
              this.passTime = 0;
              this.onUpdatePerSecond();
          }
      }
      onUpdatePerSecond() {
          mgrAllEquip.onUpdatePerSecond();
          if (mgrAllEquip.isAttrValid(STAGE_ATTR.AE_SHIELD)) {
              let ks = STAGE_ATTR[STAGE_ATTR.AE_SHIELD];
              let vl = mgrAllEquip.getEquipValue(ks, 0);
              let cd = mgrAllEquip.getEquipValue(ks, 1);
              mgrAllEquip.beginCDing(STAGE_ATTR.AE_SHIELD, cd);
              let buffId = mgrAllEquip.getBuffId(STAGE_ATTR.AE_SHIELD);
              let head = this.world.buildings.head;
              while (head) {
                  let tower = head.data;
                  head = head.next;
                  if (tower) {
                      tower.addBuffById(tower, buffId, [vl]);
                  }
              }
          }
      }
      onUnitCreate(unit, x, y, view = false) {
          if (unit instanceof Enemy) {
              if (this.enableGameView) {
                  let skin;
                  if (unit.modelDb.spine) {
                      skin = ObjectSkin.create(EnemySkinSpine);
                  }
                  else {
                      skin = ObjectSkin.create(EnemySkin);
                  }
                  skin.loadSkin(unit.roleDb, unit.modelDb);
                  unit.bindSkin(skin, view);
                  skin.playTransIn();
                  this.layerEnermy.addChild(skin);
                  this.uid2Enemy[unit.uid] = skin;
              }
              if (!view)
                  this.countEnemy++;
          }
          else if (unit instanceof Trap) {
              if (this.enableGameView) {
                  let skin = ObjectSkin.create(TrapSkin);
                  skin.initSkin(unit, this.layerEnermy);
                  this.layerEnermy.addChild(skin);
                  this.uid2Trap[unit.uid] = skin;
              }
          }
          else if (unit instanceof LogicEnemyVirtual) {
          }
      }
      flyItemToMainTower(skin, icon, quality) {
          let skinMain = this.uid2Tower[this.mainTowerUID];
          if (skinMain) {
              let item = CustomDropItemFly.create();
              this.layerGameUI.addChild(item.displayObject);
              item.displayObject.x = skin.x;
              item.displayObject.y = skin.y;
              item.displayObject.pivotX = item.width / 2;
              item.displayObject.pivotY = item.height / 2;
              item.refresh(icon, quality);
              let r = 100;
              let x = skin.x + Utils.random(-r, r);
              let y = skin.y + Utils.random(-r, r);
              cc$1.tween(item.displayObject, true)
                  .then(cc$1.jumpTo(0.3, x, y, 50, 1))
                  .delay(1)
                  .to(0.3, { x: skinMain.x, y: skinMain.y - skinMain.height * 0.5 })
                  .call(() => {
                      item.recover();
                  })
                  .start();
          }
      }
      onUnitRemove(unit, reason, view = false) {
          unit.unbindSkin();
          let skin = this.uid2Enemy[unit.uid] || this.uid2Trap[unit.uid];
          if (reason == UNIT_REMOVE_REASON.DEAD) {
              this.onEnemyDead(unit, skin);
          }
          else if (reason == UNIT_REMOVE_REASON.DEAD_BOSS) {
              this.onBossDead(unit, skin);
          }
          if (skin instanceof EnemySkin) {
              skin.playDead();
          }
          else if (skin instanceof TrapSkin) {
              this.uid2Trap[unit.uid] = null;
              skin.recover();
          }
          if (unit instanceof Enemy) {
              this.uid2Enemy[unit.uid] = null;
              if (!view)
                  this.countEnemy--;
          }
      }
      enemyDropByLevel(unit, skin, coin, show) {
          if (mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1)) {
              coin *= 2;
          }
          mgrGame.addItem(1001, coin, 47, false);
          let listDrop = [];
          if (show) {
              listDrop.push({ type: DROP_TYPE.ITEM, data: { itemId: 1001, count: coin } });
          }
          let enemyDropId = unit.getDropId();
          Level.dropItemByDropId(enemyDropId || Level.levelDb.drop_id, false, listDrop, false);
          if (this.enableGameView) {
              Global.sendMsg(MSG.DROP_ITEM_PICK_UP, { items: listDrop });
          }
          if (skin && StageConfig.enableGameEffect) {
              for (let drop of listDrop) {
                  switch (drop.type) {
                      case DROP_TYPE.ITEM:
                          let info = drop.data;
                          this.flyItemToMainTower(skin, mgrGame.getItemIcon(info.itemId), -1);
                          break;
                      case DROP_TYPE.HOLY_ITEM:
                          let item = drop.data;
                          this.flyItemToMainTower(skin, item.getIcon(), item.getQuality());
                          break;
                  }
              }
          }
      }
      showFlyMoney(skin, count) {
          for (let i = 0; i < count; i++) {
              this.flyItemToMainTower(skin, mgrGame.getItemIcon(1001), -1);
          }
      }
      dropItemByProb(prob, unit, skin) {
          if (Global.isGuiding)
              return;
          if (this.dropItemCustom(unit, skin)) {
              return;
          }
          let curtTime = Timer.time;
          if (this.lastDropTime > curtTime) {
              return;
          }
          if (StageTool.calcProb(prob * StageConfig.scaleProbDropItem)) {
              this.dropItemOnGround(unit, skin);
              let cd = Utils.random(db.game_cnf.drop_item_cd[0], db.game_cnf.drop_item_cd[1]);
              if (mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1)) {
                  cd = Math.floor(cd / 2);
              }
              this.lastDropTime = curtTime + cd;
          }
      }
      onEnemyDead(unit, skin) {
          if (!this.enemyWave.isFBMode()) {
              let coin = Math.ceil(Formula.enemyCoin(unit.lv));
              this.enemyDropByLevel(unit, skin, coin, true);
              let prob = db.game_cnf.drop_prob_enemy;
              if (mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1)) {
                  prob *= 2;
              }
              this.dropItemByProb(prob, unit, skin);
          }
          this.enemyWave.onEnemyDead(unit);
          mgrTask.doEvent(db.TASK_EVENT_ID.DEAD_ENEMY);
          this.onHPDeadRecover(unit);
      }
      onBossDead(unit, skin) {
          if (!this.enemyWave.isFBMode()) {
              let coin = Math.ceil(Formula.bossCoin(unit.lv));
              this.enemyDropByLevel(unit, skin, coin, true);
              let prob = db.game_cnf.drop_prob_boss;
              if (mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1)) {
                  prob *= 2;
              }
              this.dropItemByProb(prob, unit, skin);
          }
          this.enemyWave.onBossDead(unit);
          mgrTask.doEvent(db.TASK_EVENT_ID.DEAD_BOSS);
          this.onHPDeadRecover(unit);
      }
      onHPDeadRecover(unit) {
          let HP_DEAD_RECOVER = StageAttr.getAttr(STAGE_ATTR.HP_DEAD_RECOVER);
          if (HP_DEAD_RECOVER > 0) {
              let objectList = this.world.map.findObjectsByRange(unit.gx, unit.gy, MAP_FLAG.UNIT_STAND, LogicCamp.ENEMY, db.game_cnf.hp_recover_enemy_dead_range);
              if (objectList.length) {
                  for (let object of objectList) {
                      if (object instanceof Enemy) {
                          let cure = Math.ceil(object.getAttrMax(BASE_ATTR.HP) * HP_DEAD_RECOVER);
                          let dd = DamageCalculation.damageData;
                          dd.damage = cure;
                          object.cure(dd);
                      }
                  }
              }
          }
      }
      isAllEnemyDead(left = 0) {
          return this.countEnemy <= left;
      }
      getUnitSkinById(id) {
          let skin = this.uid2Enemy[id] || this.uid2Tower[id];
          if (skin) {
              return skin;
          }
          else {
              let unit = this.world.objectMgr.getObjectById(id);
              if (unit) {
                  return Level.convertGridPosToRealPos(unit.gx, unit.gy, false);
              }
          }
      }
      getUnitPosById(id, offset = 0.5, random = false) {
          let skin = this.uid2Enemy[id] || this.uid2Tower[id];
          if (skin) {
              return skin.getHitPoint(0, offset, random);
          }
          else {
              let unit = this.world.objectMgr.getObjectById(id);
              if (unit) {
                  return Level.convertGridPosToRealPos(unit.gx, unit.gy, false);
              }
          }
      }
      getUnitOffsetById(id, offset = 0.5) {
          let skin = this.uid2Enemy[id] || this.uid2Tower[id];
          if (skin) {
              return skin.getHitOffset(0, offset);
          }
          else {
              this.tempPos.x = 0;
              this.tempPos.y = 0;
              return this.tempPos;
          }
      }
      onTowerCreate(tower, x, y, view = false) {
          console.log("O_O tower:", tower.uid, x, y);
          if (!view)
              this.towerCount++;
          if (this.enableGameView) {
              let skin = new TowerSkin();
              skin.loadSkin(tower.towerDb);
              tower.bindSkin(skin);
              this.layerTower.addChild(skin);
              this.uid2Tower[tower.uid] = skin;
              skin.skin.on(Laya.Event.MOUSE_DOWN, this, this.onTowerDown, [tower]);
              skin.skin.on(Laya.Event.MOUSE_MOVE, this, this.onTowerTouchMove);
              skin.skin.on(Laya.Event.MOUSE_UP, this, this.onTowerUp, [tower]);
          }
      }
      onTowerMove(tower, x, y, ox, oy) {
          let skin = this.uid2Tower[tower.uid];
          if (skin) {
              tower.bindSkin(skin);
          }
          let slotOld = this.findTowerSlotByGrid(ox, oy);
          let section = this.world.map.getSectionTable(ox, oy);
          if (slotOld && !section.size) {
          }
          let slotNew = this.findTowerSlotByGrid(x, y);
          if (slotNew && slotOld) {
              mgrTower.moveTower(slotOld.id - 1, slotNew.id - 1, tower.towerDb.id);
          }
      }
      onTowerRemove(tower, reason, view = false) {
          tower.unbindSkin();
          let skin = this.uid2Tower[tower.uid];
          if (skin) {
              if (reason == UNIT_REMOVE_REASON.DEAD) {
                  skin.playDead();
              }
              else {
                  skin.recover();
                  this.uid2Tower[tower.uid] = null;
              }
          }
          if (!view)
              this.towerCount--;
          if (this.towerCount <= 0) {
              if (reason == UNIT_REMOVE_REASON.DEAD && this.enemyWave.isTowerRushMode()) {
                  this.enemyWave.towerRushFail();
              }
          }
      }
      clearTowerSkin() {
          for (let uid in this.uid2Tower) {
              let skin = this.uid2Tower[uid];
              if (skin) {
                  skin.recover();
              }
          }
          this.uid2Tower = [];
      }
      onBulletCreate(skillId, time, caster, target, index) {
          if (!this.enableGameView)
              return;
          let skillDb = db.get_skill_db(skillId);
          if (!skillDb)
              return;
          let bulletDb = db.get_bullet_db(skillDb.bullet_id);
          if (!bulletDb)
              return;
          let skinTarget = this.getUnitSkinById(target.uid);
          if (!skinTarget)
              return;
          let skinCaster = this.getUnitSkinById(caster.uid);
          if (!skinCaster)
              return;
          let shooter = null;
          if (skinCaster instanceof TowerSkin) {
              shooter = skinCaster.getShooter(index);
          }
          if (StageConfig.enableGameEffect && bulletDb.effect_lock) {
              if (shooter) {
                  shooter.lookAtTarget(caster, target);
              }
              EffectFactory.createByType(bulletDb.effect_lock, EffectFactory.layerFront, skinTarget);
          }
          if (skillDb.sound_shoot) {
              mgrSound.playSound(skillDb.sound_shoot);
          }
          if (bulletDb.num.length) {
              let directionX = target.gx - caster.gx;
              let x = target.gx;
              let y = target.gy;
              let offsets = HitAreaHelper.getHitArea(skillDb.id);
              let points = [];
              if (offsets) {
                  for (let i = 0; i < offsets.length; i = i + 2) {
                      let tx = x + offsets[i];
                      let ty = y + offsets[i + 1];
                      points.push(new Laya.Point(tx, ty));
                  }
              }
              Utils.randomSort(points);
              let num = Utils.random(bulletDb.num[0], bulletDb.num[1]);
              for (let i = 0; i < num; i++) {
                  let p1 = points[i];
                  if (p1) {
                      let p2 = Level.convertGridPosToRealPos(p1.x, p1.y, true);
                      let bullet = this.createBulletInstance(time, skinCaster, p2, skillDb, bulletDb, index, directionX);
                  }
              }
          }
          else {
              let bullet = this.createBulletInstance(time, skinCaster, skinTarget, skillDb, bulletDb, index);
              if (shooter) {
                  shooter.setBullet(bullet);
              }
          }
      }
      getBulletTargetShootPoint(target, indexShooter, indexPoint) {
          if (target.getShootPoint) {
              return target.getShootPoint(indexShooter, indexPoint, true);
          }
          else {
              this.tempPos.x = 0;
              this.tempPos.y = 0;
              return this.tempPos;
          }
      }
      createBulletInstance(time, caster, target, skillDb, bulletDb, index, directionX = null) {
          let bullet = FactoryBullet.createByBulletDb(bulletDb);
          bullet.bindSkillDb(skillDb);
          if (skillDb.effect_hit)
              bullet.effect_hit = skillDb.effect_hit;
          let shootPoint = this.getBulletTargetShootPoint(caster, index, skillDb.point_index);
          if (shootPoint) {
              bullet.node.x = shootPoint.x;
              bullet.node.y = shootPoint.y;
          }
          let shootOffsetX = shootPoint.x - caster.x;
          let shootOffsetY = shootPoint.y - caster.y;
          if (StageConfig.enableGameEffect && !bulletDb.no_shoot_effect && skillDb.effect_shoot) {
              EffectFactory.createByType(skillDb.effect_shoot, this.layerBullet, caster, null, null, shootOffsetX, shootOffsetY);
          }
          bullet.born(this.layerBullet);
          bullet.shootTarget(time, target, null, directionX);
          if (bullet.speedRotation > 0) {
              let dx = target.x - bullet.node.x;
              if (dx < 0) {
                  bullet.speedRotation = -bullet.speedRotation;
              }
          }
          bullet.bindCaster(caster, shootOffsetX, shootOffsetY);
          return bullet;
      }
      onEffectHitCreate(caster, target, skillId, count, flipX = 1) {
          if (!this.enableGameView)
              return;
          let needEffect = StageConfig.enableGameEffect;
          let skillDb = db.get_skill_db(skillId);
          let skin = this.getUnitPosById(target.uid, skillDb.hit_offset, skillDb.hit_rand);
          if (skin) {
              if (skillDb.effect_hit_no_virtual) {
                  needEffect = !(target instanceof LogicEnemyVirtual);
              }
              if (needEffect) {
                  if (skillDb.effect_hit) {
                      if (skillDb.use_hit_area) {
                          let grid = Level.convertGridPosToRealPos(target.gx, target.gy, false);
                          let effect = EffectFactory.createByType(skillDb.effect_hit, EffectFactory.layerFront, grid);
                          let node = effect.node;
                          node.scaleX = flipX * node.scaleX;
                      }
                      else {
                          EffectFactory.createByType(skillDb.effect_hit, EffectFactory.layerFront, skin);
                      }
                      if (skillDb.sound_hit) {
                          mgrSound.playSound(skillDb.sound_hit);
                      }
                  }
              }
          }
      }
      createBullet(res) {
          let sprite = Laya.Pool.getItem(res);
          if (!sprite) {
              sprite = LoaderHelper.createSprite(res);
          }
          return sprite;
      }
      loadBullet(res, animName) {
          let layerBullet = this.layerBullet;
          let sprite = this.createBullet(res);
          layerBullet.addChild(sprite);
          let anim = sprite.getChildAt(0);
          anim.interval = 1000 / 8;
          anim.play(0, true, animName);
          return sprite;
      }
      aniUrls(dir, aniName, from, to) {
          var urls = [];
          for (let i = from; i <= to; i++) {
              urls.push("res/anim/" + dir + "/" + aniName + i + ".png");
          }
          return urls;
      }
      aniUrlSingle(dir, aniName) {
          return ["res/anim/" + dir + "/" + aniName + ".png"];
      }
      initEvent() {
          if (Laya.Browser.onPC && !db.cop_db.is4399Watermark)
              Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDownPress);
          this.mapBG.owner.on(Laya.Event.MOUSE_DOWN, this, this.onTouchDown);
          this.mapBG.owner.on(Laya.Event.MOUSE_MOVE, this, this.onTouchMove);
          this.mapBG.owner.on(Laya.Event.MOUSE_UP, this, this.onTouchUp);
          Global.registerListeners(this, {
              [MSG.STAGE_DESTROY]: this.onMsgStageDestroy.bind(this),
              [MSG.TOWER_ENDNESS_BEGIN]: this.onMsgTowerEndnessBegin.bind(this),
              [MSG.TOWER_RUSH_STOP]: this.onMsgTowerRushStop.bind(this),
              [MSG.TOWER_RUSH_END]: this.onMsgTowerRushEnd.bind(this),
              [MSG.TOWER_RUSH_END_FOCUS]: this.onMsgTowerRushEndFocus.bind(this),
              [MSG.TOWER_RUSH_WIN]: this.onMsgTowerRushWin.bind(this),
              [MSG.SLOT_UNLOCK]: this.onTowerSlotUnlock.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerDeploy.bind(this),
              [MSG.TOWER_DEPLOY_END]: this.onTowerDeployEnd.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerTakeoff.bind(this),
              [MSG.TOWER_LVUP_STAR]: this.onTowerLvupQuality.bind(this),
              [MSG.TOWER_HAND_SKILL_PREPARE]: this.onTowerHandSkillPrepare.bind(this),
              [MSG.TOWER_ATTR_UPDATE_UID]: this.onTowerAttrUpdateUID.bind(this),
              [MSG.TOWER_ATTR_UPDATE]: this.onTowerAttrUpdate.bind(this),
              [MSG.TOWER_ATTR_UPDATE_MAIN]: this.onTowerAttrUpdateMain.bind(this),
              [MSG.TOWER_ATTR_UPDATE_ALL]: this.onTowerAttrUpdateAll.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.TOWER_DEBUG_CHANGE]: this.onTowerDebugChange.bind(this),
              [MSG.CHALLENGE_STORY_BEGIN]: this.onMainStoryBegin.bind(this),
              [MSG.CHALLENGE_BOSS_BEGIN]: this.onChallengeBegin.bind(this),
              [MSG.GAME_VIEW_DESTORY]: this.destroyGameView.bind(this),
              [MSG.GAME_VIEW_RESTORE]: this.restoreGameView.bind(this),
              [MSG.GAME_PAUSE]: this.pauseGame.bind(this),
              [MSG.GAME_RESUME]: this.resumeGame.bind(this),
              [MSG.REFRESH_RED_POINT_TOWER]: this.refreshRedPointTower.bind(this),
              [MSG.GUIDE_COMPLETE]: this.onGuideComplete.bind(this),
              [MSG.GUIDE_SKIP]: this.onGuideSkip.bind(this),
              [MSG.GUIDE_END]: this.onGuideEnd.bind(this),
              [MSG.TOWER_LVUP_LEVEL]: this.onTowerLvupLevel.bind(this),
              [MSG.MAP_TILE_DATA_LOAD]: this.onMapTileDataLoad.bind(this),
              [MSG.TOWER_FB_COIN_BEGIN]: this.onTowerFBCoinBegin.bind(this),
              [MSG.TOWER_FB_ITEM_BEGIN]: this.onTowerFBItemBegin.bind(this),
              [MSG.TOWER_SECRET]: this.onTowerSecretBegin.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.map_unlock_tower_slot) {
                      this.watchAdSuccess4UnlockTowerEmpty(e.params);
                  }
              },
          });
      }
      onMsgStageDestroy() {
          this.owner.destroy();
          EffectFactory.layerBottom = null;
          EffectFactory.layerFront = null;
      }
      onBattleStart() {
          this.world.remAllUnit(LogicCamp.ENEMY);
          this.countEnemy = 0;
          this.hideTowerOption();
          StageGameStatis.start();
          this.mapBG.hideEffect();
          Global.sendMsg(MSG.TOWER_RUSH_BEGIN);
          Director.openPanel("PanelComing");
          this.refreshTowerSlot();
      }
      onBattleEnd() {
          this.resumeGame();
          this.mapBG.showEffect();
          Level.clearStage();
          this.refreshTowerSlot();
      }
      onMsgTowerEndnessBegin() {
          this.enemyWave.openModeEndness();
          this.onBattleStart();
      }
      onMsgTowerRushEnd(win, mode) {
          StageAttr.resetAttr();
          this.world.remAllUnit();
          this.countEnemy = 0;
          this.loadTowers();
          this.focusSceneRushEndOut();
          if (win && mode == WaveMode.TOWER_ENDNESS && mgrGame.rushAutoNext) {
              this.autoBeginTowerEndness();
          }
          else {
              if (!win && mode == WaveMode.TOWER_ENDNESS && mgrGame.rushFailNext) {
                  Director.openPanelWithSingleton("PanelDialogCD", { cd: 30, postfix: "秒后自动开始挑战无尽模式", msg: MSG.TOWER_ENDNESS_BEGIN });
              }
              this.enemyWave.openModeIdle();
              if (mode != WaveMode.FINAL_WAR) {
                  this.loadMapById(Level.mapDb.map_id);
                  mgrSound.playMusic("sBg");
              }
          }
          if (!win) {
              mgrGame.showRushFailUI();
          }
          this.onBattleEnd();
          console.log("冲塔结束", win);
      }
      autoBeginTowerEndness() {
          Laya.timer.once(1000, this, () => {
              Global.sendMsg(MSG.TOWER_ENDNESS_BEGIN);
          });
      }
      onMsgTowerRushEndFocus() {
          this.focusSceneRushEndIn();
      }
      onMsgTowerRushStop() {
          this.pauseGame();
          this.enemyWave.towerRushFail(true);
      }
      onMsgTowerRushWin() {
          this.enemyWave.towerRushSuccess();
      }
      onTowerDeploy(towerDb) {
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let slot = this.findTowerSlotByPos(x, y);
          if (slot && this.isTowerSlotUnlcok(slot.id - 1) && !mgrTower.isTowerEquip(towerDb.id)) {
              let towerOld = this.findTowerBySlotId(slot.id);
              if (!towerOld) {
                  towerOld = this.findTowerByGrid(slot.gx, slot.gy);
              }
              if (towerOld) {
                  let towerId = towerOld.towerDb.id;
                  if (towerId == towerDb.id) {
                      return;
                  }
                  this.world.remBuilding(towerOld);
                  ResTowerManager.onTowerRem(towerId);
              }
              this.loadTowerByIdAndSlotId(towerDb.id, slot.id);
              mgrTower.equipTower(slot.id - 1, towerDb.id);
              this.refreshTowerSlotSingle(slot);
              this.hideTowerOption(true);
              Global.sendMsg(MSG.TOWER_DEPLOY_SUC);
          }
      }
      onTowerDeployEnd() {
          this.focusSceneDeployOut();
      }
      onTowerTakeoff(data) {
          let slot = this.findTowerSlotById(data.slotId);
          if (slot) {
              this.refreshTowerSlotSingle(slot);
          }
          this.hideTowerOption();
          ResTowerManager.onTowerRem(data.towerId);
      }
      onTowerLvupQuality(id) {
          let head = this.world.buildings.head;
          while (head) {
              let data = head.data;
              head = head.next;
              if (data && data.towerDb.id == id) {
                  data.syncAttacker();
                  let skin = this.uid2Tower[data.uid];
                  if (skin) {
                      skin.refreshQuality(data.towerDb.id);
                  }
                  break;
              }
          }
      }
      onTowerHandSkillPrepare(tower) {
          if (tower.superDb) {
              if (tower.superDb.no_target) {
                  tower.handCastSuperSkill();
              }
              else {
                  this.handTower = tower;
                  let skin = this.uid2Tower[tower.uid];
                  if (skin) {
                      this.showTowerRange(skin, tower);
                  }
              }
          }
      }
      onTowerAttrUpdateUID(uid) {
          let tower = this.world.objectMgr.getObjectById(uid);
          if (tower instanceof Tower) {
              tower.refreshAttr();
          }
      }
      onTowerAttrUpdate(towerId) {
          let head = this.world.buildings.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower) {
                  if (tower.towerDb.id == towerId) {
                      tower.refreshAttr();
                  }
              }
          }
      }
      onTowerAttrUpdateMain() {
          if (this.mainTower) {
              this.mainTower.refreshAttr();
          }
      }
      onTowerAttrUpdateAll() {
          let head = this.world.buildings.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower) {
                  tower.refreshAttr();
              }
          }
      }
      onTowerMainSkillChange() {
          let tower = this.world.objectMgr.getObjectById(this.mainTowerUID);
          if (tower instanceof Tower) {
              tower.refreshSkill();
          }
      }
      onTowerDebugChange(id) {
      }
      onMainStoryBegin(data) {
          this.enemyWave.openModelStory(data);
          this.onBattleStart();
      }
      onChallengeBegin(data) {
          this.enemyWave.openModelChallenge(data);
          this.onBattleStart();
      }
      onKeyDownPress(e) {
          switch (e.keyCode) {
              case Laya.Keyboard.D:
                  fgui.UIPackage.loadPackage("res/fgui/test", Laya.Handler.create(this, () => {
                      UIManager.getInstance().openDebug();
                  }));
                  break;
              case Laya.Keyboard.E:
                  let head = this.world.buildings.head;
                  while (head) {
                      let tower = head.data;
                      head = head.next;
                      if (tower) {
                          tower.letEnergyFull();
                      }
                  }
                  break;
              case Laya.Keyboard.S:
                  mgrGame.saveStageConfig();
                  break;
              case Laya.Keyboard.SPACE:
                  this.drawGrid();
                  break;
              case Laya.Keyboard.C:
                  this.graphicsWorld.clear();
                  break;
              case Laya.Keyboard.P:
                  this.drawGridPos();
                  break;
              case Laya.Keyboard.F:
                  if (this.isWorldRunning) {
                      this.pauseGame();
                  }
                  else {
                      this.resumeGame();
                  }
                  break;
              case Laya.Keyboard.E:
                  LogicConfig.enableEnemySkill = !LogicConfig.enableEnemySkill;
                  break;
              case Laya.Keyboard.V:
                  for (let i = 2; i < 8; i++) {
                      let layer = Director.getLayer(i);
                      layer.visible = !layer.visible;
                  }
                  break;
              case Laya.Keyboard.EQUAL:
                  var scale = this.scene.scaleX + 0.1;
                  this.changeSceneScale(scale);
                  break;
              case Laya.Keyboard.MINUS:
                  var scale = this.scene.scaleX - 0.1;
                  this.changeSceneScale(scale);
                  break;
              case Laya.Keyboard.A:
                  for (let uid in this.uid2Enemy) {
                      let skin = this.uid2Enemy[uid];
                      if (skin) {
                          skin.playMove();
                      }
                  }
                  break;
              case Laya.Keyboard.M:
                  {
                      let head = this.world.objectMgr.getLinkHead();
                      while (head) {
                          let object = head.getData();
                          head = head.next;
                          if (object) {
                              if (object instanceof Enemy) {
                                  object.addBuffById(this.mainTower, "3010");
                              }
                          }
                      }
                  }
                  break;
              case Laya.Keyboard.N:
                  break;
              case Laya.Keyboard.R:
                  this.world.remAllUnit(LogicCamp.ENEMY);
                  break;
              case Laya.Keyboard.G:
                  this.drawTowerRange();
                  break;
              case Laya.Keyboard.Q:
                  console.log("======================================贴图信息");
                  for (let k in Laya.Loader.textureMap) {
                      let t = Laya.Loader.textureMap[k];
                      if (t._referenceCount <= 0) {
                          Laya.loader.clearRes(k);
                      }
                      console.log(k, t._referenceCount);
                  }
                  console.log("======================================");
                  break;
              case Laya.Keyboard.H:
                  if (this.enableGameView) {
                      Global.sendMsg(MSG.GAME_VIEW_DESTORY);
                  }
                  else {
                      Global.sendMsg(MSG.GAME_VIEW_RESTORE);
                  }
                  break;
              case Laya.Keyboard.K:
                  this.killAllTower();
                  break;
              case Laya.Keyboard.J:
                  Director.openPanel("PanelGameDebug");
                  break;
              case Laya.Keyboard.T:
                  {
                      this.enemyWave.towerRushSuccess();
                  }
                  break;
              case Laya.Keyboard.O:
                  mgrTask.addGoalScore(Utils.random(1, 3), true);
                  break;
              case Laya.Keyboard.NUMBER_1:
                  StageConfig.gameTimeScale = 1;
                  break;
              case Laya.Keyboard.NUMBER_2:
                  StageConfig.gameTimeScale = 2;
                  break;
              case Laya.Keyboard.NUMBER_3:
                  StageConfig.gameTimeScale = 3;
                  break;
              case Laya.Keyboard.I:
                  Director.openPanelWithSingleton("PanelGrowPop");
                  break;
              case Laya.Keyboard.B:
                  {
                      for (let slot of this.towerSlots) {
                          slot.node.visible = !slot.node.visible;
                      }
                  }
                  break;
              case Laya.Keyboard.W:
                  this.loadMapById("3");
                  break;
              default:
                  break;
          }
      }
      destroyGameView() {
          if (this.enableGameView) {
              this.enableGameView = false;
              this.world.destroyView();
              if (this.mapBG) {
                  this.mapBG.hideEffect();
                  this.mapBG.hide();
              }
          }
      }
      restoreGameView() {
          if (!this.enableGameView) {
              this.enableGameView = true;
              this.world.restoreView();
              let head = this.world.buildings.head;
              while (head) {
                  let data = head.data;
                  head = head.next;
                  if (data) {
                      data.resetAttacker();
                  }
              }
              if (this.mapBG) {
                  this.mapBG.showEffect();
                  this.mapBG.show();
              }
          }
      }
      pauseGame() {
          this.isWorldRunning = false;
      }
      resumeGame() {
          this.isWorldRunning = true;
      }
      refreshRedPointTower() {
          let canEquip = mgrHolyItem.haveAnyItemCanEquip();
          for (let uid in this.uid2Tower) {
              let skin = this.uid2Tower[uid];
              if (skin) {
                  skin.updateRedPoint(canEquip);
              }
          }
      }
      onGuideComplete() {
          this.refreshGuide();
      }
      onGuideSkip() {
          this.world.remAllUnit(LogicCamp.ENEMY);
          this.refreshGuide();
          let towerDb = db.get_tower_db("11");
          if (towerDb) {
              mgrTower.addTower(towerDb, 53, false);
              mgrTower.tryUnlockSlot(1, true);
              mgrTower.equipTower(1, towerDb.id);
              this.loadTowerByIdAndSlotId(towerDb.id, 2);
          }
          this.enemyWave.openModeIdle();
          this.resumeGame();
          this.dropItemCustomBegin();
          this.refreshTowerSlot();
      }
      onGuideEnd() {
          this.enemyWave.openModeIdle();
          if (db.cop_db.shortcut_interval_idle && !mgrSdk.isShortcutInstalled()) {
              StageConfig.isShortcutNoticed = true;
              mgrSdk.installShortcut();
          }
          mgrGame.showFirstLoginUI(true);
          CopHelper.showDialog("PanelIntroPeace");
          this.dropItemCustomBegin();
          this.refreshTowerSlot();
      }
      onTowerLvupLevel(id) {
          if (id == "0" && mgrTower.getTowerLv(id) == 30) {
              mgrSign.showUI();
          }
      }
      onMapTileDataLoad() {
          this.loadTileMapData(this.world);
      }
      onTowerFBCoinBegin(data) {
          this.loadMapById(data.map_id);
          this.enemyWave.openModelFBCoin(data);
          this.onBattleStart();
      }
      onTowerFBItemBegin(data) {
          this.loadMapById(data.map_id);
          this.enemyWave.openModelFBItem(data);
          this.onBattleStart();
      }
      onTowerSecretBegin(data) {
          this.enemyWave.openModelSecret(data);
          this.onBattleStart();
      }
      refreshGuide() {
          this.enableTouch = mgrGuide.isGuideCompletById("main", 7);
          this.enbaleUnlockSlot = mgrGuide.isGuideCompletById("main", 12);
          this.enableShootCrossbow = this.enableTouch;
          this.enabelMoveMap = !Level.isFirstGuide();
      }
      drawTowerRange() {
          let head = this.world.buildings.head;
          while (head) {
              let data = head.data;
              head = head.next;
              if (data) {
                  data.findObjectsByRange(true);
              }
          }
      }
      createDragTower(e) {
          this.destroyDragTower();
          if (this.touchDownTower) {
              let skin = new TowerSkin();
              skin.loadSkin(this.touchDownTower.towerDb);
              skin.hideHpBar();
              this.layerGameUI.addChild(skin);
              let point = this.layerGameUI.globalToLocal(new Laya.Point(e.stageX, e.stageY));
              skin.x = point.x;
              skin.y = point.y;
              skin.alpha = 0.5;
              this.touchTowerDownSkin = skin;
          }
      }
      destroyDragTower() {
          if (this.touchTowerDownSkin) {
              this.touchTowerDownSkin.destroy();
              this.touchTowerDownSkin = null;
          }
      }
      onTouchDown(e) {
          if (!this.enableTouch)
              return;
          console.log("O_O onTouchDown");
          this.isTouchDown = true;
          this.lasttDistance = 0;
          this.multiDistance = 0;
          this.touchMode = TouchMode.NONE;
          if (!this.enemyWave.isTowerRushMode() && this.touchDownTower && this.touchDownTower.canMove()) {
              this.touchMode = TouchMode.TOWER;
          }
          else {
              if (this.enabelMoveMap) {
                  this.touchMode = TouchMode.MAP;
              }
          }
          this.lastX = e.stageX;
          this.lastY = e.stageY;
      }
      onTouchMove(e) {
          if (!this.enableTouch)
              return;
          if (this.isTouchDown) {
              let x = e.stageX;
              let y = e.stageY;
              let dx = x - this.lastX;
              let dy = y - this.lastY;
              this.touchMoveDistance += Math.sqrt(dx * dx + dy * dy);
              this.lastX = x;
              this.lastY = y;
              if (this.touchMode == TouchMode.MAP) {
                  if (e.touches) {
                      let lastTouchCount = e.touches.length;
                      if (lastTouchCount != this.lastTouchCount) {
                          this.pointDownReset = true;
                      }
                      this.lastTouchCount = lastTouchCount;
                      if (e.touches.length >= 2) {
                          let p1 = e.touches[0];
                          let p2 = e.touches[1];
                          let dx = p1.stageX - p2.stageY;
                          let dy = p1.stageY - p2.stageY;
                          let distance = Math.sqrt(dx * dx + dy * dy);
                          let cx = (p1.stageX + p2.stageX) / 2;
                          let cy = (p1.stageY + p2.stageY) / 2;
                          let localPoint = this.scene.globalToLocal(new Laya.Point(cx, cy), true, Laya.stage);
                          this.changeScenePivot(localPoint.x, localPoint.y);
                          this.moveScenePos(cx, cy);
                          if (!this.lasttDistance) {
                              this.lasttDistance = distance;
                          }
                          let delatDistance = 0;
                          if (this.lasttDistance) {
                              delatDistance = distance - this.lasttDistance;
                          }
                          this.lasttDistance = distance;
                          if (delatDistance) {
                              let scaleFinal = this.scene.scaleX + delatDistance * 0.002;
                              this.changeSceneScale(scaleFinal);
                              this.isMultiTouch = true;
                          }
                      }
                      else {
                          this.moveScenePos(e.stageX, e.stageY);
                      }
                  }
                  else {
                      this.moveScenePos(e.stageX, e.stageY);
                  }
              }
              else {
                  if (!this.touchTowerDownSkin && this.touchMoveDistance >= 50) {
                      this.createDragTower(e);
                  }
                  if (this.touchTowerDownSkin) {
                      this.moveTowerPos(e.stageX, e.stageY);
                  }
              }
          }
      }
      moveTowerBySlotId(tower, slotId) {
          let slot = db.get_tower_pos(this.towerPosGid, slotId - 1);
          if (slot) {
              if (tower) {
                  tower.slotId = slotId;
                  this.world.moveBuilding(tower, slot.x, slot.y);
                  mgrTower.equipTower(slotId - 1, tower.towerDb.id);
              }
              else {
                  mgrTower.equipTower(slotId - 1, null);
              }
              this.refreshTowerSlotSingle(this.findTowerSlotByGrid(slot.x, slot.y));
          }
      }
      addEnemyByTouch(grid) {
          let roleDb = db.get_role_db(StageConfig.configTouchEnemy.enemyId);
          if (StageConfig.configTouchEnemy.attack || this.enemyWave.isTowerRushMode()) {
              if (roleDb && roleDb.boss) {
                  this.world.addEnemy(EnemyBoss, grid.x, grid.y, StageConfig.configTouchEnemy.enemyId);
              }
              else {
                  this.world.addEnemy(Enemy, grid.x, grid.y, StageConfig.configTouchEnemy.enemyId);
              }
          }
          else {
              if (roleDb && roleDb.boss) {
                  this.world.addEnemy(EnemyIdleBoss, grid.x, grid.y, StageConfig.configTouchEnemy.enemyId);
              }
              else {
                  this.world.addEnemy(EnemyIdle, grid.x, grid.y, StageConfig.configTouchEnemy.enemyId);
              }
          }
      }
      onTouchUp(e) {
          if (!this.enableTouch)
              return;
          if (e.touches && e.touches.length > 1) {
              return;
          }
          if (Laya.Browser.onPC)
              this.isTouchDown = false;
          console.log("O_O onTouchUp");
          if (!this.isMultiTouch) {
              if (this.touchDownTower && this.touchDownTower.canMove() && this.touchTowerDownSkin) {
                  this.destroyDragTower();
                  if (this.touchDownTower != this.touchUpTower) {
                      if (this.touchSlotId && mgrTower.isTowerSlotCanMove(this.touchSlotId - 1)) {
                          if (this.touchUpTower) {
                              if (this.touchUpTower.canMove()) {
                                  this.moveTowerBySlotId(this.touchUpTower, this.touchDownTower.slotId);
                                  this.moveTowerBySlotId(this.touchDownTower, this.touchSlotId);
                              }
                              else {
                              }
                          }
                          else {
                              this.moveTowerBySlotId(null, this.touchDownTower.slotId);
                              this.moveTowerBySlotId(this.touchDownTower, this.touchSlotId);
                          }
                          this.hideTowerOption();
                      }
                      else {
                          let distanceMin = Number.MAX_VALUE;
                          let nearestPos = null;
                          for (let slot of this.towerSlots) {
                              if (mgrTower.isTowerSlotCanMove(slot.id - 1)) {
                                  let pos = slot.node.localToGlobal();
                                  let dx = e.stageX - pos.x;
                                  let dy = e.stageY - pos.y;
                                  let distance = Math.sqrt(dx * dx + dy * dy);
                                  if (distance < distanceMin && distance <= 200) {
                                      distanceMin = distance;
                                      nearestPos = slot;
                                  }
                              }
                          }
                          if (nearestPos) {
                              this.touchUpTower = this.findTowerByGrid(nearestPos.gx, nearestPos.gy);
                              if (this.touchUpTower) {
                                  if (this.touchUpTower.canMove()) {
                                      this.moveTowerBySlotId(this.touchUpTower, this.touchDownTower.slotId);
                                      this.moveTowerBySlotId(this.touchDownTower, nearestPos.id);
                                  }
                                  else {
                                  }
                              }
                              else {
                                  this.moveTowerBySlotId(null, this.touchDownTower.slotId);
                                  this.moveTowerBySlotId(this.touchDownTower, nearestPos.id);
                              }
                          }
                      }
                  }
              }
              else {
                  let grid = this.globalPos2GridPos(e.stageX, e.stageY);
                  if (this.handTower) {
                      if (this.handTower.handCastSuperSkill()) {
                          this.handTower = null;
                          this.hideTowerRange();
                      }
                  }
                  else {
                      if (!this.touchUpTower && !this.touchUpSlot && !this.isSceneMoved()) {
                          this.hideTowerOption();
                      }
                  }
                  if (!this.touchSlotId && !this.isSceneMoved()) {
                      if (StageConfig.enableEnemyTouchRemove) {
                          this.clickEnemyToRemove(grid.x, grid.y);
                      }
                      else if (StageConfig.configTouchEnemy.enable) {
                          this.addEnemyByTouch(grid);
                      }
                      else {
                          if (this.mainTower) {
                              this.shootCrossbow(e);
                          }
                      }
                  }
              }
          }
          this.resetTouchData();
      }
      clickEnemyToRemove(gx, gy) {
          let link = this.world.map.getSectionTable(gx, gy);
          let head = link.head;
          while (head) {
              let data = head.data;
              head = head.next;
              if (data instanceof Enemy) {
                  this.world.remUnit(data);
              }
          }
      }
      shootCrossbow(e) {
          if (!this.enableShootCrossbow)
              return;
          let curtTime = Utils.getTime();
          if (curtTime < this.mainLastFindTargetTick)
              return;
          this.mainLastFindTargetTick = curtTime + db.game_cnf.crossbow_click_cd;
          if (this.mainTower) {
              if (this.mainTower.shootCrossbow(e.stageX, e.stageY)) {
                  mgrTask.doEvent(db.TASK_EVENT_ID.CROSSBOW);
              }
          }
      }
      findMainTowerTargets(gx, gy) {
          if (this.mainTower.isStateInAttack()) {
              return;
          }
          let curtTime = Utils.getTime();
          if (curtTime < this.mainLastFindTargetTick) {
              return;
          }
          let isFind = false;
          isFind = this.mainTower.searchTargetsBySector(gx, gy, 30);
          if (isFind) {
              this.mainLastFindTargetTick = curtTime + 1000;
          }
      }
      getDegAngle(x1, y1, x2, y2) {
          let radian_angle = Math.atan2(y2, x2) - Math.atan2(y1, x1);
          return radian_angle * 180 / Math.PI;
      }
      resetTouchData() {
          this.touchDownTower = null;
          this.touchTowerDownSkin = null;
          this.touchUpTower = null;
          this.touchSlotId = 0;
          this.pointDownReset = true;
          this.lastTouchCount = 0;
          this.sceneMoveDistance = 0;
          this.touchMoveDistance = 0;
          this.touchUpSlot = null;
          this.isMultiTouch = false;
      }
      globalPos2GridPos(x, y) {
          this.tempPos.x = x;
          this.tempPos.y = y;
          let localPos = this.layerGameUI.globalToLocal(this.tempPos);
          let gx = Math.floor(localPos.x / tileW);
          let gy = Math.floor(localPos.y / tileH);
          localPos.x = gx;
          localPos.y = gy;
          return localPos;
      }
      localPos2GridPos(x, y) {
          let gx = Math.floor(x / tileW);
          let gy = Math.floor(y / tileH);
          this.tempPos.x = gx;
          this.tempPos.y = gy;
          return this.tempPos;
      }
      isSceneMoved() {
          return this.sceneMoveDistance >= 30;
      }
      moveScenePos(x, y) {
          if (this.pointDownReset) {
              this.pointDownReset = false;
              this.pointDown.x = x;
              this.pointDown.y = y;
          }
          else {
              let dx = x - this.pointDown.x;
              let dy = y - this.pointDown.y;
              let sx = this.scene.x + dx;
              let sy = this.scene.y + dy;
              this.pointDown.x = x;
              this.pointDown.y = y;
              this.sceneMoveDistance += Math.abs(dx) + Math.abs(dy);
              this.changeScenePos(sx, sy);
          }
      }
      moveTowerPos(x, y) {
          if (this.pointDownReset) {
              this.pointDownReset = false;
              this.pointDown.x = x;
              this.pointDown.y = y;
          }
          else {
              let dx = x - this.pointDown.x;
              let dy = y - this.pointDown.y;
              this.pointDown.x = x;
              this.pointDown.y = y;
              this.touchTowerDownSkin.x += (dx / this.scene.scaleX);
              this.touchTowerDownSkin.y += (dy / this.scene.scaleY);
          }
      }
      fixSceneX(sx) {
          let offset = this.mapBG.offsetx * this.scene.scaleX;
          let sw = Laya.stage.width;
          let mw = this.scene.width;
          let lx = sx - this.scene.pivotX * this.scene.scaleX + offset;
          let rx = lx + mw * this.scene.scaleX - offset * 2;
          if (lx > 0) {
              sx = this.scene.pivotX * this.scene.scaleX - offset;
          }
          else if (rx < sw) {
              sx = sw - (mw - this.scene.pivotX) * this.scene.scaleX + offset;
          }
          return sx;
      }
      fixSceneY(sy) {
          let offset = this.mapBG.offsety * this.scene.scaleY;
          let sh = Laya.stage.height;
          let mh = this.scene.height;
          let ly = sy - this.scene.pivotY * this.scene.scaleY + offset;
          let ry = ly + mh * this.scene.scaleY - offset * 2;
          if (ly > 0) {
              sy = this.scene.pivotY * this.scene.scaleY - offset;
          }
          else if (ry < sh) {
              sy = sh - (mh - this.scene.pivotY) * this.scene.scaleY + offset;
          }
          return sy;
      }
      changeScenePos(sx, sy) {
          this.scene.x = this.fixSceneX(sx);
          this.scene.y = this.fixSceneY(sy);
      }
      get scaleMin() {
          return this.mapBG.scaleMin;
      }
      get scaleStd() {
          return this.mapBG.scaleStd;
      }
      get scaleInt() {
          return this.mapBG.scaleInt;
      }
      changeSceneScale(scale) {
          if (scale >= this.scaleMin && scale <= this.scaleMax) {
              this.scene.scale(scale, scale);
              this.changeScenePos(this.scene.x, this.scene.y);
          }
      }
      tweenScenePos(sx, sy, time = 500) {
          let x = this.fixSceneX(sx);
          let y = this.fixSceneY(sy);
          Laya.Tween.to(this.scene, { x: x, y: y }, time);
      }
      moveCamera(offsetx, offsety) {
          this.tweenScenePos(this.scene.x - offsetx, this.scene.y - offsety, 500);
      }
      resetScenePos() {
          let x = Laya.stage.width / 2;
          let y = Laya.stage.height / 2;
          let pivotX = this.scene.width / 2;
          let pivotY = this.scene.height / 2;
          Laya.Tween.to(this.scene, { x: x, y: y, pivotX: pivotX, pivotY: pivotY, scaleX: this.scaleMin, scaleY: this.scaleMin }, 500);
      }
      focusSceneDeployIn(nx, ny) {
          let x = Laya.stage.width / 2;
          let y = Laya.stage.height / 2;
          let pivotX = this.scene.width * this.mapBG.mapDb.deploy_x;
          let pivotY = this.scene.height * this.mapBG.mapDb.deploy_y;
          let scale = this.scaleInt;
          this.scaleBeforeFocus = this.scene.scaleX;
          Laya.Tween.to(this.scene, { x: x, y: y, pivotX: pivotX, pivotY: pivotY, scaleX: scale, scaleY: scale }, 300, Laya.Ease.sineOut);
      }
      focusSceneDeployOut() {
          let x = Laya.stage.width / 2;
          let y = Laya.stage.height / 2;
          let pivotX = this.scene.width / 2;
          let pivotY = this.scene.height / 2;
          let scale = this.scaleBeforeFocus;
          Laya.Tween.to(this.scene, { x: x, y: y, pivotX: pivotX, pivotY: pivotY, scaleX: scale, scaleY: scale }, 300, Laya.Ease.sineOut);
      }
      focusSceneRushEndIn() {
          let x = Laya.stage.width / 2;
          let y = Laya.stage.height / 2;
          let pivotX = this.scene.width * this.mapBG.mapDb.deploy_x;
          let pivotY = this.scene.height * this.mapBG.mapDb.deploy_y;
          this.scaleBeforeFocus = this.scene.scaleX;
          let scale = 1.2;
          Global.sendMsg(MSG.PANEL_GAME_TOUCH, false);
          Laya.Tween.to(this.scene, { x: x, y: y, pivotX: pivotX, pivotY: pivotY, scaleX: scale, scaleY: scale }, 300);
      }
      focusSceneRushEndOut() {
          let x = Laya.stage.width / 2;
          let y = Laya.stage.height / 2;
          let pivotX = this.scene.width / 2;
          let pivotY = this.scene.height / 2;
          let scale = this.scaleBeforeFocus;
          Laya.Tween.to(this.scene, { x: x, y: y, pivotX: pivotX, pivotY: pivotY, scaleX: scale, scaleY: scale }, 500, null, Laya.Handler.create(this, this.onFocusEnd));
      }
      onFocusEnd() {
          Global.sendMsg(MSG.PANEL_GAME_TOUCH, true);
      }
      focusSceneInit() {
          let x = Laya.stage.width / 2;
          let y = Laya.stage.height / 2;
          let pivotX = this.scene.width / 2;
          let pivotY = this.scene.height / 2;
          let scale = this.scaleInt;
          Laya.Tween.to(this.scene, { x: x, y: y, pivotX: pivotX, pivotY: pivotY, scaleX: scale, scaleY: scale }, 300);
      }
      addTowerSpeed() {
          let head = this.world.buildings.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower) {
                  for (let com of tower.comAttackers) {
                  }
              }
          }
      }
      addTowerAttack() {
          let head = this.world.buildings.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower) {
                  tower.attrCur[BASE_ATTR.AD] += 1;
              }
          }
      }
      addTowerAttacker() {
          let head = this.world.buildings.head;
          while (head) {
              let tower = head.data;
              head = head.next;
              if (tower) {
                  if (tower.comAttackers.length < 3) {
                      tower.addAttacker();
                  }
              }
          }
      }
      killAllTower() {
          let head = this.world.buildings.head;
          while (head) {
              let data = head.data;
              head = head.next;
              if (data) {
                  let dd = DamageCalculation.damageData;
                  dd.damage = Math.round(data.getAttrMax(BASE_ATTR.HP) * Utils.randomRange(0.1, 0.8));
                  data.hurt(dd);
              }
          }
      }
      createPortal(gx, gy) {
          let layer = this.layerEffectBottom;
          let node = new Laya.Sprite();
          layer.addChild(node);
          let pos = Level.convertGridPosToRealPos(gx, gy);
          node.x = pos.x;
          node.y = pos.y;
          EffectFactory.createByType("effect_portal01", EffectFactory.scene3d, node);
          let effect3d = EffectFactory.create("166_e_loop_portal", EffectFactory.scene3d);
          effect3d.followNode2d(EffectFactory.camera, node, node, node, true, 0, 0);
      }
  }

  class SceneGame extends SceneBase {
      constructor() {
          super();
          this.listScene = [];
      }
      getTaskManager() {
          let taskManager = new TaskManager();
          taskManager.addCall(this.initLevel.bind(this));
          taskManager.addCall(this.initBaseRes.bind(this));
          taskManager.addCall(this.initScene.bind(this));
          this.taskManager = taskManager;
          return taskManager;
      }
      initLevel(resolve) {
          Level.load();
          resolve();
      }
      initBaseRes(resolve) {
          let loader = new TaskManager();
          loader.setParent(this.taskManager);
          loader.setLoadingCallback(resolve);
          this.addResLoader(loader);
          loader.loadAll();
      }
      get isPreloadRes() {
          return true;
      }
      addResLoader(loader) {
          loader.addRes(db.game_cnf.scene_game, RES_TYPE.PREFAB2D);
          loader.addFguiPackage("res/fgui/game");
          loader.addFguiPackage("res/fgui/tower");
          loader.addFguiPackage("res/fgui/effect");
          let mapConfig = db.get_map_config(Level.mapDb.map_id);
          if (mapConfig) {
              let path = mapConfig.map;
              let pkgReg = /ui:\/\/(\S+)\//img;
              let result = pkgReg.exec(path);
              if (result) {
                  let pkgName = result[1];
                  if (pkgName) {
                      loader.addFguiPackage(`res/fgui/${pkgName}`);
                  }
              }
          }
      }
      initScene(resolve) {
          let data = Director.createScene3DLayer(1);
          Director.createScene3DLayer(3);
          EffectFactory.setScene3d(data.scene3d);
          EffectFactory.setCamera(data.camera);
          let prefab = Laya.loader.getRes(db.game_cnf.scene_game);
          let scene2d = prefab.create();
          Director.getLayer(0).displayObject.addChild(scene2d);
          this.onSceneGameCreate(scene2d);
          resolve();
      }
      onEnter(data) {
          Director.disposeAllPanel();
          Director.openPanelWithSingleton("PanelGame");
          if (data && data.openPanel) {
              Director.openPanelWithSingleton(data.openPanel, data.context);
          }
      }
      onSceneGameCreate(scene) {
          if (StageConfig.showFPS) {
              Laya.Stat.show();
          }
          this.scene2d = scene;
          scene.addComponent(StageGame);
      }
      onExit() {
          if (this.scene2d) {
              this.scene2d.destroy();
              this.scene2d = null;
          }
          for (let scene3d of this.listScene) {
              scene3d.destroy();
          }
          this.listScene.length = 0;
          Director.destroyScene3DLayer(1);
          Director.destroyScene3DLayer(3);
      }
  }

  class EnemyWaveFinalWar extends EnemyWave {
      openModeIdle() {
          this.clear();
          this.mode = WaveMode.IDLE;
      }
  }

  class TowerDailyDamage extends Tower {
      bindSkin(skin) {
          this.skin = skin;
          skin.initSkin(this, false);
          skin.syncShooter(this);
          this.updateHpBar();
          this.updateHpBarLv();
      }
      refreshAttr() {
          let attrStd = this.attrStd;
          let attrCur = this.attrCur;
          let hurtHp = (attrStd[BASE_ATTR.HP] || 0) - (attrCur[BASE_ATTR.HP] || 0);
          let hurtMp = (attrStd[BASE_ATTR.MP] || 0) - (attrCur[BASE_ATTR.MP] || 0);
          mgrTower.calcTowerAttrByDailyDamage(this.towerDb.id, this.attrCur);
          Level.copyAttrArray(this.attrCur, this.attrStd);
          Level.resetAttrArray(this.attrScl, this.attrScl.length);
          let leftHp = attrCur[BASE_ATTR.HP] - hurtHp;
          let leftMp = attrCur[BASE_ATTR.MP] - hurtMp;
          attrCur[BASE_ATTR.HP] = Math.max(leftHp, 1);
          attrCur[BASE_ATTR.MP] = Math.max(leftMp, 0);
          this.calcAttrByBuff();
          this.updateHpBar();
          this.updateHpBarLv();
          this.searchTargets();
          mgrTower.setTowerAttrInBattle(this.towerDb.id, attrCur, this.attrStd);
      }
      updateHpBarLv() {
          if (this.skin) {
              this.skin.updateHpBarLv(mgrDailyDamage.getTowerLv(this.towerDb.id));
          }
      }
  }
  TowerDailyDamage.poolkey = "TowerDailyDamage";

  class TowerMainDailyDamage extends TowerMain {
      bindSkin(skin) {
          this.skin = skin;
          skin.initSkin(this, false);
          skin.syncShooter(this);
          this.updateHpBar();
          this.updateHpBarLv();
          let crossbow = skin.skin.getChild("cross");
          if (crossbow instanceof CustomCrossBow) {
              this.nodeCrossbow = crossbow;
              this.nodeCrossbow.visible = true;
              let gPoint = crossbow.localToGlobal();
              crossbow.removeFromParent();
              Level.stage.layerCrossbow.addChild(crossbow.displayObject);
              crossbow.x = gPoint.x;
              crossbow.y = gPoint.y;
              crossbow.scaleX = skin.skin.scaleX;
              crossbow.scaleY = skin.skin.scaleY;
          }
      }
      refreshAttr() {
          let attrStd = this.attrStd;
          let attrCur = this.attrCur;
          let hurtHp = (attrStd[BASE_ATTR.HP] || 0) - (attrCur[BASE_ATTR.HP] || 0);
          let hurtMp = (attrStd[BASE_ATTR.MP] || 0) - (attrCur[BASE_ATTR.MP] || 0);
          mgrTower.calcTowerAttrByDailyDamage(this.towerDb.id, this.attrCur);
          Level.copyAttrArray(this.attrCur, this.attrStd);
          Level.resetAttrArray(this.attrScl, this.attrScl.length);
          let leftHp = attrCur[BASE_ATTR.HP] - hurtHp;
          let leftMp = attrCur[BASE_ATTR.MP] - hurtMp;
          attrCur[BASE_ATTR.HP] = Math.max(leftHp, 1);
          attrCur[BASE_ATTR.MP] = Math.max(leftMp, 0);
          this.calcAttrByBuff();
          this.updateHpBar();
          this.updateHpBarLv();
          this.searchTargets();
          mgrTower.setTowerAttrInBattle(this.towerDb.id, attrCur, this.attrStd);
      }
      updateHpBarLv() {
          if (this.skin) {
              this.skin.updateHpBarLv(mgrDailyDamage.getTowerLv(this.towerDb.id));
          }
      }
      updateCrossbowEnergyRecover(t) {
          if (StageAttr.getAttr(STAGE_ATTR.DD_MP_REVOVER_NO)) {
              return;
          }
          super.updateCrossbowEnergyRecover(t);
      }
  }
  TowerMainDailyDamage.poolkey = "TowerMainDailyDamage";

  class StageGameDailyDamage extends StageGame {
      constructor() {
          super(...arguments);
          this.seletTowerId = "0";
      }
      onStart() {
          this.refresh();
      }
      onDestroy() {
          super.onDestroy();
          mgrDailyDamage.config = null;
      }
      initEvent() {
          if (Laya.Browser.onPC)
              Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDownPress);
          this.mapBG.owner.on(Laya.Event.MOUSE_DOWN, this, this.onTouchDown);
          this.mapBG.owner.on(Laya.Event.MOUSE_MOVE, this, this.onTouchMove);
          this.mapBG.owner.on(Laya.Event.MOUSE_UP, this, this.onTouchUp);
          Global.registerListeners(this, {
              [MSG.STAGE_DESTROY]: this.onMsgStageDestroy.bind(this),
              [MSG.TOWER_ENDNESS_BEGIN]: this.onMsgTowerEndnessBegin.bind(this),
              [MSG.TOWER_RUSH_STOP]: this.onMsgTowerRushStop.bind(this),
              [MSG.TOWER_RUSH_END]: this.onMsgTowerRushEnd.bind(this),
              [MSG.TOWER_RUSH_END_FOCUS]: this.onMsgTowerRushEndFocus.bind(this),
              [MSG.TOWER_RUSH_WIN]: this.onMsgTowerRushWin.bind(this),
              [MSG.SLOT_UNLOCK]: this.onTowerSlotUnlock.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerDeploy.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerTakeoff.bind(this),
              [MSG.TOWER_LVUP_STAR]: this.onTowerLvupQuality.bind(this),
              [MSG.TOWER_HAND_SKILL_PREPARE]: this.onTowerHandSkillPrepare.bind(this),
              [MSG.TOWER_ATTR_UPDATE_UID]: this.onTowerAttrUpdateUID.bind(this),
              [MSG.TOWER_ATTR_UPDATE]: this.onTowerAttrUpdate.bind(this),
              [MSG.TOWER_ATTR_UPDATE_MAIN]: this.onTowerAttrUpdateMain.bind(this),
              [MSG.TOWER_ATTR_UPDATE_ALL]: this.onTowerAttrUpdateAll.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.TOWER_DEBUG_CHANGE]: this.onTowerDebugChange.bind(this),
              [MSG.CHALLENGE_STORY_BEGIN]: this.onMainStoryBegin.bind(this),
              [MSG.CHALLENGE_BOSS_BEGIN]: this.onChallengeBegin.bind(this),
              [MSG.GAME_VIEW_DESTORY]: this.destroyGameView.bind(this),
              [MSG.GAME_VIEW_RESTORE]: this.restoreGameView.bind(this),
              [MSG.GAME_PAUSE]: this.pauseGame.bind(this),
              [MSG.GAME_RESUME]: this.resumeGame.bind(this),
              [MSG.REFRESH_RED_POINT_TOWER]: this.refreshRedPointTower.bind(this),
              [MSG.GUIDE_COMPLETE]: this.onGuideComplete.bind(this),
              [MSG.GUIDE_SKIP]: this.onGuideSkip.bind(this),
              [MSG.GUIDE_END]: this.onGuideEnd.bind(this),
              [MSG.TOWER_LVUP_LEVEL]: this.onTowerLvupLevel.bind(this),
              [MSG.MAP_TILE_DATA_LOAD]: this.onMapTileDataLoad.bind(this),
              [MSG.TOWER_FB_COIN_BEGIN]: this.onTowerFBCoinBegin.bind(this),
              [MSG.TOWER_FB_ITEM_BEGIN]: this.onTowerFBItemBegin.bind(this),
              [MSG.TOWER_SECRET]: this.onTowerSecretBegin.bind(this),
              [MSG.DAILY_DAMAGE_BEGIN]: this.onDailyDamageBegin.bind(this),
          });
      }
      loadMap() {
          this.mapBG.loadMapById(mgrDailyDamage.getConfig().map_id);
      }
      initEnemWave(nodeWorld) {
          this.enemyWave = nodeWorld.addComponent(EnemyWaveFinalWar);
          this.enemyWave.world = this.world;
      }
      onDailyDamageBegin() {
          this.enemyWave.openModelDailyDamage(mgrDailyDamage.getConfig());
          this.onBattleStart();
      }
      onBattleStart() {
          this.world.remAllUnit(LogicCamp.ENEMY);
          this.countEnemy = 0;
          this.hideTowerOption();
          StageGameStatis.start();
          this.mapBG.hideEffect();
      }
      loadTowerOption() {
          let towerOption = fgui.UIPackage.createObjectFromURL("ui://game/CustomTowerOptionDailyDamage");
          this.layerMenuUI.addChild(towerOption.displayObject);
          this.towerOption = towerOption;
          this.towerOption.visible = false;
      }
      refresh() {
          this.loadTowerGround();
          this.world.remAllUnit();
          this.focusSceneInit();
          this.loadTowers();
          mgrSound.playMusic("sBg");
      }
      refreshRedPointTower() {
          for (let uid in this.uid2Tower) {
              let skin = this.uid2Tower[uid];
              if (skin) {
                  skin.hideRedPoint();
              }
          }
      }
      onTowerDebugChange(id) {
          this.seletTowerId = id;
          this.refresh();
      }
      loadTowerByIdAndGrid(towerId, gx, gy) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              let shape = [];
              let towerW = towerDb.size[0];
              let towerH = towerDb.size[1];
              let offsetx = Math.floor(towerW / 4);
              for (let i = 0; i < towerW; i++) {
                  for (let j = 0; j < towerH; j++) {
                      shape.push({ x: i, y: j });
                  }
              }
              ResTowerManager.onTowerAdd(towerId);
              if (towerDb.main)
                  return this.world.addBuilding(TowerMainDailyDamage, gx - offsetx, gy, towerId, shape);
              else
                  return this.world.addBuilding(TowerDailyDamage, gx - offsetx, gy, towerId, shape);
          }
      }
      showSlotUnlock() {
      }
  }

  class SceneGameDailyDamage extends SceneGame {
      addResLoader(loader) {
          loader.addFguiPackage("res/fgui/dailydamage_game");
          loader.addFguiPackage("res/fgui/dailydamage_ad");
      }
      onSceneGameCreate(scene) {
          this.scene2d = scene;
          scene.addComponent(StageGameDailyDamage);
      }
      onEnter(withLoad) {
          Director.disposeAllPanel();
          Director.openPanelWithSingleton("PanelDailyDamageGame");
          Director.openPanelWithSingleton("PanelDailyDamageReady");
      }
  }

  class PanelDailyDamage extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "茶叶蛋试炼";
          this.sourceName = "ui://dailydamage/PanelDailyDamage";
          this.panelStyle = 1;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_history: "ScaleButton",
              cc_button_question: "ScaleButton",
              cc_button_close: "ScaleButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_damage: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_list_reward: "fgui.GList",
              cc_button_reward: "fgui.GButton",
              cc_button_begin: "fgui.GButton",
              cc_ctrl_next_no: "fgui.Controller",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      buildUi() {
          this.listReward = new ListView(this.list_reward, this, this.parseRewardItem, this.renderRewardItem);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      parseRewardItem(content, object, index) {
          content.view = object.getChild("item");
          if (index < 5)
              FguiHelper.playIdleAndIn(object, index, 0.5, 0.05);
      }
      renderRewardItem(content, data) {
          content.view.refresh(data);
      }
      refreshReward(reward) {
          if (reward) {
              let itemInfos = StageTool.convertIds2ItemInfos(reward.rewards);
              this.listReward.setListData(itemInfos);
          }
          else {
              this.listReward.setListData([]);
          }
      }
      refresh() {
          let config = mgrDailyDamage.getConfig();
          let reward = mgrDailyDamage.calcCurrentReward(config.id);
          let damage = mgrDailyDamage.getDamageToday(config.id);
          this.label_name.text = config.name;
          this.label_damage.text = StageTool.formatDailyDamage(damage);
          if (reward.next) {
              this.label_left.text = StageTool.formatDailyDamage(reward.next.damage - damage);
              this.ctrl_next_no.selectedIndex = 1;
          }
          else {
              this.ctrl_next_no.selectedIndex = 0;
          }
          this.ctrl_reward.selectedIndex = mgrDailyDamage.reward ? 1 : 0;
          this.refreshReward(reward.curt);
      }
      on_click_button_history() {
          Director.openPanelWithSingleton("PanelDailyDamageHIstory");
      }
      on_click_button_question() {
          Director.openPanelWithSingleton("PanelDailyDamageQuestion");
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_reward() {
          if (mgrHolyItem.notEnoughEmpty(4))
              return;
          mgrNetwork.callByNetwork(() => {
              if (mgrDailyDamage.tryGetReward()) {
                  this.refresh();
              }
          });
      }
      on_click_button_begin() {
          Director.runScene(SceneGameDailyDamage, "PanelLoadingGame");
      }
  }

  class PanelDailyDamageHIstory extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "茶叶蛋试炼-历史最佳";
          this.sourceName = "ui://dailydamage/PanelDailyDamageHIstory";
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_history: "fgui.GList",
          };
      }
      buildUi() {
          this.listview = new ListView(this.list_history, this, this.parseItem, this.renderItem);
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      parseItem(contet, view, index) {
          contet.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.2, 0.05);
      }
      renderItem(contet, data) {
          contet.data = data;
          contet.view.refresh(data);
      }
      refreshList() {
          this.listview.setListData(db.get_daily_damage_db_map());
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelDailyDamageQuestion extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "茶叶蛋试炼-问号帮助";
          this.sourceName = "ui://dailydamage/PanelDailyDamageQuestion";
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_desc: "fgui.GList",
          };
      }
      buildUi() {
          this.listview = new ListView(this.list_desc, this, this.parseItem, this.renderItem);
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      parseItem(contet, view, index) {
          contet.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.2, 0.05);
      }
      renderItem(contet, data) {
          contet.data = data;
          contet.view.refresh(data);
      }
      refreshList() {
          this.listview.setListData(db.get_daily_damage_db_map());
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class CustomDailyDamageADItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://dailydamage_ad/CustomDailyDamageADItem";
          this.isShowAD = false;
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_desc: "fgui.GBasicTextField",
              cc_button_ad: "fgui.GButton",
              cc_ctrl_active: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.itemData = data;
          let add = Math.floor((data.value - 1) * 100);
          this.label_desc.text = Utils.sprintf(data.desc, add);
          this.loader_icon.url = data.icon;
          let valid = mgrDailyDamage.isAdBuffValid(data.id);
          this.ctrl_active.selectedIndex = valid ? 1 : 0;
          if (!this.isShowAD && !valid) {
              this.isShowAD = true;
              mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.daily_damage_ad);
          }
      }
      on_click_button_ad() {
          if (this.itemData) {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.daily_damage_ad, this.itemData.id);
          }
      }
  }

  class PanelDailyDamageAD extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "茶叶蛋试炼-限时助力";
          this.sourceName = "ui://dailydamage_ad/PanelDailyDamageAD";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.initEvent();
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.daily_damage_ad) {
                      this.watchAdSuccess(e.params);
                  }
              },
          });
      }
      watchAdSuccess(id) {
          mgrDailyDamage.markAdBuffValid(id);
          this.listItem.refresh();
      }
      parseItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.2, 0.05);
      }
      renderItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshList() {
          let data = db.get_daily_damage_ad_map();
          this.listItem.setListData(data);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class CustomDailyDamageBar extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://dailydamage_game/CustomDailyDamageBar";
          this.exportNodeNames = {
              cc_label_damage: "fgui.GBasicTextField",
              cc_label_time: "fgui.GBasicTextField",
          };
      }
      onCreate() {
          this.label_damage.text = "0";
      }
      dispose() {
          super.dispose();
      }
      updatePerSecond(timeLeft) {
          this.label_time.text = timeLeft.toString();
          this.label_damage.text = StageTool.formatDailyDamage(StageGameStatis.getDamageAll());
      }
  }

  class PanelDailyDamageGame extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "茶叶蛋试炼-游戏中";
          this.sourceName = "ui://dailydamage_game/PanelDailyDamageGame";
          this.panelStyle = 1;
          this.bMask = false;
          this.bAutoRemovePackage = true;
          this.timePass = 0;
          this.timeMaxx = 0;
          this.exportNodeNames = {
              cc_layer_fit: "CustomLayerFit",
              cc_button_start: "fgui.GButton",
              cc_button_setting: "fgui.GButton",
              cc_money_coin: "CustomMoneyBar",
              cc_bottom: "fgui.GComponent",
              cc_button_giveup: "ScaleButton",
              cc_hand: "CustomGameHand",
              cc_button_hand: "fgui.GButton",
              cc_button_auto_skill: "fgui.GButton",
              cc_damage_bar: "CustomDailyDamageBar",
              cc_button_exit: "ScaleButton",
              cc_button_ad: "ScaleButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_hand: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
          };
      }
      buildUi() {
          this.layer_fit.fit();
          this.timePass = 0;
          this.timeMaxx = db.game_cnf.daily_damage_time;
          this.damage_bar.updatePerSecond(this.timeMaxx);
          this.resNode.makeFullScreen();
          this.initEvent();
          this.initTimer();
          this.refresh();
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_RUSH_END_FOCUS]: this.onTowrRushERndFocus.bind(this),
              [MSG.TOWER_RUSH_END]: this.onTowrRushEnd.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerChange.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerChange.bind(this),
              [MSG.TOWER_DEAD]: this.onTowerDead.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.DAILY_DAMAGE_READY_OVER]: this.onDailyDamageReadyOver.bind(this),
          });
      }
      onTowrRushERndFocus() {
          this.trans_out.play();
      }
      onTowrRushEnd(win) {
          this.exitBattle(win);
      }
      onUpdatePerSecond() {
          if (this.ctrl_state.selectedIndex == 1) {
              if (this.timePass < this.timeMaxx) {
                  this.timePass++;
                  let timeLeft = this.timeMaxx - this.timePass;
                  if (this.timePass >= this.timeMaxx) {
                      this.onTimerOver();
                  }
                  this.damage_bar.updatePerSecond(timeLeft);
              }
          }
      }
      onTimerOver() {
          StageGameStatis.pause();
          mgrDailyDamage.markDamage(StageGameStatis.getDamageAll());
          Global.sendMsg(MSG.TOWER_RUSH_WIN);
      }
      refreshGameHand() {
          if (this.ctrl_hand.selectedIndex == 1) {
              this.hand.refresh(true);
          }
      }
      onTowerDead() {
          this.refreshGameHand();
      }
      onTowerMainSkillChange() {
          this.refreshGameHand();
      }
      onTowerChange() {
          this.refreshGameHand();
      }
      onDailyDamageReadyOver() {
          if (!mgrDailyDamage.isAllActive()) {
              this.showAD();
          }
      }
      showAD() {
          Director.openPanelWithSingleton("PanelDailyDamageAD");
      }
      refresh() {
          this.button_auto_skill.selected = !StageConfig.handSuperSkill;
      }
      refrehsBossTitle(roleId) {
          let rodeDb = db.get_role_db(roleId);
          if (rodeDb) {
              let modelDb = db.get_role_model_db(rodeDb.model_id);
              if (modelDb) {
              }
          }
      }
      beginBattle() {
          this.ctrl_state.selectedIndex = 1;
          Global.sendMsg(MSG.DAILY_DAMAGE_BEGIN);
      }
      exitBattle(win) {
          Director.runScene(SceneGame, "PanelLoadingGame", { openPanel: "PanelDailyDamage" });
      }
      on_click_button_start() {
          if (mgrDailyDamage.isAnyTowerHaveLeftPoint()) {
              mgrTip.alertPrompt("塔还有未分配的属性点，\n是否确定开始战斗？", null, () => {
                  this.beginBattle();
              });
          }
          else {
              this.beginBattle();
          }
      }
      on_click_button_exit() {
          this.exitBattle(true);
      }
      on_click_button_setting() {
          Director.openPanelWithSingleton("PanelSetting");
      }
      on_click_button_giveup() {
          mgrTip.alertPrompt("确定要退出每日试炼么？", null, () => {
              Global.sendMsg(MSG.TOWER_RUSH_STOP);
          });
      }
      on_click_button_hand() {
          if (this.ctrl_hand.selectedIndex)
              this.hand.openHand();
          else
              this.hand.closeHand();
      }
      on_click_button_auto_skill() {
          StageConfig.handSuperSkill = !this.button_auto_skill.selected;
      }
      on_click_button_ad() {
          this.showAD();
      }
  }

  class PanelDailyDamageReady extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://dailydamage_game/PanelDailyDamageReady";
          this.panelLayer = 4;
          this.exportNodeNames = {
              cc_trans_in: "fgui.Transition",
          };
      }
      buildUi() {
          this.trans_in.play(Laya.Handler.create(this, this.onTransInPlayEnd));
      }
      dispose() {
          super.dispose();
      }
      onTransInPlayEnd() {
          this.closeWithTransition();
          Global.sendMsg(MSG.DAILY_DAMAGE_READY_OVER);
      }
  }

  class PanelDamageResult extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "茶叶蛋试炼-伤害结算";
          this.sourceName = "ui://dailydamage_result/PanelDamageResult";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_label_damage: "fgui.GBasicTextField",
              cc_label_history: "fgui.GBasicTextField",
              cc_label_today: "fgui.GBasicTextField",
              cc_button_exit: "fgui.GButton",
          };
      }
      buildUi() {
          this.refresh();
      }
      dispose() {
          Global.sendMsg(MSG.TOWER_RUSH_END, [true, WaveMode.DAILY_DAMAGE]);
          super.dispose();
      }
      refresh() {
          let config = mgrDailyDamage.getConfig();
          this.label_damage.text = StageTool.formatDailyDamage(mgrDailyDamage.damageLast);
          this.label_today.text = StageTool.formatDailyDamage(mgrDailyDamage.getDamageToday(config.id));
          this.label_history.text = StageTool.formatDailyDamage(mgrDailyDamage.getDamageHistory(config.id));
      }
      on_click_button_exit() {
          this.closeWithTransition();
      }
  }

  class PanelDebug extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://debug_ui/PanelDebug";
          this.exportNodeNames = {
              cc_btn_close: "fgui.GButton",
              cc_list_menu: "fgui.GList",
              cc_list_skin: "fgui.GList",
              cc_list_state: "fgui.GList",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_btn_close() {
      }
  }

  class PanelDebugEffect extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://debug_ui/PanelDebugEffect";
          this.bMask = false;
          this.isMouseDown = false;
          this.lastx = 0;
          this.lasty = 0;
          this.exportNodeNames = {
              cc_btn_close: "fgui.GButton",
              cc_list_effect: "fgui.GList",
              cc_node_effect: "fgui.GLoader",
              cc_input_search: "fgui.GTextInput",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.listEffect = new ListView(this.list_effect, this, this.parseEffectItem, this.renderEffectItem);
          this.listEffect.setOnClickItem(this, this.onClickEffectItem);
          this.refreshList();
          this.initEvent();
          this.input_search.on(Laya.Event.INPUT, this, this.onInputSearchChange);
      }
      dispose() {
          this.removeEvent();
          super.dispose();
      }
      onInputSearchChange() {
          let text = this.input_search.text;
          this.refreshList(text);
      }
      parseEffectItem(content, object) {
          content.button = object;
      }
      renderEffectItem(content, data, index) {
          content.data = data;
          content.button.title = data.id;
      }
      onClickEffectItem(content) {
          this.loadEffect(content.data);
      }
      unloadEffect() {
          if (this.modelEffect) {
              this.modelEffect.clear();
              this.modelEffect = null;
          }
      }
      loadEffect(data) {
          this.unloadEffect();
          let scene = Director.getScene3DLayer(1);
          let effect = EffectFactory.create(data.id, scene.scene3d);
          effect.followNode2d(scene.camera, this.node_effect.displayObject);
          this.modelEffect = effect;
      }
      refreshList(search = null) {
          let dataMap = db.get_model_db_map();
          let listData = [];
          for (let key in dataMap) {
              let item = db.get_model_db(key);
              if (search) {
                  if (item.id.indexOf(search) >= 0) {
                      listData.push(item);
                  }
              }
              else {
                  listData.push(item);
              }
          }
          this.listEffect.setListData(listData);
      }
      initEvent() {
          Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      removeEvent() {
          Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          this.lastx = x;
          this.lasty = y;
      }
      onMouseMove() {
          if (!this.isMouseDown)
              return;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let dx = x - this.lastx;
          let dy = y - this.lasty;
          this.lastx = x;
          this.lasty = y;
          this.node_effect.x += dx;
          this.node_effect.y += dy;
      }
      onMouseUp() {
          this.isMouseDown = false;
      }
      on_click_btn_close() {
          this.close();
      }
  }

  class PanelDebugInput extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://debug_ui/PanelDebugInput";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.exportNodeNames = {
              cc_label_input: "fgui.GTextInput",
              cc_btn_close: "fgui.GButton",
              cc_btn_ensure: "fgui.GButton",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_btn_ensure() {
          let day = mgrTime.getDateNumBySecond(Date.now());
          if (this.label_input.text == day.toString() + this.label_input.data) {
              if (this.context.funcEnsure) {
                  this.context.funcEnsure();
              }
          }
          this.close();
      }
      on_click_btn_close() {
          this.close();
      }
  }

  class PanelTest2d extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://debug_ui/PanelTest2d";
          this.panelStyle = 1;
          this.bMask = false;
          this.exportNodeNames = {
              cc_button_big: "fgui.GButton",
              cc_button_small: "fgui.GButton",
              cc_button_reset: "fgui.GButton",
              cc_button_speed: "fgui.GButton",
              cc_button_attack: "fgui.GButton",
              cc_button_num: "fgui.GButton",
              cc_label_debug: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          Level.labelDebug = this.label_debug;
      }
      dispose() {
          super.dispose();
      }
      on_click_button_big() {
          var scale = Level.stage.scene.scaleX + 0.1;
          Level.stage.changeSceneScale(scale);
      }
      on_click_button_small() {
          var scale = Level.stage.scene.scaleX - 0.1;
          Level.stage.changeSceneScale(scale);
      }
      on_click_button_reset() {
          Level.stage.resetScenePos();
      }
      on_click_button_speed() {
          Level.stage.addTowerSpeed();
      }
      on_click_button_attack() {
          Level.stage.addTowerAttack();
      }
      on_click_button_num() {
          Level.stage.addTowerAttacker();
      }
  }

  class PanelTest3d extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://debug_ui/PanelTest3d";
          this.panelStyle = 1;
          this.bMask = false;
          this.exportNodeNames = {};
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomAttrList extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://deploy/CustomAttrList";
          this.attr = null;
          this.skillId = null;
          this.exportNodeNames = {
              cc_list_attr: "fgui.GList",
          };
      }
      onCreate() {
          this.listAttr1 = new ListView(this.list_attr, this, this.parseAttrItem, this.renderAttrItem);
      }
      dispose() {
          super.dispose();
      }
      parseAttrItem(content, object) {
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asLoader;
          content.value = object.getChild("value").asTextField;
      }
      renderAttrItem(content, data) {
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.url = baseAttrDb.icon_name;
              if (this.skillId && data.k == BASE_ATTR.ATK_SPEED) {
                  let skillDb = db.get_skill_db(this.skillId);
                  let intervalBase = 1 / (skillDb.cast_time + skillDb.cd_time) * this.attr[BASE_ATTR.ATK_SPEED];
                  content.value.text = intervalBase.toFixed(baseAttrDb.digit);
              }
              else {
                  let v = Math.round(data.v);
                  if (baseAttrDb.percent) {
                      content.value.text = v * 100 + "%";
                  }
                  else {
                      content.value.text = v.toFixed(baseAttrDb.digit);
                  }
              }
          }
      }
      refresh(attr, skillId = null) {
          this.attr = attr;
          this.skillId = skillId;
          let listData1 = [];
          for (let i = 0; i < attr.length; i++) {
              let v = attr[i];
              listData1.push({ k: i, v: v });
          }
          this.listAttr1.setListData(listData1);
      }
  }

  class CustomTowerInfo extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://deploy/CustomTowerInfo";
          this.detailSkillId = null;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_list_item: "fgui.GList",
              cc_com_attr: "CustomAttrList",
              cc_com_star: "fgui.GComponent",
              cc_ctrl_star: "fgui.Controller",
              cc_button_skill_1: "fgui.GButton",
              cc_button_skill_2: "fgui.GButton",
              cc_progress_star: "fgui.GProgressBar",
              cc_com_skill_detail: "CustomSkillDetail",
              cc_label_tower_name: "fgui.GBasicTextField",
              cc_label_tower_level: "fgui.GBasicTextField",
              cc_ctrl_qualtiy: "fgui.Controller",
              cc_ctrl_skill: "fgui.Controller",
          };
      }
      onCreate() {
          this.listItem = new ListView(this.list_item, this, this.parseHolyItem, this.renderHolyItem);
          this.loader_bg.onClick(this, this.onClickBackground);
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb) {
          this.ctrl_skill.selectedIndex = 0;
          this.towerDb = towerDb;
          this.com_attr.refresh(mgrTower.getTowerAttrInBattle(towerDb.id), mgrTower.getTowerSkillId(towerDb.id));
          this.label_tower_name.text = towerDb.name;
          this.label_tower_level.text = "Lv." + mgrTower.getTowerLv(towerDb.id);
          this.ctrl_qualtiy.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
          mgrTower.refreshStarLvupBar(this.progress_star, towerDb.id, false);
          this.button_skill_1.icon = mgrTower.getSkillIcon(mgrTower.getTowerSkillId(towerDb.id));
          this.button_skill_2.icon = mgrTower.getSkillIcon(mgrTower.getTowerSuperId(towerDb.id));
          this.ctrl_star.selectedIndex = mgrTower.getTowerStar(towerDb.id);
          this.refreshHolyItem();
      }
      parseHolyItem(content, object) {
          content.have = object.getController("have");
          content.item = object.getChild("item");
      }
      renderHolyItem(content, data) {
          let slot = data.slot;
          content.data = data;
          if (slot && slot.valid) {
              if (slot.unlock) {
                  if (slot.item_uid && data.item) {
                      content.have.selectedIndex = 1;
                      content.item.refresh(data.item.holyitem, false);
                      return;
                  }
              }
          }
          content.have.selectedIndex = 0;
      }
      onShowTowerSkillDetail(skillId) {
          if (skillId) {
              if (skillId != this.detailSkillId) {
                  this.ctrl_skill.selectedIndex = 1;
                  this.com_skill_detail.refresh(skillId);
              }
              else {
                  if (this.ctrl_skill.selectedIndex)
                      this.ctrl_skill.selectedIndex = 0;
                  else
                      this.ctrl_skill.selectedIndex = 1;
              }
          }
          else {
              this.ctrl_skill.selectedIndex = 0;
          }
          this.detailSkillId = skillId;
      }
      onClickBackground() {
          if (this.ctrl_skill.selectedIndex)
              this.ctrl_skill.selectedIndex = 0;
      }
      refreshHolyItem() {
          let listData = [];
          let slots = mgrTower.getTowerHolyData(this.towerDb.id);
          for (let i = 0; i < 8; i++) {
              let slot = slots[i];
              if (slot) {
                  listData.push({ id: i, slot: slot, item: mgrHolyItem.findBagItemByUID(slot.item_uid) });
              }
              else {
                  listData.push({ id: i, slot: null, item: null });
              }
          }
          listData.sort(this.sortHolyItem.bind(this));
          this.listItem.setListData(listData);
      }
      sortHolyItem(a, b) {
          let a_score = this.calcSlotScore(a);
          let b_score = this.calcSlotScore(b);
          return a_score - b_score;
      }
      calcSlotScore(a) {
          let score = 0;
          if (a.slot) {
              score = a.slot.unlock ? -1000 : 0 + a.slot.unlock_type == HOLY_ITEM_SLOT_STATE.UNLOCK_COIN ? -100 : 0 + a.id;
          }
          else {
              score = Number.MAX_VALUE;
          }
          return score;
      }
      on_click_button_skill_1() {
          this.onShowTowerSkillDetail(this.towerDb.skill_id);
      }
      on_click_button_skill_2() {
          this.onShowTowerSkillDetail(this.towerDb.super_skill_id);
      }
  }

  class PanelDeploy extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "布阵";
          this.sourceName = "ui://deploy/PanelDeploy";
          this.panelStyle = 1;
          this.bMask = false;
          this.selectType = -1;
          this.isMouseDown = false;
          this.lastX = 0;
          this.lastY = 0;
          this.moveDistanceY = 0;
          this.isMoved = false;
          this.exportNodeNames = {
              cc_touch_bg: "fgui.GComponent",
              cc_touch_info: "fgui.GComponent",
              cc_tower_info: "CustomTowerInfo",
              cc_layer_front: "fgui.GComponent",
              cc_button_close: "ScaleButton",
              cc_list_card: "fgui.GList",
              cc_list_type: "fgui.GList",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.listCard = new ListView(this.list_card, this, this.parseCardItem, this.renderCardItem);
          this.listCard.setOnClickItem(this, this.onClickCardItem);
          this.listType = new ListView(this.list_type, this, this.parseTypeItem, this.renderTypeItem);
          this.listType.setOnClickItem(this, this.onClickTypeItem);
          this.touch_bg.onClick(this, this.onClickBackGround);
          this.touch_info.onClick(this, this.onClickBackInfo);
          this.refreshList();
          this.refreshType();
          this.initEvent();
          this.button_close.visible = mgrGuide.isGuideCompletById("main", 14);
          this.list_type.visible = !Global.isGuiding;
      }
      dispose() {
          Global.sendMsg(MSG.TOWER_DEPLOY_END);
          this.removeEvent();
          super.dispose();
      }
      refreshType() {
          let listData = [-1, 0, 1, 2];
          this.listType.setListData(listData);
          this.ctrl_type.clearPages();
          for (let i = 0; i < listData.length; i++) {
              this.ctrl_type.addPage(i.toString());
          }
          this.ctrl_type.selectedIndex = 0;
      }
      refreshList() {
          let towerDbMap = db.get_tower_db_map();
          let listData = [];
          for (let key in towerDbMap) {
              let data = db.get_tower_db(key);
              if (!data.main && mgrTower.getTowerAmount(key)) {
                  if (this.selectType < 0) {
                      listData.push(data);
                  }
                  else {
                      if (this.selectType == data.type) {
                          listData.push(data);
                      }
                  }
              }
          }
          listData.sort(this.sortCard);
          this.listCard.setListData(listData);
      }
      sortCard(a, b) {
          let score_a = mgrTower.calcTowerScore(a.id);
          let score_b = mgrTower.calcTowerScore(b.id);
          return score_b - score_a;
      }
      initEvent() {
          Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
          Laya.stage.on(Laya.Event.MOUSE_OUT, this, this.onMouseUp);
          Global.registerListeners(this, {
              [MSG.TOWER_DEPLOY_SUC]: this.onTowerDeploy.bind(this),
              [MSG.GUIDE_COMPLETE]: this.onGuideComplete.bind(this),
          });
      }
      removeEvent() {
          Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
          Laya.stage.off(Laya.Event.MOUSE_OUT, this, this.onMouseUp);
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          this.lastX = x;
          this.lastY = y;
          this.moveDistanceY = 0;
          this.isMoved = false;
      }
      onMouseMove() {
          if (!this.isMouseDown)
              return;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let dy = y - this.lastY;
          this.lastX = x;
          this.lastY = y;
          this.moveDistanceY += dy;
          if (this.selectContent && !this.dragItem && this.moveDistanceY <= -50) {
              this.createDragItem(this.selectContent);
          }
          this.moveDragItem();
          if (this.dragItem) {
              if (!this.isTouchIn(this.list_card, x, y)) {
                  this.pauseScroll();
              }
          }
      }
      onMouseUp() {
          this.isMouseDown = false;
          this.destroyDragItem();
          this.resumeScroll();
          if (this.selectContent) {
              Global.sendMsg(MSG.TOWER_DEPLOY, this.selectContent.data);
              this.listCard.getListData().sort(this.sortCard);
              this.listCard.refresh();
          }
          this.selectContent = null;
      }
      onTowerDeploy() {
      }
      onGuideComplete(guide) {
          if (guide.group == "main" && guide.id == 14) {
              this.button_close.visible = true;
          }
      }
      isTouchIn(veiw, x, y) {
          let rect = veiw.localToGlobalRect();
          rect.width = veiw.width;
          rect.height = veiw.height;
          let offsetX = rect.width * veiw.pivotX;
          let offsetY = rect.height * veiw.pivotY;
          rect.x -= offsetX;
          rect.y -= offsetY;
          return rect.contains(x, y);
      }
      pauseScroll() {
          fgui.GObject.draggingObject = this;
      }
      resumeScroll() {
          fgui.GObject.draggingObject = null;
      }
      createDragItem(content) {
          this.destroyDragItem();
          if (content.data.main)
              return;
          let view = fgui.UIPackage.createObjectFromURL(content.data.res).asCom;
          let quality = view.getController("quality");
          quality.selectedIndex = mgrTower.getTowerStar(content.data.id);
          TowerImageHelper.registLoader(view, quality);
          this.layer_front.addChild(view);
          this.dragItem = view;
          view.setScale(content.data.scale, content.data.scale);
          this.moveDragItem();
          this.isMoved = true;
          return view;
      }
      moveDragItem() {
          if (this.dragItem) {
              let x = Laya.MouseManager.instance.mouseX;
              let y = Laya.MouseManager.instance.mouseY;
              this.dragItem.x = x / Laya.stage.clientScaleX;
              this.dragItem.y = y / Laya.stage.clientScaleY;
          }
      }
      destroyDragItem() {
          if (this.dragItem) {
              this.dragItem.dispose();
              this.dragItem = null;
          }
      }
      onClickBackGround() {
          if (Level.isFirstGuide())
              return;
          this.close();
      }
      onClickBackInfo() {
          this.ctrl_state.selectedIndex = 0;
          this.selectTowerDb = null;
          this.listCard.refresh();
      }
      parseCardItem(content, root, index) {
          let object = root.getChild("item").asCom;
          content.container = object;
          content.icon = object.getChild("icon").asLoader;
          content.quality = object.getController("quality");
          content.fight = object.getController("fight");
          let star = object.getChild("star").asCom;
          content.type = star.getController("type");
          content.star = star.getController("star");
          content.level = object.getChild("level").asTextField;
          content.name = object.getChild("name").asTextField;
          content.select = root.getController("select");
          this.registListItemMouseEvent(content);
          let transIn = root.getTransition("in");
          if (transIn && index < 6) {
              let transIdle = root.getTransition("idle");
              if (transIdle) {
                  transIdle.play();
              }
              transIn.play(null, 1, 0.25 + index * 0.05);
          }
      }
      renderCardItem(content, data) {
          content.icon.url = data.icon;
          content.quality.selectedIndex = mgrTower.getTowerQualityByDB(data);
          ;
          content.data = data;
          content.star.selectedIndex = mgrTower.getTowerStar(data.id);
          content.type.selectedIndex = data.type;
          content.level.text = "Lv." + mgrTower.getTowerLv(data.id);
          content.name.text = data.name;
          let equiped = mgrTower.isTowerEquip(data.id);
          content.fight.selectedIndex = equiped ? 1 : 0;
          if (this.selectTowerDb == data) {
              content.select.selectedIndex = 1;
          }
          else {
              content.select.selectedIndex = 0;
          }
      }
      onClickCardItem(content) {
          if (Global.isGuiding)
              return;
          if (this.isMoved)
              return;
          this.tower_info.refresh(content.data);
          if (this.selectTowerDb == content.data) {
              if (this.ctrl_state.selectedIndex) {
                  this.ctrl_state.selectedIndex = 0;
              }
              else {
                  this.ctrl_state.selectedIndex = 1;
              }
              this.selectTowerDb = null;
          }
          else {
              this.ctrl_state.selectedIndex = 1;
              this.selectTowerDb = content.data;
          }
          this.listCard.refresh();
      }
      parseTypeItem(content, object, index) {
          content.container = object;
          content.ctrlType = object.getController("type");
          let transIn = object.getTransition("in");
          if (transIn && index < 4) {
              transIn.play(null, 1, 0.25 + index * 0.05);
          }
      }
      renderTypeItem(content, type, index) {
          content.ctrlType.selectedIndex = index;
          content.type = type;
      }
      onClickTypeItem(content) {
          this.selectType = content.type;
          this.refreshList();
      }
      registListItemMouseEvent(content) {
          content.icon.on(Laya.Event.MOUSE_DOWN, this, this.onListItemMouseDown, [content]);
          content.icon.on(Laya.Event.MOUSE_UP, this, this.onListItemMouseUp, [content]);
      }
      onListItemMouseDown(content) {
          if (content.fight.selectedIndex == 0) {
              this.selectContent = content;
          }
          this.onMouseDown();
      }
      onListItemMouseUp(content) {
          this.onMouseUp();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class CustomScaleBar extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://editor/CustomScaleBar";
          this.nodeScale = 1;
          this.exportNodeNames = {
              cc_button_scale_add: "fgui.GButton",
              cc_button_scale_sub: "fgui.GButton",
              cc_label_scale: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      setTarget(target, scale = 1) {
          this.nodeTarget = target;
          this.nodeScale = scale;
          this.onScaleChange();
      }
      onScaleChange() {
          this.label_scale.text = "缩放:" + this.nodeScale.toFixed(1);
          if (this.nodeTarget) {
              this.nodeTarget.scaleX = this.nodeScale;
              this.nodeTarget.scaleY = this.nodeScale;
          }
      }
      on_click_button_scale_add() {
          this.nodeScale += 0.1;
          this.onScaleChange();
      }
      on_click_button_scale_sub() {
          this.nodeScale -= 0.1;
          this.onScaleChange();
      }
  }

  class PanelEditAnim extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://editor/PanelEditAnim";
          this.animAction = "move";
          this.listPointData = [];
          this.isMouseDown = false;
          this.lastx = 0;
          this.lasty = 0;
          this.exportNodeNames = {
              cc_com_center: "fgui.GComponent",
              cc_com_point: "fgui.GComponent",
              cc_anchor: "fgui.GGraph",
              cc_btn_close: "fgui.GButton",
              cc_button_save: "fgui.GButton",
              cc_scale_bar: "CustomScaleBar",
              cc_button_flip: "fgui.GButton",
              cc_list_role: "fgui.GList",
              cc_list_action: "fgui.GList",
              cc_list_menu: "fgui.GList",
              cc_list_point: "fgui.GList",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.listAction = new ListView(this.list_action, this, this.parseAnimItem, this.renderAnimItem);
          this.listAction.setOnClickItem(this, this.onClickActionItem);
          this.listAnim = new ListView(this.list_role, this, this.parseRoleItem, this.renderRoleItem);
          this.listAnim.setOnClickItem(this, this.onClickRoleItem);
          this.listMenues = new ListView(this.list_menu, this, this.parseMenuItem, this.renderMenuItem);
          this.listMenues.setOnClickItem(this, this.onClickMenuItem);
          this.listPoint = new ListView(this.list_point, this, this.parsePointItem, this.renderPointItem);
          this.listPoint.setOnClickItem(this, this.onClickPointItem);
          this.scale_bar.setTarget(this.com_center);
          this.animation = new AnimationEx;
          this.com_center.displayObject.addChild(this.animation);
          this.refreshList();
          this.initEvent();
          AnimationHelper.init();
          this.refreshMenuList();
          this.refreshListPoint();
      }
      dispose() {
          this.removeEvent();
          super.dispose();
      }
      refreshMenuList() {
          this.listMenues.setListData(["添加", "删除", "清空"]);
      }
      parseMenuItem(content, object) {
          content.button = object.asButton;
      }
      renderMenuItem(content, name) {
          content.button.title = name;
          content.action = name;
      }
      onClickMenuItem(content) {
          switch (content.action) {
              case "添加":
                  this.addPoint();
                  break;
              case "删除":
                  this.delPoint();
                  break;
              case "清空":
                  this.clearPoint();
                  break;
          }
      }
      loadSpinePoint(role, modelDb) {
          this.clearViewPoint();
          let data = PointHelper.getPointConfig(modelDb.anim);
          if (data) {
              for (let i = 0; i < data.points.length; i++) {
                  let p = data.points[i];
                  let point = this.createRedPoint();
                  point.x = p.x;
                  point.y = p.y;
                  this.listPointData.push({ view: point });
              }
              this.selectSpineData = data;
          }
          this.selectPoint = null;
          this.refreshListPoint();
      }
      clearViewPoint() {
          for (let item of this.listPointData) {
              item.view.dispose();
          }
          this.listPointData.length = 0;
      }
      refreshListPoint() {
          this.listPoint.setListData(this.listPointData);
      }
      createRedPoint() {
          let point = fgui.UIPackage.createObjectFromURL("ui://editor/ComRedPoint").asCom;
          this.com_point.addChild(point);
          return point;
      }
      addPoint() {
          let point = this.createRedPoint();
          let data = { view: point };
          this.selectPoint = data;
          this.listPointData.push(data);
          this.refreshListPoint();
          this.onPointConfigChange();
      }
      delPoint() {
          if (this.selectPoint) {
              let newListData = [];
              for (let point of this.listPointData) {
                  if (this.selectPoint != point) {
                      newListData.push(point);
                  }
                  else {
                      point.view.dispose();
                  }
              }
              this.listPointData = newListData;
              this.selectPoint = null;
              this.refreshListPoint();
              this.onPointConfigChange();
          }
      }
      clearPoint() {
          for (let point of this.listPointData) {
              point.view.dispose();
          }
          this.listPointData = [];
          this.selectPoint = null;
          this.refreshListPoint();
          this.onPointConfigChange();
      }
      parsePointItem(content, object) {
          content.button = object.asButton;
      }
      renderPointItem(content, data, index) {
          content.data = data;
          content.button.title = (index + 1).toString();
          if (this.selectPoint == data) {
              content.button.selected = true;
          }
          else {
              content.button.selected = false;
          }
      }
      onClickPointItem(content) {
          if (this.selectPoint == content.data) {
              this.selectPoint = null;
              content.button.selected = false;
          }
          else {
              this.selectPoint = content.data;
              content.button.selected = true;
          }
      }
      refreshList() {
          this.listAction.setListData(["move", "atk", "die"]);
          let roleList = [];
          let roleMap = db.get_role_db_map();
          for (let k in roleMap) {
              let roleDb = roleMap[k];
              let roleModeDb = db.get_role_model_db(roleDb.model_id);
              if (roleModeDb && !roleModeDb.spine) {
                  roleList.push(roleDb);
              }
          }
          this.listAnim.setListData(roleList);
      }
      initEvent() {
          Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDown);
          Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      removeEvent() {
          Laya.stage.off(Laya.Event.KEY_DOWN, this, this.onKeyDown);
          Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      onKeyDown(e) {
          switch (e.keyCode) {
              case Laya.Keyboard.UP:
                  this.animation.y -= 1;
                  this.onConfigChange();
                  break;
              case Laya.Keyboard.DOWN:
                  this.animation.y += 1;
                  this.onConfigChange();
                  break;
              case Laya.Keyboard.LEFT:
                  this.animation.x -= 1;
                  this.onConfigChange();
                  break;
              case Laya.Keyboard.RIGHT:
                  this.animation.x += 1;
                  this.onConfigChange();
                  break;
          }
      }
      parseAnimItem(content, object) {
          content.button = object.asButton;
      }
      renderAnimItem(content, data) {
          content.button.title = data;
          content.data = data;
      }
      onClickActionItem(content) {
          this.animAction = content.data;
          this.play();
      }
      parseRoleItem(content, object) {
          content.button = object.asButton;
      }
      renderRoleItem(content, data) {
          content.button.title = data.name;
          content.data = data;
      }
      onClickRoleItem(content) {
          this.selectRoleDb = content.data;
          this.selectRoleModelDb = db.get_role_model_db(this.selectRoleDb.model_id);
          this.play();
      }
      play() {
          if (!this.selectRoleDb || !this.selectRoleModelDb)
              return;
          let listData = [];
          listData.push(this.selectRoleModelDb.action_atk);
          listData.push(this.selectRoleModelDb.action_die);
          listData.push(this.selectRoleModelDb.action_move);
          listData.push(this.selectRoleModelDb.action_skill);
          this.listAction.setListData(listData);
          AtlasHelper.loadAtlas(this.selectRoleModelDb.res, this.playAnim.bind(this));
      }
      playAnim() {
          let name = this.getAnimName();
          if (name) {
              this.animation.play(0, true, name);
              let cfg = AnimationHelper.getAnimationConfig(name);
              if (cfg) {
                  this.animation.x = cfg.x;
                  this.animation.y = cfg.y;
              }
              if (this.selectRoleDb && this.selectRoleModelDb)
                  this.loadSpinePoint(this.selectRoleDb, this.selectRoleModelDb);
              console.log("播放动画", name);
          }
      }
      getAnimName() {
          if (this.selectRoleModelDb && this.selectRoleModelDb.anim && this.animAction) {
              return this.selectRoleModelDb.anim + "_" + this.animAction;
          }
          else {
              return null;
          }
      }
      onConfigChange() {
          let anim = this.getAnimName();
          if (anim) {
              AnimationHelper.updateAnimtionConfig(anim, this.animation.x, this.animation.y);
              console.log("保存Animation帧配置", anim, this.animation.x, this.animation.y);
          }
      }
      onPointConfigChange() {
          if (this.selectRoleDb && this.selectRoleModelDb && this.listPointData) {
              let data = { points: [] };
              for (let item of this.listPointData) {
                  data.points.push({ x: Math.round(item.view.x), y: Math.round(item.view.y) });
              }
              PointHelper.setPointConfig(this.selectRoleModelDb.id, data);
              console.log("保存Spine帧配置", this.selectRoleModelDb.id, data);
          }
      }
      save() {
          AnimationHelper.saveConifg();
          PointHelper.saveConifg();
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          this.lastx = x;
          this.lasty = y;
      }
      onMouseMove() {
          if (!this.isMouseDown)
              return;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let dx = x - this.lastx;
          let dy = y - this.lasty;
          this.lastx = x;
          this.lasty = y;
          if (this.selectPoint) {
              this.selectPoint.view.x += dx;
              this.selectPoint.view.y += dy;
          }
      }
      onMouseUp() {
          this.isMouseDown = false;
          if (this.selectPoint) {
              this.onPointConfigChange();
          }
      }
      on_click_btn_close() {
          this.save();
          this.close();
      }
      on_click_button_save() {
          this.save();
      }
      on_click_button_flip() {
          this.com_center.scaleX = -this.com_center.scaleX;
      }
  }

  class PanelEditBullet extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://editor/PanelEditBullet";
          this.panelStyle = 1;
          this.bMask = false;
          this.isMouseDown = false;
          this.lastx = 0;
          this.lasty = 0;
          this.exportNodeNames = {
              cc_input_search: "fgui.GTextInput",
              cc_com_center: "fgui.GComponent",
              cc_btn_close: "fgui.GButton",
              cc_button_save: "fgui.GButton",
              cc_scale_bar: "CustomScaleBar",
              cc_list_effect: "fgui.GList",
              cc_list_bullet: "fgui.GList",
              cc_list_element: "fgui.GList",
              cc_list_effect_menu: "fgui.GList",
              cc_list_element_menu: "fgui.GList",
              cc_node_effect: "fgui.GLoader",
          };
      }
      buildUi() {
          Laya.Stat.hide();
          GameRemoteRouter.instance;
          this.resNode.makeFullScreen();
          this.listEffectMenu = new ListView(this.list_effect_menu, this, this.parseMenuItem, this.renderMenuItem);
          this.listEffectMenu.setOnClickItem(this, this.onClickMenuItem);
          this.listElementMenu = new ListView(this.list_element_menu, this, this.parseMenuItem, this.renderMenuItem);
          this.listElementMenu.setOnClickItem(this, this.onClickMenuItem);
          this.listEffect = new ListView(this.list_effect, this, this.parseEffectItem, this.renderEffectItem);
          this.listEffect.setOnClickItem(this, this.onClickEffectItem);
          this.listBullet = new ListView(this.list_bullet, this, this.parseBulletItem, this.renderBulletItem);
          this.listBullet.setOnClickItem(this, this.onClickBulletItem);
          this.listElement = new ListView(this.list_element, this, this.parseElementItem, this.renderElementItem);
          this.listElement.setOnClickItem(this, this.onClickElementItem);
          this.scale_bar.setTarget(this.com_center);
          this.refreshBulletList();
          this.refreshEffectList();
          this.refreshMenuList();
          this.initEvent();
          this.loadConfig();
      }
      initEvent() {
          Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
          this.input_search.on(Laya.Event.INPUT, this, this.onInputSearchChange);
      }
      removeEvent() {
          Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      onInputSearchChange() {
          let text = this.input_search.text;
          this.refreshEffectList(text);
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          this.lastx = x;
          this.lasty = y;
      }
      onMouseMove() {
          if (!this.isMouseDown)
              return;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let dx = x - this.lastx;
          let dy = y - this.lasty;
          this.lastx = x;
          this.lasty = y;
          if (this.selectElement && this.selectElement.node2d) {
              this.selectElement.node2d.x += dx;
              this.selectElement.node2d.y += dy;
          }
          else {
              this.com_center.x += dx;
              this.com_center.y += dy;
          }
      }
      onMouseUp() {
          this.isMouseDown = false;
          this.onBulletConfigChange();
      }
      refreshBulletList() {
          let dataMap = db.get_bullet_db_map();
          let listData = [];
          for (let key1 in dataMap) {
              let item = db.get_bullet_db(key1);
              listData.push(item);
          }
          listData.sort(this.sortBullet);
          this.listBullet.setListData(listData);
      }
      sortBullet(a, b) {
          return a.index - b.index;
      }
      refreshEffectList(search = null) {
          let dataMap = db.get_model_db_map();
          let listData = [];
          for (let key in dataMap) {
              let item = db.get_model_db(key);
              if (search) {
                  if (item.id.indexOf(search) >= 0) {
                      listData.push(item);
                  }
              }
              else {
                  listData.push(item);
              }
          }
          this.listEffect.setListData(listData);
      }
      refreshMenuList() {
          this.listEffectMenu.setListData(["添加"]);
          this.listElementMenu.setListData(["删除", "清除"]);
      }
      refreshBulletElement() {
          if (this.currentBullet)
              this.listElement.setListData(this.currentBullet.listEffect);
      }
      dispose() {
          this.clearEffectShow();
          this.removeEvent();
          super.dispose();
      }
      parseMenuItem(content, object) {
          content.button = object.asButton;
      }
      renderMenuItem(content, name) {
          content.button.title = name;
          content.action = name;
      }
      onClickMenuItem(content) {
          switch (content.action) {
              case "添加":
                  this.addBulletEffect();
                  break;
              case "删除":
                  this.delBulletEffect();
                  break;
              case "清除":
                  this.clearBulletEffect();
                  break;
          }
      }
      parseEffectItem(content, object) {
          content.button = object.asButton;
      }
      renderEffectItem(content, data) {
          content.button.title = data.id;
          content.data = data;
      }
      onClickEffectItem(content) {
          this.selectEffectDb = content.data;
          this.createEffectShow(content.data);
      }
      createEffectShow(effectDb) {
          this.clearEffectShow();
          let data = Director.getScene3DLayer(1);
          let effect = EffectFactory.create(effectDb.id, data.scene3d);
          effect.followNode2d(data.camera, this.node_effect.displayObject);
          effect.getNode().transform.localRotationEulerZ = -90;
          this.effectShow = effect;
      }
      clearEffectShow() {
          if (this.effectShow) {
              this.effectShow.clear();
              this.effectShow = null;
          }
      }
      parseBulletItem(content, object) {
          content.button = object.asButton;
      }
      renderBulletItem(content, data) {
          content.data = data;
          content.button.title = data.id;
      }
      onClickBulletItem(content) {
          this.loadBullet(content.data);
      }
      parseElementItem(content, object) {
          content.button = object.asButton;
      }
      renderElementItem(content, effect) {
          content.button.title = effect.effectId;
          content.effect = effect;
      }
      onClickElementItem(content) {
          if (this.selectElement == content.effect) {
              this.selectElement = null;
              content.button.selected = false;
          }
          else {
              this.selectElement = content.effect;
              content.button.selected = true;
          }
          this.listElement.refresh();
      }
      loadBullet(bulletDb) {
          this.clearBullet();
          var bullet = FactoryBullet.createBulletByClas(Bullet, bulletDb, false);
          this.currentBullet = bullet;
          this.com_center.displayObject.addChild(bullet.node);
          this.refreshBulletElement();
      }
      clearBullet() {
          if (this.currentBullet) {
              this.currentBullet.remove();
              this.currentBullet = null;
          }
      }
      addBulletEffect() {
          if (this.currentBullet && this.selectEffectDb) {
              this.currentBullet.createEffect(this.selectEffectDb.id);
              this.refreshBulletElement();
              this.onBulletConfigChange();
          }
      }
      delBulletEffect() {
          if (this.currentBullet && this.selectElement) {
              this.currentBullet.deleteEffect(this.selectElement);
              this.selectElement = null;
              this.refreshBulletElement();
              this.onBulletConfigChange();
          }
      }
      clearBulletEffect() {
          if (this.currentBullet) {
              this.currentBullet.clearEffect();
              this.selectElement = null;
              this.refreshBulletElement();
              this.onBulletConfigChange();
          }
      }
      onBulletConfigChange() {
          if (this.currentBullet) {
              let config = [];
              for (let effect of this.currentBullet.listEffect) {
                  if (effect.flagSave && effect.node2d)
                      config.push({ id: effect.effectId, x: effect.node2d.x, y: effect.node2d.y });
              }
              FactoryBullet.setBulletConfig(this.currentBullet.bulletDb.id, config);
              console.log("保存子弹配置", FactoryBullet.jsonBulletConfig);
          }
      }
      loadConfig() {
          FactoryBullet.loadConfig();
      }
      saveConifg() {
          if (!GameRemoteRouter.instance) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存子弹配置!");
              let data = FactoryBullet.jsonBulletConfig || {};
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: FactoryBullet.pathConfig,
                      data: data,
                  },
              });
          }
      }
      on_click_btn_close() {
          this.close();
      }
      on_click_button_save() {
          this.saveConifg();
      }
  }

  let gridW$1 = 20;
  let gridH$1 = 20;
  let tileW$1 = Level.tileW;
  let tileH$1 = Level.tileH;
  let gridCenterX$1 = Math.floor(gridW$1 / 2) - 1;
  let gridCenterY$1 = Math.floor(gridH$1 / 2) - 1;
  let space$1 = 4;
  let space_half = Math.floor(space$1 / 2);
  class PanelEditHIt extends PanelBase {
      constructor() {
          super(...arguments);
          this.panelLayer = 1;
          this.sourceName = "ui://editor/PanelEditHIt";
          this.flipX = 1;
          this.hitAreaPoint = null;
          this.selectSkillId = null;
          this.isMouseDown = false;
          this.lastx = 0;
          this.lasty = 0;
          this.exportNodeNames = {
              cc_com_bg: "fgui.GComponent",
              cc_com_center: "fgui.GComponent",
              cc_layer_touch: "fgui.GComponent",
              cc_btn_close: "fgui.GButton",
              cc_button_save: "fgui.GButton",
              cc_btn_clear: "fgui.GButton",
              cc_btn_flip: "fgui.GButton",
              cc_list_skill: "fgui.GList",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          GameRemoteRouter.instance;
          this.graphicsWorld = this.com_center.displayObject.graphics;
          this.listSkill = new ListView(this.list_skill, this, this.parseSkillItem, this.renderSkillItem);
          this.listSkill.setOnClickItem(this, this.onClickSkillItem);
          this.drawGrid(this.com_center.displayObject.graphics);
          this.initEvent();
          this.refreshSkillList();
          Global.sendMsg(MSG.STAGE_DESTROY);
          HitAreaHelper.loadConfig();
      }
      dispose() {
          this.removeEvent();
          super.dispose();
      }
      refreshSkillList() {
          let listData = [];
          let skillMap = db.get_skill_db_map();
          for (let k in skillMap) {
              let skillDb = db.get_skill_db(k);
              if (skillDb.use_hit_area)
                  listData.push(skillDb);
          }
          this.listSkill.setListData(listData);
      }
      parseSkillItem(content, object) {
          content.button = object.asButton;
      }
      renderSkillItem(content, data) {
          content.button.title = data.name;
          content.data = data;
      }
      ;
      onClickSkillItem(content) {
          if (!content)
              return;
          this.selectContent = content;
          this.clearBullet();
          this.selectSkillId = content.data.id;
          this.hitAreaPoint = HitAreaHelper.getHitArea(this.selectSkillId);
          this.drawHitArea(this.hitAreaPoint);
          let skillDb = content.data;
          if (skillDb.effect_lock.length) {
              for (let effectId of skillDb.effect_lock) {
                  EffectFactory.createByType(effectId, this.com_center.displayObject, { x: 0, y: 0 });
              }
          }
          if (skillDb.effect_hit) {
              let effect = EffectFactory.createByType(skillDb.effect_hit, this.com_center.displayObject, { x: 0, y: 0 });
              let node = effect.node;
              node.scaleX = this.flipX * Math.abs(node.scaleX);
          }
          if (skillDb.effect_shoot) {
              let effect = EffectFactory.createByType(skillDb.effect_shoot, this.com_center.displayObject, { x: 0, y: 0 });
              let node = effect.node;
              node.scaleX = this.flipX * Math.abs(node.scaleX);
          }
          if (skillDb.effect_cast) {
              let effect = EffectFactory.createByType(skillDb.effect_cast, this.com_center.displayObject, { x: 0, y: 0 }, null, null, null, null);
              let node = effect.node;
              if (node instanceof Laya.Sprite) {
                  node.scaleX = this.flipX * Math.abs(node.scaleX);
              }
              else if (node instanceof Laya.Sprite3D) {
                  if (this.flipX > 0) {
                      node.transform.localRotationEulerY = 0;
                  }
                  else {
                      node.transform.localRotationEulerY = 180;
                  }
              }
          }
          let bulletDb = db.get_bullet_db(skillDb.bullet_id);
          if (bulletDb) {
              var bullet = FactoryBullet.createByBulletDb(bulletDb);
              this.currentBullet = bullet;
              this.com_center.displayObject.addChild(bullet.node);
              bullet.node.alpha = 0.5;
          }
      }
      clearBullet() {
          if (this.currentBullet) {
              this.currentBullet.remove();
              this.currentBullet = null;
          }
      }
      drawGrid(graphics) {
          let lineColor = "#aa000055";
          this.graphicsWorld.clear();
          let offsetX = -gridW$1 * tileW$1 / 2 - tileW$1 / 2;
          let offsetY = -gridH$1 * tileH$1 / 2 - tileH$1 / 2;
          for (let w = 0; w < gridW$1; w++) {
              for (let h = 0; h < gridH$1; h++) {
                  let color = "#00000000";
                  graphics.drawRect(offsetX + tileW$1 * w, offsetY + tileH$1 * h, tileW$1, tileH$1, color, lineColor);
              }
          }
          console.log("O_O 刷新格子");
      }
      drawGridSingle(x, y) {
          x = this.flipX * x;
          let offsetX = -tileW$1 / 2;
          let offsetY = -tileH$1 / 2;
          let lineColor = "#00aa0055";
          let color = "#00aa00aa";
          this.graphicsWorld.drawRect(offsetX + tileW$1 * x, offsetY + tileH$1 * y, tileW$1, tileH$1, color, lineColor);
      }
      initEvent() {
          this.layer_touch.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDown);
      }
      removeEvent() {
          this.layer_touch.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.off(Laya.Event.KEY_DOWN, this, this.onKeyDown);
      }
      onKeyDown(e) {
          switch (e.keyCode) {
              case Laya.Keyboard.UP:
                  this.com_center.y -= 2;
                  break;
              case Laya.Keyboard.DOWN:
                  this.com_center.y += 2;
                  break;
              case Laya.Keyboard.LEFT:
                  this.com_center.x -= 2;
                  break;
              case Laya.Keyboard.RIGHT:
                  this.com_center.x += 2;
                  break;
          }
      }
      isPointInList(x, y, list) {
          for (let i = 0; i < list.length; i = i + 2) {
              let lx = list[i];
              let ly = list[i + 1];
              if (x == lx && y == ly) {
                  return true;
              }
          }
          return false;
      }
      addPointInList(x, y, list) {
          list.push(x);
          list.push(y);
      }
      delPointInList(x, y, list) {
          for (let i = 0; i < list.length; i = i + 2) {
              let lx = list[i];
              let ly = list[i + 1];
              if (x == lx && y == ly) {
                  list.splice(i, 2);
                  return true;
              }
          }
          return false;
      }
      drawHitArea(list) {
          this.graphicsWorld.clear();
          for (let i = 0; i < list.length; i = i + 2) {
              let lx = list[i];
              let ly = list[i + 1];
              this.drawGridSingle(lx, ly);
          }
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let localPos = this.com_center.globalToLocal(x, y);
          localPos.x += tileW$1 / 2;
          localPos.y += tileH$1 / 2;
          let gx = Math.floor(localPos.x / tileW$1) * this.flipX;
          let gy = Math.floor(localPos.y / tileH$1);
          if (this.hitAreaPoint && this.selectSkillId) {
              if (!this.isPointInList(gx, gy, this.hitAreaPoint)) {
                  this.addPointInList(gx, gy, this.hitAreaPoint);
              }
              else {
                  this.delPointInList(gx, gy, this.hitAreaPoint);
              }
              this.drawHitArea(this.hitAreaPoint);
              HitAreaHelper.setHitAreaConfig(this.selectSkillId, this.hitAreaPoint);
          }
          console.log("O_O onMouseDown", gx, gy);
      }
      onMouseMove() {
      }
      onMouseUp() {
      }
      on_click_btn_close() {
          this.close();
      }
      on_click_button_save() {
          if (!GameRemoteRouter.instance) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存击中范围配置!");
              let data = HitAreaHelper.jsonHitAreaConfig || {};
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: HitAreaHelper.pathConfig,
                      data: data,
                  },
              });
          }
      }
      on_click_btn_clear() {
          if (this.hitAreaPoint && this.selectSkillId) {
              this.hitAreaPoint = [];
              this.drawHitArea(this.hitAreaPoint);
              HitAreaHelper.setHitAreaConfig(this.selectSkillId, this.hitAreaPoint);
          }
      }
      on_click_btn_flip() {
          this.flipX = -this.flipX;
          this.onClickSkillItem(this.selectContent);
      }
  }

  class PanelEditSpine extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://editor/PanelEditSpine";
          this.bClickMask = false;
          this.listPointData = [];
          this.isMouseDown = false;
          this.lastx = 0;
          this.lasty = 0;
          this.exportNodeNames = {
              cc_btn_close: "fgui.GButton",
              cc_node_spine: "fgui.GComponent",
              cc_anchor: "fgui.GGraph",
              cc_button_save: "fgui.GButton",
              cc_scale_bar: "CustomScaleBar",
              cc_list_spine: "fgui.GList",
              cc_list_point: "fgui.GList",
              cc_list_menu: "fgui.GList",
              cc_list_anim: "fgui.GList",
              cc_list_type: "fgui.GList",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          GameRemoteRouter.instance;
          this.listMenues = new ListView(this.list_menu, this, this.parseMenuItem, this.renderMenuItem);
          this.listMenues.setOnClickItem(this, this.onClickMenuItem);
          this.listSpine = new ListView(this.list_spine, this, this.parseSpineItem, this.renderSpineItem);
          this.listSpine.setOnClickItem(this, this.onClickSpineItem);
          this.listPoint = new ListView(this.list_point, this, this.parsePointItem, this.renderPointItem);
          this.listPoint.setOnClickItem(this, this.onClickPointItem);
          this.listAnim = new ListView(this.list_anim, this, this.parseAnimItem, this.renderAnimItem);
          this.listAnim.setOnClickItem(this, this.onClickAnimItem);
          this.scale_bar.setTarget(this.node_spine);
          this.initEvent();
          this.refreshList();
          this.refreshMenuList();
          this.refreshListPoint();
      }
      dispose() {
          this.removeEvent();
          super.dispose();
      }
      refreshMenuList() {
          this.listMenues.setListData(["添加", "删除", "清空"]);
      }
      parseMenuItem(content, object) {
          content.button = object.asButton;
      }
      renderMenuItem(content, name) {
          content.button.title = name;
          content.action = name;
      }
      onClickMenuItem(content) {
          switch (content.action) {
              case "添加":
                  this.addPoint();
                  break;
              case "删除":
                  this.delPoint();
                  break;
              case "清空":
                  this.clearPoint();
                  break;
          }
      }
      parseSpineItem(content, object) {
          content.button = object;
      }
      renderSpineItem(content, data, index) {
          content.data = data;
          content.button.title = data.id;
      }
      onClickSpineItem(content) {
          this.loadSpine(content.data);
      }
      parsePointItem(content, object) {
          content.button = object.asButton;
      }
      renderPointItem(content, data, index) {
          content.data = data;
          content.button.title = (index + 1).toString();
          if (this.selectPoint == data) {
              content.button.selected = true;
          }
          else {
              content.button.selected = false;
          }
      }
      onClickPointItem(content) {
          if (this.selectPoint == content.data) {
              this.selectPoint = null;
              content.button.selected = false;
          }
          else {
              this.selectPoint = content.data;
              content.button.selected = true;
          }
      }
      parseAnimItem(content, object) {
          content.button = object.asButton;
      }
      renderAnimItem(content, data) {
          content.button.title = data;
          content.data = data;
      }
      refreshAnimList(data) {
          let list = [];
          for (let i = 1; i <= 16; i++) {
              let anim = data["l" + i];
              if (anim) {
                  list.push(anim);
              }
          }
          this.listAnim.setListData(list);
      }
      onClickAnimItem(content) {
          if (this.modelSpine) {
              this.modelSpine.playAnimation(content.data, false);
              if (this.selectModelEffectDb) {
                  let modelEffect = this.selectModelEffectDb[content.data];
                  if (modelEffect) {
                      let point = this.getPoint(modelEffect.index) || this.modelSpine;
                      let effect = EffectFactory.createByType(modelEffect.effect, this.anchor.displayObject, point, null, null, null, null, null, 1);
                  }
              }
              console.warn("动画时间", content.data, this.modelSpine.getAnimTime(content.data));
          }
      }
      unloadSpine() {
          if (this.modelSpine) {
              this.modelSpine.destroy();
              this.modelSpine = null;
          }
      }
      loadSpine(data) {
          this.unloadSpine();
          this.selectSpineDb = data;
          this.selectModelEffectDb = db.get_role_model_effect_map()[data.id];
          let spine = Spine.create(data.id);
          this.anchor.displayObject.addChild(spine);
          spine.playAnimation(data.l2, false);
          this.modelSpine = spine;
          this.loadSpinePoint(data);
          this.refreshAnimList(data);
      }
      refreshList() {
          let dataMap = db.get_spine_db_map();
          let listData = [];
          for (let key in dataMap) {
              let item = db.get_spine_db(key);
              listData.push(item);
          }
          listData.sort(this.sortList);
          this.listSpine.setListData(listData);
      }
      sortList(a, b) {
          let aa = a.id.charCodeAt(0);
          let bb = b.id.charCodeAt(0);
          return aa - bb;
      }
      loadSpinePoint(spine) {
          this.clearViewPoint();
          let data = PointHelper.getPointConfig(spine.id);
          if (data) {
              for (let i = 0; i < data.points.length; i++) {
                  let p = data.points[i];
                  let point = this.createRedPoint();
                  point.x = p.x;
                  point.y = p.y;
                  this.listPointData.push({ view: point });
              }
              this.selectSpineData = data;
          }
          this.selectPoint = null;
          this.refreshListPoint();
      }
      clearViewPoint() {
          for (let item of this.listPointData) {
              item.view.dispose();
          }
          this.listPointData.length = 0;
      }
      refreshListPoint() {
          this.listPoint.setListData(this.listPointData);
      }
      createRedPoint() {
          let point = fgui.UIPackage.createObjectFromURL("ui://editor/ComRedPoint").asCom;
          this.node_spine.addChild(point);
          return point;
      }
      addPoint() {
          let point = this.createRedPoint();
          let data = { view: point };
          this.selectPoint = data;
          this.listPointData.push(data);
          this.refreshListPoint();
          this.onConfigChange();
      }
      delPoint() {
          if (this.selectPoint) {
              let newListData = [];
              for (let point of this.listPointData) {
                  if (this.selectPoint != point) {
                      newListData.push(point);
                  }
                  else {
                      point.view.dispose();
                  }
              }
              this.listPointData = newListData;
              this.selectPoint = null;
              this.refreshListPoint();
              this.onConfigChange();
          }
      }
      getPoint(index) {
          let data = this.listPointData[index];
          if (data) {
              return data.view;
          }
          return null;
      }
      clearPoint() {
          for (let point of this.listPointData) {
              point.view.dispose();
          }
          this.listPointData = [];
          this.selectPoint = null;
          this.refreshListPoint();
          this.onConfigChange();
      }
      onConfigChange() {
          if (this.selectSpineDb && this.listPointData) {
              let data = { points: [] };
              for (let item of this.listPointData) {
                  data.points.push({ x: Math.round(item.view.x), y: Math.round(item.view.y) });
              }
              PointHelper.setPointConfig(this.selectSpineDb.id, data);
              console.log("保存Spine帧配置", this.selectSpineDb.id, data);
          }
      }
      saveConifg() {
          if (!GameRemoteRouter.instance) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存Spine配置!");
              let data = PointHelper.jsonPointConfig || {};
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: PointHelper.pathConfig,
                      data: data,
                  },
              });
          }
      }
      initEvent() {
          Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      removeEvent() {
          Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          this.lastx = x;
          this.lasty = y;
      }
      onMouseMove() {
          if (!this.isMouseDown)
              return;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let dx = x - this.lastx;
          let dy = y - this.lasty;
          this.lastx = x;
          this.lasty = y;
          if (this.selectPoint) {
              this.selectPoint.view.x += dx;
              this.selectPoint.view.y += dy;
          }
          else {
              this.node_spine.x += dx;
              this.node_spine.y += dy;
          }
      }
      onMouseUp() {
          this.isMouseDown = false;
          this.onConfigChange();
      }
      on_click_btn_close() {
          this.close();
      }
      on_click_button_save() {
          this.saveConifg();
      }
  }

  class PanelEditTrajectory extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://editor/PanelEditTrajectory";
          this.panelStyle = 1;
          this.bMask = false;
          this.isMouseDown = false;
          this.lastx = 0;
          this.lasty = 0;
          this.exportNodeNames = {
              cc_layer_game: "fgui.GComponent",
              cc_point_player: "fgui.GComponent",
              cc_point_enemy: "fgui.GComponent",
              cc_layer_touch: "fgui.GComponent",
              cc_btn_close: "fgui.GButton",
              cc_button_save: "fgui.GButton",
              cc_list_bullet: "fgui.GList",
              cc_list_menu: "fgui.GList",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          Global.sendMsg(MSG.STAGE_DESTROY);
          this.listBullet = new ListView(this.list_bullet, this, this.parseBulletItem, this.renderBulletItem);
          this.listBullet.setOnClickItem(this, this.onClickBulletItem);
          this.initEvent();
          this.refreshBulletList();
      }
      dispose() {
          this.removeEvent();
          super.dispose();
      }
      initEvent() {
          this.layer_touch.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          this.layer_touch.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          this.layer_touch.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
          Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDown);
      }
      removeEvent() {
          this.layer_touch.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown);
          this.layer_touch.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
          this.layer_touch.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
          Laya.stage.off(Laya.Event.KEY_DOWN, this, this.onKeyDown);
      }
      onMouseDown() {
          this.isMouseDown = true;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          this.lastx = x;
          this.lasty = y;
      }
      onMouseMove() {
          if (!this.isMouseDown)
              return;
          let x = Laya.MouseManager.instance.mouseX / Laya.stage.clientScaleX;
          let y = Laya.MouseManager.instance.mouseY / Laya.stage.clientScaleY;
          let dx = x - this.lastx;
          let dy = y - this.lasty;
          this.lastx = x;
          this.lasty = y;
          this.point_enemy.x += dx;
          this.point_enemy.y += dy;
      }
      onMouseUp() {
          this.isMouseDown = false;
      }
      onKeyDown() {
          this.loadBullet();
      }
      refreshBulletList() {
          let dataMap = db.get_bullet_db_map();
          let listData = [];
          for (let key1 in dataMap) {
              let item = db.get_bullet_db(key1);
              listData.push(item);
          }
          listData.sort(this.sortBullet);
          this.listBullet.setListData(listData);
      }
      sortBullet(a, b) {
          return a.index - b.index;
      }
      parseBulletItem(content, object) {
          content.button = object.asButton;
      }
      renderBulletItem(content, data) {
          content.data = data;
          content.button.title = data.name + data.desc;
      }
      onClickBulletItem(content) {
          this.selectBulletDb = content.data;
          this.loadBullet();
      }
      clearBullet() {
          if (this.currentBullet) {
              this.currentBullet.remove();
              this.currentBullet = null;
          }
      }
      loadBullet() {
          let bulletDb = this.selectBulletDb;
          if (bulletDb) {
              this.clearBullet();
              var bullet = FactoryBullet.createByBulletDb(bulletDb);
              let skillDb = db.get_skill_db(bulletDb.id);
              if (skillDb) {
                  bullet.effect_hit = skillDb.effect_hit;
              }
              this.currentBullet = bullet;
              bullet.born(this.layer_game.displayObject);
              let time = 0.5;
              let fx = this.point_player.x;
              let fy = this.point_player.y;
              bullet.node.x = fx;
              bullet.node.y = fy;
              bullet.shootTarget(time, this.point_enemy);
          }
      }
      on_click_btn_close() {
          this.close();
      }
      on_click_button_save() {
          this.close();
      }
  }

  class mgrExplore extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static onStart() {
          this.buildShopIds();
          this.buildMapId();
      }
      static onDifferentDay() {
          let count = mgrGame.getItemCount(1018);
          if (count < db.game_cnf.explore_daily_count) {
              BaseFacade.mItem.setItem(1018, db.game_cnf.explore_daily_count);
          }
          BaseFacade.mItem.setItem(1019, 0);
          this.data.holyid2count = {};
          this.data.shopad = 0;
          this.buildShopIds(true);
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
              this.onDifferentDay();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrExplore.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static setShopCount(shopIndex, count) {
          this.data.shopidx2count[shopIndex] = count;
          this.saveRecord();
      }
      static getShopCount(shopIndex) {
          return this.data.shopidx2count[shopIndex] || 0;
      }
      static addShopCount(shopIndex, add = 1) {
          this.setShopCount(shopIndex, this.getShopCount(shopIndex) + add);
      }
      static getShopLeftCountByDB(data, index) {
          let left = 0;
          if (data) {
              left = data.limit - this.getShopCount(index);
              if (left < 0)
                  left = 0;
          }
          return left;
      }
      static canBuyByDB(data, index) {
          return this.getShopCount(index) < data.limit;
      }
      static tryBuyShop(data, index) {
          if (mgrHolyItem.notEnoughEmptyByItemId(data.item_id, 8))
              return;
          if (data && this.canBuyByDB(data, index) && mgrGame.subItem(data.price_item_id, data.price_item_cost, 70)) {
              this.addShopCount(index, 1);
              mgrGame.addItem(data.item_id, data.item_num, 62, true);
              Global.sendMsg(MSG.EXPLORE_SHOP_REFRESH);
          }
      }
      static setHolyCount(shopId, count) {
          this.data.holyid2count[shopId] = count;
          this.saveRecord();
      }
      static getHolyCount(shopId) {
          return this.data.holyid2count[shopId] || 0;
      }
      static addHolyCount(shopId, add = 1) {
          this.setHolyCount(shopId, this.getHolyCount(shopId) + add);
      }
      static tryBuyHolyItem(data) {
          if (mgrHolyItem.notEnoughEmpty(1))
              return;
          if (data && mgrGame.subItem(data.price_item_id, data.price_item_cost, 70)) {
              mgrGame.addItem(data.item_id, data.item_num, 62, true);
              Global.sendMsg(MSG.EXPLORE_HOLY_REFRESH);
          }
      }
      static buildShopIds(force = false) {
          if (this.data.shopids.length == 0 || force) {
              let listShop = [];
              let shopMap = db.get_explore_shop_db_map();
              for (let id in shopMap) {
                  let shopDb = db.get_explore_shop_db(id);
                  listShop.push(shopDb);
              }
              this.data.shopids.length = 0;
              for (let i = 0; i < 8; i++) {
                  let shopDb = StageTool.calcWeightItem(listShop);
                  if (shopDb) {
                      this.data.shopids.push(shopDb.id);
                  }
              }
              this.data.shopidx2count = {};
              this.saveRecord();
          }
      }
      static getShopDbs() {
          let listShop = [];
          for (let id of this.data.shopids) {
              let shopDb = db.get_explore_shop_db(id);
              if (shopDb)
                  listShop.push(shopDb);
          }
          return listShop;
      }
      static getExplorePoint(pointId) {
          return this.data.points[pointId] || {};
      }
      static setExplorePoint(pointId, data) {
          this.data.points[pointId] = data;
          this.saveRecord();
      }
      static beginExplorePoint(pointId, towerIds) {
          let data = this.getExplorePoint(pointId);
          if (!data) {
              return false;
          }
          let hourDb = db.get_explore_time(data.hourId - 1);
          if (!hourDb) {
              return false;
          }
          if (towerIds.length < hourDb.popu) {
              mgrTip.showMsgTip("当前探索人数不足");
              return false;
          }
          if (!mgrGame.subItem(1018, 1, 70)) {
              return false;
          }
          data.time = mgrTime.curtTime();
          data.towerIds = towerIds;
          this.setExplorePoint(pointId, data);
          Global.sendMsg(MSG.EXPLORE_POINT_BEGIN);
          return true;
      }
      static subExplorePointTime(pointId) {
          let data = this.getExplorePoint(pointId);
          if (!data) {
              return;
          }
          let hourDb = db.get_explore_time(data.hourId - 1);
          if (!hourDb) {
              return;
          }
          let addTime = Math.ceil(hourDb.hour * 0.5 * 3600);
          data.time -= addTime;
          data.watchad = 1;
          this.setExplorePoint(pointId, data);
      }
      static isExploring(data) {
          if (!data)
              return false;
          let hourDb = db.get_explore_time(data.hourId - 1);
          if (!hourDb) {
              return false;
          }
          if (data.time <= 0) {
              return false;
          }
          let passTime = mgrTime.curtTime() - data.time;
          if (passTime < 0)
              return true;
          return passTime < hourDb.hour * 3600;
      }
      static isExploreComplete(data) {
          if (!data)
              return false;
          let hourDb = db.get_explore_time(data.hourId - 1);
          if (!hourDb) {
              return false;
          }
          if (data.time <= 0) {
              return false;
          }
          let passTime = mgrTime.curtTime() - data.time;
          if (passTime < 0)
              return false;
          return passTime >= hourDb.hour * 3600;
      }
      static findRandItemCount(itemId, items) {
          for (let i = 0; i < items.length; i += 2) {
              let id = items[i];
              let cn = items[i + 1];
              if (id && cn) {
                  if (id == itemId) {
                      return cn;
                  }
              }
          }
          return 0;
      }
      static calcMapRefresh() {
          let mapDb = db.get_explore_map(this.mapId - 1);
          if (mapDb) {
              let countComplete = 0;
              for (let i = 0; i < mapDb.point_num; i++) {
                  let data = this.getExplorePoint(i);
                  if (data && data.reward) {
                      countComplete++;
                  }
              }
              if (countComplete >= mapDb.point_num) {
                  this.buildMapId(true);
              }
          }
      }
      static calcBuffCount(buffDb, towerIds) {
          let count = 0;
          if (buffDb) {
              let towerIdFilter = {};
              for (let id of buffDb.tower_ids) {
                  towerIdFilter[id] = true;
              }
              for (let id of towerIds) {
                  if (towerIdFilter[id]) {
                      count++;
                  }
              }
          }
          return count;
      }
      static getExploreReward(pointId) {
          let pointData = this.getExplorePoint(pointId);
          if (pointData && !pointData.reward && this.isExploreComplete(pointData)) {
              let dropData = [];
              let hourDb = db.get_explore_time(pointData.hourId - 1);
              let buffDb = db.get_explore_buff(pointData.buffId - 1);
              if (hourDb && buffDb) {
                  let itemIdRand = pointData.itemIdRand;
                  let itemCnRand = this.findRandItemCount(itemIdRand, hourDb.item_rand);
                  if (mgrHolyItem.notEnoughEmptyByItemId(itemIdRand, 8)) {
                      return;
                  }
                  let buffCn = this.calcBuffCount(buffDb, pointData.towerIds);
                  let buffFactor = 1 + buffCn * buffDb.add;
                  let itemIdFix = hourDb.item_fix[0] || 0;
                  let ItemCnFix = Math.round((hourDb.item_fix[1] || 0) * Utils.randomRange(0.8, 1.2) * buffFactor);
                  mgrGame.addItem(itemIdFix, ItemCnFix, 70, false, dropData);
                  let itemType = mgrGame.getItemType(itemIdRand);
                  if (itemType == 1 || itemType == 5) {
                      itemCnRand = Math.round(itemCnRand * Utils.randomRange(0.8, 1.2) * buffFactor);
                  }
                  mgrGame.addItem(itemIdRand, itemCnRand, 70, false, dropData);
              }
              pointData.reward = true;
              this.setExplorePoint(pointId, pointData);
              Level.showItemGet(dropData);
              this.calcMapRefresh();
              Global.sendMsg(MSG.EXPLORE_POINT_COMPLETE);
          }
      }
      static getLeftTime(data) {
          let hourDb = db.get_explore_time(data.hourId - 1);
          if (!hourDb) {
              return 0;
          }
          let passTime = mgrTime.curtTime() - data.time;
          if (passTime < 0)
              return 0;
          let leftTime = hourDb.hour * 3600 - passTime;
          if (leftTime < 0)
              leftTime = 0;
          return leftTime;
      }
      static getAllExploreTower() {
          let allTowerId = {};
          for (let k in this.data.points) {
              let data = this.data.points[k];
              if (data && data.towerIds && this.isExploring(data)) {
                  for (let id of data.towerIds) {
                      allTowerId[id] = true;
                  }
              }
          }
          return allTowerId;
      }
      static allComplete() {
          for (let k in this.data.points) {
              let data = this.data.points[k];
              if (data && this.isExploring(data)) {
                  let hourDb = db.get_explore_time(data.hourId - 1);
                  if (hourDb) {
                      data.time -= hourDb.hour * 3600;
                  }
              }
          }
          this.saveRecord();
      }
      static set mapId(v) {
          this.data.mapId = v;
          this.saveRecord();
      }
      static get mapId() {
          return this.data.mapId;
      }
      static set autoId(v) {
          this.data.autoId = v;
          this.saveRecord();
      }
      static get autoId() {
          return this.data.autoId;
      }
      static set shopad(v) {
          this.data.shopad = v;
          this.saveRecord();
      }
      static get shopad() {
          return this.data.shopad;
      }
      static buildMapId(force = false) {
          if (this.mapId == 0 || force) {
              let hourArr = db.get_explore_time_map();
              let mapArr = db.get_explore_map_map();
              let buffArr = db.get_explore_buff_map();
              let mapDb = Utils.randomItem(mapArr);
              if (mapDb) {
                  this.mapId = mapDb.id;
                  for (let i = 0; i < mapDb.point_num; i++) {
                      let data = this.getExplorePoint(i);
                      let hourDb = Utils.randomItem(hourArr);
                      let buffDb = buffArr[(this.autoId++) % buffArr.length];
                      let itemArr = [];
                      for (let j = 0; j < hourDb.item_rand.length; j += 2) {
                          let itemId = hourDb.item_rand[j];
                          let itemCn = hourDb.item_rand[j + 1];
                          if (itemId && itemCn) {
                              itemArr.push(itemId);
                          }
                      }
                      data.hourId = hourDb.id;
                      data.buffId = buffDb.id;
                      data.reward = false;
                      data.towerIds = null;
                      data.time = 0;
                      data.itemIdRand = Utils.randomItem(itemArr);
                      data.watchad = 0;
                      this.setExplorePoint(i, data);
                  }
                  Global.sendMsg(MSG.EXPLORE_MAP_REFRESH);
              }
          }
      }
      static canBuyExploreCount() {
          return mgrGame.getItemCount(1019) < db.game_cnf.explore_count_buy_ad;
      }
      static getBuyExploreLeftCount() {
          let left = db.game_cnf.explore_count_buy_ad - mgrGame.getItemCount(1019);
          return Math.max(left, 0);
      }
  }
  mgrExplore.RECORD_KEY = "game166_explore_v1.0";
  mgrExplore.dataDefault = {
      shopidx2count: {},
      holyid2count: {},
      shopids: [],
      points: {},
      mapId: 0,
      autoId: 0,
      shopad: 0,
  };

  class CustomExploreHead extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExploreHead";
          this.pointId = 0;
          this.exportNodeNames = {
              cc_loader_hero: "fgui.GLoader",
              cc_label_left: "fgui.GBasicTextField",
              cc_button_ad: "fgui.GButton",
              cc_button_complete: "fgui.GButton",
              cc_button_add: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      onCreate() {
          this.ctrl_state.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
      }
      dispose() {
          super.dispose();
      }
      onStateChange() {
          switch (this.ctrl_state.selectedIndex) {
              case 1:
                  mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.explore_sub_time);
                  break;
          }
      }
      refreshByPointId(i) {
          this.pointId = i;
          this.refresh();
          this.refreshLeftTime();
          FguiHelper.playIdleAndIn(this, i, 0.5, 0.05);
      }
      refresh() {
          this.button_ad.visible = false;
          let pointData = mgrExplore.getExplorePoint(this.pointId);
          if (pointData) {
              if (pointData.time) {
                  let towerDb = db.get_tower_db_map()[pointData.towerIds[0]];
                  if (towerDb) {
                      this.loader_hero.url = towerDb.icon_small;
                  }
                  if (mgrExplore.isExploring(pointData)) {
                      let watchad = pointData.watchad || 0;
                      if (watchad == 0) {
                          let hourDb = db.get_explore_time(pointData.hourId - 1);
                          if (hourDb) {
                              this.button_ad.title = "减少" + (hourDb.hour * 0.5).toFixed(1) + "h";
                          }
                          this.button_ad.visible = true;
                      }
                      this.ctrl_state.selectedIndex = 1;
                  }
                  else {
                      if (pointData.reward) {
                          this.ctrl_state.selectedIndex = 3;
                      }
                      else {
                          this.ctrl_state.selectedIndex = 2;
                      }
                  }
              }
              else {
                  this.ctrl_state.selectedIndex = 0;
              }
          }
      }
      refreshLeftTime() {
          let pointData = mgrExplore.getExplorePoint(this.pointId);
          if (pointData) {
              if (this.ctrl_state.selectedIndex == 1) {
                  let leftTime = mgrExplore.getLeftTime(pointData);
                  this.label_left.text = Utils.cdTimeFormat(leftTime);
                  if (leftTime <= 0) {
                      this.refresh();
                  }
              }
          }
      }
      on_click_button_complete() {
          mgrExplore.getExploreReward(this.pointId);
      }
      on_click_button_add() {
          if (!mgrGame.checkItem(1018, 1, false)) {
              mgrTip.showMsgTip("当前探索次数不足");
              return;
          }
          Director.openPanelWithSingleton("PanelExploreSelectHero", { pointId: this.pointId });
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.explore_sub_time, this.pointId);
      }
  }

  class CustomExploreHolyItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExploreHolyItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_buy: "fgui.GButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_load_head: "fgui.GLoader",
              cc_ctrl_soldout: "fgui.Controller",
          };
      }
      onCreate() {
          this.item.setOnClickCallback(this.onClickItem.bind(this));
      }
      dispose() {
          super.dispose();
      }
      onClickItem() {
          Director.openPanelWithSingleton("PanelExploreItemInfo", { shopDb: this.shopDb });
          return true;
      }
      getTowerHead(towerId) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              return towerDb.icon_head;
          }
          return "";
      }
      refresh(data) {
          this.shopDb = data;
          if (!data.invalid) {
              this.item.refreshById(data.item_id, data.item_num);
              this.label_title.text = mgrGame.getItemName(data.item_id);
              this.button_buy.title = data.price_item_cost.toString();
              this.button_buy.icon = mgrGame.getItemIcon(data.price_item_id);
              this.load_head.url = this.getTowerHead(data.tower_id);
          }
          this.ctrl_soldout.selectedIndex = data.invalid ? 1 : 0;
      }
      on_click_button_buy() {
          if (this.shopDb) {
              mgrExplore.tryBuyHolyItem(this.shopDb);
          }
      }
  }

  class CustomExploreShopItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExploreShopItem";
          this.shopIndex = 0;
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_buy: "fgui.GButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_ctrl_soldout: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data, index) {
          this.shopDb = data;
          this.shopIndex = index;
          this.item.refreshById(data.item_id, data.item_num);
          this.label_title.text = mgrGame.getItemName(data.item_id);
          this.label_left.text = mgrExplore.getShopLeftCountByDB(data, index) + "/" + data.limit;
          this.button_buy.title = data.price_item_cost.toString();
          this.button_buy.icon = mgrGame.getItemIcon(data.price_item_id);
          this.button_buy.enabled = mgrExplore.canBuyByDB(data, index);
          this.ctrl_soldout.selectedIndex = mgrExplore.canBuyByDB(data, index) ? 0 : 1;
      }
      on_click_button_buy() {
          if (this.shopDb) {
              mgrExplore.tryBuyShop(this.shopDb, this.shopIndex);
          }
      }
  }

  class CustomExploreTowerItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExploreTowerItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_select: "fgui.Controller",
              cc_ctrl_explore: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data, isExploring) {
          let quality = mgrTower.getTowerQualityByDB(data);
          this.loader_icon.icon = data.icon_small;
          this.ctrl_quality.selectedIndex = quality;
          this.ctrl_explore.selectedIndex = isExploring ? 1 : 0;
      }
      select() {
          this.ctrl_select.selectedIndex = 1;
      }
      unselect() {
          this.ctrl_select.selectedIndex = 0;
      }
      isSelected() {
          return this.ctrl_select.selectedIndex == 1;
      }
  }

  class CustomExplorePage1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExplorePage1";
          this.bInited = false;
          this.exportNodeNames = {
              cc_button_add: "ScaleButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_loader_map: "fgui.GComponent",
          };
      }
      init() {
          this.onFocus();
          if (this.bInited)
              return;
          this.bInited = true;
          this.listExploreHead = [];
          this.loadMap(mgrExplore.mapId);
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.refreshKey.bind(this),
              [MSG.EXPLORE_MAP_REFRESH]: this.onExploreMapRefresh.bind(this),
              [MSG.EXPLORE_POINT_BEGIN]: this.onExplorePointBegin.bind(this),
              [MSG.EXPLORE_POINT_COMPLETE]: this.onExplorePointComplete.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.explore_sub_time) {
                      this.onExploreSubTime(e.params);
                  }
              },
          });
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
          this.onUpdatePerSecond();
          this.refreshKey();
      }
      dispose() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
          super.dispose();
      }
      onExploreMapRefresh() {
          this.loadMap(mgrExplore.mapId);
      }
      onExplorePointBegin() {
          this.refreshPoint();
      }
      onExplorePointComplete() {
          this.refreshPoint();
      }
      onExploreSubTime(pointId) {
          mgrExplore.subExplorePointTime(pointId);
          this.onUpdatePerSecond();
          this.refreshPoint();
      }
      onFocus() {
      }
      onUpdatePerSecond() {
          for (let head of this.listExploreHead) {
              head.refreshLeftTime();
          }
      }
      loadMap(mapId) {
          let mapDb = db.get_explore_map(mapId - 1);
          if (mapDb) {
              this.label_name.text = mapDb.name;
              let map = fgui.UIPackage.createObjectFromURL(mapDb.map);
              if (map) {
                  this.loader_map.addChild(map);
                  this.onMapLoad(map.asCom);
              }
          }
      }
      onMapLoad(map) {
          if (this.map) {
              this.map.dispose();
              this.map = null;
          }
          this.map = map;
          let loaderMap = map.getChild("map").asLoader;
          if (loaderMap) {
              loaderMap.url = loaderMap.data;
          }
          let index = 0;
          this.listExploreHead.length = 0;
          for (let i = 0; i < map.numChildren; i++) {
              let child = map.getChildAt(i);
              if (child instanceof CustomExploreHead) {
                  this.listExploreHead.push(child);
                  child.refreshByPointId(index);
                  index++;
              }
          }
      }
      refreshPoint() {
          for (let head of this.listExploreHead) {
              head.refresh();
          }
      }
      refreshKey() {
          this.label_left.text = mgrGame.getItemCount(1018).toString();
      }
      on_click_button_add() {
          Director.openPanelWithSingleton("PanelExploreKeyAdd");
      }
  }

  class CustomExplorePage2 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExplorePage2";
          this.bInited = false;
          this.exportNodeNames = {
              cc_button_ad: "fgui.GButton",
              cc_list_shop: "fgui.GList",
          };
      }
      init() {
          this.onFocus();
          if (this.bInited)
              return;
          this.bInited = true;
          this.listShop = new ListView(this.list_shop, this, this.parseShopItem, this.renderShopItem);
          this.refreshShopList();
          Global.registerListeners(this, {
              [MSG.EXPLORE_SHOP_REFRESH]: this.onExploreShopRefresh.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.explore_refresh_shop) {
                      this.onWatchAdSucc();
                  }
              },
          });
      }
      dispose() {
          super.dispose();
      }
      onExploreShopRefresh() {
          this.listShop.refresh();
      }
      onWatchAdSucc() {
          mgrExplore.shopad = 1;
          mgrExplore.buildShopIds(true);
          this.refreshShopList();
      }
      onFocus() {
          this.refreshButton();
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.explore_refresh_shop);
      }
      parseShopItem(content, view, index) {
          content.view = view;
          if (index < 4) {
              FguiHelper.playIdleAndIn(view, index, 0, 0.1);
          }
          else {
              FguiHelper.playIdleAndIn(view, index - 4, 0.1, 0.1);
          }
      }
      renderShopItem(content, data, index) {
          content.data = data;
          content.view.refresh(data, index);
      }
      refreshShopList() {
          let listData = mgrExplore.getShopDbs();
          this.listShop.setListData(listData);
          this.refreshButton();
      }
      refreshButton() {
          this.button_ad.visible = mgrExplore.shopad ? false : true;
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.explore_refresh_shop);
      }
  }

  class CustomExplorePage3 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://explore/CustomExplorePage3";
          this.bInited = false;
          this.exportNodeNames = {
              cc_list_shop: "fgui.GList",
          };
      }
      init() {
          this.onFocus();
          if (this.bInited)
              return;
          this.bInited = true;
          this.listShop = new ListView(this.list_shop, this, this.parseShopItem, this.renderShopItem);
          this.refreshShopList();
          Global.registerListeners(this, {
              [MSG.EXPLORE_HOLY_REFRESH]: this.onExploreHolyRefresh.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      onExploreHolyRefresh() {
          this.listShop.refresh();
      }
      onFocus() {
      }
      parseShopItem(content, view, index) {
          content.view = view;
          if (index < 4) {
              FguiHelper.playIdleAndIn(view, index, 0, 0.1);
          }
          else {
              FguiHelper.playIdleAndIn(view, index - 4, 0.1, 0.1);
          }
      }
      renderShopItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshShopList() {
          let listData = [];
          let shopList = db.get_explore_holy_db_map();
          for (let k in shopList) {
              let shop = db.get_explore_holy_db(k);
              listData.push(shop);
          }
          this.listShop.setListData(listData);
      }
  }

  class PanelExplore extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "寻宝历练";
          this.sourceName = "ui://explore/PanelExplore";
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_page1: "CustomExplorePage1",
              cc_page2: "CustomExplorePage2",
              cc_page3: "CustomExplorePage3",
              cc_button_explore: "fgui.GButton",
              cc_button_shop: "fgui.GButton",
              cc_button_treasure: "fgui.GButton",
              cc_item_bar: "CustomBarItem",
              cc_button_close: "ScaleButton",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.layer_full.makeFullScreen();
          this.item_bar.setItemId(1017);
          this.item_bar.refresh();
          this.onStateChange();
      }
      dispose() {
          super.dispose();
      }
      onStateChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.page1.init();
                  break;
              case 1:
                  this.page2.init();
                  break;
              case 2:
                  this.page3.init();
                  break;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_explore() {
      }
      on_click_button_shop() {
      }
      on_click_button_treasure() {
      }
  }

  class PanelExploreItemInfo extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "秘藏珍宝详情";
          this.sourceName = "ui://explore/PanelExploreItemInfo";
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_button_close: "ScaleButton",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_tower: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_from: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.closeWithTransition);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          let shopDb = this.context.shopDb;
          if (shopDb) {
              this.loader_icon.url = mgrGame.getItemIcon(shopDb.item_id);
              this.label_name.text = shopDb.name;
              this.label_desc.text = shopDb.attr;
              this.label_from.text = shopDb.desc;
              this.label_tower.text = shopDb.tower;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelExploreKeyAdd extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "探索购买次数";
          this.sourceName = "ui://explore/PanelExploreKeyAdd";
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_ad: "fgui.GButton",
              cc_button_close: "fgui.GButton",
              cc_label_left: "fgui.GBasicTextField",
              cc_ctrl_buy: "fgui.Controller",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.refresh();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.explore_add) {
                      this.addExploreCount();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.explore_add);
      }
      dispose() {
          super.dispose();
      }
      addExploreCount() {
          mgrGame.addItem(1019, 1, 20, false);
          mgrGame.addItem(1018, 1, 20, false);
          this.closeWithTransition();
      }
      refresh() {
          this.label_left.text = mgrExplore.getBuyExploreLeftCount().toString();
          this.ctrl_buy.selectedIndex = mgrExplore.canBuyExploreCount() ? 0 : 1;
      }
      onClickBackground() {
          this.closeWithTransition();
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.explore_add);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelExploreSelectHero extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "派遣英雄选择";
          this.sourceName = "ui://explore/PanelExploreSelectHero";
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_type: "fgui.GBasicTextField",
              cc_label_buff: "fgui.GBasicTextField",
              cc_label_popu: "fgui.GBasicTextField",
              cc_label_hour: "fgui.GBasicTextField",
              cc_list_tower: "fgui.GList",
              cc_item_1: "CustomItem",
              cc_item_2: "CustomItem",
              cc_button_go: "fgui.GButton",
          };
      }
      buildUi() {
          this.heroFilter = mgrExplore.getAllExploreTower();
          this.towerIdMap = {};
          this.listTower = new ListView(this.list_tower, this, this.parseTowerItem, this.renderTowerItem);
          this.listTower.setOnClickItem(this, this.onClickTowerItem);
          this.refreshTowerList();
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      parseTowerItem(content, view, index) {
          content.view = view;
          let s = Math.floor(index / 6);
          FguiHelper.playIdleAndIn(view, index - 4 * s, 0.1 + 0.1 * s, 0.02);
      }
      renderTowerItem(content, data, index) {
          content.data = data;
          content.view.refresh(data, this.heroFilter[data.id]);
      }
      calcTowerCount() {
          let count = 0;
          for (let k in this.towerIdMap) {
              if (this.towerIdMap[k]) {
                  count++;
              }
          }
          return count;
      }
      calcBuffCount(buffDb) {
          let count = 0;
          if (buffDb) {
              let towerIdFilter = {};
              for (let id of buffDb.tower_ids) {
                  towerIdFilter[id] = true;
              }
              for (let k in this.towerIdMap) {
                  if (this.towerIdMap[k] && towerIdFilter[k]) {
                      count++;
                  }
              }
          }
          return count;
      }
      onClickTowerItem(content) {
          let hourDb = this.getHourDb();
          if (!hourDb)
              return;
          let view = content.view;
          let data = content.data;
          if (this.heroFilter[data.id]) {
              return;
          }
          if (view.isSelected()) {
              view.unselect();
              this.towerIdMap[data.id] = false;
          }
          else {
              let count = this.calcTowerCount();
              if (count >= hourDb.popu) {
                  mgrTip.showMsgTip("当前探索人数已满");
                  return;
              }
              view.select();
              this.towerIdMap[data.id] = true;
          }
          this.refresh();
      }
      refreshTowerList() {
          let towerDbMap = db.get_tower_db_map();
          let listData = [];
          for (let key in towerDbMap) {
              let data = db.get_tower_db(key);
              if (!data.main && mgrTower.getTowerAmount(key)) {
                  listData.push(data);
              }
          }
          listData.sort(this.sortCard.bind(this));
          this.listTower.setListData(listData);
      }
      sortCard(a, b) {
          let score_a = (this.heroFilter[a.id] ? -1 : 1) * mgrTower.calcTowerScoreExplore(a.id);
          let score_b = (this.heroFilter[b.id] ? -1 : 1) * mgrTower.calcTowerScoreExplore(b.id);
          return score_b - score_a;
      }
      getHourDb() {
          let pointData = mgrExplore.getExplorePoint(this.context.pointId);
          if (pointData) {
              return db.get_explore_time(pointData.hourId - 1);
          }
          return null;
      }
      refresh() {
          let pointData = mgrExplore.getExplorePoint(this.context.pointId);
          if (pointData) {
              let hourDb = db.get_explore_time(pointData.hourId - 1);
              let buffDb = db.get_explore_buff(pointData.buffId - 1);
              if (hourDb && buffDb) {
                  let popu = this.calcTowerCount();
                  let buff = this.calcBuffCount(buffDb);
                  this.label_hour.text = hourDb.name;
                  this.label_popu.text = popu + "/" + hourDb.popu;
                  this.label_buff.text = Math.floor(buff * buffDb.add * 100) + "%";
                  this.item_1.refreshById(hourDb.item_fix[0], 0);
                  this.item_2.refreshById(pointData.itemIdRand, 0);
                  this.label_type.text = buffDb.name;
                  this.label_desc.text = buffDb.desc;
              }
          }
      }
      getTowerIds() {
          let ids = [];
          for (let k in this.towerIdMap) {
              if (this.towerIdMap[k]) {
                  ids.push(k);
              }
          }
          return ids;
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_go() {
          if (mgrExplore.beginExplorePoint(this.context.pointId, this.getTowerIds())) {
              this.closeWithTransition();
          }
      }
  }

  class CustomFBCoinItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://fb_coin/CustomFBCoinItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_cost: "fgui.GBasicTextField",
              cc_button_challenge: "fgui.GButton",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.config = data;
          this.label_title.text = data.name;
          this.label_desc.text = data.desc;
          this.loader_icon.url = data.icon;
          this.ctrl_unlock.selectedIndex = mgrFB.isFBCoinPass(data.prev_id) ? 0 : 1;
      }
      on_click_button_challenge() {
          if (mgrGame.checkItem(1011, 1)) {
              Global.sendMsg(MSG.TOWER_FB_COIN_BEGIN, this.config);
          }
      }
  }

  class PanelFBCoin extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "金币副本";
          this.sourceName = "ui://fb_coin/PanelFBCoin";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer: "fgui.GComponent",
              cc_money_bar: "CustomBarTicket",
              cc_label_sweep: "fgui.GBasicTextField",
              cc_button_sweep: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
              cc_ctrl_sweep: "fgui.Controller",
          };
      }
      buildUi() {
          Global.registerListeners(this, {
              [MSG.TOWER_FB_COIN_BEGIN]: this.closeWithTransition.bind(this),
              [MSG.TOWER_FB_ITEM_BEGIN]: this.closeWithTransition.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.sweep_fb_coin) {
                      this.watchAdSuccess();
                  }
              },
          });
          this.layer.makeFullScreen();
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.refreshList();
          let haveSweep = mgrFB.getFBCoinMaxPass() != null;
          this.ctrl_sweep.selectedIndex = haveSweep ? 1 : 0;
          if (haveSweep) {
              this.label_sweep.text = Utils.sprintf("一键扫荡%d次已通关的最高层", db.game_cnf.fb_sweep_ticket);
              mgrGame.statisVideoShowByButton(this.button_sweep, db.ADV_DB_ADVNAME.sweep_fb_coin);
          }
      }
      dispose() {
          super.dispose();
      }
      watchAdSuccess() {
          let config = mgrFB.getFBCoinMaxPass();
          if (config) {
              let tickets = db.game_cnf.fb_sweep_ticket;
              if (mgrGame.subItem(1011, tickets, 57)) {
                  for (let i = 0; i < tickets; i++) {
                      let dropData = [];
                      let reward_ids = config.reward_ids;
                      for (let i = 0; i < reward_ids.length; i += 2) {
                          let itemId = reward_ids[i];
                          let count = reward_ids[i + 1];
                          if (itemId && count) {
                              mgrGame.addItem(itemId, count, 22, false, dropData);
                          }
                      }
                      Level.showItemGet(dropData);
                      mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_FB_COIN);
                  }
              }
          }
      }
      refreshList() {
          let listData = db.get_fb_coin_db_map();
          this.listItem.setListData(listData);
      }
      parseItem(item, view, index) {
          item.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.4, 0.1, 5);
      }
      renderItem(item, data) {
          item.view.refresh(data);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_sweep() {
          mgrNetwork.callByNetwork(() => {
              if (mgrGame.checkItem(1011, db.game_cnf.fb_sweep_ticket, true)) {
                  mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.sweep_fb_coin);
              }
          });
      }
  }

  class PanelFBDoor extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "副本入口";
          this.sourceName = "ui://fb_door/PanelFBDoor";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_node_spine: "fgui.GLoader",
              cc_button_fb_coin: "fgui.GButton",
              cc_button_fb_item: "fgui.GButton",
              cc_button_shop: "fgui.GButton",
              cc_button_fianlwar: "fgui.GButton",
              cc_ctrl_finawar: "fgui.Controller",
              cc_button_smelter: "fgui.GButton",
              cc_ctrl_smelter: "fgui.Controller",
              cc_button_damage: "fgui.GButton",
              cc_ctrl_daily_damage: "fgui.Controller",
              cc_button_weapon: "fgui.GButton",
              cc_ctrl_weapon: "fgui.Controller",
              cc_button_explore: "fgui.GButton",
              cc_ctrl_explore: "fgui.Controller",
              cc_button_close: "ScaleButton",
          };
      }
      buildUi() {
          Global.registerListeners(this, {
              [MSG.TOWER_RUSH_BEGIN]: this.closeWithTransition.bind(this),
              [MSG.TOWER_FB_COIN_BEGIN]: this.closeWithTransition.bind(this),
              [MSG.TOWER_FB_ITEM_BEGIN]: this.closeWithTransition.bind(this),
          });
          this.loadSpine();
          CopHelper.updateAdvButtonState(this.button_shop, db.ADV_DB_ADVNAME.shop_ad);
          this.ctrl_finawar.selectedIndex = mgrGame.isFinalWarUnlock() ? 1 : 0;
          this.ctrl_smelter.selectedIndex = mgrGame.isSmelterUnlock() ? 1 : 0;
          this.ctrl_daily_damage.selectedIndex = mgrGame.isDailyDamageUnlock() ? 1 : 0;
          this.ctrl_weapon.selectedIndex = mgrGame.isAllEquipUnlock() ? 1 : 0;
          this.ctrl_explore.selectedIndex = mgrGame.isExploreUnlock() ? 1 : 0;
      }
      dispose() {
          this.clearSpine();
          super.dispose();
      }
      loadSpine() {
          this.spine = Spine.create("yetai");
          if (this.spine) {
              this.node_spine.displayObject.addChild(this.spine);
              this.spine.playAnimation("idle", true);
          }
      }
      clearSpine() {
          if (this.spine) {
              this.spine.destroyAndClear();
              this.spine = null;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_fb_coin() {
          Director.openPanelWithSingleton("PanelFBCoin");
      }
      on_click_button_fb_item() {
          Director.openPanelWithSingleton("PanelFBItem");
      }
      on_click_button_shop() {
          Director.openPanelWithSingleton("PanelShop");
      }
      on_click_button_fianlwar() {
          if (mgrGame.isFinalWarUnlock(true)) {
              Director.openPanelWithSingleton("PanelFinalWar");
          }
      }
      on_click_button_smelter() {
          if (mgrGame.isSmelterUnlock(true)) {
              Director.openPanelWithSingleton("PanelSmelter");
          }
      }
      on_click_button_damage() {
          if (mgrGame.isDailyDamageUnlock(true)) {
              Director.openPanelWithSingleton("PanelDailyDamage");
          }
      }
      on_click_button_weapon() {
          if (mgrGame.isAllEquipUnlock(true)) {
              Director.openPanelWithSingleton("PanelAllTowerEquip");
          }
      }
      on_click_button_explore() {
          if (mgrGame.isExploreUnlock(true)) {
              Director.openPanelWithSingleton("PanelExplore");
          }
      }
  }

  class CustomFBItemItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://fb_item/CustomFBItemItem";
          this.exportNodeNames = {
              cc_button_challenge: "fgui.GButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.config = data;
          this.label_title.text = data.name;
          this.label_desc.text = data.desc;
          this.ctrl_unlock.selectedIndex = mgrFB.isFBItemPass(data.prev_id) ? 0 : 1;
      }
      on_click_button_challenge() {
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          if (mgrGame.checkItem(1011, 1)) {
              Global.sendMsg(MSG.TOWER_FB_ITEM_BEGIN, this.config);
          }
      }
  }

  class PanelFBItem extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物副本";
          this.bAutoRemovePackage = true;
          this.sourceName = "ui://fb_item/PanelFBItem";
          this.exportNodeNames = {
              cc_layer: "fgui.GComponent",
              cc_money_bar: "CustomBarTicket",
              cc_label_sweep: "fgui.GBasicTextField",
              cc_button_sweep: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_button_show: "ScaleButton",
              cc_list_item: "fgui.GList",
              cc_list_show: "fgui.GList",
              cc_ctrl_sweep: "fgui.Controller",
          };
      }
      buildUi() {
          Global.registerListeners(this, {
              [MSG.TOWER_FB_COIN_BEGIN]: this.closeWithTransition.bind(this),
              [MSG.TOWER_FB_ITEM_BEGIN]: this.closeWithTransition.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.sweep_fb_item) {
                      this.watchAdSuccess();
                  }
              },
          });
          this.layer.makeFullScreen();
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.listShow = new ListView(this.list_show, this, this.parseItemShow, this.renderItemShow);
          this.refreshList();
          this.refreshListShow();
          let haveSweep = mgrFB.getFBItemMaxPass() != null;
          this.ctrl_sweep.selectedIndex = haveSweep ? 1 : 0;
          if (haveSweep) {
              this.label_sweep.text = Utils.sprintf("一键扫荡%d次已通关的最高层", db.game_cnf.fb_sweep_ticket);
              mgrGame.statisVideoShowByButton(this.button_sweep, db.ADV_DB_ADVNAME.sweep_fb_item);
          }
      }
      dispose() {
          super.dispose();
      }
      watchAdSuccess() {
          let config = mgrFB.getFBItemMaxPass();
          if (config) {
              let tickets = db.game_cnf.fb_sweep_ticket;
              if (mgrGame.subItem(1011, tickets, 57)) {
                  for (let i = 0; i < tickets; i++) {
                      let dropData = [];
                      let dropId = config.drop_id[mgrTime.getCurrentWeek() % config.drop_id.length];
                      Level.dropItemByDropId(dropId, false, dropData, true);
                      Level.showItemGet(dropData);
                      mgrTask.doEvent(db.TASK_EVENT_ID.COMPLETE_FB_ITEM);
                  }
              }
          }
      }
      refreshList() {
          let listData = db.get_fb_holyitem_db_map();
          this.listItem.setListData(listData);
      }
      parseItem(item, view, index) {
          item.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.4, 0.1, 5);
      }
      renderItem(item, data) {
          item.view.refresh(data);
      }
      parseItemShow(content, object, index) {
          content.icon = object.getChild("icon").asLoader;
          if (index < 7)
              FguiHelper.playIdleAndIn(object, index, 0.2, 0.1);
      }
      renderItemShow(content, id) {
          let holyItemDb = db.get_holy_item_db(id);
          if (holyItemDb) {
              content.icon.url = holyItemDb.icon;
          }
      }
      refreshListShow() {
          let listData = db.get_fb_holyitem_show_map();
          let showDb = listData[mgrTime.getCurrentWeek() % listData.length];
          this.listShow.setListData(showDb.holyitem_ids);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_show() {
          Director.openPanelWithSingleton("PanelFBItemShow");
      }
      on_click_button_sweep() {
          mgrNetwork.callByNetwork(() => {
              if (mgrHolyItem.notEnoughEmpty(8 * db.game_cnf.fb_sweep_ticket))
                  return;
              if (mgrGame.checkItem(1011, db.game_cnf.fb_sweep_ticket, true)) {
                  mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.sweep_fb_item);
              }
          });
      }
  }

  class CustomFBItemShowItem1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://fb_item_show/CustomFBItemShowItem1";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(id) {
          let holyItemDb = db.get_holy_item_db(id);
          if (holyItemDb) {
              this.loader_icon.url = holyItemDb.icon;
          }
      }
  }

  class CustomFBItemShowItem2 extends CustomFBItemShowItem1 {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://fb_item_show/CustomFBItemShowItem2";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomFBItemShowLine1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://fb_item_show/CustomFBItemShowLine1";
          this.exportNodeNames = {
              cc_label_title: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
          };
      }
      onCreate() {
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
      }
      dispose() {
          super.dispose();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, id) {
          content.view.refresh(id);
      }
      refresh(data) {
          this.label_title.text = data.name;
          this.listItem.setListData(data.holyitem_ids);
      }
  }

  class CustomFBItemShowLine2 extends CustomFBItemShowLine1 {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://fb_item_show/CustomFBItemShowLine2";
          this.exportNodeNames = {
              cc_label_title: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelFBItemShow extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物副本轮转展示";
          this.bAutoRemovePackage = true;
          this.sourceName = "ui://fb_item_show/PanelFBItemShow";
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_week: "fgui.GList",
          };
      }
      buildUi() {
          this.listWeek = new ListView(this.list_week, this, this.parseWeekItem, this.renderWeekItem, false, false);
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      parseWeekItem(content, view) {
          content.view = view;
      }
      renderWeekItem(content, data) {
          content.view.refresh(data);
      }
      refreshList() {
          let listData = [];
          listData.push(db.get_fb_holyitem_show(1));
          listData.push(db.get_fb_holyitem_show(2));
          listData.push(db.get_fb_holyitem_show(3));
          listData.push(db.get_fb_holyitem_show(4));
          listData.push(db.get_fb_holyitem_show(5));
          listData.push(db.get_fb_holyitem_show(6));
          listData.push(db.get_fb_holyitem_show(0));
          this.listWeek.setListData(listData);
      }
      on_click_button_close() {
          this.close();
      }
  }

  class CustomFianlWarItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://finalwar/CustomFianlWarItem";
          this.showAD = false;
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_label_history: "fgui.GBasicTextField",
              cc_item_reward: "CustomItem",
              cc_button_sweep: "fgui.GButton",
              cc_ctrl_select: "fgui.Controller",
              cc_ctrl_sweep: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.warDb = data;
          this.loader_icon.url = data.icon;
          this.label_name.text = data.name;
          this.label_diffcult.text = mgrFinalWar.getFinalWarLevel(data.id).toString();
          let maxLv = mgrFinalWar.getFinalWarMaxLv(data.id) || 1;
          this.label_history.text = maxLv.toString();
          this.item_reward.refreshById(data.item_id, 0);
          this.ctrl_sweep.selectedIndex = mgrFinalWar.canSweep(data) ? 1 : 0;
          if (!this.showAD) {
              if (mgrGame.statisVideoShowByButton(this.button_sweep, db.ADV_DB_ADVNAME.finalwar_sweep)) {
                  this.showAD = true;
              }
          }
      }
      select() {
          this.ctrl_select.selectedIndex = 1;
      }
      unselect() {
          this.ctrl_select.selectedIndex = 0;
      }
      on_click_button_sweep() {
          if (this.warDb) {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.finalwar_sweep, this.warDb.id);
          }
      }
  }

  class CustomHopelessWarItem extends CustomFianlWarItem {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://finalwar/CustomHopelessWarItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_label_history: "fgui.GBasicTextField",
              cc_item_reward: "CustomItem",
              cc_button_sweep: "fgui.GButton",
              cc_com_tip: "fgui.GComponent",
              cc_label_tip: "fgui.GBasicTextField",
              cc_ctrl_select: "fgui.Controller",
              cc_ctrl_sweep: "fgui.Controller",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
      on_click_button_sweep() {
          super.on_click_button_sweep();
      }
  }

  class TowerFinalWar extends Tower {
      bindSkin(skin) {
          this.skin = skin;
          skin.initSkin(this, false);
          skin.syncShooter(this);
          this.updateHpBar();
          this.updateHpBarLv();
      }
      refreshAttr() {
          let attrStd = this.attrStd;
          let attrCur = this.attrCur;
          let hurtHp = (attrStd[BASE_ATTR.HP] || 0) - (attrCur[BASE_ATTR.HP] || 0);
          let hurtMp = (attrStd[BASE_ATTR.MP] || 0) - (attrCur[BASE_ATTR.MP] || 0);
          mgrTower.calcTowerAttrByFinalWar(this.towerDb.id, this.attrCur);
          Level.copyAttrArray(this.attrCur, this.attrStd);
          Level.resetAttrArray(this.attrScl, this.attrScl.length);
          let leftHp = attrCur[BASE_ATTR.HP] - hurtHp;
          let leftMp = attrCur[BASE_ATTR.MP] - hurtMp;
          attrCur[BASE_ATTR.HP] = Math.max(leftHp, 1);
          attrCur[BASE_ATTR.MP] = Math.max(leftMp, 0);
          this.calcAttrByBuff();
          this.updateHpBar();
          this.updateHpBarLv();
          this.searchTargets();
          mgrTower.setTowerAttrInBattle(this.towerDb.id, attrCur, this.attrStd);
      }
      updateHpBarLv() {
          if (this.skin) {
              this.skin.updateHpBarLv(mgrFinalWar.getTowerLv(this.towerDb.id));
          }
      }
  }
  TowerFinalWar.poolkey = "TowerFinalWar";

  class TowerMainFinalWar extends TowerMain {
      bindSkin(skin) {
          this.skin = skin;
          skin.initSkin(this, false);
          skin.syncShooter(this);
          this.updateHpBar();
          this.updateHpBarLv();
          let crossbow = skin.skin.getChild("cross");
          if (crossbow instanceof CustomCrossBow) {
              this.nodeCrossbow = crossbow;
              this.nodeCrossbow.visible = true;
              let gPoint = crossbow.localToGlobal();
              crossbow.removeFromParent();
              Level.stage.layerCrossbow.addChild(crossbow.displayObject);
              crossbow.x = gPoint.x;
              crossbow.y = gPoint.y;
              crossbow.scaleX = skin.skin.scaleX;
              crossbow.scaleY = skin.skin.scaleY;
          }
      }
      refreshAttr() {
          let attrStd = this.attrStd;
          let attrCur = this.attrCur;
          let hurtHp = (attrStd[BASE_ATTR.HP] || 0) - (attrCur[BASE_ATTR.HP] || 0);
          let hurtMp = (attrStd[BASE_ATTR.MP] || 0) - (attrCur[BASE_ATTR.MP] || 0);
          mgrTower.calcTowerAttrByFinalWar(this.towerDb.id, this.attrCur);
          Level.copyAttrArray(this.attrCur, this.attrStd);
          Level.resetAttrArray(this.attrScl, this.attrScl.length);
          let leftHp = attrCur[BASE_ATTR.HP] - hurtHp;
          let leftMp = attrCur[BASE_ATTR.MP] - hurtMp;
          attrCur[BASE_ATTR.HP] = Math.max(leftHp, 1);
          attrCur[BASE_ATTR.MP] = Math.max(leftMp, 0);
          this.calcAttrByBuff();
          this.updateHpBar();
          this.updateHpBarLv();
          this.searchTargets();
          mgrTower.setTowerAttrInBattle(this.towerDb.id, attrCur, this.attrStd);
      }
      updateHpBarLv() {
          if (this.skin) {
              this.skin.updateHpBarLv(mgrFinalWar.getTowerLv(this.towerDb.id));
          }
      }
  }
  TowerMainFinalWar.poolkey = "TowerMainFinalWar";

  class StageGameFinalWar extends StageGame {
      constructor() {
          super(...arguments);
          this.seletTowerId = "0";
      }
      onStart() {
          this.refresh();
      }
      initEvent() {
          if (Laya.Browser.onPC)
              Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDownPress);
          this.mapBG.owner.on(Laya.Event.MOUSE_DOWN, this, this.onTouchDown);
          this.mapBG.owner.on(Laya.Event.MOUSE_MOVE, this, this.onTouchMove);
          this.mapBG.owner.on(Laya.Event.MOUSE_UP, this, this.onTouchUp);
          Global.registerListeners(this, {
              [MSG.STAGE_DESTROY]: this.onMsgStageDestroy.bind(this),
              [MSG.TOWER_ENDNESS_BEGIN]: this.onMsgTowerEndnessBegin.bind(this),
              [MSG.TOWER_RUSH_STOP]: this.onMsgTowerRushStop.bind(this),
              [MSG.TOWER_RUSH_END]: this.onMsgTowerRushEnd.bind(this),
              [MSG.TOWER_RUSH_END_FOCUS]: this.onMsgTowerRushEndFocus.bind(this),
              [MSG.SLOT_UNLOCK]: this.onTowerSlotUnlock.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerDeploy.bind(this),
              [MSG.TOWER_DEPLOY_END]: this.onTowerDeployEnd.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerTakeoff.bind(this),
              [MSG.TOWER_LVUP_STAR]: this.onTowerLvupQuality.bind(this),
              [MSG.TOWER_HAND_SKILL_PREPARE]: this.onTowerHandSkillPrepare.bind(this),
              [MSG.TOWER_ATTR_UPDATE_UID]: this.onTowerAttrUpdateUID.bind(this),
              [MSG.TOWER_ATTR_UPDATE]: this.onTowerAttrUpdate.bind(this),
              [MSG.TOWER_ATTR_UPDATE_MAIN]: this.onTowerAttrUpdateMain.bind(this),
              [MSG.TOWER_ATTR_UPDATE_ALL]: this.onTowerAttrUpdateAll.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.TOWER_DEBUG_CHANGE]: this.onTowerDebugChange.bind(this),
              [MSG.CHALLENGE_STORY_BEGIN]: this.onMainStoryBegin.bind(this),
              [MSG.CHALLENGE_BOSS_BEGIN]: this.onChallengeBegin.bind(this),
              [MSG.GAME_VIEW_DESTORY]: this.destroyGameView.bind(this),
              [MSG.GAME_VIEW_RESTORE]: this.restoreGameView.bind(this),
              [MSG.GAME_PAUSE]: this.pauseGame.bind(this),
              [MSG.GAME_RESUME]: this.resumeGame.bind(this),
              [MSG.REFRESH_RED_POINT_TOWER]: this.refreshRedPointTower.bind(this),
              [MSG.GUIDE_COMPLETE]: this.onGuideComplete.bind(this),
              [MSG.GUIDE_SKIP]: this.onGuideSkip.bind(this),
              [MSG.GUIDE_END]: this.onGuideEnd.bind(this),
              [MSG.TOWER_LVUP_LEVEL]: this.onTowerLvupLevel.bind(this),
              [MSG.MAP_TILE_DATA_LOAD]: this.onMapTileDataLoad.bind(this),
              [MSG.TOWER_FB_COIN_BEGIN]: this.onTowerFBCoinBegin.bind(this),
              [MSG.TOWER_FB_ITEM_BEGIN]: this.onTowerFBItemBegin.bind(this),
              [MSG.TOWER_SECRET]: this.onTowerSecretBegin.bind(this),
              [MSG.FINAL_WAR_BEGIN]: this.onFinalWarBegin.bind(this),
              [MSG.FINAL_WAR_READY]: this.onFinalWarReady.bind(this),
          });
      }
      loadMap() {
          let map_id = mgrFinalWar.getFinalWarDb().map_id;
          if (map_id) {
              this.loadMapById(map_id);
          }
          else {
              super.loadMap();
          }
      }
      get towerPosGid() {
          return this.mapBG.getMapTowerPosGid();
      }
      isTowerSlotUnlcok(id) {
          return true;
      }
      initEnemWave(nodeWorld) {
          this.enemyWave = nodeWorld.addComponent(EnemyWaveFinalWar);
          this.enemyWave.world = this.world;
      }
      onFinalWarBegin() {
          this.enemyWave.openModelFinalWar(mgrFinalWar.getFinalWarDb());
          this.onBattleStart();
      }
      onFinalWarReady() {
          this.mapBG.playTransIn();
      }
      onBattleStart() {
          this.world.remAllUnit(LogicCamp.ENEMY);
          this.countEnemy = 0;
          this.hideTowerOption();
          StageGameStatis.start();
          this.mapBG.hideEffect();
      }
      loadTowerOption() {
          let towerOption = fgui.UIPackage.createObjectFromURL("ui://game/CustomTowerOptionFinalWar");
          this.layerMenuUI.addChild(towerOption.displayObject);
          this.towerOption = towerOption;
          this.towerOption.visible = false;
      }
      refresh() {
          this.loadTowerGround();
          this.world.remAllUnit();
          this.focusSceneInit();
          this.loadTowers();
          mgrSound.playMusic("sBg");
      }
      refreshRedPointTower() {
          for (let uid in this.uid2Tower) {
              let skin = this.uid2Tower[uid];
              if (skin) {
                  skin.hideRedPoint();
              }
          }
      }
      onTowerDebugChange(id) {
          this.seletTowerId = id;
          this.refresh();
      }
      loadTowerByIdAndGrid(towerId, gx, gy) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              let shape = [];
              let towerW = towerDb.size[0];
              let towerH = towerDb.size[1];
              let offsetx = Math.floor(towerW / 4);
              for (let i = 0; i < towerW; i++) {
                  for (let j = 0; j < towerH; j++) {
                      shape.push({ x: i, y: j });
                  }
              }
              ResTowerManager.onTowerAdd(towerId);
              if (towerDb.main)
                  return this.world.addBuilding(TowerMainFinalWar, gx - offsetx, gy, towerId, shape);
              else
                  return this.world.addBuilding(TowerFinalWar, gx - offsetx, gy, towerId, shape);
          }
      }
      showSlotUnlock() {
      }
      addEnemyByTouch(grid) {
          this.world.addEnemy(EnemyBossFinalWar, grid.x, grid.y, StageConfig.configTouchEnemy.enemyId);
      }
      onUnitCreate(unit, x, y, view = false) {
          if (unit instanceof Enemy) {
              if (this.enableGameView) {
                  let skin;
                  if (unit.modelDb.spine) {
                      skin = ObjectSkin.create(EnemySkinSpine);
                  }
                  else {
                      skin = ObjectSkin.create(EnemySkin);
                  }
                  skin.playTransIn();
                  if (unit instanceof EnemyBossFinalWar) {
                      skin.loadSkin(unit.roleDb, unit.modelDb, false);
                  }
                  else {
                      skin.loadSkin(unit.roleDb, unit.modelDb, true);
                  }
                  unit.bindSkin(skin);
                  this.layerEnermy.addChild(skin);
                  this.uid2Enemy[unit.uid] = skin;
              }
              if (!view)
                  this.countEnemy++;
          }
          else if (unit instanceof Trap) {
              if (this.enableGameView) {
                  let skin = ObjectSkin.create(TrapSkin);
                  skin.initSkin(unit, this.layerEnermy);
                  this.layerEnermy.addChild(skin);
                  this.uid2Trap[unit.uid] = skin;
              }
          }
          else if (unit instanceof LogicEnemyVirtual) {
          }
      }
  }

  class SceneGameFinalWar extends SceneGame {
      addResLoader(loader) {
          loader.addFguiPackage("res/fgui/finalwar_game");
          let mapConfig = db.get_map_config(mgrFinalWar.getFinalWarDb().map_id);
          if (mapConfig) {
              this.loadFguiUrl(loader, mapConfig.map);
          }
      }
      loadFguiUrl(loader, value) {
          let pkgReg = /ui:\/\/(\S+)\//img;
          let result = pkgReg.exec(value);
          if (result) {
              let pkgName = result[1];
              loader.addFguiPackage(`res/fgui/${pkgName}`);
          }
      }
      onSceneGameCreate(scene) {
          this.scene2d = scene;
          scene.addComponent(StageGameFinalWar);
      }
      onEnter(withLoad) {
          Director.disposeAllPanel();
          let type = mgrFinalWar.getFinalWarDb().type;
          if (type == 1) {
              Director.openPanelWithSingleton("PanelFinalWarGame2");
          }
          else {
              Director.openPanelWithSingleton("PanelFinalWarGame");
          }
      }
  }

  class PanelFinalWar extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "终极一战";
          this.sourceName = "ui://finalwar/PanelFinalWar";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_shop: "ScaleButton",
              cc_button_close: "ScaleButton",
              cc_list_war1: "fgui.GList",
              cc_list_war2: "fgui.GList",
              cc_button_challenge: "fgui.GButton",
              cc_button_war_1: "fgui.GButton",
              cc_button_war_2: "fgui.GButton",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.listWar1 = new ListView(this.list_war1, this, this.parseWarItem, this.renderWarItem);
          this.listWar2 = new ListView(this.list_war2, this, this.parseWarItem, this.renderWarItem);
          this.listWar1.setOnClickItem(this, this.onClickWarItem1);
          this.listWar2.setOnClickItem(this, this.onClickWarItem2);
          let index = this.context.index;
          if (index != null) {
              if (index < this.ctrl_page.pageCount) {
                  this.ctrl_page.selectedIndex = index;
              }
          }
          else {
              this.selectWarDb = mgrFinalWar.getFinalWarDb();
              if (this.selectWarDb && this.selectWarDb.type < this.ctrl_page.pageCount) {
                  this.ctrl_page.selectedIndex = this.selectWarDb.type;
              }
          }
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.finalwar_sweep) {
                      this.watchAdSuccess(e.params);
                  }
              },
          });
          this.onStateChange();
      }
      dispose() {
          super.dispose();
      }
      onStateChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.refrehsWarList1();
                  break;
              case 1:
                  this.refrehsWarList2();
                  break;
          }
      }
      watchAdSuccess(id) {
          let finalWarDb = db.get_finalwar_db(id - 1);
          if (finalWarDb) {
              mgrFinalWar.sweep(finalWarDb);
          }
          this.listWar1.refresh();
          this.listWar2.refresh();
      }
      parseWarItem(content, view) {
          content.view = view;
      }
      renderWarItem(content, data) {
          content.data = data;
          content.view.refresh(data);
          if (this.selectWarDb == data) {
              content.view.select();
          }
          else {
              content.view.unselect();
          }
      }
      onClickWarItem1(content) {
          this.selectWarDb = content.data;
          this.listWar1.refresh();
      }
      onClickWarItem2(content) {
          this.selectWarDb = content.data;
          this.listWar2.refresh();
      }
      refrehsWarList1() {
          let listData1 = [];
          let listWar1 = db.get_finalwar_db_map();
          for (let war of listWar1) {
              if (war.type == 0) {
                  listData1.push(war);
              }
          }
          if (this.selectWarDb && listData1[0]) {
              if (this.selectWarDb.type != 0) {
                  this.selectWarDb = listData1[0];
              }
          }
          else {
              this.selectWarDb = mgrFinalWar.getFinalWarDb() || listData1[0];
          }
          this.listWar1.setListData(listData1);
      }
      refrehsWarList2() {
          let listData2 = [];
          let listWar1 = db.get_finalwar_db_map();
          for (let war of listWar1) {
              if (war.type == 1) {
                  listData2.push(war);
              }
          }
          if (this.selectWarDb && listData2[0]) {
              if (this.selectWarDb.type != 1) {
                  this.selectWarDb = listData2[0];
              }
          }
          else {
              this.selectWarDb = listData2[0];
          }
          this.listWar2.setListData(listData2);
      }
      getSelectWarDb() {
          return this.selectWarDb;
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_challenge() {
          if (this.selectWarDb) {
              mgrFinalWar.loadFinalWarByDB(this.getSelectWarDb());
              Director.runScene(SceneGameFinalWar, "PanelLoadingGame");
          }
      }
      on_click_button_war_1() {
      }
      on_click_button_war_2() {
      }
      on_click_button_shop() {
          Director.openPanelWithSingleton("PanelFinaWarShop");
      }
  }

  class PanelFinalWarBegin extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://finalwar_game/PanelFinalWarBegin";
          this.panelLayer = 4;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_trans_in: "fgui.Transition",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.refresh();
          this.trans_in.play(Laya.Handler.create(this, this.onTransInPlayEnd));
          mgrSound.playMusic("sBgBattle");
          mgrSound.playSound("battle_enter");
      }
      dispose() {
          super.dispose();
      }
      onTransInPlayEnd() {
          this.closeWithTransition();
      }
      refresh() {
          this.label_diffcult.text = mgrFinalWar.getFinalWarDiffcult().toString();
      }
  }

  class PanelFinalWarBegin3 extends PanelFinalWarBegin {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://finalwar_3_begin/PanelFinalWarBegin3";
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_trans_in: "fgui.Transition",
          };
      }
      buildUi() {
          super.buildUi();
      }
      dispose() {
          Global.sendMsg(MSG.FINAL_WAR_READY);
          super.dispose();
      }
      onTransInPlayEnd() {
          this.closeWithTransition();
      }
  }

  class PanelFinalWarBegin2 extends PanelFinalWarBegin {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://finalwar_game/PanelFinalWarBegin2";
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_trans_in: "fgui.Transition",
          };
      }
      buildUi() {
          super.buildUi();
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelFinalWarGame extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "歼灭战游戏中";
          this.sourceName = "ui://finalwar_game/PanelFinalWarGame";
          this.panelStyle = 1;
          this.bMask = false;
          this.uidBoss = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_fit: "CustomLayerFit",
              cc_button_start: "fgui.GButton",
              cc_button_setting: "fgui.GButton",
              cc_title: "fgui.GComponent",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_button_autonext: "fgui.GButton",
              cc_money_coin: "CustomMoneyBar",
              cc_boss_bar: "fgui.GComponent",
              cc_progress_hurt: "fgui.GProgressBar",
              cc_progress_3: "fgui.GProgressBar",
              cc_progress_2: "fgui.GProgressBar",
              cc_progress_1: "fgui.GProgressBar",
              cc_loader_boss_head: "fgui.GLoader",
              cc_label_progress_boss: "fgui.GBasicTextField",
              cc_label_name_boss: "fgui.GBasicTextField",
              cc_boss_state: "fgui.Controller",
              cc_bottom: "fgui.GComponent",
              cc_button_giveup: "ScaleButton",
              cc_hand: "CustomGameHand",
              cc_button_hand: "fgui.GButton",
              cc_button_auto_skill: "fgui.GButton",
              cc_button_exit: "ScaleButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_hand: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
          };
      }
      buildUi() {
          this.layer_fit.fit();
          this.resNode.makeFullScreen();
          this.initEvent();
          this.initTimer();
          this.refresh();
          let wardDb = mgrFinalWar.getFinalWarDb();
          if (wardDb && wardDb.panel_begin) {
              Director.openPanelWithSingleton(wardDb.panel_begin);
          }
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.WAVE_CMD_FINAL_BOSS]: this.onWaveCmdFinalBoss.bind(this),
              [MSG.WAVE_CMD_FINAL_BOSS_REBORN]: this.onWaveCmdFinalBossReborn.bind(this),
              [MSG.WAVE_CMD_FINAL_BOSS_DEAD]: this.onWaveCmdFinalBossDead.bind(this),
              [MSG.TOWER_RUSH_END_FOCUS]: this.onTowrRushERndFocus.bind(this),
              [MSG.TOWER_RUSH_END]: this.onTowrRushEnd.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerChange.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerChange.bind(this),
              [MSG.TOWER_DEAD]: this.onTowerDead.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.TOWER_FINALWAR_BEGIN]: this.beginBattle.bind(this),
          });
      }
      onTowrRushERndFocus() {
          this.trans_out.play();
      }
      onTowrRushEnd(win) {
          this.exitBattle(win);
      }
      onUpdatePerSecond() {
          this.refreshFinalWarBossHpBar();
      }
      onWaveCmdFinalBoss(data) {
          this.boss_state.selectedIndex = 0;
          this.uidBoss = data.uid;
          this.refrehsBossTitle(data.roleId);
          this.refreshFinalWarBossHpBar();
      }
      onWaveCmdFinalBossReborn() {
          let index = (this.boss_state.selectedIndex + 1) % this.boss_state.pageCount;
          this.boss_state.selectedIndex = index;
          let roleId = this.refreshFinalWarBossHpBar();
          if (roleId) {
              this.refrehsBossTitle(roleId);
          }
      }
      onWaveCmdFinalBossDead() {
          this.refreshFinalWarBossHpBarDead();
      }
      refreshGameHand() {
          if (this.ctrl_hand.selectedIndex == 1) {
              this.hand.refresh(true);
          }
      }
      onTowerDead() {
          this.refreshGameHand();
      }
      onTowerMainSkillChange() {
          this.refreshGameHand();
      }
      onTowerChange() {
          this.refreshGameHand();
      }
      getBossProgress() {
          let progress;
          switch (this.boss_state.selectedIndex) {
              case 1:
                  progress = this.progress_2;
                  break;
              case 2:
                  progress = this.progress_3;
                  break;
              default:
                  progress = this.progress_1;
                  break;
          }
          return progress;
      }
      refreshFinalWarBossHpBar() {
          if (this.uidBoss) {
              let enemy = Level.stage.world.objectMgr.getObjectById(this.uidBoss);
              if (enemy instanceof Enemy) {
                  let curt = enemy.getAttr(BASE_ATTR.HP);
                  let maxx = enemy.getAttrMax(BASE_ATTR.HP);
                  this.label_progress_boss.text = curt + "/" + maxx;
                  this.label_progress_boss.visible = true;
                  let value = curt / maxx * 100;
                  this.getBossProgress().tweenValue(value, 0.1);
                  this.progress_hurt.tweenValue(value, 1);
                  this.boss_bar.visible = true;
                  return enemy.roleDb.id;
              }
          }
          else {
              this.refreshFinalWarBossHpBarDead();
          }
      }
      refreshFinalWarBossHpBarDead() {
          this.getBossProgress().tweenValue(0, 0.1);
          this.progress_hurt.tweenValue(0, 1);
      }
      refresh() {
          let warName = mgrFinalWar.getFinalWarName();
          this.label_diffcult.text = "难度 " + mgrFinalWar.getFinalWarDiffcult();
          this.label_name_boss.text = mgrFinalWar.getFinalWarName();
          this.label_title.text = warName;
          this.button_auto_skill.selected = !StageConfig.handSuperSkill;
          this.button_autonext.selected = mgrFinalWar.winAutoNext;
      }
      refrehsBossTitle(roleId) {
          let rodeDb = db.get_role_db(roleId);
          if (rodeDb) {
              let modelDb = db.get_role_model_db(rodeDb.model_id);
              if (modelDb) {
                  this.loader_boss_head.url = modelDb.head_icon;
              }
              this.label_name_boss.text = rodeDb.name;
          }
      }
      beginBattle() {
          this.ctrl_state.selectedIndex = 1;
          Global.sendMsg(MSG.FINAL_WAR_BEGIN);
      }
      exitBattle(win, force = false) {
          if (!force && mgrFinalWar.winAutoNext) {
              this.ctrl_state.selectedIndex = 0;
              this.refresh();
              let finalDb = mgrFinalWar.getFinalWarDb();
              Director.openPanelWithSingleton("PanelDialogCD", { cd: 30, postfix: "秒后自动开始挑战" + finalDb.name, msg: MSG.TOWER_FINALWAR_BEGIN });
          }
          else {
              Director.runScene(SceneGame, "PanelLoadingGame", { openPanel: "PanelFinalWar" });
          }
      }
      on_click_button_start() {
          if (mgrFinalWar.isAnyTowerHaveLeftPoint()) {
              mgrTip.alertPrompt("塔还有未分配的属性点，\n是否确定开始战斗？", null, () => {
                  this.beginBattle();
              });
          }
          else {
              this.beginBattle();
          }
      }
      on_click_button_exit() {
          this.exitBattle(true, true);
      }
      on_click_button_setting() {
          Director.openPanelWithSingleton("PanelSetting");
      }
      on_click_button_giveup() {
          Global.sendMsg(MSG.GAME_PAUSE);
          mgrTip.alertPrompt("确定要退出歼灭战么？", null, () => {
              Global.sendMsg(MSG.TOWER_RUSH_STOP);
          }, () => {
              Global.sendMsg(MSG.GAME_RESUME);
          });
      }
      on_click_button_hand() {
          if (this.ctrl_hand.selectedIndex)
              this.hand.openHand();
          else
              this.hand.closeHand();
      }
      on_click_button_auto_skill() {
          StageConfig.handSuperSkill = !this.button_auto_skill.selected;
      }
      on_click_button_autonext() {
          mgrFinalWar.winAutoNext = this.button_autonext.selected;
      }
  }

  class PanelFinalWarGame2 extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "绝境战游戏中";
          this.sourceName = "ui://finalwar_game/PanelFinalWarGame2";
          this.panelStyle = 1;
          this.bMask = false;
          this.uidBoss = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_fit: "CustomLayerFit",
              cc_button_start: "fgui.GButton",
              cc_button_setting: "fgui.GButton",
              cc_money_coin: "CustomMoneyBar",
              cc_title: "fgui.GComponent",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_diffcult: "fgui.GBasicTextField",
              cc_button_autonext: "fgui.GButton",
              cc_boss_bar: "fgui.GComponent",
              cc_progress_hurt: "fgui.GProgressBar",
              cc_progress_3: "fgui.GProgressBar",
              cc_progress_2: "fgui.GProgressBar",
              cc_progress_1: "fgui.GProgressBar",
              cc_progress_energy: "fgui.GProgressBar",
              cc_loader_boss_head: "fgui.GLoader",
              cc_label_progress_boss: "fgui.GBasicTextField",
              cc_label_name_boss: "fgui.GBasicTextField",
              cc_boss_state: "fgui.Controller",
              cc_bottom: "fgui.GComponent",
              cc_button_giveup: "ScaleButton",
              cc_hand: "CustomGameHand2",
              cc_button_hand: "fgui.GButton",
              cc_button_auto_skill: "fgui.GButton",
              cc_button_exit: "ScaleButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_hand: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
          };
      }
      buildUi() {
          this.layer_fit.fit();
          this.resNode.makeFullScreen();
          this.initEvent();
          this.initTimer();
          this.refresh();
          let wardDb = mgrFinalWar.getFinalWarDb();
          if (wardDb && wardDb.panel_begin) {
              Director.openPanelWithSingleton(wardDb.panel_begin);
          }
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.WAVE_CMD_FINAL_BOSS]: this.onWaveCmdFinalBoss.bind(this),
              [MSG.WAVE_CMD_FINAL_BOSS_REBORN]: this.onWaveCmdFinalBossReborn.bind(this),
              [MSG.WAVE_CMD_FINAL_BOSS_DEAD]: this.onWaveCmdFinalBossDead.bind(this),
              [MSG.TOWER_RUSH_END_FOCUS]: this.onTowrRushERndFocus.bind(this),
              [MSG.TOWER_RUSH_END]: this.onTowrRushEnd.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerChange.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerChange.bind(this),
              [MSG.TOWER_DEAD]: this.onTowerDead.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.TOWER_FINALWAR_BEGIN]: this.beginBattle.bind(this),
          });
      }
      onTowrRushERndFocus() {
          this.trans_out.play();
      }
      onTowrRushEnd(win) {
          this.exitBattle(win);
      }
      onUpdatePerSecond() {
          this.refreshFinalWarBossHpBar();
      }
      onWaveCmdFinalBoss(data) {
          this.boss_state.selectedIndex = 0;
          this.uidBoss = data.uid;
          this.refrehsBossTitle(data.roleId);
          this.refreshFinalWarBossHpBar();
      }
      onWaveCmdFinalBossReborn() {
          let index = (this.boss_state.selectedIndex + 1) % this.boss_state.pageCount;
          this.boss_state.selectedIndex = index;
          let roleId = this.refreshFinalWarBossHpBar();
          if (roleId) {
              this.refrehsBossTitle(roleId);
          }
      }
      onWaveCmdFinalBossDead() {
          this.refreshFinalWarBossHpBarDead();
      }
      refreshGameHand() {
          if (this.ctrl_hand.selectedIndex == 1) {
              this.hand.refresh(true);
          }
      }
      onTowerDead() {
          this.refreshGameHand();
      }
      onTowerMainSkillChange() {
          this.refreshGameHand();
      }
      onTowerChange() {
          this.refreshGameHand();
      }
      getBossProgress() {
          let progress;
          switch (this.boss_state.selectedIndex) {
              case 1:
                  progress = this.progress_2;
                  break;
              case 2:
                  progress = this.progress_3;
                  break;
              default:
                  progress = this.progress_1;
                  break;
          }
          return progress;
      }
      refreshFinalWarBossHpBar() {
          if (this.uidBoss) {
              let enemy = Level.stage.world.objectMgr.getObjectById(this.uidBoss);
              if (enemy instanceof EnemyBossFinalWar) {
                  let curt = enemy.getAttr(BASE_ATTR.HP);
                  let maxx = enemy.getAttrMax(BASE_ATTR.HP);
                  this.label_progress_boss.text = curt + "/" + maxx;
                  this.label_progress_boss.visible = true;
                  let value = curt / maxx * 100;
                  this.getBossProgress().tweenValue(value, 0.1);
                  this.progress_hurt.tweenValue(value, 1);
                  this.boss_bar.visible = true;
                  let curtAngry = enemy.getAttr(BASE_ATTR.ANGRY);
                  let maxxAngry = enemy.getAttrMax(BASE_ATTR.ANGRY);
                  this.progress_energy.tweenValue(curtAngry / maxxAngry * 100, 1);
                  return enemy.roleDb.id;
              }
          }
          else {
              this.refreshFinalWarBossHpBarDead();
          }
      }
      refreshFinalWarBossHpBarDead() {
          this.getBossProgress().tweenValue(0, 0.1);
          this.progress_hurt.tweenValue(0, 1);
      }
      refresh() {
          let warName = mgrFinalWar.getFinalWarName();
          this.label_diffcult.text = "难度 " + mgrFinalWar.getFinalWarDiffcult();
          this.label_name_boss.text = mgrFinalWar.getFinalWarName();
          this.label_title.text = warName;
          this.button_auto_skill.selected = !StageConfig.handSuperSkill;
          this.button_autonext.selected = mgrFinalWar.winAutoNext;
      }
      refrehsBossTitle(roleId) {
          let rodeDb = db.get_role_db(roleId);
          if (rodeDb) {
              let modelDb = db.get_role_model_db(rodeDb.model_id);
              if (modelDb) {
                  this.loader_boss_head.url = modelDb.head_icon;
              }
              this.label_name_boss.text = rodeDb.name;
          }
      }
      beginBattle() {
          this.ctrl_state.selectedIndex = 1;
          Global.sendMsg(MSG.FINAL_WAR_BEGIN);
      }
      exitBattle(win, force = false) {
          if (!force && mgrFinalWar.winAutoNext) {
              this.ctrl_state.selectedIndex = 0;
              this.refresh();
              let finalDb = mgrFinalWar.getFinalWarDb();
              Director.openPanelWithSingleton("PanelDialogCD", { cd: 30, postfix: "秒后自动开始挑战" + finalDb.name, msg: MSG.TOWER_FINALWAR_BEGIN });
          }
          else {
              Director.runScene(SceneGame, "PanelLoadingGame", { openPanel: "PanelFinalWar" });
          }
      }
      on_click_button_start() {
          if (mgrFinalWar.isAnyTowerHaveLeftPoint()) {
              mgrTip.alertPrompt("塔还有未分配的属性点，\n是否确定开始战斗？", null, () => {
                  this.beginBattle();
              });
          }
          else {
              this.beginBattle();
          }
      }
      on_click_button_exit() {
          this.exitBattle(true, true);
      }
      on_click_button_setting() {
          Director.openPanelWithSingleton("PanelSetting");
      }
      on_click_button_giveup() {
          Global.sendMsg(MSG.GAME_PAUSE);
          mgrTip.alertPrompt("确定要退出歼灭战么？", null, () => {
              Global.sendMsg(MSG.TOWER_RUSH_STOP);
          }, () => {
              Global.sendMsg(MSG.GAME_RESUME);
          });
      }
      on_click_button_hand() {
          if (this.ctrl_hand.selectedIndex)
              this.hand.openHand();
          else
              this.hand.closeHand();
      }
      on_click_button_auto_skill() {
          StageConfig.handSuperSkill = !this.button_auto_skill.selected;
      }
      on_click_button_autonext() {
          mgrFinalWar.winAutoNext = this.button_autonext.selected;
      }
  }

  class CustomFinalWarShopItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://finalwar_shop/CustomFinalWarShopItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_buy: "fgui.GButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_ctrl_soldout: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.shopDb = data;
          this.item.refreshById(data.item_id, data.item_num);
          this.label_title.text = mgrGame.getItemName(data.item_id);
          this.label_left.text = mgrExchange.getExchangeLeftCountByDB(data) + "/" + data.limit;
          this.button_buy.title = data.price_item_cost.toString();
          this.button_buy.icon = mgrGame.getItemIcon(data.price_item_id);
          this.ctrl_soldout.selectedIndex = mgrExchange.canExchangeByDB(data) ? 0 : 1;
      }
      on_click_button_buy() {
          if (this.shopDb && mgrHolyItem.notEnoughEmptyByItemId(this.shopDb.item_id, this.shopDb.item_num))
              return;
          mgrExchange.tryExchangeShop(this.shopDb);
      }
  }

  class PanelFinaWarShop extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "战功兑换";
          this.sourceName = "ui://finalwar_shop/PanelFinaWarShop";
          this.panelStyle = 0;
          this.bMask = false;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_item_bar: "CustomBarItem",
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.item_bar.setItemId(1020);
          this.listShop = new ListView(this.list_item, this, this.parseShopItem, this.renderShopItem);
          this.refresh();
          Global.registerListeners(this, {
              [MSG.EXCHANGE_SHOP_REFRESH]: this.onExchangeShopRefresh.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      onExchangeShopRefresh() {
          this.listShop.refresh();
      }
      refresh() {
          this.refreshShopList();
      }
      parseShopItem(content, view, index) {
          content.view = view;
          if (index < 4) {
              FguiHelper.playIdleAndIn(view, index, 0.15, 0.1);
          }
          else {
              FguiHelper.playIdleAndIn(view, index - 4, 0.25, 0.1);
          }
      }
      renderShopItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshShopList() {
          let listData = [];
          let shopList = db.get_shop_exchange_db_map();
          for (let k in shopList) {
              let shop = db.get_shop_exchange_db(k);
              if (shop.type == 2) {
                  listData.push(shop);
              }
          }
          this.listShop.setListData(listData);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelFinalWarWin extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "歼灭成功";
          this.sourceName = "ui://finalwar_win/PanelFinalWarWin";
          this.panelLayer = 4;
          this.bMask = false;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          Laya.timer.once(1500, this, this.onTransInPlayEnd);
      }
      dispose() {
          super.dispose();
      }
      onTransInPlayEnd() {
          this.closeWithTransition();
      }
  }

  class CustomBossCrazy extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomBossCrazy";
          this.exportNodeNames = {
              cc_label_crazy: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      showCrazyLayer(layer) {
          this.label_crazy.text = layer.toString();
          this.visible = true;
      }
  }

  class CustomBoxReward extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "宝箱奖励";
          this.sourceName = "ui://game/CustomBoxReward";
          this.exportNodeNames = {
              cc_button_box: "fgui.GButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_ctrl_boxreward: "fgui.Controller",
          };
      }
      onCreate() {
          let reward = mgrGame.getBoxRewardDb();
          if (reward && mgrAdv.checkActive(db.ADV_DB_ADVNAME.unlock_newbie_reward_box)) {
              this.initEvent();
              this.initTimer();
              this.refresh();
              this.onStateChange();
          }
          else {
              this.visible = false;
          }
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.unlock_newbie_reward_box) {
                      this.watchAdSuccess();
                  }
              },
          });
          this.ctrl_boxreward.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
      }
      onStateChange() {
          if (this.ctrl_boxreward.selectedIndex == 2) {
              mgrGame.statisVideoShow(db.ADV_DB_ADVNAME.unlock_newbie_reward_box);
          }
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      updatePerSecond() {
          mgrGame.boxRewardTime += 1;
          this.refresh();
      }
      refresh() {
          let reward = mgrGame.getBoxRewardDb();
          if (reward) {
              let leftTime = reward.time * 60 - mgrGame.boxRewardTime;
              if (leftTime > 0) {
                  this.label_title.text = Utils.cdTimeFormat(leftTime);
                  this.ctrl_boxreward.selectedIndex = 0;
              }
              else {
                  this.label_title.text = "点击领取";
                  if (reward.ad) {
                      this.ctrl_boxreward.selectedIndex = 2;
                  }
                  else {
                      this.ctrl_boxreward.selectedIndex = 1;
                  }
              }
          }
          else {
              this.dispose();
          }
      }
      watchAdSuccess() {
          mgrGame.tryGetBoxReward();
      }
      on_click_button_box() {
          let reward = mgrGame.getBoxRewardDb();
          if (reward) {
              let leftTime = reward.time * 60 - mgrGame.boxRewardTime;
              if (leftTime <= 0) {
                  if (reward.ad) {
                      mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.unlock_newbie_reward_box);
                      return;
                  }
              }
          }
          Director.openPanelWithSingleton("PanelBoxReward");
      }
  }

  class CustomBroadcast extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomBroadcast";
          this.listPointSuper = [];
          this.listPointItem = [];
          this.listCastSuper = [];
          this.listCastItem = [];
          this.indexCastSuper = 0;
          this.indexCastItem = 0;
          this.exportNodeNames = {
              cc_super_cast2: "CustomSuperCast",
              cc_super_cast1: "CustomSuperCast",
              cc_holyitem_cast4: "CustomItemCast",
              cc_holyitem_cast3: "CustomItemCast",
              cc_holyitem_cast2: "CustomItemCast",
              cc_holyitem_cast1: "CustomItemCast",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      init() {
          this.initCastItem(this.listPointSuper, this.listCastSuper, this.super_cast1);
          this.initCastItem(this.listPointSuper, this.listCastSuper, this.super_cast2);
          this.initCastItem(this.listPointItem, this.listCastItem, this.holyitem_cast1);
          this.initCastItem(this.listPointItem, this.listCastItem, this.holyitem_cast2);
          this.initCastItem(this.listPointItem, this.listCastItem, this.holyitem_cast3);
          this.initCastItem(this.listPointItem, this.listCastItem, this.holyitem_cast4);
          this.initEvent();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_CAST_SUPER_SKILL]: this.onTowerCastSuerSkill.bind(this),
              [MSG.DROP_ITEM_PICK_UP]: this.onDropItemPickUp.bind(this),
          });
      }
      onTowerCastSuerSkill(skillDb) {
          this.showSuperCast(skillDb);
      }
      onDropItemPickUp(datas) {
          for (let data of datas.items) {
              this.showItemCast(data);
          }
      }
      initCastItem(listPoint, listObject, object) {
          listPoint.push({ x: object.x, y: object.y });
          listObject.push(object);
          object.hide();
      }
      showSuperCast(skillDb) {
          let len = this.listCastSuper.length;
          let lastIndex = (this.indexCastSuper - 1) % len;
          let lastItem = this.listCastSuper[lastIndex];
          if (lastItem && lastItem.isPlaying()) {
              Laya.Tween.to(lastItem, this.listPointSuper[1], 300, null, null, null, true);
              lastItem.sortingOrder = 1;
          }
          let curtItem = this.listCastSuper[this.indexCastSuper % len];
          let firstPoint = this.listPointSuper[0];
          curtItem.x = firstPoint.x;
          curtItem.y = firstPoint.y;
          Laya.Tween.clearAll(curtItem);
          curtItem.show(skillDb);
          curtItem.sortingOrder = 0;
          this.indexCastSuper++;
      }
      showItemCast(data) {
          let len = this.listCastItem.length;
          let lastIndex = (this.indexCastItem - 1) % len;
          let lastItem = this.listCastItem[lastIndex];
          if (lastItem && lastItem.isPlaying()) {
              let lastData = lastItem.drapData;
              if (lastData.type == data.type && lastData.data.itemId == data.data.itemId) {
                  data.data.count += lastData.data.count;
                  lastItem.show(data);
                  return;
              }
          }
          for (let i = 1; i <= 3; i++) {
              let lastIndex = (this.indexCastItem - i) % len;
              let lastItem = this.listCastItem[lastIndex];
              if (lastItem && lastItem.isPlaying()) {
                  lastItem.index++;
                  let pos = this.listPointItem[lastItem.index];
                  if (pos) {
                      Laya.Tween.to(lastItem, pos, 300, null, null, null, true);
                      lastItem.sortingOrder = 1;
                  }
              }
          }
          let curtItem = this.listCastItem[this.indexCastItem % len];
          let firstPoint = this.listPointItem[0];
          curtItem.x = firstPoint.x;
          curtItem.y = firstPoint.y;
          Laya.Tween.clearAll(curtItem);
          curtItem.index = 0;
          curtItem.show(data);
          curtItem.sortingOrder = 0;
          this.indexCastItem++;
      }
  }

  class CustomGuideTip extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomGuideTip";
          this.exportNodeNames = {
              cc_label_title: "fgui.GBasicTextField",
              cc_ctrl_show: "fgui.Controller",
          };
      }
      static randomShow() {
          let listGuideTip = [];
          for (let id in this.allGuideTip) {
              let ui = this.allGuideTip[id];
              if (ui && ui.canShow())
                  listGuideTip.push(ui);
          }
          let ui = Utils.randomItem(listGuideTip);
          if (ui) {
              ui.show(db.game_cnf.guide_tip_time_hide);
          }
          return ui;
      }
      onCreate() {
          CustomGuideTip.allGuideTip[this.id] = this;
          this.initEvent();
      }
      dispose() {
          Laya.timer.clearAll(this);
          delete CustomGuideTip.allGuideTip[this.id];
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.GUIDE_TIP_UPDATE]: this.onGuideTipUpdate.bind(this),
              [MSG.TOWER_ENDNESS_BEGIN]: this.onTowerRushBegin.bind(this),
              [MSG.CHALLENGE_STORY_BEGIN]: this.onTowerRushBegin.bind(this),
              [MSG.CHALLENGE_BOSS_BEGIN]: this.onTowerRushBegin.bind(this),
          });
      }
      onGuideTipUpdate(msg, data) {
          let msgHide = this.msgHide || this.data;
          if (msg == msgHide) {
              this.hide();
              Global.sendMsg(MSG.GUIDE_TIP_CORRECT);
          }
      }
      onTowerRushBegin() {
          if (this.towerId) {
              this.hide();
          }
      }
      setTip(tip) {
          this.label_title.text = tip;
      }
      setMsg(msg) {
          this.msgHide = msg;
      }
      setTowerId(towerId) {
          this.towerId = towerId;
          this.setMsg("CLICK_TOWER_ATTR_" + towerId);
      }
      canShow() {
          if (this.towerId) {
              return Level.stage.enemyWave.isIdleMode() && mgrTower.canLvupTowerLevel(this.towerId);
          }
          return true;
      }
      show(second = 20) {
          this.ctrl_show.selectedIndex = 1;
          Laya.timer.once(1000 * second, this, this.hide);
      }
      hide() {
          this.ctrl_show.selectedIndex = 0;
          Laya.timer.clear(this, this.hide);
      }
  }
  CustomGuideTip.allGuideTip = {};

  class CustomH5Share extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomH5Share";
          this.exportNodeNames = {
              cc_button_share: "fgui.GButton",
              cc_loader_reward_icon: "fgui.GLoader",
              cc_label_reward_num: "fgui.GBasicTextField",
              cc_ctrl_share_state: "fgui.Controller",
          };
      }
      onCreate() {
          Global.registerListeners(this, {
              [BASE_MSG.SDK_SHARE_SUC]: this.onMsgSdkShareSuc.bind(this),
          });
          CopHelper.updateButtonVisible(this, db.cop_db.isShareEnabled && CopHelper.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_share));
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onMsgSdkShareSuc() {
          this.getShareReward();
          this.refresh();
      }
      refresh() {
          let rewardDb = mgrGame.getRewardByTime("share", mgrGame.getItemCount(3001) + 1, 25, false);
          if (rewardDb) {
              this.loader_reward_icon.url = mgrGame.getItemIcon(rewardDb.item_id);
              this.label_reward_num.text = rewardDb.item_num.toString();
              this.ctrl_share_state.selectedIndex = 1;
          }
          else {
              this.ctrl_share_state.selectedIndex = 0;
          }
      }
      getShareReward() {
          mgrGame.addItem(3001, 1, 25, false);
          mgrGame.getRewardByTime("share", mgrGame.getItemCount(3001), 25);
      }
      on_click_button_share() {
          mgrGame.share();
      }
  }

  class CustomH5VideoRecord extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomH5VideoRecord";
          this.exportNodeNames = {
              cc_button_record: "fgui.GButton",
              cc_ctrl_record: "fgui.Controller",
          };
      }
      onCreate() {
          Global.registerListeners(this, {
              [BASE_MSG.VIDEO_RECORDER_STATUS_CHANGED]: this.onMsgRecordGameVideoStateChanged.bind(this),
          });
          this.onMsgRecordGameVideoStateChanged();
          CopHelper.updateButtonVisible(this, mgrVideoRecorder.isOpenVideoRecord());
      }
      dispose() {
          super.dispose();
      }
      onMsgRecordGameVideoStateChanged() {
          if (mgrVideoRecorder.recordStatus == RECORD_STATUS.PRE_RECORD) {
              this.ctrl_record.setSelectedIndex(0);
          }
          else if (mgrVideoRecorder.recordStatus == RECORD_STATUS.RECORDING) {
              this.ctrl_record.setSelectedIndex(1);
          }
          else if (mgrVideoRecorder.recordStatus == RECORD_STATUS.RECORD_FINISH) {
              this.ctrl_record.setSelectedIndex(2);
          }
      }
      on_click_button_record() {
          if (mgrVideoRecorder.recordStatus == RECORD_STATUS.PRE_RECORD) {
              mgrVideoRecorder.startRecordGameVideo();
          }
          else if (mgrVideoRecorder.recordStatus == RECORD_STATUS.RECORDING) {
              mgrVideoRecorder.stopRecordGameVideo();
          }
          else if (mgrVideoRecorder.recordStatus == RECORD_STATUS.RECORD_FINISH) {
              mgrGame.shareVideo();
          }
      }
  }

  class CustomHandSkill extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomHandSkill";
          this.isReady = false;
          this.exportNodeNames = {
              cc_loader_effect: "fgui.GLoader",
              cc_loader_icon: "fgui.GLoader",
              cc_loader_icon_ready: "fgui.GLoader",
              cc_progress_hp: "fgui.GProgressBar",
              cc_progress_mp: "fgui.GProgressBar",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_ready: "fgui.Controller",
              cc_ctrl_cast: "fgui.Controller",
          };
      }
      onCreate() {
          this.grayed = true;
          this.isReady = false;
          this.initTimer();
          this.onClick(this, this.onClickTower);
          this.transSkill01 = this.getTransition("skill01");
          this.transSkill02 = this.getTransition("skill02");
          this.ctrl_cast.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      bindTowerId(towerId, ready) {
          this.towerId = towerId;
          this.towerDb = db.get_tower_db(towerId);
          let skillDb = db.get_skill_db(mgrTower.getTowerSuperId(this.towerDb.id));
          this.loader_icon.url = skillDb.icon_hand;
          this.loader_icon_ready.url = skillDb.icon_hand_ready;
          this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(this.towerDb);
          if (!ready)
              this.ctrl_cast.setSelectedIndex(0);
          this.progress_hp.value = 0;
          this.progress_mp.value = 0;
          this.grayed = false;
          this.isReady = ready;
          if (ready)
              this.refreshEnergy();
          else
              this.refreshEnergyProgressBar();
      }
      onStateChange() {
          switch (this.ctrl_cast.selectedIndex) {
              case 0:
                  this.transSkill01.stop();
                  this.transSkill02.play();
                  break;
              case 1:
                  this.transSkill02.stop();
                  this.transSkill01.play();
                  break;
          }
      }
      unbindTower() {
          this.towerId = null;
          this.grayed = true;
          this.loader_icon.url = "";
          this.loader_icon_ready.url = "";
          this.progress_hp.value = 0;
          this.progress_mp.value = 0;
          this.ctrl_quality.selectedIndex = 0;
      }
      onTransInEnd() {
          if (!this.towerId)
              return;
          this.isReady = true;
          this.refreshEnergy();
      }
      refreshEnergyProgressBar() {
          let tower = Level.stage.findTowerById(this.towerId);
          if (tower) {
              this.progress_hp.value = tower.getAttrPercent(BASE_ATTR.HP) * 100;
              this.progress_mp.value = tower.getEnergyPercent() * 100;
          }
      }
      refreshEnergy() {
          let tower = Level.stage.findTowerById(this.towerId);
          if (tower) {
              this.progress_hp.value = tower.getAttrPercent(BASE_ATTR.HP) * 100;
              this.progress_mp.value = tower.getEnergyPercent() * 100;
              if (tower.isEnergyFull()) {
                  this.ctrl_cast.selectedIndex = 1;
              }
              else {
                  this.ctrl_cast.selectedIndex = 0;
              }
              this.grayed = false;
          }
          else {
              this.ctrl_cast.selectedIndex = 0;
              this.grayed = true;
          }
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onTimerUpdate);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onTimerUpdate);
      }
      onTimerUpdate() {
          if (this.isReady) {
              this.refreshEnergy();
          }
      }
      onClickTower() {
          let tower = Level.stage.findTowerById(this.towerId);
          if (tower && this.ctrl_cast.selectedIndex) {
              tower.handCastSuperSkill();
              this.refreshEnergy();
              let data = Director.getScene3DLayer(3);
              let effect = EffectFactory.create("166_ui_once_glow_02", data.scene3d);
              effect.followFguiNode(data.camera, this);
              mgrSound.playSound("cast_super_skill");
          }
      }
  }

  class CustomHandSkillBig extends CustomHandSkill {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomHandSkillBig";
          this.exportNodeNames = {
              cc_loader_effect: "fgui.GLoader",
              cc_loader_icon: "fgui.GLoader",
              cc_loader_icon_ready: "fgui.GLoader",
              cc_progress_hp: "fgui.GProgressBar",
              cc_progress_mp: "fgui.GProgressBar",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_ready: "fgui.Controller",
              cc_ctrl_cast: "fgui.Controller",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomIceBreak extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomIceBreak";
          this.exportNodeNames = {
              cc_button_box: "fgui.GButton",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_box() {
      }
  }

  class CustomItemCast extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomItemCast";
          this.index = 0;
          this.isRunning = false;
          this.exportNodeNames = {
              cc_item: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_label_holiitem_name: "fgui.GBasicTextField",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_type: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
          };
      }
      onCreate() {
          this.handerPlayEnd = Laya.Handler.create(this, this.onPlayEnd, null, false);
      }
      dispose() {
          super.dispose();
      }
      onPlayEnd() {
          this.isRunning = false;
      }
      isPlaying() {
          return this.isRunning;
      }
      hide() {
          this.visible = false;
      }
      show(data) {
          this.drapData = data;
          this.visible = true;
          this.isRunning = true;
          this.trans_out.stop();
          this.trans_out.play(this.handerPlayEnd);
          switch (data.type) {
              case DROP_TYPE.ITEM:
                  this.ctrl_type.selectedIndex = 1;
                  let info = data.data;
                  this.loader_icon.url = mgrGame.getItemIcon(info.itemId);
                  this.label_item_name.text = "x " + info.count;
                  break;
              case DROP_TYPE.HOLY_ITEM:
                  this.ctrl_type.selectedIndex = 0;
                  let item = data.data;
                  this.ctrl_quality.selectedIndex = item.getQuality();
                  this.loader_icon.url = item.getIcon();
                  this.label_holiitem_name.text = item.getName() + "x1";
                  break;
          }
      }
  }

  class CustomSuperCast extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomSuperCast";
          this.isRunning = false;
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_trans_out: "fgui.Transition",
          };
      }
      onCreate() {
          this.handerPlayEnd = Laya.Handler.create(this, this.onPlayEnd, null, false);
      }
      dispose() {
          super.dispose();
      }
      onPlayEnd() {
          this.isRunning = false;
      }
      isPlaying() {
          return this.isRunning;
      }
      hide() {
          this.visible = false;
      }
      show(skillDb) {
          this.visible = true;
          this.isRunning = true;
          this.trans_out.stop();
          this.trans_out.play(this.handerPlayEnd);
          this.loader_icon.url = skillDb.icon_broadcast;
      }
  }

  class CustomTaskDesk extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomTaskDesk";
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_label_task: "fgui.GBasicTextField",
              cc_label_progress: "fgui.GBasicTextField",
              cc_button_goal: "fgui.GButton",
              cc_button_seven: "fgui.GButton",
              cc_state_task: "fgui.Controller",
              cc_state_mini: "fgui.Controller",
              cc_guide: "fgui.Controller",
          };
      }
      onCreate() {
          this.loader_bg.onClick(this, this.onClickTaskDesk);
          this.refreshSeven();
          this.refresh();
          this.updateGoal();
          this.initEvent();
      }
      refresh() {
          let task = mgrTask.getMiniTask();
          if (task) {
              if (this.curtTaskId != task.id) {
                  this.curtTaskId = task.id;
                  mgrTask.statisTaskShow(task);
              }
              let curt = mgrTask.getTaskCountByDB(task);
              let need = mgrTask.getTaskNeed(task);
              if (curt >= need) {
                  this.state_mini.setSelectedIndex(1);
                  this.updateGuide(1);
              }
              else {
                  this.state_mini.setSelectedIndex(0);
                  this.updateGuide(0);
                  this.label_task.text = Utils.sprintf(task.desc, need);
                  this.label_progress.text = "（" + curt + "/" + need + "）";
              }
          }
          else {
              this.label_task.text = mgrTask.getMiniCDLeftTime() + "秒后出现新任务!";
              this.state_mini.setSelectedIndex(2);
              this.updateGuide(0);
          }
      }
      refreshSeven() {
          this.button_seven.visible = mgrTaskSeven.isNeedShow();
      }
      updateGuide(index) {
          this.guide.setSelectedIndex(index);
      }
      calcCurtGoal() {
          let listData = db.get_goal_db_map();
          let curtGoal = null;
          let score = mgrTask.goalScore;
          let scoreCount = 0;
          for (let i = 0; i < listData.length; i++) {
              let data = listData[i];
              scoreCount += data.score_need;
              if (score < scoreCount) {
                  curtGoal = data;
                  break;
              }
          }
          if (!curtGoal) {
              curtGoal = listData[listData.length - 2];
          }
          return curtGoal;
      }
      updateGoal() {
          let curtGoal = this.calcCurtGoal();
          this.button_goal.text = "Lv." + (curtGoal.id - 1);
          if (mgrTask.isAnyTaskCanReward()) {
              this.state_task.setSelectedIndex(1);
          }
          else {
              this.state_task.setSelectedIndex(0);
          }
          StageTool.updateRedPoint4Button(this.button_goal, mgrTask.isAnyGoalCanReward());
          if (this.button_seven.visible) {
              StageTool.updateRedPoint4Button(this.button_seven, mgrTaskSeven.haveReadPoint());
          }
      }
      dispose() {
          this.removeEvent();
          super.dispose();
      }
      initEvent() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeEvent() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      updatePerSecond() {
          this.refresh();
          this.updateGoal();
      }
      onClickTaskDesk() {
          let task = mgrTask.getMiniTask();
          if (task && mgrTask.isTaskCompleteByDB(task)) {
              mgrNetwork.callByNetwork(() => {
                  mgrTask.getTaskRewardByDB(task);
              });
              return;
          }
          Director.openPanel("PanelTask", { index: 0 });
      }
      on_click_button_goal() {
          Director.openPanel("PanelTask", { index: 1 });
      }
      on_click_button_seven() {
          Director.openPanelWithSingleton("PanelTaskSeven");
      }
  }

  class CustomTowerOption extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "塔选项";
          this.sourceName = "ui://game/CustomTowerOption";
          this.exportNodeNames = {
              cc_button_info: "fgui.GButton",
              cc_button_takeoff: "fgui.GButton",
              cc_button_deploy: "fgui.GButton",
              cc_ctrl_layout: "fgui.Controller",
          };
      }
      onCreate() {
          this.initEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.REFRESH_RED_POINT_TOWER]: this.refreshRedPoint.bind(this),
          });
      }
      bindTower(tower, isTowerRush = false) {
          this.tower = tower;
          this.button_info.enabled = tower != null;
          this.button_deploy.enabled = !isTowerRush;
          this.button_deploy.visible = !Level.isFirstGuide();
          if (tower) {
              let slot = db.get_tower_pos(mgrTower.defaultPosGid, tower.slotId - 1);
              if (slot) {
                  this.ctrl_layout.selectedIndex = slot.layout;
              }
          }
          this.refreshRedPoint();
      }
      refreshRedPoint() {
          if (this.tower) {
              Level.updateRedPoint4Button(this.button_info, mgrTower.haveRedPoint(this.tower.towerDb.id));
          }
          else {
              Level.updateRedPoint4Button(this.button_info, false);
          }
      }
      on_click_button_deploy() {
          console.log("布阵", this.tower);
          Director.openPanel("PanelDeploy");
      }
      on_click_button_info() {
          console.log("详情", this.tower);
          if (this.tower) {
              Global.sendMsg(MSG.GUIDE_TIP_UPDATE, "CLICK_TOWER_ATTR_" + this.tower.towerDb.id);
              Director.openPanel("PanelTowerInfo", { towerDb: this.tower.towerDb, uid: this.tower.uid });
          }
      }
      on_click_button_takeoff() {
          if (this.tower) {
              this.tower.takeoff();
              this.tower = null;
          }
          this.visible = false;
      }
  }

  class PanelAddPoint extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "加点界面";
          this.sourceName = "ui://tower_info/PanelAddPoint";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bMask = false;
          this.type = 0;
          this.exportNodeNames = {
              cc_layer_bg: "fgui.GComponent",
              cc_com_add: "fgui.GComponent",
              cc_button_add_1: "fgui.GButton",
              cc_button_add_half: "fgui.GButton",
              cc_button_add_all: "fgui.GButton",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.layer_bg.onClick(this, this.onClickBackGround);
          this.towerId = this.context.towerId;
          this.type = this.context.type || 0;
          let point = this.context.point;
          if (point) {
              this.com_add.x = point.x;
              this.com_add.y = point.y;
          }
          StageTool.addLongClickEvent(this.button_add_1, this, this.onLongClickBegin, this.onLongClickUpdate, this.onLongClickEnd);
      }
      dispose() {
          StageTool.remLongClickEvent(this.button_add_1, this);
          super.dispose();
      }
      updatePoint(point) {
          if (point) {
              this.com_add.x = point.x;
              this.com_add.y = point.y;
          }
      }
      onLongClickBegin(id) {
          if (this.destroyed)
              return;
      }
      onLongClickUpdate() {
          if (this.destroyed)
              return;
          this.addPointQuick(1);
      }
      onLongClickEnd(id) {
          if (this.destroyed)
              return;
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD);
      }
      onClickBackGround() {
          this.closeWithTransition();
      }
      addPoint(add = 1) {
          switch (this.context.type) {
              case PanelAddPoint.TYPE_ADD_BASE:
                  mgrTower.assignTowerPointBase(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_POWER:
                  mgrTower.assignTowerPointPower(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_MANA:
                  mgrTower.assignTowerPointMana(this.towerId, add);
                  break;
          }
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD);
      }
      addPointQuick(add = 1) {
          switch (this.context.type) {
              case PanelAddPoint.TYPE_ADD_BASE:
                  mgrTower.assignTowerPointBase(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_POWER:
                  mgrTower.assignTowerPointPower(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_MANA:
                  mgrTower.assignTowerPointMana(this.towerId, add);
                  break;
          }
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD_QUICK);
      }
      on_click_button_add_1() {
          this.addPoint();
      }
      on_click_button_add_half() {
          this.addPoint(mgrTower.calcTowerPointLeftHalf(this.towerId));
      }
      on_click_button_add_all() {
          this.addPoint(mgrTower.calcTowerPointLeft(this.towerId));
      }
  }
  PanelAddPoint.TYPE_ADD_BASE = 1;
  PanelAddPoint.TYPE_ADD_POWER = 2;
  PanelAddPoint.TYPE_ADD_MANA = 3;

  var TOWER_INFO_STATE;
  (function (TOWER_INFO_STATE) {
      TOWER_INFO_STATE[TOWER_INFO_STATE["INFO"] = 0] = "INFO";
      TOWER_INFO_STATE[TOWER_INFO_STATE["SELECT_EMPTY"] = 1] = "SELECT_EMPTY";
      TOWER_INFO_STATE[TOWER_INFO_STATE["SELECT_ITEM"] = 2] = "SELECT_ITEM";
  })(TOWER_INFO_STATE || (TOWER_INFO_STATE = {}));
  var LONG_CLICK_CODE;
  (function (LONG_CLICK_CODE) {
      LONG_CLICK_CODE[LONG_CLICK_CODE["NONE"] = 0] = "NONE";
      LONG_CLICK_CODE[LONG_CLICK_CODE["LVUP"] = 1] = "LVUP";
      LONG_CLICK_CODE[LONG_CLICK_CODE["ADD_BASE"] = 2] = "ADD_BASE";
      LONG_CLICK_CODE[LONG_CLICK_CODE["ADD_POWER"] = 3] = "ADD_POWER";
      LONG_CLICK_CODE[LONG_CLICK_CODE["ADD_MANA"] = 4] = "ADD_MANA";
  })(LONG_CLICK_CODE || (LONG_CLICK_CODE = {}));
  class PanelTowerInfo extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "塔详情";
          this.sourceName = "ui://tower_info/PanelTowerInfo";
          this.panelStyle = 0;
          this.countLongClickUpdate = 0;
          this.detailSkillId = null;
          this.exportNodeNames = {
              cc_loader_tower: "fgui.GComponent",
              cc_com_info: "fgui.GComponent",
              cc_button_talent: "ScaleButton",
              cc_image_recomm_hp: "fgui.GImage",
              cc_image_recomm_ad: "fgui.GImage",
              cc_image_recomm_ap: "fgui.GImage",
              cc_label_base: "fgui.GBasicTextField",
              cc_label_power: "fgui.GBasicTextField",
              cc_label_mana: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_label_level_cur: "fgui.GBasicTextField",
              cc_label_level_max: "fgui.GBasicTextField",
              cc_button_reset: "fgui.GButton",
              cc_button_add_base: "fgui.GButton",
              cc_button_add_power: "fgui.GButton",
              cc_button_add_mana: "fgui.GButton",
              cc_button_lvup: "fgui.GButton",
              cc_button_lvbreak: "fgui.GButton",
              cc_com_hp: "fgui.GComponent",
              cc_com_ad: "fgui.GComponent",
              cc_com_ap: "fgui.GComponent",
              cc_com_range: "fgui.GComponent",
              cc_com_crit: "fgui.GComponent",
              cc_com_crit_dmg: "fgui.GComponent",
              cc_com_atk_speed: "fgui.GComponent",
              cc_node_effect: "fgui.GLoader",
              cc_level_max: "fgui.Controller",
              cc_progress_hp: "fgui.GProgressBar",
              cc_progress_energy: "fgui.GProgressBar",
              cc_slot_info: "fgui.GComponent",
              cc_button_preset_open: "fgui.GButton",
              cc_button_preset_apply: "fgui.GButton",
              cc_button_preset_1: "fgui.GButton",
              cc_button_preset_2: "fgui.GButton",
              cc_button_preset_3: "fgui.GButton",
              cc_button_preset_4: "fgui.GButton",
              cc_button_preset_5: "fgui.GButton",
              cc_list_item: "fgui.GList",
              cc_ctrl_preset_page: "fgui.Controller",
              cc_ctrl_preset_open: "fgui.Controller",
              cc_money_coin: "CustomMoneyBar",
              cc_layer_skill_bg: "fgui.GComponent",
              cc_com_skill_info: "CustomTowerSkillInfo",
              cc_com_bag: "fgui.GComponent",
              cc_list_bag: "fgui.GList",
              cc_list_sort: "fgui.GList",
              cc_button_sort: "fgui.GButton",
              cc_button_filter_select: "fgui.GButton",
              cc_button_filter: "fgui.GButton",
              cc_ctrl_sort: "fgui.Controller",
              cc_ctrl_filter: "fgui.Controller",
              cc_com_item_info: "CustomHolyItemInfo",
              cc_com_skill_detail: "CustomSkillDetail",
              cc_button_close: "ScaleButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_detail: "fgui.Controller",
          };
      }
      buildUi() {
          this.listAttr = [];
          this.towerDb = this.context.towerDb;
          let contextItem = this.context.item;
          this.contextItem = contextItem;
          this.haveEmptySlot = mgrTower.haveEmptySlot(this.towerDb.id);
          this.qualityDb = db.get_tower_quality(mgrTower.getTowerQualityByDB(this.towerDb));
          this.labelTowerHp = this.progress_hp.getChild("text").asTextField;
          this.labelTowerMp = this.progress_energy.getChild("text").asTextField;
          let skin = new TowerSkin();
          skin.loadSkin(this.towerDb, true);
          this.skin = skin;
          this.loader_tower.displayObject.addChild(skin);
          this.label_cost = this.button_lvup.getChild("cost").asLabel;
          this.listSlot = new ListView(this.list_item, this, this.parseSlotItem, this.renderSlotItem);
          this.listSlot.setOnClickItem(this, this.onClickSlotItem);
          this.listBag = new HolyItemList(this.list_bag, this, this.onClickBagItem);
          this.com_item_info.bindListener(this.onHolyItemChange.bind(this), this.onHolyItemLvup.bind(this));
          this.listSort = new ListView(this.list_sort, this, this.parseSortItem, this.renderSortItem);
          this.listSort.setOnClickItem(this, this.onClickSortItem);
          this.layer_skill_bg.makeFullScreen();
          this.layer_skill_bg.onClick(this, this.onClickSkillBg);
          this.ctrl_filter.on(fgui.Events.STATE_CHANGED, this, this.onFilterStateChange);
          this.ctrl_preset_page.on(fgui.Events.STATE_CHANGED, this, this.onPresetStateChange);
          this.ctrl_preset_open.on(fgui.Events.STATE_CHANGED, this, this.onPresetStateChange);
          this.listSort.setListData([
              "默认排序",
              "品质排序",
              "强化等级排序",
              "种类排序",
          ]);
          this.initEvent();
          this.refresh();
          this.refreshPointRecommAdd();
          if (!Global.isGuiding)
              StageTool.addLongClickEvent(this.button_lvup, this, this.onLongClickBegin, this.onLongClickUpdate, this.onLongClickEnd, [LONG_CLICK_CODE.LVUP]);
          this.parseAttr();
          this.renderAttr();
          this.updateHpBar();
          if (contextItem) {
              this.refreshHolyItemInfo(contextItem, true);
          }
      }
      refreshPointRecommAdd() {
          let skillDb = db.get_skill_db(mgrTower.getTowerSkillId(this.towerDb.id));
          if (skillDb) {
              this.image_recomm_hp.visible = false;
              this.image_recomm_ad.visible = false;
              this.image_recomm_ap.visible = false;
              for (let add of skillDb.recomm_add) {
                  switch (add) {
                      case "HP":
                          this.image_recomm_hp.visible = true;
                          break;
                      case "AD":
                          this.image_recomm_ad.visible = true;
                          break;
                      case "AP":
                          this.image_recomm_ap.visible = true;
                          break;
                  }
              }
          }
      }
      parseAttr() {
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_hp").asCom, BASE_ATTR.HP));
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_ad").asCom, BASE_ATTR.AD));
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_ap").asCom, BASE_ATTR.AP));
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_range").asCom, BASE_ATTR.RANGE));
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_crit").asCom, BASE_ATTR.CRIT));
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_crit_dmg").asCom, BASE_ATTR.CRIT_DMG));
          this.listAttr.push(this.parseAttrItem(this.com_info.getChild("cc_com_atk_speed").asCom, BASE_ATTR.ATK_SPEED));
      }
      parseAttrItem(com, attrId) {
          return { base: com.getChild("base").asLabel, add: com.getChild("add").asLabel, max: com.getChild("max").asLabel, id: attrId };
      }
      onLongClickBegin(id) {
          if (this.destroyed)
              return;
          this.countLongClickUpdate = 0;
          switch (id) {
              case LONG_CLICK_CODE.LVUP:
                  break;
          }
      }
      onLongClickUpdate(id) {
          if (this.destroyed)
              return;
          this.countLongClickUpdate++;
          switch (id) {
              case LONG_CLICK_CODE.LVUP:
                  if (mgrTower.lvupTowerLevel(this.towerDb.id)) {
                      this.onTowerLvup();
                      this.refreshLvupQuick();
                  }
                  break;
          }
      }
      onLongClickEnd(id) {
          if (this.destroyed)
              return;
          switch (id) {
              case LONG_CLICK_CODE.LVUP:
                  this.refresh();
                  break;
          }
      }
      updatePerSecond() {
          this.updateHpBar();
      }
      updateHpBar() {
          let attrCur = mgrTower.towerAttrCurInBattle[this.towerDb.id];
          let attrMax = mgrTower.towerAttrMaxInBattle[this.towerDb.id];
          if (attrCur && attrMax) {
              let percentHp = attrCur[BASE_ATTR.HP] / attrMax[BASE_ATTR.HP] * 100;
              let percentMp = attrCur[BASE_ATTR.MP] / attrMax[BASE_ATTR.MP] * 100;
              this.progress_hp.tweenValue(percentHp, 0.1);
              this.progress_energy.tweenValue(percentMp, 0.1);
              this.labelTowerHp.text = attrCur[BASE_ATTR.HP].toString();
              this.labelTowerMp.text = Math.round(attrCur[BASE_ATTR.MP]).toString();
          }
      }
      dispose() {
          if (this.skin) {
              this.skin.destroy();
              this.skin = null;
          }
          Laya.timer.clear(this, this.updatePerSecond);
          StageTool.remLongClickEvent(this.button_lvup);
          super.dispose();
          Global.sendMsg(MSG.TOWER_ATTR_UPDATE_UID, this.context.uid);
      }
      parseSlotItem(content, object) {
          content.object = object;
          content.quality = object.getController("quality");
          content.state = object.getController("state");
          content.select = object.getController("select");
          content.coinUnlock = object.getChild("coin_unlock").asLabel;
          content.starUnlock = object.getChild("star_unlock").asLabel;
          content.levelUnlock = object.getChild("level_unlock").asLabel;
          content.item = object.getChild("item");
          content.item.touchable = false;
      }
      renderSlotItem(content, data) {
          content.data = data;
          let slot = data.slot;
          if (slot && slot.valid) {
              if (slot.unlock) {
                  if (data.item) {
                      content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
                      content.item.refresh(data.item.holyitem, false);
                      if (this.contextItem && !this.haveEmptySlot) {
                          this.onClickSlotItem(content);
                          this.contextItem = null;
                      }
                  }
                  else {
                      content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ADD;
                      Level.updateRedPoint4Button(content.object, mgrHolyItem.haveAnyItemCanEquip());
                      if (this.contextItem && this.haveEmptySlot) {
                          this.onClickSlotItem(content);
                          this.contextItem = null;
                      }
                  }
              }
              else {
                  content.state.selectedIndex = slot.unlock_type;
                  switch (slot.unlock_type) {
                      case HOLY_ITEM_SLOT_STATE.UNLOCK_COIN:
                          let cost = mgrTower.getUnlocklTowerSlotCost(this.towerDb.id);
                          content.coinUnlock.text = cost.toString();
                          break;
                      case HOLY_ITEM_SLOT_STATE.UNLOCK_LEVEL:
                          let level = db.game_cnf.main_item_slot_unlock_lv[data.index];
                          content.levelUnlock.text = level + "级解锁";
                          break;
                      case HOLY_ITEM_SLOT_STATE.UNLOCK_STAR:
                          let star = db.game_cnf.tower_item_slot_unlock_star[data.index];
                          content.starUnlock.text = mgrTower.getTowerStarName(star) + "解锁";
                          break;
                  }
              }
          }
          else {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.INVALID;
          }
      }
      onClickSlotItem(content) {
          if (content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.INVALID) {
              return;
          }
          if (content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.ITEM || content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.ADD) {
              if (this.selectSlotContent) {
                  this.selectSlotContent.select.selectedIndex = 0;
              }
              this.selectSlotContent = content;
              content.select.selectedIndex = 1;
          }
          switch (content.state.selectedIndex) {
              case HOLY_ITEM_SLOT_STATE.ITEM:
                  this.refreshHolyItemInfo(content.data.item, true);
                  break;
              case HOLY_ITEM_SLOT_STATE.ADD:
                  this.refreshEquipState(null);
                  mgrGame.tryOpenPanelIntro("PanelIntroBag", "info_have_item");
                  let selectHolytem = this.listBag.selectHolytem;
                  if (selectHolytem && selectHolytem.holyitem) {
                      this.refreshHolyItemInfo(selectHolytem, true);
                  }
                  else {
                      if (this.ctrl_state.selectedIndex != TOWER_INFO_STATE.SELECT_ITEM) {
                          this.ctrl_state.selectedIndex = TOWER_INFO_STATE.SELECT_EMPTY;
                      }
                  }
                  break;
              case HOLY_ITEM_SLOT_STATE.UNLOCK_COIN:
                  Director.openPanelWithSingleton("PanelHolyitemSlotUnlock", this.towerDb.id);
                  break;
          }
      }
      parseSortItem(content, object, index) {
          content.button = object;
      }
      renderSortItem(content, name, index) {
          content.button.title = name;
          content.index = index;
      }
      onClickSortItem(content) {
          mgrHolyItem.sortType = content.index;
          this.refreshBagItem(mgrHolyItem.sortType);
          this.ctrl_sort.selectedIndex = 0;
      }
      refreshEquipState(data) {
          if (this.selectSlotContent && this.selectSlotContent.data.item) {
              if (this.selectSlotContent.data.item == data) {
                  this.com_item_info.getEquipController().selectedIndex = 2;
              }
              else {
                  this.com_item_info.getEquipController().selectedIndex = 1;
              }
          }
          else {
              this.com_item_info.getEquipController().selectedIndex = 0;
          }
      }
      refreshHolyItemInfo(data, changeState = false) {
          if (!data)
              return;
          this.refreshEquipState(data);
          this.com_item_info.refresh(data);
          if (changeState)
              this.ctrl_state.selectedIndex = TOWER_INFO_STATE.SELECT_ITEM;
          this.listBag.refreshWithSelect(data);
      }
      onClickBagItem(content) {
          if (content.data) {
              if (content.data.holyitem) {
                  this.refreshHolyItemInfo(content.data, true);
                  return;
              }
          }
          this.ctrl_state.selectedIndex = TOWER_INFO_STATE.SELECT_EMPTY;
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_LVUP_STAR]: this.refresh.bind(this),
              [MSG.TOWER_LV_LIMIT_BREAK]: this.refresh.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onMainSkillChange.bind(this),
              [MSG.HOLY_ITEM_FEED]: this.onHolyItemFeed.bind(this),
              [MSG.TOWER_ATTR_UPDATE]: this.onTowerAttrUpdate.bind(this),
              [MSG.SHOW_TOWER_SKILL_DETAIL]: this.onShowTowerSkillDetail.bind(this),
              [MSG.HOLY_ITEM_SELL]: this.onHolyItemSell.bind(this),
              [MSG.HOLY_ITEM_LOCK]: this.onHolyItemLock.bind(this),
              [MSG.HOLY_ITEM_SLOT_UNLOCK]: this.refresh.bind(this),
              [MSG.PANEL_ADD_POINT_ADD]: this.refreshAttr.bind(this),
              [MSG.PANEL_ADD_POINT_ADD_QUICK]: this.refreshAttrQuick.bind(this),
              [MSG.HOLY_ITEM_FILTER_CHANGE]: this.onFilterStateChange.bind(this),
              [MSG.TOWER_PRESET_CHANGE]: this.onTowerPresetChange.bind(this),
          });
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      getTowerLv() {
          return mgrTower.getTowerLv(this.towerDb.id);
      }
      refresh(reset = false) {
          let limit = mgrTower.getTowerLvLimit(this.towerDb.id);
          let towerLv = this.getTowerLv();
          if (limit) {
              this.label_level_cur.text = towerLv;
              this.label_level_max.text = "/" + limit;
          }
          else {
              this.label_level_cur.text = towerLv;
              this.label_level_max.text = "";
          }
          if (mgrTower.isTowerStarFull(this.towerDb.id)) {
              this.level_max.selectedIndex = towerLv >= limit ? 1 : 0;
          }
          this.label_cost.text = mgrTower.getTowerLvupCost(this.towerDb.id).toString();
          this.skin.refreshQuality(this.towerDb.id);
          if (this.towerDb.main) {
              this.skin.refreshSkillByDB(this.towerDb, reset);
              this.button_talent.visible = true;
          }
          else {
              this.button_talent.visible = false;
              this.skin.syncShooterByDB(this.towerDb);
          }
          this.refreshAttr();
          this.refreshSlotItem();
          this.refreshBagItem(mgrHolyItem.sortType);
          this.refreshSkill();
          this.refreshRedPoint();
          if (this.com_item_info.haveItem()) {
              this.refreshHolyItemInfo(this.com_item_info.selectItem);
          }
          else {
              this.refreshHolyItemInfo(this.listBag.getDataByIndex(0));
          }
      }
      refreshLvupQuick() {
          let limit = mgrTower.getTowerLvLimit(this.towerDb.id);
          if (limit) {
              this.label_level_cur.text = this.getTowerLv();
              this.label_level_max.text = "/" + limit;
          }
          else {
              this.label_level_cur.text = this.getTowerLv();
              this.label_level_max.text = "";
          }
          this.label_cost.text = mgrTower.getTowerLvupCost(this.towerDb.id).toString();
      }
      onHolyItemChange(selectIndex) {
          console.log("点击圣物更换", this.listBag.selectHolytem);
          if (this.selectSlotContent && this.selectSlotContent.data && this.listBag.selectHolytem) {
              let openPreset = this.isOpenPreset();
              let presetId = this.getPresetId();
              switch (selectIndex) {
                  case 0:
                  case 1:
                      let holyitem = this.listBag.selectHolytem.holyitem;
                      if (holyitem && holyitem.isEquiped()) {
                          let msg;
                          if (openPreset) {
                              msg = "该圣物已被" + holyitem.getEquipTowerName() + "所装备，是否【预设给" + this.towerDb.name + "】？";
                          }
                          else {
                              msg = "该圣物已被" + holyitem.getEquipTowerName() + "所装备，是否【装备给" + this.towerDb.name + "】？";
                          }
                          mgrTip.alertPrompt(msg, "", () => {
                              mgrHolyItem.takeOnHolyItem(this.listBag.selectHolytem, this.towerDb.id, this.selectSlotContent.data.id, openPreset, presetId);
                              this.refreshSlotItem();
                              this.refreshHolyItemInfo(this.listBag.selectHolytem);
                          });
                          return;
                      }
                      mgrHolyItem.takeOnHolyItem(this.listBag.selectHolytem, this.towerDb.id, this.selectSlotContent.data.id, openPreset, presetId);
                      break;
                  case 2:
                      mgrHolyItem.takeOffHolyItem(this.towerDb.id, this.selectSlotContent.data.id, openPreset, presetId);
                      break;
              }
              this.refreshSlotItem();
              this.refreshHolyItemInfo(this.listBag.selectHolytem);
          }
      }
      onHolyItemLvup() {
          console.log("点击圣物升级", this.listBag.selectHolytem);
          Director.openPanel("PanelHolyItemLvup", { item: this.listBag.selectHolytem });
      }
      isOpenPreset() {
          return this.ctrl_preset_open.selectedIndex == 1;
      }
      getPresetId() {
          return this.ctrl_preset_page.selectedIndex;
      }
      refreshSlotItem() {
          let listData = [];
          let towerId = this.towerDb.id;
          let slots = mgrTower.getTowerHolyData(towerId);
          let presetId = this.getPresetId();
          let openPreset = this.isOpenPreset();
          let preset = mgrTower.getHolyItemPresetByID(towerId, presetId);
          let indexStar = 0;
          let indexCoin = 0;
          let indexLevel = 0;
          for (let i = 0; i < 8; i++) {
              let slot = slots[i];
              if (slot) {
                  let index = 0;
                  switch (slot.unlock_type) {
                      case HOLY_ITEM_SLOT_STATE.UNLOCK_COIN:
                          index = indexCoin;
                          if (slot.item_uid)
                              indexCoin++;
                          break;
                      case HOLY_ITEM_SLOT_STATE.UNLOCK_LEVEL:
                          index = indexLevel;
                          indexLevel++;
                          break;
                      case HOLY_ITEM_SLOT_STATE.UNLOCK_STAR:
                          index = indexStar;
                          indexStar++;
                          break;
                  }
                  let item;
                  if (openPreset) {
                      item = mgrHolyItem.findBagItemByUID(preset[i]);
                  }
                  else {
                      item = mgrHolyItem.findBagItemByUIDAndTowerId(slot.item_uid, towerId);
                  }
                  listData.push({ id: i, slot: slot, index: index, item: item });
              }
              else {
                  listData.push({ id: i, slot: null, index: HOLY_ITEM_SLOT_STATE.INVALID, item: null });
              }
          }
          listData.sort(this.sortHolyItem.bind(this));
          this.listSlot.setListData(listData);
      }
      calcSlotScore(a) {
          let score = 0;
          if (a.slot) {
              score = a.slot.unlock ? -1000 : 0 + a.slot.unlock_type == HOLY_ITEM_SLOT_STATE.UNLOCK_COIN ? -100 : 0 + a.id;
          }
          else {
              score = Number.MAX_VALUE;
          }
          return score;
      }
      sortHolyItem(a, b) {
          let a_score = this.calcSlotScore(a);
          let b_score = this.calcSlotScore(b);
          return a_score - b_score;
      }
      refreshBagItem(sortType) {
          let useFilter = this.ctrl_filter.selectedIndex ? true : false;
          let listData = mgrHolyItem.getBagItems(sortType, useFilter);
          this.listBag.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      formatPoint(value) {
          if (value) {
              return "+" + value;
          }
          else {
              return value.toString();
          }
      }
      renderAttr() {
          let tower = Level.stage.world.objectMgr.getObjectById(this.context.uid);
          if (tower instanceof Tower) {
              tower.refreshAttr();
          }
          let attrBase = mgrTower.calcTowerAttrBase(this.towerDb.id);
          StageAttr.calcAttrTower(attrBase);
          let attrCurt = mgrTower.getTowerAttrInBattle(this.towerDb.id);
          for (let item of this.listAttr) {
              let attrId = item.id;
              let vBase = attrBase[attrId];
              let vCurt = attrCurt[attrId];
              let vAddd = vCurt - vBase;
              let baseAttrDb = db.get_attr_base(attrId);
              if (baseAttrDb) {
                  if (attrId == BASE_ATTR.HP || attrId == BASE_ATTR.AD || attrId == BASE_ATTR.AP) {
                      vAddd = vCurt - vBase;
                      item.base.text = vBase.toString();
                      item.add.text = "+" + vAddd;
                  }
                  if (attrId == BASE_ATTR.ATK_SPEED) {
                      let skillDb = db.get_skill_db(mgrTower.getTowerSkillId(this.towerDb.id));
                      let atkSpeed = attrCurt[BASE_ATTR.ATK_SPEED];
                      let interval = skillDb.cast_time + skillDb.cd_time;
                      let apsBase = 1 / interval * this.towerDb.atk_speed;
                      let apsCurt = 1 / interval * atkSpeed;
                      let delta = (apsCurt - apsBase).toFixed(baseAttrDb.digit);
                      item.base.text = apsBase.toFixed(baseAttrDb.digit);
                      item.add.text = "+" + delta;
                      if (baseAttrDb.max && apsCurt >= baseAttrDb.max) {
                          item.max.text = "(上限" + baseAttrDb.max + ")";
                          item.max.visible = true;
                      }
                      else {
                          item.max.visible = false;
                      }
                  }
                  else {
                      let base;
                      let addd;
                      if (baseAttrDb.percent) {
                          base = Math.round(vBase * 100) + "%";
                      }
                      else {
                          base = vBase.toString();
                      }
                      item.base.text = base;
                      if (vAddd > 0) {
                          if (baseAttrDb.percent) {
                              addd = Math.round(vAddd * 100) + "%";
                          }
                          else {
                              addd = vAddd.toFixed(baseAttrDb.digit);
                          }
                          item.add.text = "+" + addd;
                      }
                      else {
                          item.add.text = "+0";
                      }
                  }
              }
          }
      }
      refreshAttr() {
          this.renderAttr();
          this.label_left.text = mgrTower.calcTowerPointLeft(this.towerDb.id).toString();
          let data = mgrTower.getTowerPointAdd(this.towerDb.id);
          this.label_base.text = this.formatPoint(data.base);
          this.label_power.text = this.formatPoint(data.power);
          this.label_mana.text = this.formatPoint(data.mana);
          this.refreshRedPoint();
      }
      refreshAttrQuick() {
          this.label_left.text = mgrTower.calcTowerPointLeft(this.towerDb.id).toString();
          let data = mgrTower.getTowerPointAdd(this.towerDb.id);
          this.label_base.text = this.formatPoint(data.base);
          this.label_power.text = this.formatPoint(data.power);
          this.label_mana.text = this.formatPoint(data.mana);
      }
      refreshSkill() {
          this.com_skill_info.refresh(this.towerDb);
      }
      onTowerPresetChange() {
          this.refreshSlotItem();
      }
      onFilterStateChange() {
          this.refreshBagItem(mgrHolyItem.sortType);
      }
      onPresetStateChange() {
          this.refreshSlotItem();
      }
      onMainSkillChange() {
          this.ctrl_detail.selectedIndex = 0;
          this.refresh(true);
          this.refreshPointRecommAdd();
      }
      onHolyItemFeed() {
          this.refresh();
      }
      onTowerAttrUpdate() {
          this.refresh();
      }
      onHolyItemSell() {
          this.refresh();
          if (!this.com_item_info.haveItem()) {
              this.ctrl_state.selectedIndex = TOWER_INFO_STATE.SELECT_EMPTY;
          }
      }
      onHolyItemLock(uid) {
          this.refreshBagItem(mgrHolyItem.sortType);
      }
      onShowTowerSkillDetail(skillId) {
          if (skillId) {
              if (skillId != this.detailSkillId) {
                  this.ctrl_detail.selectedIndex = 1;
                  this.com_skill_detail.refresh(skillId);
              }
              else {
                  if (this.ctrl_detail.selectedIndex)
                      this.ctrl_detail.selectedIndex = 0;
                  else
                      this.ctrl_detail.selectedIndex = 1;
              }
          }
          else {
              this.ctrl_detail.selectedIndex = 0;
          }
          this.detailSkillId = skillId;
      }
      onClickSkillBg() {
          this.ctrl_detail.selectedIndex = 0;
          this.detailSkillId = null;
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_lvup, mgrTower.canLvupTowerLevel(this.towerDb.id));
          let haveAttrPoint = mgrTower.calcTowerPointLeft(this.towerDb.id) > 0;
          Level.updateRedPoint4Button(this.button_add_base, haveAttrPoint);
          Level.updateRedPoint4Button(this.button_add_mana, haveAttrPoint);
          Level.updateRedPoint4Button(this.button_add_power, haveAttrPoint);
      }
      onTowerLvup() {
          if (this.towerDb.main) {
              mgrTask.doEvent(db.TASK_EVENT_ID.LVUP_TOWER_MAIN);
              mgrGame.showIceBreakUI();
          }
          else {
              mgrTask.doEvent(db.TASK_EVENT_ID.LVUP_TOWER);
          }
          let lv = this.getTowerLv();
          GameStatistics.statisCommonEvent(this.towerDb.lv_statis_point, Math.min(lv, 2000));
      }
      openPointAddUI(button, type) {
          let point = button.localToGlobal();
          Director.openPanelWithSingleton("PanelAddPoint", { towerId: this.towerDb.id, point: point, type: type });
      }
      applyPreset() {
          this.ctrl_preset_open.selectedIndex = 0;
          mgrTower.applyHolyItemPreset(this.towerDb.id, this.getPresetId());
          this.refreshSlotItem();
      }
      on_click_button_close() {
          if (this.ctrl_state.selectedIndex != TOWER_INFO_STATE.INFO) {
              this.ctrl_state.selectedIndex = TOWER_INFO_STATE.INFO;
              return;
          }
          if (this.ctrl_preset_open.selectedIndex) {
              this.ctrl_preset_open.selectedIndex = 0;
              return;
          }
          this.closeWithTransition();
      }
      on_click_button_lvup() {
          mgrNetwork.callByNetwork(() => {
              if (mgrTower.lvupTowerLevel(this.towerDb.id)) {
                  let data = Director.getScene3DLayer(3);
                  let effect = EffectFactory.create("141_ui_once_bk_levp_03", data.scene3d);
                  effect.followFguiNode(data.camera, this.node_effect);
                  this.onTowerLvup();
                  this.refresh();
              }
          });
      }
      on_click_button_add_base() {
          this.openPointAddUI(this.button_add_base, PanelAddPoint.TYPE_ADD_BASE);
      }
      on_click_button_add_power() {
          this.openPointAddUI(this.button_add_power, PanelAddPoint.TYPE_ADD_POWER);
      }
      on_click_button_add_mana() {
          this.openPointAddUI(this.button_add_mana, PanelAddPoint.TYPE_ADD_MANA);
      }
      on_click_button_reset() {
          mgrTower.resetTowerPoint(this.towerDb.id);
          this.refreshAttr();
      }
      on_click_button_sort() {
      }
      on_click_button_talent() {
          Director.openPanelWithSingleton("PanelTalent");
      }
      on_click_button_lvbreak() {
          Director.openPanelWithSingleton("PanelTowerLvBreak", { towerDb: this.towerDb });
      }
      on_click_button_filter_select() {
      }
      on_click_button_filter() {
          Director.openPanelWithSingleton("PanelHolyItemFilter");
      }
      on_click_button_preset_apply() {
          this.applyPreset();
      }
      on_click_button_preset_1() {
      }
      on_click_button_preset_2() {
      }
      on_click_button_preset_3() {
      }
      on_click_button_preset_open() {
      }
      on_click_button_preset_4() {
      }
      on_click_button_preset_5() {
      }
  }

  class PanelTowerInfoFinalWar extends PanelTowerInfo {
      buildUi() {
          super.buildUi();
          this.com_skill_info.hideStarLvupMenu();
          this.button_talent.visible = false;
          this.button_lvup.visible = false;
          this.button_lvbreak.visible = false;
          this.button_preset_open.visible = false;
      }
      dispose() {
          super.dispose();
      }
      getTowerLv() {
          return mgrFinalWar.getTowerLv(this.towerDb.id);
      }
      renderSlotItem(content, data) {
          content.data = data;
          let slot = data.slot;
          if (slot && slot.valid) {
              if (slot.unlock) {
                  if (data.item) {
                      content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
                      content.item.refresh(data.item.holyitem, false);
                  }
                  else {
                      content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.INVALID;
                  }
              }
              else {
                  content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.INVALID;
              }
          }
          else {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.INVALID;
          }
      }
      onClickSlotItem(content) {
          if (content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.INVALID) {
              return;
          }
          if (content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.ITEM || content.state.selectedIndex == HOLY_ITEM_SLOT_STATE.ADD) {
              if (this.selectSlotContent) {
                  this.selectSlotContent.select.selectedIndex = 0;
              }
              this.selectSlotContent = content;
              content.select.selectedIndex = 1;
          }
          switch (content.state.selectedIndex) {
              case HOLY_ITEM_SLOT_STATE.ITEM:
                  let object = content.object;
                  Director.openPanelWithSingleton("PanelHolyitemInfo", { item: content.data.item.holyitem, point: object.localToGlobal(object.width * 0.5, object.height * 0.5) });
                  break;
          }
      }
      renderAttr() {
          let attrBase = mgrTower.calcTowerAttrBaseByFinalWar(this.towerDb.id);
          StageAttr.calcAttrTower(attrBase);
          let attrCurt = mgrTower.calcTowerAttrByFinalWar(this.towerDb.id);
          this.button_reset.visible = true;
          for (let item of this.listAttr) {
              let attrId = item.id;
              let vBase = attrBase[attrId];
              let vCurt = attrCurt[attrId];
              let vAddd = vCurt - vBase;
              let baseAttrDb = db.get_attr_base(attrId);
              if (baseAttrDb) {
                  if (attrId == BASE_ATTR.HP || attrId == BASE_ATTR.AD || attrId == BASE_ATTR.AP) {
                      vAddd = vCurt - vBase;
                      item.base.text = vBase.toString();
                      item.add.text = "+" + vAddd;
                  }
                  if (attrId == BASE_ATTR.ATK_SPEED) {
                      let skillDb = db.get_skill_db(mgrTower.getTowerSkillId(this.towerDb.id));
                      let atkSpeed = attrCurt[BASE_ATTR.ATK_SPEED];
                      let interval = skillDb.cast_time + skillDb.cd_time;
                      let apsBase = 1 / interval * this.towerDb.atk_speed;
                      let apsCurt = 1 / interval * atkSpeed;
                      let delta = (apsCurt - apsBase).toFixed(baseAttrDb.digit);
                      item.base.text = apsBase.toFixed(baseAttrDb.digit);
                      item.add.text = "+" + delta;
                      if (baseAttrDb.max && apsCurt >= baseAttrDb.max) {
                          item.max.text = "(上限" + baseAttrDb.max + ")";
                          item.max.visible = true;
                      }
                      else {
                          item.max.visible = false;
                      }
                  }
                  else {
                      let base;
                      let addd;
                      if (baseAttrDb.percent) {
                          base = Math.round(vBase * 100) + "%";
                      }
                      else {
                          base = vBase.toString();
                      }
                      item.base.text = base;
                      if (vAddd > 0) {
                          if (baseAttrDb.percent) {
                              addd = Math.round(vAddd * 100) + "%";
                          }
                          else {
                              addd = vAddd.toFixed(baseAttrDb.digit);
                          }
                          item.add.text = "+" + addd;
                      }
                      else {
                          item.add.text = "+0";
                      }
                  }
              }
          }
      }
      refreshAttr() {
          this.renderAttr();
          this.label_left.text = mgrFinalWar.calcTowerPointLeft(this.towerDb.id).toString();
          let data = mgrFinalWar.getTowerPointAdd(this.towerDb.id);
          this.label_base.text = this.formatPoint(data.base);
          this.label_power.text = this.formatPoint(data.power);
          this.label_mana.text = this.formatPoint(data.mana);
          this.refreshRedPoint();
      }
      refreshAttrQuick() {
          this.label_left.text = mgrFinalWar.calcTowerPointLeft(this.towerDb.id).toString();
          let data = mgrFinalWar.getTowerPointAdd(this.towerDb.id);
          this.label_base.text = this.formatPoint(data.base);
          this.label_power.text = this.formatPoint(data.power);
          this.label_mana.text = this.formatPoint(data.mana);
      }
      openPointAddUI(button, type) {
          let point = button.localToGlobal();
          Director.openPanelWithSingleton("PanelAddPointFinalWar", { towerId: this.towerDb.id, point: point, type: type });
      }
      on_click_button_talent() {
      }
      on_click_button_reset() {
          mgrFinalWar.resetTowerPoint(this.towerDb.id);
          this.refreshAttr();
      }
      on_click_button_add_base() {
          super.on_click_button_add_base();
      }
      on_click_button_add_power() {
          super.on_click_button_add_power();
      }
      on_click_button_add_mana() {
          super.on_click_button_add_mana();
      }
      on_click_button_lvup() {
      }
      on_click_button_lvbreak() {
      }
      on_click_button_preset_open() {
      }
      on_click_button_preset_apply() {
      }
      on_click_button_preset_1() {
      }
      on_click_button_preset_2() {
      }
      on_click_button_preset_3() {
      }
      on_click_button_sort() {
      }
      on_click_button_filter_select() {
      }
      on_click_button_filter() {
      }
      on_click_button_close() {
          super.on_click_button_close();
      }
      on_click_button_preset_4() {
      }
      on_click_button_preset_5() {
      }
  }

  class CustomTowerOptionFinalWar extends CustomTowerOption {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomTowerOptionFinalWar";
          this.exportNodeNames = {
              cc_button_info: "fgui.GButton",
              cc_button_takeoff: "fgui.GButton",
              cc_button_deploy: "fgui.GButton",
              cc_ctrl_layout: "fgui.Controller",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
      bindTower(tower, isTowerRush = false) {
          this.tower = tower;
          this.button_info.enabled = tower != null;
          if (tower) {
              let slot = db.get_tower_pos(mgrTower.defaultPosGid, tower.slotId - 1);
              if (slot) {
                  this.ctrl_layout.selectedIndex = slot.layout;
              }
          }
      }
      on_click_button_info() {
          if (this.tower) {
              Global.sendMsg(MSG.GUIDE_TIP_UPDATE, "CLICK_TOWER_ATTR_" + this.tower.towerDb.id);
              Director.openPanelByClass(PanelTowerInfoFinalWar, "PanelTowerInfoFinalWar", { towerDb: this.tower.towerDb, uid: this.tower.uid });
          }
      }
      on_click_button_takeoff() {
      }
      on_click_button_deploy() {
          Director.openPanel("PanelDeploy");
      }
  }

  class PanelAddPointDailyDamage extends PanelAddPoint {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_info/PanelAddPointFinalWar";
          this.exportNodeNames = {
              cc_layer_bg: "fgui.GComponent",
              cc_com_add: "fgui.GComponent",
              cc_button_add_1: "fgui.GButton",
              cc_button_add_half: "fgui.GButton",
              cc_button_add_all: "fgui.GButton",
          };
      }
      buildUi() {
          super.buildUi();
      }
      dispose() {
          super.dispose();
      }
      addPoint(add = 1) {
          switch (this.context.type) {
              case PanelAddPoint.TYPE_ADD_BASE:
                  mgrDailyDamage.assignTowerPointBase(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_POWER:
                  mgrDailyDamage.assignTowerPointPower(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_MANA:
                  mgrDailyDamage.assignTowerPointMana(this.towerId, add);
                  break;
          }
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD);
      }
      addPointQuick(add = 1) {
          switch (this.context.type) {
              case PanelAddPoint.TYPE_ADD_BASE:
                  mgrDailyDamage.assignTowerPointBase(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_POWER:
                  mgrDailyDamage.assignTowerPointPower(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_MANA:
                  mgrDailyDamage.assignTowerPointMana(this.towerId, add);
                  break;
          }
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD_QUICK);
      }
      on_click_button_add_1() {
          this.addPoint();
      }
      on_click_button_add_half() {
          this.addPoint(mgrDailyDamage.calcTowerPointLeftHalf(this.towerId));
      }
      on_click_button_add_all() {
          this.addPoint(mgrDailyDamage.calcTowerPointLeft(this.towerId));
      }
  }

  class PanelTowerInfoDailyDamage extends PanelTowerInfoFinalWar {
      buildUi() {
          super.buildUi();
      }
      dispose() {
          super.dispose();
      }
      getTowerLv() {
          return mgrDailyDamage.getTowerLv(this.towerDb.id);
      }
      renderAttr() {
          let attrBase = mgrTower.calcTowerAttrBaseByDailyDamage(this.towerDb.id);
          StageAttr.calcAttrTower(attrBase);
          let attrCurt = mgrTower.calcTowerAttrByDailyDamage(this.towerDb.id);
          this.button_reset.visible = true;
          for (let item of this.listAttr) {
              let attrId = item.id;
              let vBase = attrBase[attrId];
              let vCurt = attrCurt[attrId];
              let vAddd = vCurt - vBase;
              let baseAttrDb = db.get_attr_base(attrId);
              if (baseAttrDb) {
                  if (attrId == BASE_ATTR.HP || attrId == BASE_ATTR.AD || attrId == BASE_ATTR.AP) {
                      vAddd = vCurt - vBase;
                      item.base.text = vBase.toString();
                      item.add.text = "+" + vAddd;
                  }
                  if (attrId == BASE_ATTR.ATK_SPEED) {
                      let skillDb = db.get_skill_db(mgrTower.getTowerSkillId(this.towerDb.id));
                      let atkSpeed = attrCurt[BASE_ATTR.ATK_SPEED];
                      let interval = skillDb.cast_time + skillDb.cd_time;
                      let apsBase = 1 / interval * this.towerDb.atk_speed;
                      let apsCurt = 1 / interval * atkSpeed;
                      let delta = (apsCurt - apsBase).toFixed(baseAttrDb.digit);
                      item.base.text = apsBase.toFixed(baseAttrDb.digit);
                      item.add.text = "+" + delta;
                      if (baseAttrDb.max && apsCurt >= baseAttrDb.max) {
                          item.max.text = "(上限" + baseAttrDb.max + ")";
                          item.max.visible = true;
                      }
                      else {
                          item.max.visible = false;
                      }
                  }
                  else {
                      let base;
                      let addd;
                      if (baseAttrDb.percent) {
                          base = Math.round(vBase * 100) + "%";
                      }
                      else {
                          base = vBase.toString();
                      }
                      item.base.text = base;
                      if (vAddd > 0) {
                          if (baseAttrDb.percent) {
                              addd = Math.round(vAddd * 100) + "%";
                          }
                          else {
                              addd = vAddd.toFixed(baseAttrDb.digit);
                          }
                          item.add.text = "+" + addd;
                      }
                      else {
                          item.add.text = "+0";
                      }
                  }
              }
          }
      }
      refreshAttr() {
          this.renderAttr();
          this.label_left.text = mgrDailyDamage.calcTowerPointLeft(this.towerDb.id).toString();
          let data = mgrDailyDamage.getTowerPointAdd(this.towerDb.id);
          this.label_base.text = this.formatPoint(data.base);
          this.label_power.text = this.formatPoint(data.power);
          this.label_mana.text = this.formatPoint(data.mana);
          this.refreshRedPoint();
      }
      refreshAttrQuick() {
          this.label_left.text = mgrDailyDamage.calcTowerPointLeft(this.towerDb.id).toString();
          let data = mgrDailyDamage.getTowerPointAdd(this.towerDb.id);
          this.label_base.text = this.formatPoint(data.base);
          this.label_power.text = this.formatPoint(data.power);
          this.label_mana.text = this.formatPoint(data.mana);
      }
      openPointAddUI(button, type) {
          let point = button.localToGlobal();
          Director.openPanelWithSingletonByClass(PanelAddPointDailyDamage, "PanelAddPointDailyDamage", { towerId: this.towerDb.id, point: point, type: type });
      }
      on_click_button_talent() {
      }
      on_click_button_reset() {
          mgrDailyDamage.resetTowerPoint(this.towerDb.id);
          this.refreshAttr();
      }
      on_click_button_add_base() {
          super.on_click_button_add_base();
      }
      on_click_button_add_power() {
          super.on_click_button_add_power();
      }
      on_click_button_add_mana() {
          super.on_click_button_add_mana();
      }
      on_click_button_lvup() {
      }
      on_click_button_lvbreak() {
      }
      on_click_button_preset_open() {
      }
      on_click_button_preset_apply() {
      }
      on_click_button_preset_1() {
      }
      on_click_button_preset_2() {
      }
      on_click_button_preset_3() {
      }
      on_click_button_sort() {
      }
      on_click_button_filter_select() {
      }
      on_click_button_filter() {
      }
      on_click_button_close() {
          super.on_click_button_close();
      }
  }

  class CustomTowerOptionDailyDamage extends CustomTowerOptionFinalWar {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomTowerOptionDailyDamage";
          this.exportNodeNames = {
              cc_button_info: "fgui.GButton",
              cc_button_takeoff: "fgui.GButton",
              cc_button_deploy: "fgui.GButton",
              cc_ctrl_layout: "fgui.Controller",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
      on_click_button_info() {
          if (this.tower) {
              Global.sendMsg(MSG.GUIDE_TIP_UPDATE, "CLICK_TOWER_ATTR_" + this.tower.towerDb.id);
              Director.openPanelByClass(PanelTowerInfoDailyDamage, "PanelTowerInfoDailyDamage", { towerDb: this.tower.towerDb, uid: this.tower.uid });
          }
      }
      on_click_button_takeoff() {
      }
      on_click_button_deploy() {
      }
  }

  class CustomWechatHutuiListVer extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomWechatHutuiListVer";
          this.exportNodeNames = {
              cc_list_item: "fgui.GList",
          };
      }
      onCreate() {
          if (!CopHelper.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_jump_other_game_left)) {
              this.visible = false;
          }
          else {
              this.listView = new ListView(this.list_item, this, this.parseExpertItem, this.renderExpertItem);
              this.listView.setOnClickItem(this, this.onClickExpertItem);
              mgrSdk.openJump("list");
              Global.registerListeners(this, {
                  [BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
              });
          }
      }
      dispose() {
          super.dispose();
      }
      onMsgOpenJumpResult(e) {
          if (e.type == "list") {
              if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
                  this.visible = false;
                  return;
              }
              else {
                  this.visible = true;
              }
              let datas = e.jumpInfo;
              this.datas = datas;
              this.listView.setListData(this.datas);
              if (this.datas && this.datas.length >= 6) {
                  let tween = cc$1.tween();
                  for (let i = 0; i < this.datas.length - 5; i++) {
                      tween.delay(2).call(() => {
                          this.listView.scrollToView(i, true, true);
                      });
                  }
                  for (let i = this.datas.length - 6; i >= 0; i--) {
                      tween.delay(2).call(() => {
                          this.listView.scrollToView(i, true, true);
                      });
                  }
                  cc$1.tween(this)
                      .repeatForever(tween)
                      .start();
              }
          }
      }
      parseExpertItem(content, button) {
          content.button = button;
      }
      renderExpertItem(content, data) {
          content.button.icon = data.url;
          content.index = data.index;
      }
      onClickExpertItem(content) {
          mgrSdk.jumpOtherGame(content.index, "list");
      }
  }

  class CustomWechatHutuiSingle extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomWechatHutuiSingle";
          this.exportNodeNames = {
              cc_button_jump: "fgui.GButton",
          };
      }
      onCreate() {
          if (!CopHelper.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_jump_other_game)) {
              this.visible = false;
          }
          else {
              Global.registerListeners(this, {
                  [BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
              });
              mgrSdk.openJump("single");
              Timer.callLoop(2, () => {
                  mgrSdk.openJump("single");
              }, this);
          }
      }
      dispose() {
          super.dispose();
      }
      onMsgOpenJumpResult(e) {
          if (e.type == "single") {
              if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
                  this.visible = false;
                  return;
              }
              else {
                  this.visible = true;
              }
              let datas = e.jumpInfo;
              this.datas = datas;
              this.button_jump.icon = this.datas[0].url;
          }
      }
      on_click_button_jump() {
          if (this.datas && this.datas[0]) {
              mgrSdk.jumpOtherGame(this.datas[0].index, "single");
          }
      }
  }

  class CustomBattleBar extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomBattleBar";
          this.exportNodeNames = {
              cc_progress_coming: "fgui.GProgressBar",
              cc_com_next: "fgui.GComponent",
              cc_label_layer: "fgui.GBasicTextField",
              cc_button_autonext: "fgui.GButton",
              cc_button_failnext: "fgui.GButton",
              cc_com_tip: "fgui.GComponent",
              cc_label_tip: "fgui.GBasicTextField",
              cc_list_word: "fgui.GList",
              cc_ctrl_battle_bar_mode: "fgui.Controller",
          };
      }
      onCreate() {
          this.lableProgressComing = this.progress_coming.getChild("text").asTextField;
          this.listWord = new ListView(this.list_word, this, this.parseWordItem, this.renderWordItem);
          this.listWord.setOnClickItem(this, this.clickWordItem);
          this.com_tip.onClick(this, this.onClickWordTip);
          this.initEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.GAME_PROGRESS_CHANGE]: this.onGameProgressChange.bind(this),
          });
      }
      onGameProgressChange(percent) {
          if (percent > 100)
              percent = 100;
          this.lableProgressComing.text = percent.toFixed(2) + "%";
          this.progress_coming.tweenValue(percent, 0.1);
      }
      parseWordItem(content, view) {
          content.view = view;
      }
      renderWordItem(content, data) {
          content.data = data;
          content.view.icon = data.icon;
      }
      refreshWordList() {
          let listData = [];
          let attr = StageAttr.stageAttr;
          for (let i = 0; i < STAGE_ATTR.LEN_SECRET; i++) {
              let v = attr[i];
              if (v > 0) {
                  let key = STAGE_ATTR[i];
                  let wordDb = db.get_secret_word_db(key);
                  if (wordDb)
                      listData.push(wordDb);
              }
          }
          this.listWord.setListData(listData);
      }
      clickWordItem(content) {
          let data = content.data;
          let gPos = content.view.localToGlobal();
          let lPos = this.globalToLocal(gPos.x, gPos.y);
          this.com_tip.x = lPos.x + content.view.width * 0.5;
          this.label_tip.text = Utils.sprintf(data.desc, Math.floor(StageAttr.getAttrBySK(data.id) * 100));
          if (this.lastWordDb != data) {
              this.com_tip.visible = true;
          }
          else {
              this.com_tip.visible = !this.com_tip.visible;
          }
          this.lastWordDb = data;
      }
      refresh(mode) {
          this.label_layer.text = mgrGame.levelId.toString();
          this.button_autonext.selected = mgrGame.rushAutoNext;
          this.button_failnext.selected = mgrGame.rushFailNext;
          if (mode < this.ctrl_battle_bar_mode.pageCount)
              this.ctrl_battle_bar_mode.selectedIndex = mode;
          this.progress_coming.value = 0;
          this.lableProgressComing.text = "0%";
          this.com_tip.visible = false;
          this.refreshWordList();
      }
      onClickWordTip() {
          this.com_tip.visible = false;
      }
      on_click_button_autonext() {
          mgrGame.rushAutoNext = this.button_autonext.selected;
      }
      on_click_button_failnext() {
          mgrGame.rushFailNext = this.button_failnext.selected;
      }
  }

  class CustomGameHand extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomGameHand";
          this.listTowerSkill = [];
          this.exportNodeNames = {
              cc_tower_0: "CustomHandSkillBig",
              cc_tower_1: "CustomHandSkill",
              cc_tower_2: "CustomHandSkill",
              cc_tower_3: "CustomHandSkill",
              cc_tower_4: "CustomHandSkill",
              cc_tower_5: "CustomHandSkill",
              cc_tower_6: "CustomHandSkill",
              cc_trans_in: "fgui.Transition",
          };
      }
      onCreate() {
          for (let i = 0; i < 7; i++) {
              this.listTowerSkill.push(this["tower_" + i]);
          }
      }
      dispose() {
          super.dispose();
      }
      openHand() {
          this.refresh(false);
          this.trans_in.stop();
          this.trans_in.play(Laya.Handler.create(this, this.onTransInEnd));
      }
      onTransInEnd() {
          for (let i = 0; i < this.listTowerSkill.length; i++) {
              let towerSkill = this.listTowerSkill[i];
              if (towerSkill) {
                  towerSkill.onTransInEnd();
              }
          }
      }
      refresh(ready) {
          let listTowerIds = [];
          let towerPos = db.get_tower_pos_map()[mgrTower.defaultPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              let id = mgrTower.getSlotTower(pos.id - 1);
              if (id) {
                  listTowerIds.push(id);
              }
          }
          for (let i = 0; i < this.listTowerSkill.length; i++) {
              let towerSkill = this.listTowerSkill[i];
              let towerId = listTowerIds[i];
              if (towerSkill) {
                  if (towerId != null) {
                      towerSkill.bindTowerId(towerId, ready);
                  }
                  else {
                      towerSkill.unbindTower();
                  }
              }
          }
      }
      closeHand() {
      }
  }

  class CustomGameHand2 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/CustomGameHand2";
          this.listTowerSkill = [];
          this.exportNodeNames = {
              cc_tower_0: "CustomHandSkillBig",
              cc_tower_1: "CustomHandSkill",
              cc_tower_2: "CustomHandSkill",
              cc_tower_3: "CustomHandSkill",
              cc_tower_4: "CustomHandSkill",
              cc_tower_5: "CustomHandSkill",
              cc_tower_6: "CustomHandSkill",
              cc_tower_7: "CustomHandSkill",
              cc_tower_8: "CustomHandSkill",
              cc_tower_9: "CustomHandSkill",
              cc_tower_10: "CustomHandSkill",
              cc_trans_in: "fgui.Transition",
          };
      }
      onCreate() {
          for (let i = 0; i < 11; i++) {
              this.listTowerSkill.push(this["tower_" + i]);
          }
      }
      dispose() {
          super.dispose();
      }
      openHand() {
          this.refresh(false);
          this.trans_in.stop();
          this.trans_in.play(Laya.Handler.create(this, this.onTransInEnd));
      }
      onTransInEnd() {
          for (let i = 0; i < this.listTowerSkill.length; i++) {
              let towerSkill = this.listTowerSkill[i];
              if (towerSkill) {
                  towerSkill.onTransInEnd();
              }
          }
      }
      refresh(ready) {
          let listTowerIds = [];
          let towerPos = db.get_tower_pos_map()[mgrTower.defaultPosGid];
          for (let i = 0; i < towerPos.length; i++) {
              let pos = towerPos[i];
              let id = mgrTower.getSlotTower(pos.id - 1);
              if (id) {
                  listTowerIds.push(id);
              }
          }
          for (let i = 0; i < this.listTowerSkill.length; i++) {
              let towerSkill = this.listTowerSkill[i];
              let towerId = listTowerIds[i];
              if (towerSkill) {
                  if (towerId != null) {
                      towerSkill.bindTowerId(towerId, ready);
                  }
                  else {
                      towerSkill.unbindTower();
                  }
              }
          }
      }
      closeHand() {
      }
  }

  class PanelADFree extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/PanelADFree";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_label_desc: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_ensure() {
          let funcEnsure = this.context.funcEnsure;
          if (funcEnsure) {
              funcEnsure();
          }
          this.close();
      }
  }

  class PanelComing extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/PanelComing";
          this.bMask = false;
          this.exportNodeNames = {
              cc_node_effect: "fgui.GLoader",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          let transIn = this.resNode.getTransition("in");
          transIn.play(Laya.Handler.create(this, this.onTransInEnd), 1);
          Laya.timer.once(300, this, this.onCreateEffect);
          mgrSound.playMusic("sBgBattle");
          mgrSound.playSound("battle_enter");
      }
      onCreateEffect() {
          if (this.destroyed)
              return;
          let data = Director.getScene3DLayer(3);
          let effect = EffectFactory.create("166_ui_once_glow_01", data.scene3d);
          ;
          if (effect) {
              effect.followFguiNode(data.camera, this.node_effect);
          }
      }
      onTransInEnd() {
          let transOut = this.resNode.getTransition("out");
          transOut.play(Laya.Handler.create(this, this.onTransOut), 1);
          Global.sendMsg(MSG.TOWER_RUSH_READY);
      }
      onMsgTowerRushEnd() {
          this.close();
      }
      dispose() {
          Laya.timer.clearAll(this);
          super.dispose();
      }
      onTransOut() {
          this.close();
      }
  }

  class mgrOffline extends Manager {
      static onLoad() {
          super.onLoad();
          this.initEvent();
      }
      static onStart() {
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static initEvent() {
          Global.registerListeners(this, {
              [MSG.TIME_OFFLINE_TIME]: this.onTimeOfflineTime.bind(this),
          });
      }
      static onTimeOfflineTime(second) {
          this.calcOfflineReward(second);
      }
      static getRewardData() {
          return this.data.reward;
      }
      static setRewardData(reward) {
          this.data.reward = reward;
          this.saveRecord();
      }
      static calcOfflineReward(second) {
          if (Global.isGuiding)
              return;
          if (second < db.game_cnf.time_offline_min * 60)
              return;
          let reward = this.calcRewardData(second);
          this.setRewardData(reward);
          console.log("计算离线奖励:", second, reward.coin, reward.diamond);
      }
      static canReward() {
          return this.getRewardData() != null;
      }
      static showOfflineUI() {
          if (this.canReward()) {
              Director.openPanel("PanelOffline");
          }
      }
      static calcRewardData(second) {
          let minute = second / 60;
          let minuteMax = db.game_cnf.time_offline_max;
          if (minute > minuteMax) {
              minute = minuteMax;
          }
          if (minute >= db.game_cnf.time_offline_min) {
              let towerLvMax = Math.min(1000, mgrTower.getTowerLvMax());
              let coin = Formula.offlineCoin(mgrGame.getEnemyCoin(), minute);
              let diamond = Formula.offlineDiamond(towerLvMax, minute);
              coin = Math.min(coin, db.game_cnf.offline_limit_coin);
              diamond = Math.min(diamond, db.game_cnf.offline_limit_diamond);
              return { coin: coin, diamond: diamond };
          }
          return null;
      }
      static getReward(scale = 1) {
          let rewardData = this.getRewardData();
          if (rewardData) {
              this.setRewardData(null);
              let dropData = [];
              if (rewardData.coin) {
                  mgrGame.addItem(1001, rewardData.coin * scale, 32, false, dropData);
              }
              if (rewardData.diamond) {
                  mgrGame.addItem(1000, rewardData.diamond * scale, 32, false, dropData);
              }
              Level.showItemGet(dropData);
          }
      }
  }
  mgrOffline.RECORD_KEY = "game166_offline_v1.0";
  mgrOffline.dataDefault = {
      reward: null,
  };

  class mgrPrayCoin extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static onDifferentDay() {
          this.useTime = 0;
          this.useDeepTime = 0;
          this.useFreeTime = 0;
          this.freeLastTime = 0;
          this.saveRecord();
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrPrayCoin.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static getRewardCount() {
          let mineCountInit = db.cop_db.mine_configs[0];
          let minCountAdd = db.cop_db.mine_configs[2];
          return mineCountInit + minCountAdd * this.useDeepTime;
      }
      static set useTime(value) {
          this.data.use_time = value;
          this.saveRecord();
      }
      static get useTime() {
          return this.data.use_time;
      }
      static set useDeepTime(value) {
          this.data.use_time_deep = value;
          this.saveRecord();
      }
      static get useDeepTime() {
          return this.data.use_time_deep;
      }
      static set useFreeTime(value) {
          this.data.use_time_free = value;
          this.saveRecord();
      }
      static get useFreeTime() {
          return this.data.use_time_free;
      }
      static set freeLastTime(value) {
          this.data.free_last_time = value;
          this.saveRecord();
      }
      static get freeLastTime() {
          return this.data.free_last_time;
      }
      static getLeftTime() {
          let dailyTime = db.cop_db.mine_configs[4];
          let left = dailyTime - this.useTime;
          if (left < 0)
              left = 0;
          return left;
      }
      static getDesc() {
          let scale = db.cop_db.mine_configs[1];
          let add = db.cop_db.mine_configs[2];
          return Utils.sprintf(db.game_cnf.pray_coin_desc, scale, add);
      }
      static checkFreeCD() {
          let cd = db.cop_db.mine_configs[3];
          let curtTime = Timer.time;
          let lastTime = this.freeLastTime;
          let passTime = 0;
          if (lastTime > 0) {
              passTime = curtTime - lastTime;
          }
          else {
              passTime = cd;
          }
          return passTime >= cd;
      }
      static getFreeCDLeftTime() {
          let cd = db.cop_db.mine_configs[3];
          let curtTime = Timer.time;
          let lastTime = this.freeLastTime;
          let passTime = 0;
          if (lastTime > 0) {
              passTime = curtTime - lastTime;
          }
          else {
              passTime = cd;
          }
          let leftTime = cd - passTime;
          return leftTime;
      }
      static startFreeCD() {
          this.freeLastTime = Timer.time;
      }
      static getReward(scale = 1) {
          let count = this.getRewardCount();
          mgrGame.addItem(1000, count * scale, 45, false);
          let items = [];
          for (let i = 0; i < scale; i++) {
              let item = { itemId: 1000, count: count };
              items.push({ data: item });
          }
          Director.openPanel("PanelItemGet", { items: items });
      }
      static canDigFree() {
          return this.checkFreeCD() && this.getLeftTime() > 0;
      }
      static digDeep() {
          if (this.getLeftTime()) {
              let mindSuperScale = db.cop_db.mine_configs[1];
              this.getReward(mindSuperScale);
              this.useTime++;
              this.useDeepTime++;
              this.onDig();
          }
      }
      static digFree() {
          if (this.checkFreeCD() && this.getLeftTime()) {
              this.getReward();
              this.useTime++;
              this.useFreeTime++;
              this.startFreeCD();
              this.onDig();
          }
      }
      static onDig() {
          mgrTask.doEvent(db.TASK_EVENT_ID.OPEN_PRAY_COIN);
          Global.sendMsg(MSG.PRAY_COIN_REFRESH);
          Global.sendMsg(MSG.REFRESH_RED_POINT);
      }
      static haveRedPoint() {
          return this.canDigFree();
      }
  }
  mgrPrayCoin.RECORD_KEY = "game166_mine_v1.0";
  mgrPrayCoin.dataDefault = {
      use_time: 0,
      use_time_deep: 0,
      use_time_free: 0,
      free_last_time: 0,
  };

  var PRAY_BOX_STATE;
  (function (PRAY_BOX_STATE) {
      PRAY_BOX_STATE[PRAY_BOX_STATE["EMPTY"] = 0] = "EMPTY";
      PRAY_BOX_STATE[PRAY_BOX_STATE["BORN"] = 1] = "BORN";
      PRAY_BOX_STATE[PRAY_BOX_STATE["BORN_COMPLETE"] = 2] = "BORN_COMPLETE";
      PRAY_BOX_STATE[PRAY_BOX_STATE["OPEN"] = 3] = "OPEN";
      PRAY_BOX_STATE[PRAY_BOX_STATE["OPEN_COMPLETE"] = 4] = "OPEN_COMPLETE";
  })(PRAY_BOX_STATE || (PRAY_BOX_STATE = {}));
  class mgrPrayBox extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
              [MSG.TIME_OFFLINE_TIME]: this.onTimeOfflineTime.bind(this),
          });
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      static onDifferentDay() {
      }
      static onTimeOfflineTime(second) {
          this.onOfflineTimePass(second);
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          let isInit = false;
          if (!this.data) {
              isInit = true;
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          this.data.boxes.length = this.data.num;
          this.listBoxSort = [];
          let indexFrom = 0;
          if (isInit) {
              let pray_box_init_ids = db.game_cnf.pray_box_init_ids;
              for (let i = 0; i < pray_box_init_ids.length; i++) {
                  let id = pray_box_init_ids[i];
                  let boxDb = db.get_pray_box_db_map()[id];
                  if (boxDb) {
                      let box = { id: id, state: PRAY_BOX_STATE.BORN_COMPLETE, time_born: 0, time_open: 0, time_pass: 0 };
                      if (i == 0) {
                          box.state = PRAY_BOX_STATE.OPEN_COMPLETE;
                      }
                      this.data.boxes[indexFrom] = box;
                      this.listBoxSort.push({ box: box, boxDb: boxDb });
                      indexFrom++;
                  }
              }
          }
          for (let i = indexFrom; i < this.data.num; i++) {
              let box = this.data.boxes[i];
              if (!box) {
                  box = { id: "", state: PRAY_BOX_STATE.EMPTY, time_born: 0, time_open: 0, time_pass: 0 };
                  this.data.boxes[i] = box;
              }
              this.listBoxSort.push({ box: box, boxDb: db.get_pray_box_db_map()[box.id] });
          }
          console.log("mgrPrayBox.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onUpdatePerSecond() {
          this.calcTimePassBox(1);
      }
      static calcTimePassBox(second = 1) {
          let needSort = false;
          let needSave = false;
          let findBorn = false;
          let findOpen = false;
          for (let warp of this.listBoxSort) {
              let box = warp.box;
              switch (box.state) {
                  case PRAY_BOX_STATE.BORN:
                      findBorn = true;
                      box.time_pass += second;
                      if (box.time_pass >= db.game_cnf.pray_box_interval) {
                          box.time_pass = 0;
                          box.state = PRAY_BOX_STATE.BORN_COMPLETE;
                          needSave = true;
                      }
                      break;
                  case PRAY_BOX_STATE.OPEN:
                      findOpen = true;
                      box.time_pass += second;
                      if (warp.boxDb && box.time_pass >= warp.boxDb.time) {
                          box.time_pass = 0;
                          box.state = PRAY_BOX_STATE.OPEN_COMPLETE;
                          needSave = true;
                      }
                      break;
              }
          }
          if (!findBorn) {
              this.buildBox();
              needSort = true;
          }
          if (needSort) {
              this.listBoxSort.sort(this.sortBoxList);
          }
          if (needSave) {
              Global.sendMsg(MSG.PRAY_BOX_REFRESH);
              this.saveRecord();
          }
      }
      static calcTimePassBoxLoop(second = 1) {
          let needSave = false;
          for (let warp of this.listBoxSort) {
              let box = warp.box;
              switch (box.state) {
                  case PRAY_BOX_STATE.OPEN:
                      box.time_pass += second;
                      if (warp.boxDb && box.time_pass >= warp.boxDb.time) {
                          box.time_pass = 0;
                          box.state = PRAY_BOX_STATE.OPEN_COMPLETE;
                          needSave = true;
                      }
                      break;
              }
          }
          while (second > 0) {
              let isAction = false;
              let needSort = false;
              for (let warp of this.listBoxSort) {
                  let box = warp.box;
                  switch (box.state) {
                      case PRAY_BOX_STATE.BORN:
                          isAction = true;
                          box.time_pass += second;
                          if (box.time_pass >= db.game_cnf.pray_box_interval) {
                              second = box.time_pass - db.game_cnf.pray_box_interval;
                              box.time_pass = 0;
                              box.state = PRAY_BOX_STATE.BORN_COMPLETE;
                              this.buildBox();
                              needSort = true;
                          }
                          else {
                              second = 0;
                          }
                          needSave = true;
                          break;
                  }
              }
              if (needSort) {
                  this.listBoxSort.sort(this.sortBoxList);
              }
              if (!isAction) {
                  break;
              }
          }
          if (needSave) {
              Global.sendMsg(MSG.PRAY_BOX_REFRESH);
              this.saveRecord();
          }
      }
      static onOfflineTimePass(second) {
          if (second > 0)
              this.calcTimePassBoxLoop(second);
      }
      static clacBoxSortScore(box) {
          let score = 0;
          switch (box.state) {
              case PRAY_BOX_STATE.EMPTY:
                  score = Number.MAX_VALUE / 2;
                  break;
              case PRAY_BOX_STATE.OPEN:
              case PRAY_BOX_STATE.OPEN_COMPLETE:
                  score = Number.MAX_VALUE;
                  break;
              case PRAY_BOX_STATE.BORN:
                  score = box.time_born + Number.MAX_VALUE / 4;
                  break;
              case PRAY_BOX_STATE.BORN_COMPLETE:
                  score = box.time_born;
                  break;
          }
          return score;
      }
      static sortBoxList(a, b) {
          let score_a = mgrPrayBox.clacBoxSortScore(a.box);
          let score_b = mgrPrayBox.clacBoxSortScore(b.box);
          return score_a - score_b;
      }
      static findEmptyBox() {
          let boxes = this.listBoxSort;
          for (let i = 0; i < boxes.length; i++) {
              let warp = boxes[i];
              if (warp.box.state == PRAY_BOX_STATE.EMPTY) {
                  return warp;
              }
          }
          return null;
      }
      static buildBox() {
          let warp = this.findEmptyBox();
          if (warp) {
              let box = warp.box;
              let boxDb = this.buildBoxReward();
              box.id = boxDb.id;
              box.state = PRAY_BOX_STATE.BORN;
              box.time_born = Utils.getTime();
              box.time_pass = 0;
              warp.boxDb = boxDb;
              this.saveRecord();
          }
      }
      static buildBoxReward() {
          let dataMap = db.get_pray_box_db_map();
          let listData = [];
          for (let k in dataMap) {
              listData.push(db.get_pray_box_db(k));
          }
          return this.calcWeightItem(listData);
      }
      static calcWeightItem(items) {
          let weightTotal = 0;
          for (let i = 0; i < items.length; i++) {
              weightTotal += items[i].weight || 0;
          }
          let r = Utils.random(0, weightTotal - 1);
          let vpt = 0;
          let item = null;
          for (let i = 0; i < items.length; i++) {
              vpt += items[i].weight || 0;
              if (r < vpt) {
                  item = items[i];
                  break;
              }
          }
          return item;
      }
      static getBoxes() {
          this.listBoxSort.sort(this.sortBoxList);
          return this.listBoxSort;
      }
      static getBoxOpen() {
          return this.listBoxSort[6];
      }
      static printBoxList() {
          console.log("################################");
          for (let i = 0; i < this.listBoxSort.length; i++) {
              let box = this.listBoxSort[i];
              console.log("-->", i, box.boxDb.id, PRAY_BOX_STATE[box.box.state]);
          }
      }
      static openBox() {
          if (this.findOpeningBox()) {
              return false;
          }
          this.listBoxSort.sort(this.sortBoxList);
          let warp = this.listBoxSort[0];
          let box = warp.box;
          if (box.state == PRAY_BOX_STATE.BORN_COMPLETE) {
              box.state = PRAY_BOX_STATE.OPEN;
              box.time_open = Utils.getTime();
              box.time_pass = 0;
              this.listBoxSort.sort(this.sortBoxList);
              this.saveRecord();
              return true;
          }
          return false;
      }
      static findBornCompleteBox() {
          for (let box of this.data.boxes) {
              if (box.state == PRAY_BOX_STATE.BORN_COMPLETE) {
                  return box;
              }
          }
          return null;
      }
      static findOpeningBox() {
          for (let box of this.data.boxes) {
              if (box.state == PRAY_BOX_STATE.OPEN || box.state == PRAY_BOX_STATE.OPEN_COMPLETE) {
                  return box;
              }
          }
          return null;
      }
      static makeOpenComplete() {
          for (let box of this.data.boxes) {
              if (box.state == PRAY_BOX_STATE.OPEN) {
                  box.state = PRAY_BOX_STATE.OPEN_COMPLETE;
                  Global.sendMsg(MSG.REFRESH_RED_POINT);
                  this.saveRecord();
                  return true;
              }
          }
          return false;
      }
      static getOpenBoxReward() {
          for (let box of this.data.boxes) {
              if (box.state == PRAY_BOX_STATE.OPEN_COMPLETE) {
                  box.state = PRAY_BOX_STATE.EMPTY;
                  let boxDb = db.get_pray_box_db(box.id);
                  if (boxDb) {
                      if (boxDb.is_coin) {
                          let scale = Utils.randomRange(boxDb.scale[0], boxDb.scale[1]);
                          let cost = mgrGame.getEnemyCoin();
                          let reward = Math.round(scale * cost);
                          if (reward > 0) {
                              mgrGame.addItem(1001, reward, 51);
                          }
                      }
                      else {
                          Level.dropItemByDropId(boxDb.reward_id);
                      }
                      mgrTask.doEvent(db.TASK_EVENT_ID.OPEN_PRAY_BOX);
                      Global.sendMsg(MSG.REFRESH_RED_POINT);
                  }
                  this.listBoxSort.sort(this.sortBoxList);
                  this.saveRecord();
                  return true;
              }
          }
          return false;
      }
      static haveRedPoint() {
          for (let box of this.data.boxes) {
              if (box.state == PRAY_BOX_STATE.OPEN_COMPLETE) {
                  return true;
              }
          }
          return false;
      }
  }
  mgrPrayBox.RECORD_KEY = "game166_box_v1.0";
  mgrPrayBox.dataDefault = {
      num: 7,
      boxes: [],
  };

  class PanelGame extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "游戏界面";
          this.sourceName = "ui://game/PanelGame";
          this.panelStyle = 1;
          this.bMask = false;
          this.lastMenuBuffRunning = false;
          this.guideTipTimePass = 0;
          this.guideTipTimeWait = db.game_cnf.guide_tip_time_init;
          this.passtimeShortcutNotice = 0;
          this.isBottomOut = false;
          this.exportNodeNames = {
              cc_layer_fit: "CustomLayerFit",
              cc_layer_touch: "fgui.GComponent",
              cc_broadcast: "CustomBroadcast",
              cc_money_coin: "CustomMoneyBar",
              cc_menu_bar: "fgui.GComponent",
              cc_button_setting: "fgui.GButton",
              cc_button_notice: "fgui.GButton",
              cc_button_sign: "fgui.GButton",
              cc_button_grow: "fgui.GButton",
              cc_button_collect: "fgui.GButton",
              cc_button_debug: "fgui.GButton",
              cc_task_desk: "CustomTaskDesk",
              cc_button_reward: "fgui.GButton",
              cc_button_statis: "fgui.GButton",
              cc_com_bottom_button: "fgui.GComponent",
              cc_button_fb: "fgui.GButton",
              cc_button_boss: "fgui.GButton",
              cc_button_secret: "fgui.GButton",
              cc_com_scale: "fgui.GComponent",
              cc_button_scale: "fgui.GButton",
              cc_ctrl_game_scale: "fgui.Controller",
              cc_bottom: "fgui.GComponent",
              cc_button_giveup: "ScaleButton",
              cc_button_reward_factor: "ScaleButton",
              cc_button_bag: "fgui.GButton",
              cc_button_tower: "fgui.GButton",
              cc_button_pray: "fgui.GButton",
              cc_button_summon: "fgui.GButton",
              cc_button_challenge: "fgui.GButton",
              cc_button_main: "fgui.GButton",
              cc_label_reward_factor: "fgui.GBasicTextField",
              cc_ctrl_button_state: "fgui.Controller",
              cc_hand: "CustomGameHand",
              cc_button_hand: "fgui.GButton",
              cc_button_buff: "fgui.GButton",
              cc_button_peace: "fgui.GButton",
              cc_button_auto_skill: "fgui.GButton",
              cc_com_menu2: "fgui.GComponent",
              cc_com_addtodesk: "CustomH5ADDToDesk",
              cc_com_record: "CustomH5VideoRecord",
              cc_com_share: "CustomH5Share",
              cc_button_privacy: "fgui.GButton",
              cc_button_next_day: "fgui.GButton",
              cc_button_newyear: "fgui.GButton",
              cc_ctrl_privacy_style: "fgui.Controller",
              cc_button_more: "fgui.GButton",
              cc_button_qq: "fgui.GButton",
              cc_battle_bar: "CustomBattleBar",
              cc_layer_no_touch: "fgui.GComponent",
              cc_button_offline: "ScaleButton",
              cc_loader_4399: "fgui.GLoader",
              cc_ctrl_hand: "fgui.Controller",
              cc_ctrl_game_state: "fgui.Controller",
              cc_ctrl_guide: "fgui.Controller",
              cc_ctrl_notouch: "fgui.Controller",
              cc_ctrl_game_mode: "fgui.Controller",
              cc_trans_bottom_out: "fgui.Transition",
              cc_trans_bottom_in: "fgui.Transition",
          };
      }
      buildUi() {
          this.layer_fit.fit();
          this.resNode.makeFullScreen();
          this.initEvent();
          this.broadcast.init();
          this.ctrlMenuBuff = this.button_buff.getController("buff");
          this.tranMenuBuff = this.button_buff.getTransition("loop");
          let coin = this.money_coin.getIconCoin();
          this.posCoin = coin.localToGlobal();
          this.ctrl_game_scale.on(fgui.Events.STATE_CHANGED, this, this.onGameStateChange);
          this.refresh();
          this.refreshRedPoint();
          this.initTimer();
          this.refreshGuide();
          this.button_debug.visible = false;
          this.button_offline.visible = false;
          this.updateButton4COP();
          this.showDialog();
      }
      updateButton4COP() {
          if (db.cop_db.is4399Watermark) {
              this.loader_4399.visible = true;
              this.loader_4399.url = "res/icon/channel/logo_4399.png";
          }
          let hideQQ = mgrKV.getKV("QQ_GAME_HIDE");
          if (hideQQ) {
              this.button_qq.visible = false;
          }
          else {
              CopHelper.updateButtonVisible(this.button_qq, mgrSdk.numQQGroup);
          }
          CopHelper.updateButtonVisible(this.button_more, db.cop_db.isJumpLeisureEnabled);
          CopHelper.updateButtonVisible(this.button_privacy, db.cop_db.b_advanced_game);
          CopHelper.updateAdvButtonState(this.button_buff, db.ADV_DB_ADVNAME.gain_buff);
          this.button_newyear.visible = mgrNewyear.isTimeValid();
          if (db.cop_db.advanced_game_style < this.ctrl_privacy_style.pageCount)
              this.ctrl_privacy_style.selectedIndex = db.cop_db.advanced_game_style;
      }
      dispose() {
          this.removeEvent();
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      onUpdatePerSecond() {
          this.updateGuideTip();
          this.updateMenuBuff();
          this.updateShortcutInstall();
          mgrGame.updatePirate();
      }
      updateMenuBuff() {
          let isRunning = mgrGain.isMagicRunning(db.MAGIC_DB_ID.buff1);
          if (isRunning) {
              this.ctrlMenuBuff.selectedIndex = 1;
              let leftTime = mgrGain.getLeftTime(db.MAGIC_DB_ID.buff1);
              if (leftTime >= 3600) {
                  this.button_buff.title = Utils.dateFormat(leftTime, "H:i:s");
              }
              else {
                  this.button_buff.title = Utils.dateFormat(leftTime, "i:s");
              }
          }
          else {
              this.ctrlMenuBuff.selectedIndex = 0;
          }
          if (isRunning != this.lastMenuBuffRunning) {
              if (isRunning) {
                  this.tranMenuBuff.play(null, -1);
              }
              else {
                  this.tranMenuBuff.stop();
              }
              this.refresh();
          }
          this.lastMenuBuffRunning = isRunning;
      }
      updateGuideTip() {
          if (!Level.stage.enemyWave.isIdleMode())
              return;
          if (mgrTower.getTowerLv("0") > db.game_cnf.guide_tip_time_level)
              return;
          this.guideTipTimePass += 1;
          if (this.guideTipTimePass >= this.guideTipTimeWait) {
              this.guideTipTimePass = 0;
              CustomGuideTip.randomShow();
              this.guideTipTimeWait = db.game_cnf.guide_tip_time_cd_auto;
          }
      }
      resetGuideTipCD(cd = 90) {
          this.guideTipTimePass = 0;
          this.guideTipTimeWait = cd;
      }
      isFBUnlock() {
      }
      refresh() {
          if (this.button_fb) {
              let isFBUnlock = mgrGame.isFBUnlock();
              let unlockFb = this.button_fb.getController("lock");
              if (unlockFb) {
                  unlockFb.selectedIndex = isFBUnlock ? 0 : 1;
              }
          }
          if (this.button_secret) {
              let isSecretUnlock = mgrGame.isSecretUnlock();
              let unlockSecret = this.button_secret.getController("lock");
              if (unlockSecret) {
                  unlockSecret.selectedIndex = isSecretUnlock ? 0 : 1;
              }
          }
          let isBossUnlock = mgrGame.isUnlockByGetWayId("9");
          let unlockBoss = this.button_boss.getController("lock");
          if (unlockBoss) {
              unlockBoss.selectedIndex = isBossUnlock ? 0 : 1;
          }
          this.button_main.title = mgrGame.getMainStoryDesc();
          this.button_challenge.title = "第" + mgrGame.levelId + "关";
          this.label_reward_factor.text = Math.ceil(mgrGame.getEnemyCoin() * 10).toString();
          this.button_auto_skill.selected = !StageConfig.handSuperSkill;
          this.ctrl_game_scale.selectedIndex = StageConfig.gameTimeScale > 1 ? 1 : 0;
          this.button_scale.title = "x" + StageConfig.gameTimeScale;
          this.button_next_day.visible = mgrSign.isNextDayRewardValid();
          let mode = this.getGameMode();
          if (mode < this.ctrl_game_mode.pageCount)
              this.ctrl_game_mode.selectedIndex = mode;
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_ENDNESS_BEGIN]: this.onEndnessBegin.bind(this),
              [MSG.TOWER_RUSH_END]: this.onTowerRushEnd.bind(this),
              [MSG.TOWER_RUSH_READY]: this.onTowerRushReady.bind(this),
              [MSG.TOWER_RUSH_END_FOCUS]: this.onTowrRushERndFocus.bind(this),
              [MSG.CHALLENGE_STORY_BEGIN]: this.onMainStoryBegin.bind(this),
              [MSG.CHALLENGE_BOSS_BEGIN]: this.onChallengeBegin.bind(this),
              [MSG.REFRESH_RED_POINT]: this.refreshRedPoint.bind(this),
              [MSG.GAME_GAIN_BEGIN]: this.refresh.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerChange.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerChange.bind(this),
              [MSG.GUIDE_COMPLETE]: this.onGuideComplete.bind(this),
              [MSG.GUIDE_SKIP]: this.onGuideSkip.bind(this),
              [MSG.PANEL_GAME_TOUCH]: this.onGameTouch.bind(this),
              [MSG.GUIDE_TIP_CORRECT]: this.onGuideTipCorrect.bind(this),
              [MSG.TOWER_DEAD]: this.onTowerDead.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
              [MSG.HOLY_ITEM_SELL]: this.onHolyBagItemChange.bind(this),
              [MSG.HOLY_ITEM_ADDD]: this.onHolyBagItemChange.bind(this),
              [MSG.HOLY_ITEM_FEED]: this.onHolyBagItemChange.bind(this),
              [MSG.MSG_BAG_EQUIP_EX]: this.onHolyBagItemChange.bind(this),
              [MSG.SIGN_UDPATE]: this.refreshRedPoint.bind(this),
              [MSG.OFFLINE_SHOW_BUTTON]: this.onOfflineShowButton.bind(this),
              [MSG.OFFLINE_GET_REWARD]: this.onOfflineGetReward.bind(this),
              [MSG.GAME_VIEW_DESTORY]: this.destroyGameView.bind(this),
              [MSG.GAME_VIEW_RESTORE]: this.restoreGameView.bind(this),
              [MSG.TOWER_NEW_GET]: this.onTowerNewGet.bind(this),
              [MSG.NEXT_DAY_REWARD]: this.refresh.bind(this),
          });
      }
      removeEvent() {
      }
      refreshGameHand() {
          if (this.ctrl_hand.selectedIndex == 1) {
              this.hand.refresh(true);
          }
      }
      onGameStateChange() {
          switch (this.ctrl_game_scale.selectedIndex) {
              case 0:
                  StageConfig.gameTimeScale = 1;
                  break;
              case 1:
                  StageConfig.gameTimeScale = mgrGame.calcGameScaleNum();
                  break;
          }
          this.button_scale.title = "x" + StageConfig.gameTimeScale;
      }
      onTowerChange() {
          this.refreshGameHand();
      }
      onGuideComplete() {
          this.refreshGuide();
      }
      onGuideSkip() {
          this.refreshGuide();
          mgrGame.showFirstLoginUI();
      }
      onGameTouch(enable) {
          this.ctrl_notouch.selectedIndex = enable ? 0 : 1;
      }
      onGuideTipCorrect() {
          this.resetGuideTipCD(db.game_cnf.guide_tip_time_cd_hand);
      }
      onTowerDead() {
          this.refreshGameHand();
      }
      onTowerMainSkillChange() {
          this.refreshGameHand();
      }
      onHolyBagItemChange() {
          Level.updateRedPoint4Button(this.button_bag, mgrHolyItem.isBagFull(), "full");
      }
      onEndnessBegin() {
          if (this.ctrl_button_state.selectedIndex != 1)
              this.playBottomTransOut(1);
      }
      onTowerRushEnd(win, mode) {
          this.refresh();
          if (win && mgrGame.rushAutoNext && mode == WaveMode.TOWER_ENDNESS) {
              this.ctrl_game_state.selectedIndex = 1;
          }
          else {
              if (this.isBottomOut) {
                  this.playBottomTransIn(0);
              }
              else {
                  this.playBottomTransOutIn(0);
              }
          }
      }
      getGameMode() {
          return Level.stage.enemyWave.mode;
      }
      onTowerRushReady() {
          this.playBottomTransIn(1);
          this.refresh();
          this.battle_bar.refresh(this.ctrl_game_mode.selectedIndex);
      }
      onTowrRushERndFocus() {
          this.playBottomTransOut(0);
      }
      onMainStoryBegin() {
          this.playBottomTransOut(1);
      }
      onChallengeBegin() {
          this.playBottomTransOut(1);
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_summon, mgrGame.getItemCount(1005) > 0);
          Level.updateRedPoint4Button(this.button_bag, mgrHolyItem.isBagFull(), "full");
          Level.updateRedPoint4Button(this.button_pray, mgrPrayCoin.haveRedPoint() || mgrPrayBox.haveRedPoint());
          Level.updateRedPoint4Button(this.button_boss, mgrTalent.haveRedPoint());
          Level.updateRedPoint4Button(this.button_sign, mgrSign.canSign(mgrSign.day));
          Level.updateRedPoint4Button(this.button_collect, mgrCollect.isAnyCollectCanReward());
          Level.updateRedPoint4Button(this.button_reward, Level.canGetTowerRushReward());
          Level.updateRedPoint4Button(this.button_newyear, mgrNewyear.haveRedPoint());
      }
      onOfflineShowButton() {
          this.button_offline.visible = true;
      }
      onOfflineGetReward() {
          this.button_offline.visible = false;
      }
      destroyGameView() {
          this.resNode.visible = false;
      }
      restoreGameView() {
          this.resNode.visible = true;
      }
      onTowerNewGet() {
          Level.updateRedPoint4Button(this.button_collect, mgrCollect.isAnyCollectCanReward());
      }
      updateShortcutInstall() {
          if (StageConfig.isShortcutNoticed)
              return;
          this.passtimeShortcutNotice += 1;
          if (mgrSdk.isShortcutInstalled() || !db.cop_db.shortcut_interval_idle) {
              StageConfig.isShortcutNoticed = true;
          }
          else {
              if (this.passtimeShortcutNotice >= db.cop_db.shortcut_interval_idle && this.ctrl_game_mode.selectedIndex == 0) {
                  StageConfig.isShortcutNoticed = true;
                  mgrSdk.installShortcut();
              }
          }
      }
      refreshGuide() {
          let haveGuide = Level.isFirstGuide();
          this.ctrl_guide.selectedIndex = haveGuide ? 1 : 0;
          if (!haveGuide) {
              this.ctrl_game_mode.selectedIndex = 0;
          }
      }
      showDialog() {
          if (Level.isFirstGuide())
              return;
          mgrOffline.showOfflineUI();
          mgrSign.showUI();
          mgrGame.showIceBreakUI();
          mgrGame.showFirstLoginUI();
      }
      playBottomTransOutIn(index = 1) {
          this.isBottomOut = true;
          this.ctrl_game_state.selectedIndex = index;
          this.trans_bottom_in.stop();
          this.trans_bottom_out.play(Laya.Handler.create(this, this.playBottomTransIn, [index]));
      }
      playBottomTransIn(index) {
          this.isBottomOut = false;
          this.ctrl_button_state.selectedIndex = index;
          this.ctrl_game_state.selectedIndex = index;
          this.trans_bottom_out.stop();
          this.trans_bottom_in.play();
      }
      playBottomTransOut(index = 1) {
          this.isBottomOut = true;
          this.trans_bottom_in.stop();
          this.trans_bottom_out.play(Laya.Handler.create(this, this.playBottomTransOutEnd, [index]));
      }
      playBottomTransOutEnd(index) {
          this.ctrl_game_state.selectedIndex = index;
      }
      onTouchDown(e) {
          Level.stage.onTouchDown(e);
      }
      onTouchMove(e) {
          Level.stage.onTouchMove(e);
      }
      onTouchUp(e) {
          Level.stage.onTouchUp(e);
      }
      onTouchOut(e) {
          Level.stage.onTouchUp(e);
      }
      on_click_button_hand() {
          if (this.ctrl_hand.selectedIndex)
              this.hand.openHand();
          else
              this.hand.closeHand();
      }
      on_click_button_challenge() {
          Global.sendMsg(MSG.GUIDE_TIP_UPDATE, "CLICK_BUTTON_CHALLENGE");
          if (!mgrGame.tryOpenPanelIntro("PanelIntroChallenge")) {
              Global.sendMsg(MSG.TOWER_ENDNESS_BEGIN);
          }
      }
      on_click_button_bag() {
          Director.openPanelWithSingleton("PanelHolyItemBag");
      }
      on_click_button_tower() {
          Global.sendMsg(MSG.GAME_VIEW_DESTORY);
          Director.openPanelWithSingleton("PanelTowerShow");
      }
      on_click_button_main() {
          Global.sendMsg(MSG.GUIDE_TIP_UPDATE, "CLICK_BUTTON_MAIN");
          Director.openPanelWithSingleton("PanelChallenge", { index: 0 });
      }
      on_click_button_summon() {
          Director.openPanelWithSingleton("PanelSummon");
      }
      on_click_button_pray() {
          Director.openPanelWithSingleton("PanelPray", { page: 1 });
      }
      on_click_button_debug() {
          fgui.UIPackage.loadPackage("res/fgui/test", Laya.Handler.create(this, () => {
              UIManager.getInstance().openDebug();
          }));
      }
      on_click_button_giveup() {
          Global.sendMsg(MSG.TOWER_RUSH_STOP);
      }
      on_click_button_reward_factor() {
          Director.openPanelWithSingleton("PanelRewardFactor");
      }
      on_click_button_buff() {
          Director.openPanelWithSingleton("PanelMenuBuff");
      }
      on_click_button_peace() {
          Director.openPanelWithSingleton("PanelIntroPeace");
      }
      on_click_button_setting() {
          Director.openPanelWithSingleton("PanelSetting");
      }
      on_click_button_sign() {
          Director.openPanelWithSingleton("PanelSign");
      }
      on_click_button_collect() {
          Director.openPanelWithSingleton("PanelCollect");
      }
      on_click_button_notice() {
          Director.openPanelWithSingleton("PanelNotice");
      }
      on_click_button_reward() {
          Director.openPanelWithSingleton("PanelTowerRushReward");
      }
      on_click_button_auto_skill() {
          StageConfig.handSuperSkill = !this.button_auto_skill.selected;
      }
      on_click_button_scale() {
          mgrGame.gameScaleNum = StageConfig.gameTimeScale;
      }
      on_click_button_statis() {
          Director.openPanelWithSingleton("PanelGameStatis");
      }
      on_click_button_boss() {
          if (mgrGame.isUnlockByGetWayId("9", true)) {
              Director.openPanelWithSingleton("PanelChallenge", { index: 1 });
          }
      }
      on_click_button_qq() {
          this.button_qq.visible = false;
          mgrKV.setKV("QQ_GAME_HIDE", 1);
          mgrSdk.joinQqGroup();
      }
      on_click_button_offline() {
          mgrOffline.showOfflineUI();
      }
      on_click_button_fb() {
          if (mgrGame.isFBUnlock(true)) {
              Director.openPanelWithSingleton("PanelFBDoor");
          }
      }
      on_click_button_more() {
          mgrSdk.openMoreWonderful();
      }
      on_click_button_privacy() {
          mgrSdk.openAdvancedSetting();
      }
      on_click_button_secret() {
          if (mgrGame.isSecretUnlock(true)) {
              Director.openPanelWithSingleton("PanelSecret");
          }
      }
      on_click_button_grow() {
          Director.openPanelWithSingleton("PanelGrow");
      }
      on_click_button_next_day() {
          Director.openPanelWithSingleton("PanelNextDayReward");
      }
      on_click_button_newyear() {
          this.button_newyear.visible = mgrNewyear.isTimeValid();
          if (this.button_newyear.visible) {
              Director.openPanelWithSingleton("PanelNewyear");
          }
      }
  }

  class PanelGameDebug extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/PanelGameDebug";
          this.bMask = false;
          this.panelStyle = 0;
          this.exportNodeNames = {
              cc_button_speed: "fgui.GButton",
              cc_button_reset: "fgui.GButton",
              cc_button_small: "fgui.GButton",
              cc_button_big: "fgui.GButton",
              cc_button_attack: "fgui.GButton",
              cc_button_num: "fgui.GButton",
              cc_button_debug: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
      }
      dispose() {
          super.dispose();
      }
      on_click_button_big() {
          var scale = Level.stage.scene.scaleX + 0.1;
          Level.stage.changeSceneScale(scale);
      }
      on_click_button_small() {
          var scale = Level.stage.scene.scaleX - 0.1;
          Level.stage.changeSceneScale(scale);
      }
      on_click_button_reset() {
          Level.stage.resetScenePos();
      }
      on_click_button_speed() {
          Level.stage.addTowerSpeed();
      }
      on_click_button_attack() {
          Level.stage.addTowerAttack();
      }
      on_click_button_num() {
          Level.stage.addTowerAttacker();
      }
      on_click_button_debug() {
          fgui.UIPackage.loadPackage("res/fgui/test", Laya.Handler.create(this, () => {
              UIManager.getInstance().openDebug();
          }));
      }
  }

  class PanelIdle extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/PanelIdle";
          this.panelLayer = 8;
          this.panelStyle = 1;
          this.exportNodeNames = {
              cc_money_bar: "CustomMoneyBar",
              cc_lable_time: "fgui.GBasicTextField",
              cc_button_unlock: "ScaleButton",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.money_bar.hideDiamondAdd();
          this.initTimer();
          this.refresh();
          Global.sendMsg(MSG.GAME_VIEW_DESTORY);
      }
      dispose() {
          this.removeTimer();
          super.dispose();
          Global.sendMsg(MSG.GAME_VIEW_RESTORE);
      }
      refresh() {
          let date = new Date();
          this.lable_time.text = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
      }
      updatePerSecond() {
          this.refresh();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      on_click_button_unlock() {
          this.close();
      }
  }

  class PanelPirate extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/PanelPirate";
          this.panelLayer = 8;
          this.panelStyle = 1;
          this.exportNodeNames = {
              cc_lable_time: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelRewardFactor extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "挂机奖励系数";
          this.sourceName = "ui://game/PanelRewardFactor";
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_label_title: "fgui.GBasicTextField",
              cc_lable_desc1: "fgui.GBasicTextField",
              cc_label_desc2: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_ensure() {
          this.close();
      }
  }

  class mgrChannel extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [BASE_MSG.SDK_ADD_ITEM]: this.onMsgSdkAddItem.bind(this),
              [BASE_MSG.SDK_PRE_PAY]: this.onMsgPrePay.bind(this),
              [BASE_MSG.SDK_EXIT_GAME]: this.onMsgExitGame.bind(this),
          });
      }
      static onMsgSdkAddItem(e) {
          mgrGame.addItem(e.itemId, e.count, e.reason);
      }
      static onMsgPrePay(payId) {
          let items = BaseFacade.mPay._onGetGoods(payId, 9);
          mgrTip.alertItems(items);
      }
      static onMsgExitGame() {
          if (Global.isGuiding)
              return;
          if (this.__backDialog) {
              this.__backDialog.close();
              this.__backDialog = null;
              return;
          }
          this.__backDialog = Director.openPanel("PanelDialog", {
              desc: "要离开游戏了吗？",
              confirmText: "离开",
              cancelText: "继续",
              confirm: () => {
                  if (window[`conch`])
                      window[`conch`].exit();
              },
              cancel: () => {
                  this.__backDialog = null;
              }
          });
      }
      static tryOpenInstall() {
      }
      static updateADGiveupButton(button) {
          if (!button)
              return;
          if (mgrNative.isHtml5Platform()) {
              button.visible = true;
          }
          else {
              button.visible = false;
          }
      }
  }
  mgrChannel.__backDialog = null;

  class PanelTowerSlotUnlock extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "解锁条件";
          this.sourceName = "ui://game/PanelTowerSlotUnlock";
          this.bOpenAndCloseAnim = true;
          this.passTimeAutoAD = 0;
          this.isAutoAD = false;
          this.isAutoADOpen = false;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_unlock_level: "fgui.GBasicTextField",
              cc_label_unlock_cost: "fgui.GBasicTextField",
              cc_button_unlock: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
              cc_loader_flag_1: "fgui.GLoader",
              cc_loader_flag_2: "fgui.GLoader",
              cc_ctrl_condition1: "fgui.Controller",
              cc_ctrl_condition2: "fgui.Controller",
          };
      }
      buildUi() {
          this.initTimer();
          this.slot = this.context;
          let count = mgrTower.calcSlotUnlockCount();
          let unlockLv = db.game_cnf.slot_unlock_lv[count];
          let unlockCost = db.game_cnf.slot_unlock_cost[count];
          let isLevelEnough = unlockLv <= mgrTower.getMainTowerLv();
          let isMoneyEnough = unlockCost <= mgrGame.getItemCount(1000);
          this.ctrl_condition1.selectedIndex = isLevelEnough ? 1 : 0;
          this.ctrl_condition2.selectedIndex = isMoneyEnough ? 1 : 0;
          this.label_unlock_level.text = unlockLv.toString();
          this.label_unlock_cost.text = unlockCost.toString();
          this.button_unlock.enabled = isLevelEnough && isMoneyEnough;
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.unlock_tower_slot) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.unlock_tower_slot);
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          this.checkAutoADOpen();
          Laya.timer.loop(1000, this, this.updatePerSecond);
          this.updatePerSecond();
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      checkAutoADOpen() {
          if (db.cop_db.auto_open_ad_cd) {
              let curtTime = Timer.time;
              if (!StageTool.checkAutoOpenCD(curtTime)) {
                  StageTool.beginAutoOpenCD(curtTime);
                  this.isAutoADOpen = true;
              }
          }
      }
      updatePerSecond() {
          if (this.isAutoADOpen && !this.isAutoAD) {
              let leftTimeAutoAD = db.cop_db.auto_open_ad_cd - this.passTimeAutoAD;
              if (leftTimeAutoAD > 0) {
                  this.button_ad.titleFontSize = 20;
                  this.button_ad.title = leftTimeAutoAD + "秒后解锁";
                  this.passTimeAutoAD++;
              }
              else {
                  this.isAutoAD = true;
                  this.button_ad.title = "立刻解锁";
                  this.on_click_button_ad();
              }
          }
      }
      watchAdSuccess() {
          if (mgrTower.tryUnlockSlot(this.slot.id - 1, true)) {
              this.close();
          }
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_unlock() {
          if (this.slot) {
              if (mgrTower.tryUnlockSlot(this.slot.id - 1)) {
                  this.close();
              }
          }
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.unlock_tower_slot);
      }
      on_click_button_giveupad() {
          this.closeWithTransition();
      }
  }

  class PanelWarning extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game/PanelWarning";
          this.panelLayer = 8;
          this.panelStyle = 1;
          this.exportNodeNames = {
              cc_label_title: "fgui.GBasicTextField",
              cc_button_exit: "fgui.GButton",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          Global.sendMsg(MSG.GAME_PAUSE);
          mgrGame.warnCount++;
      }
      dispose() {
          super.dispose();
      }
      on_click_button_exit() {
          if (window[`conch`]) {
              window[`conch`].exit();
          }
          else {
              if (Laya.Browser.window)
                  Laya.Browser.window.location.reload(true);
          }
      }
  }

  class PanelBossComing extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game_boss_coming/PanelBossComing";
          this.bMask = false;
          this.exportNodeNames = {};
      }
      buildUi() {
          this.resNode.makeFullScreen();
          let trans = this.resNode.getTransition("in");
          trans.play(Laya.Handler.create(this, this.close));
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelBossComing2 extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game_boss_coming/PanelBossComing2";
          this.bMask = false;
          this.exportNodeNames = {};
      }
      buildUi() {
          this.resNode.makeFullScreen();
          let trans = this.resNode.getTransition("in");
          trans.play(Laya.Handler.create(this, this.close));
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelMenuBuff extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "寻宝猎人";
          this.sourceName = "ui://game_buff/PanelMenuBuff";
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_time_curt: "fgui.GBasicTextField",
              cc_label_time_next: "fgui.GBasicTextField",
              cc_label_time_left: "fgui.GBasicTextField",
              cc_effect_node: "FguiEffect",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
          };
      }
      buildUi() {
          this.createScene3DEffect(0);
          this.initTimer();
          this.refresh();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.gain_buff) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.gain_buff);
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.refresh);
      }
      removeTimer() {
          Laya.timer.clear(this, this.refresh);
      }
      refresh() {
          let leftTime = mgrGain.getLeftTime(db.MAGIC_DB_ID.buff1);
          if (leftTime >= 3600) {
              this.label_time_left.text = Utils.dateFormat(leftTime, "H:i:s");
          }
          else {
              this.label_time_left.text = Utils.dateFormat(leftTime, "i:s");
          }
          this.label_time_curt.text = mgrGain.getMagicTime(db.MAGIC_DB_ID.buff1).toString();
          this.label_time_next.text = mgrGain.getMagicTimeNext(db.MAGIC_DB_ID.buff1).toString();
      }
      watchAdSuccess() {
          this.closeWithTransition("click");
          mgrGain.startMagic(db.MAGIC_DB_ID.buff1);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_ad() {
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.gain_buff);
          });
      }
      on_click_button_giveupad() {
          this.closeWithTransition();
      }
  }

  class PanelDropBoxAD extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "神秘矿产";
          this.sourceName = "ui://game_mine/PanelDropBoxAD";
          this.bAutoRemovePackage = true;
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_ad: "fgui.GButton",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.pick_reward) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.pick_reward);
      }
      dispose() {
          super.dispose();
      }
      watchAdSuccess() {
          this.getADReward();
      }
      getADReward() {
          let dropDb = this.context.dropDb;
          if (dropDb) {
              switch (dropDb.type) {
                  case 2:
                      {
                          let listDrop = [];
                          let itemId = dropDb.coin_id;
                          let coin_value = dropDb.coin_value;
                          let count = Utils.random(coin_value[0], coin_value[1]);
                          if (count) {
                              mgrGame.addItem(itemId, count, 20, false);
                              listDrop.push({ type: DROP_TYPE.ITEM, data: { itemId: itemId, count: count } });
                          }
                          let countPiece = Utils.random(dropDb.piece[0], dropDb.piece[1]);
                          if (countPiece) {
                              mgrGame.addItem(1006, countPiece, 20, false);
                              listDrop.push({ type: DROP_TYPE.ITEM, data: { itemId: 1006, count: countPiece } });
                          }
                          Level.dropItemByDropId(dropDb.drop_id, false, listDrop);
                          Level.showItemGet(listDrop);
                          mgrTask.doEvent(db.TASK_EVENT_ID.PICKUP_BOX);
                          break;
                      }
              }
          }
          this.closeWithTransition();
          Global.sendMsg(MSG.DROP_BOX_PICK_UP_AD, this.context.uid);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_ad() {
          if (mgrHolyItem.notEnoughEmpty(6))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.pick_reward);
          });
      }
  }

  class CustomWinItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://game_result/CustomWinItem";
          this.exportNodeNames = {
              cc_item: "CustomCommItem",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.item.refresh(data);
      }
      playTransIn(delay = 0) {
          this.item.playTransIn(delay);
      }
  }

  class PanelGameLose extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "关卡失败";
          this.sourceName = "ui://game_result/PanelGameLose";
          this.bMask = false;
          this.exportNodeNames = {};
      }
      buildUi() {
          let tranIn = this.resNode.getTransition("in");
          if (tranIn) {
              tranIn.play(Laya.Handler.create(this, this.close));
          }
          if (!this.context.force) {
              mgrSound.playSound("level_lose");
          }
      }
      dispose() {
          Global.sendMsg(MSG.TOWER_RUSH_END, [false, this.context.mode]);
          super.dispose();
      }
  }

  class PanelGameWin extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "关卡胜利";
          this.sourceName = "ui://game_result/PanelGameWin";
          this.bMask = false;
          this.mode = WaveMode.IDLE;
          this.exportNodeNames = {
              cc_com_factor: "fgui.GComponent",
              cc_label_factor_curt: "fgui.GBasicTextField",
              cc_label_factor_next: "fgui.GBasicTextField",
              cc_ctrl_factor: "fgui.Controller",
          };
      }
      buildUi() {
          this.mode = this.context.mode;
          if (this.mode == WaveMode.TOWER_ENDNESS) {
              this.ctrl_factor.selectedIndex = 1;
              this.label_factor_curt.text = Math.ceil(mgrGame.getEnemyCoinByLevel(mgrGame.levelId - 1) * 10).toString();
              this.label_factor_next.text = Math.ceil(mgrGame.getEnemyCoinByLevel(mgrGame.levelId) * 10).toString();
          }
          let tranIn = this.resNode.getTransition("in");
          if (tranIn) {
              tranIn.play(Laya.Handler.create(this, this.close));
          }
          mgrSound.playSound("level_win");
      }
      dispose() {
          Global.sendMsg(MSG.TOWER_RUSH_END, [true, this.mode]);
          super.dispose();
      }
      onTranPlayComplete() {
          this.close();
      }
  }

  class PanelGameWinReward extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "关卡胜利(奖励)";
          this.sourceName = "ui://game_result/PanelGameWinReward";
          this.panelStyle = 0;
          this.mode = WaveMode.IDLE;
          this.exportNodeNames = {
              cc_list_item: "fgui.GList",
              cc_button_ensure: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_effect_node: "FguiEffect",
              cc_ctrl_more: "fgui.Controller",
          };
      }
      buildUi() {
          this.createScene3DEffect(0);
          this.mode = this.context.mode;
          this.refreshMore();
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.refreshItem();
          mgrSound.playSound("level_win");
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.more_reward) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.more_reward);
          Laya.timer.once(1500, this, this.onTimeDelay);
      }
      dispose() {
          Laya.timer.clearAll(this);
          Global.sendMsg(MSG.TOWER_RUSH_END, [true, this.mode]);
          super.dispose();
      }
      onTimeDelay() {
          if (this.destroyed)
              return;
          if (this.mode == WaveMode.FINAL_WAR) {
              if (mgrFinalWar.winAutoNext) {
                  this.on_click_button_ensure();
              }
          }
      }
      parseItem(content, object) {
          content.view = object;
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
          content.view.playTransIn(0.2 + index * 0.05);
      }
      refreshItem() {
          let listData = this.context.items || [];
          this.listItem.setListData(listData);
      }
      refreshMore() {
          let config = this.context.config;
          if (this.mode == WaveMode.TOWER_MAIN_STORY && config) {
              this.ctrl_more.selectedIndex = 1;
          }
          else {
              this.ctrl_more.selectedIndex = 0;
          }
      }
      watchAdSuccess() {
          let config = this.context.config;
          if (this.mode == WaveMode.TOWER_MAIN_STORY && config) {
              Level.getStoryRushMoreReward(config);
          }
          this.ctrl_more.selectedIndex = 0;
      }
      on_click_button_ensure() {
          this.close();
          if (this.mode == WaveMode.TOWER_MAIN_STORY) {
              if (!mgrGame.showUnlockInfo()) {
                  Director.openPanelWithSingleton("PanelChallenge", { index: 0 });
              }
          }
          else if (this.mode == WaveMode.TOWER_CHALLENGE) {
              Director.openPanelWithSingleton("PanelChallenge", { index: 1 });
          }
          else if (this.mode == WaveMode.FB_COIN) {
              Director.openPanelWithSingleton("PanelFBCoin");
          }
          else if (this.mode == WaveMode.FB_ITEM) {
              Director.openPanelWithSingleton("PanelFBItem");
          }
          else if (this.mode == WaveMode.SECRET) {
              Director.openPanelWithSingleton("PanelSecret");
          }
          else if (this.mode == WaveMode.FINAL_WAR) {
              if (!mgrFinalWar.winAutoNext) {
                  Director.runScene(SceneGame, "PanelLoadingGame");
              }
          }
      }
      on_click_button_ad() {
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.more_reward);
          });
      }
  }

  class CustomGrowLvupItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowLvupItem";
          this.exportNodeNames = {
              cc_head: "CustomTowerHead",
              cc_progress_bar: "fgui.GProgressBar",
              cc_button_go: "fgui.GButton",
              cc_label_bar: "fgui.GBasicTextField",
              cc_ctrl_color: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb, index, scoreMax) {
          this.towerDb = towerDb;
          this.head.refresh(towerDb);
          this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          let scoreCur = mgrTower.getTowerLv(towerDb.id);
          this.label_bar.text = "Lv." + scoreCur + "/" + scoreMax;
          this.progress_bar.value = scoreCur;
          this.progress_bar.max = scoreMax;
      }
      refreshHolyItem(towerDb, index, scoreMax) {
          this.towerDb = towerDb;
          this.head.refresh(towerDb);
          this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          let scoreCur = mgrTower.calcAllHolyItemLv(towerDb.id);
          this.label_bar.text = scoreCur + "/" + scoreMax;
          this.progress_bar.value = scoreCur;
          this.progress_bar.max = scoreMax;
      }
      on_click_button_go() {
          Director.openPanelWithSingleton("PanelTowerInfo", { towerDb: this.towerDb });
      }
  }

  class CustomGrowPage1Item extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage1Item";
          this.scoreVpt = 0;
          this.exportNodeNames = {
              cc_content: "fgui.GComponent",
              cc_button_question: "fgui.GButton",
              cc_button_arrow: "fgui.GButton",
              cc_list_item: "fgui.GList",
              cc_loader_score: "fgui.GLoader",
              cc_label_num: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
              cc_ctrl_score: "fgui.Controller",
              cc_ctrl_color: "fgui.Controller",
          };
      }
      onCreate() {
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
      }
      dispose() {
          super.dispose();
      }
      onRefresh() {
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(this.contentData.data.style, data, index, this.scoreVpt);
      }
      refresh(list, content, index) {
          if (index != null)
              this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          this.listParent = list;
          this.contentData = content;
          let data = content.data;
          this.label_num.text = data.id + ".";
          this.label_title.text = data.name;
          let listData = this.getListData(data.style);
          let score = this.calcScore(data, listData);
          let scoreIndex = this.calcABCDIndex(data, score);
          let scoreMax = data.score[scoreIndex] || 0;
          this.scoreVpt = Math.round(scoreMax / data.base);
          if (scoreIndex < this.ctrl_score.pageCount)
              this.ctrl_score.selectedIndex = scoreIndex;
          if (this.listParent.getExDataByIndex(data.id)) {
              switch (data.style) {
                  case 0:
                      listData.sort(this.sortByLevel);
                      break;
                  case 1:
                      listData.sort(this.sortByStar);
                      break;
                  case 2:
                      listData.sort(this.sortByQuality);
                      break;
                  case 3:
                      listData.sort(this.sortByHolyitem);
                      break;
              }
              this.listItem.setListData(listData);
          }
          else {
              this.listItem.setListData([]);
          }
          this.list_item.resizeToFit();
          this.height = this.content.height;
      }
      calcScore(data, listData) {
          let score = 0;
          switch (data.style) {
              case 0:
                  for (let towerDb of listData) {
                      score += mgrTower.getTowerLv(towerDb.id);
                  }
                  break;
              case 1:
                  for (let towerDb of listData) {
                      score += mgrTower.getTowerStar(towerDb.id);
                  }
                  break;
              case 2:
                  for (let towerDb of listData) {
                      score += (mgrTower.getTowerQualityByDB(towerDb) + 1);
                  }
                  break;
              case 3:
                  for (let towerDb of listData) {
                      score += mgrTower.calcAllHolyItemLv(towerDb.id);
                  }
                  break;
          }
          return score;
      }
      calcABCDIndex(data, score) {
          let index = data.score.length - 1;
          for (let i = data.score.length - 1; i >= 0; i--) {
              if (score > data.score[i]) {
                  break;
              }
              index = i;
          }
          return index;
      }
      getListData(style) {
          let listData = [];
          let towerPos = db.get_tower_pos_map()[mgrTower.defaultPosGid];
          switch (style) {
              case 0:
                  for (let i = 0; i < towerPos.length; i++) {
                      let pos = towerPos[i];
                      let id = mgrTower.getSlotTower(pos.id - 1);
                      if (id) {
                          let towerDb = db.get_tower_db(id);
                          if (towerDb) {
                              listData.push(towerDb);
                          }
                      }
                  }
                  break;
              case 1:
                  for (let i = 0; i < towerPos.length; i++) {
                      let pos = towerPos[i];
                      let id = mgrTower.getSlotTower(pos.id - 1);
                      if (id) {
                          let towerDb = db.get_tower_db(id);
                          if (towerDb && !towerDb.main) {
                              listData.push(towerDb);
                          }
                      }
                  }
                  break;
              case 2:
                  for (let i = 0; i < towerPos.length; i++) {
                      let pos = towerPos[i];
                      let id = mgrTower.getSlotTower(pos.id - 1);
                      if (id) {
                          let towerDb = db.get_tower_db(id);
                          if (towerDb && !towerDb.main) {
                              listData.push(towerDb);
                          }
                      }
                  }
                  break;
              case 3:
                  for (let i = 0; i < towerPos.length; i++) {
                      let pos = towerPos[i];
                      let id = mgrTower.getSlotTower(pos.id - 1);
                      if (id) {
                          let towerDb = db.get_tower_db(id);
                          if (towerDb) {
                              listData.push(towerDb);
                          }
                      }
                  }
                  break;
          }
          return listData;
      }
      sortByLevel(a, b) {
          let score_a = mgrTower.calcTowerScoreLevel(a.id);
          let score_b = mgrTower.calcTowerScoreLevel(b.id);
          return score_b - score_a;
      }
      sortByStar(a, b) {
          let score_a = mgrTower.calcTowerScoreStar(a.id);
          let score_b = mgrTower.calcTowerScoreStar(b.id);
          return score_b - score_a;
      }
      sortByQuality(a, b) {
          let score_a = mgrTower.calcTowerScoreQuality(a.id);
          let score_b = mgrTower.calcTowerScoreQuality(b.id);
          return score_b - score_a;
      }
      sortByHolyitem(a, b) {
          let score_a = mgrTower.calcTowerScoreHolyItem(a.id);
          let score_b = mgrTower.calcTowerScoreHolyItem(b.id);
          return score_b - score_a;
      }
      click() {
          this.button_arrow.selected = !this.button_arrow.selected;
          this.on_click_button_arrow();
      }
      on_click_button_question() {
          Director.openPanelWithSingleton("PanelGrowTip", { tip: this.contentData.data.question, point: this.button_question.localToGlobal() });
      }
      on_click_button_arrow() {
          if (this.listParent && this.contentData) {
              this.listParent.setExDataByIndex(this.contentData.data.id, !this.listParent.getExDataByIndex(this.contentData.data.id));
              this.refresh(this.listParent, this.contentData);
              this.listParent.refreshAndKeepPos();
          }
      }
  }

  class CustomGrowPage1SubItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage1SubItem";
          this.exportNodeNames = {
              cc_level: "CustomGrowLvupItem",
              cc_star: "CustomGrowStarupItem",
              cc_quality: "CustomGrowQualityupItem",
              cc_ctrl_style: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(style, data, index, scoreMax) {
          if (style < this.ctrl_style.pageCount)
              this.ctrl_style.selectedIndex = style;
          switch (style) {
              case 0:
                  this.level.refresh(data, index, scoreMax);
                  break;
              case 1:
                  this.star.refresh(data, index);
                  break;
              case 2:
                  this.quality.refresh(data, index);
                  break;
              case 3:
                  this.level.refreshHolyItem(data, index, scoreMax);
                  break;
          }
      }
  }

  class CustomGrowPage2Item extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage2Item";
          this.scoreVpt = 0;
          this.exportNodeNames = {
              cc_content: "fgui.GComponent",
              cc_button_arrow: "fgui.GButton",
              cc_list_item: "fgui.GList",
              cc_loader_icon: "fgui.GLoader",
              cc_label_desc: "fgui.GBasicTextField",
              cc_ctrl_color: "fgui.Controller",
          };
      }
      onCreate() {
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
      }
      dispose() {
          super.dispose();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(data, index);
      }
      refresh(list, content, index) {
          if (index != null)
              this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          this.listParent = list;
          this.contentData = content;
          let data = content.data;
          let itemDb = db.get_item_db(data.item_id);
          if (itemDb) {
              this.loader_icon.url = itemDb.icon;
              this.label_desc.text = data.desc || itemDb.desc;
          }
          let listData = this.getListData(data);
          if (this.listParent.getExDataByIndex(data.id)) {
              this.listItem.setListData(listData);
          }
          else {
              this.listItem.setListData([]);
          }
          this.list_item.resizeToFit();
          this.height = this.content.height;
      }
      getListData(data) {
          let listData = [];
          for (let id of data.ways) {
              let wayDb = db.get_grow_item_getway(id);
              if (wayDb) {
                  listData.push(wayDb);
              }
          }
          return listData;
      }
      click() {
          this.button_arrow.selected = !this.button_arrow.selected;
          this.on_click_button_arrow();
      }
      on_click_button_arrow() {
          if (this.listParent && this.contentData) {
              this.listParent.setExDataByIndex(this.contentData.data.id, !this.listParent.getExDataByIndex(this.contentData.data.id));
              this.refresh(this.listParent, this.contentData);
              this.listParent.refreshAndKeepPos();
          }
      }
  }

  class CustomGrowPage2SubItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage2SubItem";
          this.exportNodeNames = {
              cc_label_sub_title: "fgui.GBasicTextField",
              cc_label_sub_desc: "fgui.GBasicTextField",
              cc_label_sub_unlock: "fgui.GBasicTextField",
              cc_button_go: "fgui.GButton",
              cc_ctrl_color: "fgui.Controller",
              cc_ctrl_lock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(wayDb, index) {
          this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          this.wayDb = wayDb;
          this.label_sub_title.text = wayDb.name;
          this.label_sub_desc.text = wayDb.desc;
          let step = mgrGame.getLevelStoryStep();
          let isUnlock = step >= wayDb.unlock_index;
          this.ctrl_lock.selectedIndex = isUnlock ? 0 : 1;
          let storyDb = mgrGame.findStoryDbByIndex(wayDb.unlock_index);
          if (storyDb) {
              this.label_sub_unlock.text = Utils.sprintf("（通关主线%d解锁）", storyDb.id + "-" + storyDb.lv);
          }
          else {
              this.label_sub_unlock.text = "";
          }
      }
      on_click_button_go() {
          if (this.wayDb) {
              if (this.wayDb.panel) {
                  Director.openPanelWithSingleton(this.wayDb.panel, { index: this.wayDb.index, page: this.wayDb.index });
              }
              else if (this.wayDb.msg) {
                  Global.sendMsg(this.wayDb.msg);
              }
          }
      }
  }

  class ListViewTower {
      constructor(list, childPath) {
          this.childPath = "";
          this.childPath = childPath;
          this.listView = new ListView(list, this, this.parseItem, this.renderItem);
      }
      parseItem(content, view) {
          if (this.childPath) {
              content.view = view.getChild(this.childPath);
          }
          else {
              content.view = view;
          }
      }
      renderItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      setData(listData) {
          this.listView.setListData(listData);
      }
      setDataByTowerIds(towerIds) {
          let listData = [];
          for (let id of towerIds) {
              let towerDb = db.get_tower_db(id);
              if (towerDb) {
                  listData.push(towerDb);
              }
          }
          this.listView.setListData(listData);
      }
  }

  class CustomGrowPage3Item extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage3Item";
          this.scoreVpt = 0;
          this.exportNodeNames = {
              cc_content: "fgui.GComponent",
              cc_sub_item: "CustomGrowPage3SubItem",
              cc_button_arrow: "fgui.GButton",
              cc_label_sub_title: "fgui.GBasicTextField",
              cc_list_tower: "fgui.GList",
              cc_ctrl_color: "fgui.Controller",
              cc_ctrl_expand: "fgui.Controller",
          };
      }
      onCreate() {
          this.listTower = new ListViewTower(this.list_tower, "head");
      }
      dispose() {
          super.dispose();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
      }
      refresh(list, content, index) {
          if (index != null)
              this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          this.listParent = list;
          this.contentData = content;
          let data = content.data;
          this.label_sub_title.text = data.name;
          this.listTower.setDataByTowerIds(data.tower_ids);
          this.sub_item.refresh(data);
          if (this.listParent.getExDataByIndex(data.id)) {
              this.ctrl_expand.selectedIndex = 1;
          }
          else {
              this.ctrl_expand.selectedIndex = 0;
          }
          this.height = this.content.height;
      }
      click() {
          this.button_arrow.selected = !this.button_arrow.selected;
          this.on_click_button_arrow();
      }
      on_click_button_arrow() {
          if (this.listParent && this.contentData) {
              this.listParent.setExDataByIndex(this.contentData.data.id, !this.listParent.getExDataByIndex(this.contentData.data.id));
              this.refresh(this.listParent, this.contentData);
              this.listParent.refreshAndKeepPos();
          }
      }
  }

  class CustomGrowPage3SubItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage3SubItem";
          this.exportNodeNames = {
              cc_label_sub_desc: "fgui.GBasicTextField",
              cc_list_sub_tower1: "fgui.GList",
              cc_list_sub_tower2: "fgui.GList",
          };
      }
      onCreate() {
          this.listTowerDps = new ListViewTower(this.list_sub_tower1, "head");
          this.listTowerAux = new ListViewTower(this.list_sub_tower2, "head");
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.listTowerDps.setDataByTowerIds(data.tower_dps);
          this.listTowerAux.setDataByTowerIds(data.tower_aux);
          this.label_sub_desc.text = data.desc;
      }
  }

  class CustomGrowPage4Item extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage4Item";
          this.scoreVpt = 0;
          this.exportNodeNames = {
              cc_content: "fgui.GComponent",
              cc_content_expand: "fgui.GComponent",
              cc_button_arrow: "fgui.GButton",
              cc_label_sub_desc: "fgui.GBasicTextField",
              cc_label_num: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_ctrl_color: "fgui.Controller",
              cc_ctrl_expand: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
      }
      refresh(list, content, index) {
          if (index != null)
              this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          this.listParent = list;
          this.contentData = content;
          let data = content.data;
          this.label_num.text = data.id + ".";
          this.label_desc.text = data.question;
          this.label_sub_desc.text = data.answer;
          if (this.listParent.getExDataByIndex(data.id)) {
              this.ctrl_expand.selectedIndex = 1;
              this.height = this.content_expand.height;
          }
          else {
              this.ctrl_expand.selectedIndex = 0;
              this.height = this.content.height;
          }
      }
      click() {
          this.button_arrow.selected = !this.button_arrow.selected;
          this.on_click_button_arrow();
      }
      on_click_button_arrow() {
          if (this.listParent && this.contentData) {
              this.listParent.setExDataByIndex(this.contentData.data.id, !this.listParent.getExDataByIndex(this.contentData.data.id));
              this.refresh(this.listParent, this.contentData);
              this.listParent.refreshAndKeepPos();
          }
      }
  }

  class CustomGrowPage4SubItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage4SubItem";
          this.exportNodeNames = {
              cc_label_sub_desc: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.label_sub_desc.text = data.answer;
      }
  }

  class CustomGrowQualityupItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowQualityupItem";
          this.exportNodeNames = {
              cc_head: "CustomTowerHead",
              cc_button_go: "fgui.GButton",
              cc_quality_curt: "fgui.GComponent",
              cc_quality_next: "fgui.GComponent",
              cc_ctrl_color: "fgui.Controller",
              cc_ctlr_quality_max: "fgui.Controller",
          };
      }
      onCreate() {
          this.qualityCurt = this.quality_curt.getController("quality");
          this.qualityNext = this.quality_next.getController("quality");
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb, index) {
          this.towerDb = towerDb;
          this.head.refresh(towerDb);
          this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          let quality = mgrTower.getTowerQualityByDB(towerDb);
          if (mgrTower.isTowerQualityMax(quality)) {
              this.ctlr_quality_max.selectedIndex = 1;
          }
          else {
              this.ctlr_quality_max.selectedIndex = 0;
              this.qualityNext.selectedIndex = quality + 1;
          }
          this.qualityCurt.selectedIndex = quality;
      }
      on_click_button_go() {
          if (mgrGame.isSecretUnlock(true)) {
              Director.openPanelWithSingleton("PanelSecret", { index: 2, towerDb: this.towerDb });
          }
      }
  }

  class CustomGrowStarupItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowStarupItem";
          this.exportNodeNames = {
              cc_head: "CustomTowerHead",
              cc_button_go: "fgui.GButton",
              cc_ctrl_star: "fgui.Controller",
              cc_ctrl_color: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb, index) {
          this.towerDb = towerDb;
          this.head.refresh(towerDb);
          this.ctrl_color.selectedIndex = index % this.ctrl_color.pageCount;
          this.ctrl_star.selectedIndex = mgrTower.getTowerStar(towerDb.id);
      }
      on_click_button_go() {
          Director.openPanelWithSingleton("PanelTowerStar", { towerDb: this.towerDb });
      }
  }

  class CustomGrowPage1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage1";
          this.bInited = false;
          this.exportNodeNames = {
              cc_list_type: "fgui.GList",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          this.listItem = new ListView(this.list_type, this, this.parseItem, this.renderItem);
          this.listItem.setOnClickItem(this, this.clickItem);
          this.listItem.setExData({});
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      onRefresh() {
          this.listItem.refresh();
      }
      parseItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.3, 0.05, 8);
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(this.listItem, content, index);
      }
      clickItem(content) {
          content.view.click();
      }
      refreshList() {
          let listData = db.get_grow_page1_map();
          this.listItem.setListData(listData);
      }
  }

  class CustomGrowPage2 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage2";
          this.id2expand = {};
          this.bInited = false;
          this.exportNodeNames = {
              cc_list_type: "fgui.GList",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          this.listItem = new ListView(this.list_type, this, this.parseItem, this.renderItem);
          this.listItem.setOnClickItem(this, this.clickItem);
          this.listItem.setExData({});
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      onRefresh() {
      }
      parseItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0, 0.05, 8);
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(this.listItem, content, index);
      }
      clickItem(content) {
          content.view.click();
      }
      refreshList() {
          let listData = db.get_grow_page2_map();
          this.listItem.setListData(listData);
      }
  }

  class CustomGrowPage3 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage3";
          this.id2expand = {};
          this.bInited = false;
          this.exportNodeNames = {
              cc_list_type: "fgui.GList",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          this.listItem = new ListView(this.list_type, this, this.parseItem, this.renderItem);
          this.listItem.setOnClickItem(this, this.clickItem);
          this.listItem.setExData({});
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      onRefresh() {
      }
      parseItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0, 0.05, 8);
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(this.listItem, content, index);
      }
      clickItem(content) {
          content.view.click();
      }
      refreshList() {
          let listData = db.get_grow_page3_map();
          this.listItem.setListData(listData);
      }
  }

  class CustomGrowPage4 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/CustomGrowPage4";
          this.id2expand = {};
          this.bInited = false;
          this.exportNodeNames = {
              cc_list_type: "fgui.GList",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          this.listItem = new ListView(this.list_type, this, this.parseItem, this.renderItem);
          this.listItem.setOnClickItem(this, this.clickItem);
          this.listItem.setExData({});
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      onRefresh() {
      }
      parseItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0, 0.05, 8);
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(this.listItem, content, index);
      }
      clickItem(content) {
          content.view.click();
      }
      refreshList() {
          let listData = db.get_grow_page4_map();
          this.listItem.setListData(listData);
      }
  }

  class PanelGrow extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "变强";
          this.sourceName = "ui://grow/PanelGrow";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_page1: "CustomGrowPage1",
              cc_page2: "CustomGrowPage2",
              cc_page3: "CustomGrowPage3",
              cc_page4: "CustomGrowPage4",
              cc_button_page1: "fgui.GButton",
              cc_button_page2: "fgui.GButton",
              cc_button_page3: "fgui.GButton",
              cc_button_page4: "fgui.GButton",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.initEvent();
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.onStateChange();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_RUSH_BEGIN]: this.onTowerRushBegin.bind(this),
              [MSG.GROW_CLOSE]: this.onGrowClose.bind(this),
              [BASE_MSG.UI_PANEL_CLOSED]: this.onUIPanelClosed.bind(this),
          });
      }
      onTowerRushBegin() {
          this.closeWithTransition();
      }
      onGrowClose() {
          this.closeWithTransition();
      }
      onUIPanelClosed() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.page1.onRefresh();
                  break;
              case 1:
                  this.page2.onRefresh();
                  break;
              case 2:
                  this.page3.onRefresh();
                  break;
              case 3:
                  this.page4.onRefresh();
                  break;
          }
      }
      onStateChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.page1.init();
                  break;
              case 1:
                  this.page2.init();
                  break;
              case 2:
                  this.page3.init();
                  break;
              case 3:
                  this.page4.init();
                  break;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_page1() {
      }
      on_click_button_page2() {
      }
      on_click_button_page3() {
      }
      on_click_button_page4() {
      }
  }

  class PanelGrowTip extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://grow/PanelGrowTip";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_com_tip: "fgui.GComponent",
              cc_label_tip: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.layer_full.onClick(this, this.closeWithTransition);
          this.label_tip.text = this.context.tip || "";
          let point = this.context.point;
          if (point) {
              this.com_tip.x = point.x;
              this.com_tip.y = point.y;
          }
      }
      dispose() {
          super.dispose();
      }
  }

  class PanelGrowPop extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "变强弹窗";
          this.sourceName = "ui://grow_pop/PanelGrowPop";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_button_go: "fgui.GButton",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_go() {
          this.closeWithTransition();
          Director.openPanelWithSingleton("PanelGrow");
      }
  }

  class CustomHolyItemBuildItem extends CustomButton {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem/CustomHolyItemBuildItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.itemDb = data;
          this.loader_icon.url = data.icon;
      }
  }

  class CustomHolyItemCondition extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem/CustomHolyItemCondition";
          this.selectNum = 1;
          this.exportNodeNames = {
              cc_button_word: "fgui.GButton",
              cc_button_quality: "fgui.GButton",
              cc_button_num: "fgui.GButton",
              cc_list_word: "fgui.GList",
              cc_list_quality: "fgui.GList",
              cc_list_num: "fgui.GList",
              cc_ctrl_word: "fgui.Controller",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_num: "fgui.Controller",
          };
      }
      onCreate() {
          this.listWord = new ListView(this.list_word, this, this.parseWordItem, this.renderWordItem);
          this.listQuality = new ListView(this.list_quality, this, this.parseQualityItem, this.renderQualityItem);
          this.listNum = new ListView(this.list_num, this, this.parseNumItem, this.renderNumItem);
          this.listWord.setOnClickItem(this, this.clickWordItem);
          this.listQuality.setOnClickItem(this, this.clickQualityItem);
          this.listNum.setOnClickItem(this, this.clickNumItem);
      }
      dispose() {
          super.dispose();
      }
      refresh(wordFiler) {
          this.wordFiler = wordFiler;
          this.refreshWordList();
          this.refreshQualityList();
          this.refreshNumList();
          this.selectWordDb = db.get_holy_item_word_map()[wordFiler.id - 1];
          this.selectQualityDb = db.get_holy_item_quality(wordFiler.quality);
          this.selectNum = wordFiler.num;
          this.button_word.title = this.selectWordDb ? this.selectWordDb.name_base : "全选";
          this.button_quality.title = this.selectQualityDb.name;
          this.button_quality.titleColor = this.selectQualityDb.color;
          this.refreshButtonNum(wordFiler.num);
      }
      parseWordItem(content, object) {
          content.title = object.getChild("title").asTextField;
      }
      renderWordItem(content, wordId) {
          let wordDb = db.get_holy_item_word_map()[wordId - 1];
          if (wordDb) {
              content.title.text = wordDb.name_base;
          }
          else {
              content.title.text = "全选";
          }
          content.wordId = wordId;
      }
      clickWordItem(content) {
          let wordDb = db.get_holy_item_word_map()[content.wordId - 1];
          if (wordDb) {
              this.button_word.title = wordDb.name_base;
          }
          else {
              this.button_word.title = "全选";
          }
          this.ctrl_word.selectedIndex = 0;
          if (this.wordFiler) {
              this.wordFiler.id = content.wordId;
              mgrHolyItem.saveRecord();
          }
      }
      refreshWordList() {
          let listData = [];
          let dataMap = db.get_holy_item_word_map();
          for (let data of dataMap) {
              listData.push(data.id);
          }
          listData.push(0);
          this.listWord.setListData(listData);
      }
      parseQualityItem(content, object) {
          content.title = object.getChild("title").asTextField;
      }
      renderQualityItem(content, quality) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              content.title.text = qualityDb.name;
              content.title.color = qualityDb.color;
          }
          content.qualityDb = qualityDb;
      }
      clickQualityItem(content) {
          this.button_quality.title = content.qualityDb.name;
          this.button_quality.titleColor = content.qualityDb.color;
          this.ctrl_quality.selectedIndex = 0;
          if (this.wordFiler) {
              this.wordFiler.quality = content.qualityDb.quality;
              mgrHolyItem.saveRecord();
          }
      }
      refreshQualityList() {
          this.listQuality.setListData([3, 2, 1, 0]);
      }
      parseNumItem(content, object) {
          content.title = object.getChild("title").asTextField;
      }
      renderNumItem(content, num) {
          content.num = num;
          if (num < 0) {
              content.title.text = "=" + (-num);
          }
          else {
              content.title.text = "≥" + num;
          }
      }
      refreshButtonNum(num) {
          if (num < 0) {
              this.button_num.title = "=" + (-num);
          }
          else {
              this.button_num.title = "≥" + num;
          }
      }
      clickNumItem(content) {
          this.refreshButtonNum(content.num);
          this.ctrl_num.selectedIndex = 0;
          if (this.wordFiler) {
              this.wordFiler.num = content.num;
              mgrHolyItem.saveRecord();
          }
      }
      refreshNumList() {
          this.listNum.setListData([-4, -3, -2, -1, 4, 3, 2, 1]);
      }
      closePopList() {
          this.ctrl_word.selectedIndex = 0;
          this.ctrl_quality.selectedIndex = 0;
          this.ctrl_num.selectedIndex = 0;
      }
      on_click_button_word() {
      }
      on_click_button_quality() {
      }
      on_click_button_num() {
      }
  }

  class CustomHolyItemConditionBuild extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem/CustomHolyItemConditionBuild";
          this.selectWordId = 0;
          this.exportNodeNames = {
              cc_button_word: "fgui.GButton",
              cc_list_word: "fgui.GList",
              cc_label_title: "fgui.GBasicTextField",
              cc_ctrl_word: "fgui.Controller",
          };
      }
      onCreate() {
          this.listWord = new ListView(this.list_word, this, this.parseWordItem, this.renderWordItem);
          this.listWord.setOnClickItem(this, this.clickWordItem);
      }
      dispose() {
          super.dispose();
      }
      refresh(title) {
          this.label_title.text = title;
          this.refreshWordList();
          this.refreshButtonTitle(this.selectWordId);
      }
      parseWordItem(content, object) {
          content.title = object.getChild("title").asTextField;
      }
      renderWordItem(content, wordId) {
          let wordDb = db.get_holy_item_word_map()[wordId - 1];
          if (wordDb) {
              content.title.text = wordDb.name_base;
          }
          else {
              content.title.text = "随机";
          }
          content.wordId = wordId;
      }
      refreshWordList() {
          let listData = [];
          let dataMap = db.get_holy_item_word_map();
          listData.push(0);
          for (let data of dataMap) {
              listData.push(data.id);
          }
          this.listWord.setListData(listData);
      }
      refreshButtonTitle(wordId) {
          let wordDb = db.get_holy_item_word_map()[wordId - 1];
          if (wordDb) {
              this.button_word.title = wordDb.name_base;
          }
          else {
              this.button_word.title = "随机";
          }
      }
      clickWordItem(content) {
          this.selectWordId = content.wordId;
          this.refreshButtonTitle(content.wordId);
          this.ctrl_word.selectedIndex = 0;
      }
      getSelectWordId() {
          return this.selectWordId;
      }
      on_click_button_word() {
      }
  }

  class CustomHolyItemConditionSell extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem/CustomHolyItemConditionSell";
          this.selectNum = 1;
          this.exportNodeNames = {
              cc_button_quality: "fgui.GButton",
              cc_button_num: "fgui.GButton",
              cc_button_select: "fgui.GButton",
              cc_list_quality: "fgui.GList",
              cc_list_num: "fgui.GList",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_num: "fgui.Controller",
          };
      }
      onCreate() {
          this.listQuality = new ListView(this.list_quality, this, this.parseQualityItem, this.renderQualityItem);
          this.listNum = new ListView(this.list_num, this, this.parseNumItem, this.renderNumItem);
          this.listQuality.setOnClickItem(this, this.clickQualityItem);
          this.listNum.setOnClickItem(this, this.clickNumItem);
      }
      dispose() {
          super.dispose();
      }
      refresh(wordFiler) {
          this.wordFiler = wordFiler;
          this.refreshQualityList();
          this.refreshNumList();
          this.selectQualityDb = db.get_holy_item_quality(wordFiler.quality);
          this.selectNum = wordFiler.num;
          this.button_quality.title = this.selectQualityDb.name;
          this.button_quality.titleColor = this.selectQualityDb.color;
          this.button_num.title = "≥" + wordFiler.num;
          this.button_select.selected = mgrHolyItem.checkFilterAutoSellCondition ? true : false;
      }
      parseQualityItem(content, object) {
          content.title = object.getChild("title").asTextField;
      }
      renderQualityItem(content, quality) {
          let qualityDb = db.get_holy_item_quality(quality);
          if (qualityDb) {
              content.title.text = qualityDb.name;
              content.title.color = qualityDb.color;
          }
          content.qualityDb = qualityDb;
      }
      clickQualityItem(content) {
          this.button_quality.title = content.qualityDb.name;
          this.button_quality.titleColor = content.qualityDb.color;
          this.ctrl_quality.selectedIndex = 0;
          if (this.wordFiler) {
              this.wordFiler.quality = content.qualityDb.quality;
              mgrHolyItem.saveRecord();
          }
      }
      refreshQualityList() {
          this.listQuality.setListData([3, 2, 1, 0]);
      }
      parseNumItem(content, object) {
          content.title = object.getChild("title").asTextField;
      }
      renderNumItem(content, num) {
          content.num = num;
          content.title.text = "≥" + num;
      }
      clickNumItem(content) {
          this.button_num.title = "≥" + content.num;
          this.ctrl_num.selectedIndex = 0;
          if (this.wordFiler) {
              this.wordFiler.num = content.num;
              mgrHolyItem.saveRecord();
          }
      }
      refreshNumList() {
          this.listNum.setListData([4, 3, 2, 1]);
      }
      closePopList() {
          this.ctrl_quality.selectedIndex = 0;
          this.ctrl_num.selectedIndex = 0;
      }
      on_click_button_quality() {
      }
      on_click_button_num() {
      }
      on_click_button_select() {
          mgrHolyItem.checkFilterAutoSellCondition = this.button_select.selected ? 1 : 0;
      }
  }

  class CustomHolyItemFilterItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem/CustomHolyItemFilterItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_select: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.itemDb = data;
          this.loader_icon.url = data.icon;
          this.ctrl_select.selectedIndex = mgrHolyItem.checkFilterItemId(data.id) ? 1 : 0;
      }
      click() {
          if (this.ctrl_select.selectedIndex)
              this.ctrl_select.selectedIndex = 0;
          else
              this.ctrl_select.selectedIndex = 1;
          if (this.itemDb) {
              mgrHolyItem.setFilterHolyItemId(this.itemDb.id, this.ctrl_select.selectedIndex > 0);
          }
      }
      refreshAutoSell(data) {
          this.itemDb = data;
          this.loader_icon.url = data.icon;
          this.ctrl_select.selectedIndex = mgrHolyItem.checkFilterAutoSellItemId(data.id) ? 1 : 0;
      }
      clickAutoSell() {
          if (this.ctrl_select.selectedIndex)
              this.ctrl_select.selectedIndex = 0;
          else
              this.ctrl_select.selectedIndex = 1;
          if (this.itemDb) {
              mgrHolyItem.setFilterAutoSellItemId(this.itemDb.id, this.ctrl_select.selectedIndex > 0);
          }
      }
  }

  class CustomSubCondition extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem/CustomSubCondition";
          this.exportNodeNames = {};
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
  }

  var BAG_EX_TYPE;
  (function (BAG_EX_TYPE) {
      BAG_EX_TYPE[BAG_EX_TYPE["HOLYITEM"] = 0] = "HOLYITEM";
  })(BAG_EX_TYPE || (BAG_EX_TYPE = {}));
  class PanelBagEx extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "背包扩展";
          this.sourceName = "ui://holyitem/PanelBagEx";
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.curtType = BAG_EX_TYPE.HOLYITEM;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_curt: "fgui.GBasicTextField",
              cc_label_next: "fgui.GBasicTextField",
              cc_button_ad: "fgui.GButton",
              cc_button_go: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
              cc_ctrl_max: "fgui.Controller",
          };
      }
      buildUi() {
          this.button_go.title = db.game_cnf.bag_ex_cost.toString();
          this.refresh();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.bag_expand) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.bag_expand);
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      dispose() {
          super.dispose();
      }
      expandBag() {
          switch (this.curtType) {
              case BAG_EX_TYPE.HOLYITEM:
                  mgrHolyItem.addBagSize(db.game_cnf.bag_ex_add);
                  break;
          }
          this.refresh();
      }
      watchAdSuccess() {
          this.expandBag();
      }
      refresh() {
          this.button_go.title = db.game_cnf.bag_ex_cost.toString();
          switch (this.curtType) {
              case BAG_EX_TYPE.HOLYITEM:
                  this.label_curt.text = mgrHolyItem.getBagSize().toString();
                  let sizeNext = (mgrHolyItem.getBagSize() + db.game_cnf.bag_ex_add);
                  this.label_next.text = Math.min(sizeNext, mgrHolyItem.getBagSizeMax()).toString();
                  break;
          }
          this.ctrl_max.selectedIndex = mgrHolyItem.isBagSizeMax() ? 1 : 0;
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_go() {
          if (mgrGame.subItem(1000, db.game_cnf.bag_ex_cost, 52)) {
              this.expandBag();
          }
      }
      on_click_button_ad() {
          switch (this.curtType) {
              case BAG_EX_TYPE.HOLYITEM:
                  mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.bag_expand);
                  break;
          }
      }
      on_click_button_giveupad() {
          this.closeWithTransition();
      }
  }

  class PanelHolyItemAutoSell extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "自动售出";
          this.sourceName = "ui://holyitem/PanelHolyItemAutoSell";
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_quality_0: "fgui.GButton",
              cc_button_quality_1: "fgui.GButton",
              cc_button_quality_2: "fgui.GButton",
              cc_button_quality_3: "fgui.GButton",
              cc_button_all_select: "fgui.GButton",
              cc_button_all_unselect: "fgui.GButton",
              cc_sellcondition: "CustomHolyItemConditionSell",
              cc_button_save: "fgui.GButton",
              cc_button_reset: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.listItem = new ListView(this.list_item, this, this.parseTypeItem, this.renderTypeItem);
          this.listItem.setOnClickItem(this, this.clickTypeItem);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      parseTypeItem(content, object) {
          content.view = object.getChild("item");
      }
      renderTypeItem(content, data) {
          content.data = data;
          content.view.refreshAutoSell(data);
      }
      clickTypeItem(content) {
          content.view.clickAutoSell();
      }
      refreshTypeList() {
          let listData = [];
          let holyMap = db.get_holy_item_db_map();
          for (let k in holyMap) {
              listData.push(db.get_holy_item_db(k));
          }
          this.listItem.setListData(listData);
      }
      refresh() {
          let config = mgrHolyItem.getConvertConfig();
          this.button_quality_0.selected = config.green;
          this.button_quality_1.selected = config.blue;
          this.button_quality_2.selected = config.purple;
          this.button_quality_3.selected = config.orange;
          this.refreshTypeList();
          this.sellcondition.refresh(mgrHolyItem.getFilterAutoSellCondition());
      }
      closePopList() {
          this.sellcondition.closePopList();
      }
      on_click_button_save() {
          let config = mgrHolyItem.getConvertConfig();
          if (config.orange && !mgrHolyItem.checkFilterAutoSellCondition) {
              mgrTip.alertPrompt("即将自动出售橙色品质圣物，是否确认按当前设定自动出售圣物？", "提示", () => {
                  mgrHolyItem.autoSell();
                  this.closeWithTransition();
              });
          }
          else {
              mgrHolyItem.autoSell();
              this.closeWithTransition();
          }
      }
      on_click_button_quality_3() {
          mgrHolyItem.getConvertConfig().orange = this.button_quality_3.selected;
          mgrHolyItem.saveRecord();
      }
      on_click_button_quality_2() {
          mgrHolyItem.getConvertConfig().purple = this.button_quality_2.selected;
          mgrHolyItem.saveRecord();
      }
      on_click_button_quality_1() {
          mgrHolyItem.getConvertConfig().blue = this.button_quality_1.selected;
          mgrHolyItem.saveRecord();
      }
      on_click_button_quality_0() {
          mgrHolyItem.getConvertConfig().green = this.button_quality_0.selected;
          mgrHolyItem.saveRecord();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_all_select() {
          let holyMap = db.get_holy_item_db_map();
          for (let id in holyMap) {
              mgrHolyItem.setFilterAutoSellItemId(id, true);
          }
          this.listItem.refresh();
      }
      on_click_button_all_unselect() {
          let holyMap = db.get_holy_item_db_map();
          for (let id in holyMap) {
              mgrHolyItem.setFilterAutoSellItemId(id, false);
          }
          this.listItem.refresh();
      }
      on_click_button_reset() {
          mgrHolyItem.resetFilterAutoSell();
          this.closePopList();
          this.refresh();
      }
  }

  class PanelHolyItemBag extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物背包";
          this.sourceName = "ui://holyitem/PanelHolyItemBag";
          this.panelStyle = 0;
          this.exportNodeNames = {
              cc_bag: "fgui.GComponent",
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
              cc_list_sort: "fgui.GList",
              cc_com_holyitem: "CustomHolyItemInfoBagEx",
              cc_button_sort: "fgui.GButton",
              cc_button_condition: "fgui.GButton",
              cc_button_condition_select: "fgui.GButton",
              cc_button_auto_sell: "fgui.GButton",
              cc_button_bag_ex: "fgui.GButton",
              cc_towers: "fgui.GComponent",
              cc_list_tower: "fgui.GList",
              cc_label_bag: "fgui.GBasicTextField",
              cc_mask_black: "fgui.GGraph",
              cc_ctrl_sort: "fgui.Controller",
              cc_ctrl_have: "fgui.Controller",
              cc_ctrl_towers: "fgui.Controller",
              cc_ctrl_full: "fgui.Controller",
              cc_ctrl_filter: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
              cc_trans_in: "fgui.Transition",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.listSort = new ListView(this.list_sort, this, this.parseSortItem, this.renderSortItem);
          this.listSort.setOnClickItem(this, this.onClickSortItem);
          this.listTower = new ListView(this.list_tower, this, this.parseTowerItem, this.renderTowerItem);
          this.listTower.setOnClickItem(this, this.onClickTowerItem);
          this.listSort.setListData([
              "默认排序",
              "品质排序",
              "强化等级排序",
              "种类排序",
          ]);
          this.ctrl_filter.on(fgui.Events.STATE_CHANGED, this, this.onFilterStateChange);
          this.listItem = new HolyItemList(this.list_item, this, this.onClickBagItem);
          this.listItem.setOnItemSelectCallBack(this.onBagItemSelect.bind(this));
          this.refresh(mgrHolyItem.sortType);
          this.refreshTowerList();
          this.com_holyitem.setOnClickEquipCallback(this.onClickItemEquip.bind(this));
          this.mask_black.onClick(this, this.onClickEquipMask);
          this.initEvent();
          mgrGame.tryOpenPanelIntro("PanelIntroBag", "bag_have_item");
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.HOLY_ITEM_FEED]: this.onHolyItemFeed.bind(this),
              [MSG.HOLY_ITEM_SELL]: this.onHolyItemSell.bind(this),
              [MSG.HOLY_ITEM_LOCK]: this.onHolyItemLock.bind(this),
              [MSG.HOLY_ITEM_ADDD]: this.onHolyItemAddd.bind(this),
              [MSG.TOWER_ATTR_UPDATE]: this.onTowerAttrUpdate.bind(this),
              [MSG.MSG_BAG_EQUIP_EX]: this.onBagEquipEx.bind(this),
              [MSG.HOLY_ITEM_BAG_LVUP_OPEN]: this.onPanelLvupOpen.bind(this),
              [MSG.PANEL_HOLYITEM_LVUP_CLOSE]: this.onPanelLvupClose.bind(this),
              [MSG.HOLY_ITEM_FILTER_CHANGE]: this.onHolyItemFilterChange.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      refresh(sortType, item) {
          if (sortType == null) {
              sortType = mgrHolyItem.sortType;
          }
          let useFilter = this.ctrl_filter.selectedIndex ? true : false;
          let listData = mgrHolyItem.getBagItems(sortType, useFilter);
          let haveItem = false;
          for (let item of listData) {
              if (item.holyitem) {
                  haveItem = true;
                  break;
              }
          }
          if (!useFilter) {
              this.ctrl_have.selectedIndex = haveItem ? 0 : 1;
          }
          this.listItem.setListData(listData);
          let selectItem = item || listData[0];
          this.listItem.refreshWithSelect(selectItem);
          if (selectItem) {
              this.com_holyitem.refresh(selectItem);
          }
          this.button_sort.title = this.listSort.getListData()[sortType];
          let count = 0;
          for (let item of listData) {
              if (item.holyitem)
                  count++;
          }
          this.label_bag.text = "背包：" + count + "/" + mgrHolyItem.getBagSize();
          this.ctrl_full.selectedIndex = mgrHolyItem.isBagFull() ? 1 : 0;
      }
      onClickBagItem(content) {
      }
      onBagItemSelect(content) {
          if (content.data) {
              if (content.data.holyitem) {
                  this.com_holyitem.refresh(content.data);
              }
          }
      }
      onClickItemEquip(button) {
          this.ctrl_towers.selectedIndex = 1;
          this.refreshTowerList();
          this.afterClickItemEquip();
      }
      afterClickItemEquip() {
      }
      onClickEquipMask() {
          this.ctrl_towers.selectedIndex = 0;
      }
      onFilterStateChange() {
          this.refresh();
      }
      onHolyItemFeed() {
          this.refresh();
      }
      onHolyItemSell() {
          this.refresh();
      }
      onHolyItemLock(uid) {
          let content = this.listItem.selectContent;
          if (content && content.data && content.data.holyitem && content.data.holyitem.getUID() == uid) {
              this.listItem.renderBagItem(content, content.data);
          }
          else {
              this.refresh(mgrHolyItem.sortType, this.com_holyitem.selectItem);
          }
      }
      onHolyItemAddd() {
          this.refresh(mgrHolyItem.sortType, this.com_holyitem.selectItem);
      }
      onTowerAttrUpdate() {
          this.refresh(mgrHolyItem.sortType, this.com_holyitem.selectItem);
      }
      onBagEquipEx() {
          this.refresh(mgrHolyItem.sortType, this.com_holyitem.selectItem);
      }
      onPanelLvupOpen() {
          this.trans_out.play(Laya.Handler.create(this, this.onTransInEnd));
      }
      onTransInEnd() {
          Director.openPanel("PanelHolyItemLvup", { item: this.com_holyitem.selectItem });
      }
      onPanelLvupClose() {
          this.trans_in.play();
      }
      onHolyItemFilterChange() {
          this.refresh();
      }
      parseSortItem(content, object, index) {
          content.button = object;
      }
      renderSortItem(content, name, index) {
          content.button.title = name;
          content.index = index;
      }
      onClickSortItem(content) {
          mgrHolyItem.sortType = content.index;
          this.refresh(mgrHolyItem.sortType);
          this.ctrl_sort.selectedIndex = 0;
      }
      parseTowerItem(content, object, index) {
          content.icon = object.getChild("icon").asLoader;
          content.full = object.getController("full");
          content.quality = object.getController("quality");
      }
      renderTowerItem(content, data, index) {
          content.towerDb = data;
          content.quality.selectedIndex = mgrTower.getTowerQualityByDB(data);
          ;
          content.full.selectedIndex = mgrTower.haveEmptySlot(data.id) ? 0 : 1;
          let itemDb = db.get_item_db(data.item_id);
          if (itemDb) {
              content.icon.url = itemDb.icon;
          }
      }
      onClickTowerItem(content) {
          this.ctrl_towers.selectedIndex = 0;
          Director.openPanelWithSingleton("PanelTowerInfo", { towerDb: content.towerDb, item: this.com_holyitem.selectItem });
          this.afterClickTowerItem();
      }
      afterClickTowerItem() {
      }
      refreshTowerList() {
          let towerDbMap = db.get_tower_db_map();
          let listData = [];
          for (let key in towerDbMap) {
              let data = db.get_tower_db(key);
              if (data.main || mgrTower.getTowerAmount(key)) {
                  listData.push(data);
              }
          }
          listData.sort(this.sortCard);
          this.listTower.setListData(listData);
      }
      sortCard(a, b) {
          let score_a = mgrTower.calcTowerScoreBag(a.id);
          let score_b = mgrTower.calcTowerScoreBag(b.id);
          return score_b - score_a;
      }
      on_click_button_close() {
          this.closeWithTransition("cc_trans_out");
      }
      on_click_button_auto_sell() {
          Director.openPanelWithSingleton("PanelHolyItemAutoSell");
      }
      on_click_button_sort() {
      }
      on_click_button_bag_ex() {
          Director.openPanelWithSingleton("PanelBagEx");
      }
      on_click_button_condition() {
          Director.openPanelWithSingleton("PanelHolyItemFilter");
      }
      on_click_button_condition_select() {
      }
  }

  class PanelHolyItemBuilder extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "自选词条";
          this.sourceName = "ui://holyitem/PanelHolyItemBuilder";
          this.panelLayer = 4;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_word1: "CustomHolyItemConditionBuild",
              cc_word2: "CustomHolyItemConditionBuild",
              cc_word3: "CustomHolyItemConditionBuild",
              cc_word4: "CustomHolyItemConditionBuild",
              cc_button_ensure: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.listItem = new ListView(this.list_item, this, this.parseTypeItem, this.renderTypeItem);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          this.refreshTypeList();
          this.word1.refresh("词条1");
          this.word2.refresh("词条2");
          this.word3.refresh("词条3");
          this.word4.refresh("词条4");
      }
      parseTypeItem(content, view) {
          content.view = view;
      }
      renderTypeItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshTypeList() {
          let listData = [];
          let holyMap = db.get_holy_item_db_map();
          for (let k in holyMap) {
              let itemDb = db.get_holy_item_db(k);
              if (itemDb.smelt) {
                  listData.push(itemDb);
              }
          }
          this.listItem.setListData(listData);
          this.listItem.selectedIndex = 0;
      }
      on_click_button_ensure() {
          let itemDb = this.listItem.getSelectData();
          if (itemDb) {
              let id1 = this.word1.getSelectWordId();
              let id2 = this.word2.getSelectWordId();
              let id3 = this.word3.getSelectWordId();
              let id4 = this.word4.getSelectWordId();
              let holyItem = HolyItemMaker.buildHolyItemByOption({
                  itemDb: itemDb,
                  quality: EQUIP_QUALITY.ORANGE,
                  wordQuality: [3, 3, 3, 3],
                  wordIds: [id1, id2, id3, id4],
              });
              let dropData = [];
              mgrHolyItem.addHolyItem(holyItem, dropData);
              Level.showItemGet(dropData);
          }
          let callback = this.context.callback;
          if (callback) {
              callback();
          }
          this.closeWithTransition();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelHolyItemBuilderBox extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "自选泰坦";
          this.sourceName = "ui://holyitem/PanelHolyItemBuilderBox";
          this.panelStyle = 0;
          this.IdMain = "";
          this.IdVice = "";
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_ensure: "fgui.GButton",
              cc_button_item1: "fgui.GButton",
              cc_button_item2: "fgui.GButton",
              cc_button_close: "ScaleButton",
          };
      }
      buildUi() {
          this.ctrlItem1Have = this.button_item1.getController("item");
          this.ctrlItem2Have = this.button_item2.getController("item");
          Global.registerListeners(this, {
              [MSG.SMELTER_SELECT_ITEM]: this.onSmelterSelectItem.bind(this),
          });
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onSmelterSelectItem(data) {
          switch (data.index) {
              case 1:
                  this.onSelectItemMain(data.itemDb);
                  break;
              case 2:
                  this.onSelectItemVice(data.itemDb);
                  break;
          }
      }
      onSelectItemMain(itemDb) {
          this.IdMain = itemDb.id;
          this.refresh();
      }
      onSelectItemVice(itemDb) {
          this.IdVice = itemDb.id;
          this.refresh();
      }
      refresh() {
          let itemDbMain = db.get_holy_item_db_map()[this.IdMain];
          let itemDbVice = db.get_holy_item_db_map()[this.IdVice];
          if (itemDbMain) {
              this.button_item1.icon = itemDbMain.icon;
              this.ctrlItem1Have.selectedIndex = 1;
          }
          else {
              this.ctrlItem1Have.selectedIndex = 0;
          }
          if (itemDbVice) {
              this.button_item2.icon = itemDbVice.icon;
              this.ctrlItem2Have.selectedIndex = 1;
          }
          else {
              this.ctrlItem2Have.selectedIndex = 0;
          }
      }
      on_click_button_ensure() {
          let itemDbMain = db.get_holy_item_db_map()[this.IdMain];
          let itemDbVice = db.get_holy_item_db_map()[this.IdVice];
          if (!itemDbMain) {
              mgrTip.showMsgTip("请选择主圣物");
              return;
          }
          if (!itemDbVice) {
              mgrTip.showMsgTip("请选择副圣物");
              return;
          }
          if (itemDbMain && itemDbVice) {
              let holyItem = HolyItemMaker.buildHolyItemByOption({ quality: EQUIP_QUALITY.RED, itemDb: itemDbMain, itemDbSub: itemDbVice });
              mgrHolyItem.addHolyItem(holyItem);
              Director.openPanelWithSingleton("PanelSmelterSuc", holyItem);
              let callback = this.context.callback;
              if (callback) {
                  callback();
              }
              this.closeWithTransition();
          }
      }
      on_click_button_item1() {
          Director.openPanelWithSingleton("PanelSmelterSelectItem", { index: 1, selectId: this.IdVice });
      }
      on_click_button_item2() {
          Director.openPanelWithSingleton("PanelSmelterSelectItem", { index: 2, selectId: this.IdMain });
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelHolyItemFilter extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物筛选";
          this.sourceName = "ui://holyitem/PanelHolyItemFilter";
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_quality_0: "fgui.GButton",
              cc_button_quality_1: "fgui.GButton",
              cc_button_quality_2: "fgui.GButton",
              cc_button_quality_3: "fgui.GButton",
              cc_condition_1: "CustomHolyItemCondition",
              cc_condition_2: "CustomHolyItemCondition",
              cc_button_all_select: "fgui.GButton",
              cc_button_all_unselect: "fgui.GButton",
              cc_button_ensure: "fgui.GButton",
              cc_button_reset: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.listItem = new ListView(this.list_item, this, this.parseTypeItem, this.renderTypeItem);
          this.listItem.setOnClickItem(this, this.clickTypeItem);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onClickBackground() {
          this.closePopList();
      }
      refresh() {
          this.refreshTypeList();
          this.refreshQuality();
          this.refreshCondition();
      }
      parseTypeItem(content, view) {
          content.view = view;
      }
      renderTypeItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      clickTypeItem(content) {
          content.view.click();
      }
      refreshTypeList() {
          let listData = [];
          let holyMap = db.get_holy_item_db_map();
          for (let k in holyMap) {
              listData.push(db.get_holy_item_db(k));
          }
          this.listItem.setListData(listData);
      }
      refreshQuality() {
          this.button_quality_0.selected = mgrHolyItem.checkFilterQuality(EQUIP_QUALITY.GREEN);
          this.button_quality_1.selected = mgrHolyItem.checkFilterQuality(EQUIP_QUALITY.BLUE);
          this.button_quality_2.selected = mgrHolyItem.checkFilterQuality(EQUIP_QUALITY.PURPLE);
          this.button_quality_3.selected = mgrHolyItem.checkFilterQuality(EQUIP_QUALITY.ORANGE);
      }
      refreshCondition() {
          this.condition_1.refresh(mgrHolyItem.getFilterCondition1());
          this.condition_2.refresh(mgrHolyItem.getFilterCondition2());
      }
      closePopList() {
          this.condition_1.closePopList();
          this.condition_2.closePopList();
      }
      on_click_button_quality_0() {
          mgrHolyItem.setFilterHolyItemQuality(EQUIP_QUALITY.GREEN, this.button_quality_0.selected);
      }
      on_click_button_quality_1() {
          mgrHolyItem.setFilterHolyItemQuality(EQUIP_QUALITY.BLUE, this.button_quality_1.selected);
      }
      on_click_button_quality_2() {
          mgrHolyItem.setFilterHolyItemQuality(EQUIP_QUALITY.PURPLE, this.button_quality_2.selected);
      }
      on_click_button_quality_3() {
          mgrHolyItem.setFilterHolyItemQuality(EQUIP_QUALITY.ORANGE, this.button_quality_3.selected);
      }
      on_click_button_all_select() {
          let holyMap = db.get_holy_item_db_map();
          for (let id in holyMap) {
              mgrHolyItem.setFilterHolyItemId(id, true);
          }
          this.listItem.refresh();
      }
      on_click_button_all_unselect() {
          let holyMap = db.get_holy_item_db_map();
          for (let id in holyMap) {
              mgrHolyItem.setFilterHolyItemId(id, false);
          }
          this.listItem.refresh();
      }
      on_click_button_ensure() {
          Global.sendMsg(MSG.HOLY_ITEM_FILTER_CHANGE);
          this.closeWithTransition();
      }
      on_click_button_reset() {
          mgrHolyItem.resetFilterHolyItem();
          this.closePopList();
          this.refresh();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class CustomProgressLvup extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem_lvup/CustomProgressLvup";
          this.exportNodeNames = {
              cc_progress_lvup1: "fgui.GProgressBar",
              cc_progress_lvup2: "fgui.GProgressBar",
              cc_label_add1: "fgui.GBasicTextField",
              cc_label_add2: "fgui.GBasicTextField",
              cc_label_total1: "fgui.GBasicTextField",
              cc_label_total2: "fgui.GBasicTextField",
              cc_label_left_bracket: "fgui.GBasicTextField",
              cc_ctrl_add: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      setProgress(cur, add, max) {
          this.setRealProgrees(cur / max * 100);
          cur += add;
          this.setPreviewProgress(cur / max * 100);
          this.label_total1.text = (cur).toString();
          this.label_total2.text = "/" + max + ")";
          this.ctrl_add.selectedIndex = add > 0 ? 1 : 0;
      }
      hideExpLabel() {
          this.label_total1.visible = false;
          this.label_total2.visible = false;
          this.label_left_bracket.visible = false;
      }
      setPreviewProgress(value) {
          if (value > this.progress_lvup1.value)
              this.progress_lvup1.tweenValue(value, 0.2);
          else
              this.progress_lvup1.value = value;
      }
      setRealProgrees(value) {
          if (value > this.progress_lvup2.value)
              this.progress_lvup2.tweenValue(value, 0.2);
          else
              this.progress_lvup2.value = value;
      }
      setLv(value) {
          this.label_add2.text = "+" + value;
      }
      setPreviewLvAdd(value) {
          this.label_add1.text = "+" + value;
      }
  }

  class PanelHolyItemChoose extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物选择";
          this.sourceName = "ui://holyitem_lvup/PanelHolyItemChoose";
          this.panelStyle = 0;
          this.bMask = false;
          this.bAutoRemovePackage = true;
          this.typeFilter = null;
          this.exportNodeNames = {
              cc_choose: "fgui.GComponent",
              cc_button_close: "ScaleButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
              cc_list_sort: "fgui.GList",
              cc_com_holyitem: "CustomHolyItemInfoBag",
              cc_button_sort: "fgui.GButton",
              cc_button_filter_select: "fgui.GButton",
              cc_button_filter: "fgui.GButton",
              cc_ctrl_detail: "fgui.Controller",
              cc_ctrl_sort: "fgui.Controller",
              cc_ctrl_filter: "fgui.Controller",
              cc_ctrl_filter_show: "fgui.Controller",
          };
      }
      buildUi() {
          this.itemExcept = this.context.itemExcept;
          this.typeFilter = this.context.typeFilter;
          this.initEvent();
          this.ctrl_filter.on(fgui.Events.STATE_CHANGED, this, this.onFilterStateChange);
          this.listSort = new ListView(this.list_sort, this, this.parseSortItem, this.renderSortItem);
          this.listSort.setOnClickItem(this, this.onClickSortItem);
          this.listSort.setListData([
              "默认排序",
              "品质排序",
              "强化等级排序",
              "种类排序",
          ]);
          this.listItem = new HolyItemList(this.list_item, this, this.onClickBagItem);
          this.listItem.setOnItemUseCallBack(this.onItemUseChange.bind(this));
          this.listItem.openUse = true;
          this.refresh(mgrHolyItem.sortType);
          this.com_holyitem.hideButton();
          this.ctrl_filter_show.selectedIndex = 1;
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.HOLY_ITEM_LOCK]: this.onHolyItemLock.bind(this),
          });
      }
      dispose() {
          super.dispose();
          Global.sendMsg(MSG.HOLY_ITEM_SELECT_REFRESH);
      }
      parseSortItem(content, object, index) {
          content.button = object;
      }
      renderSortItem(content, name, index) {
          content.button.title = name;
          content.index = index;
      }
      onClickSortItem(content) {
          mgrHolyItem.sortType = content.index;
          this.refresh(mgrHolyItem.sortType);
          this.ctrl_sort.selectedIndex = 0;
      }
      onItemUseChange(content, use) {
          Global.sendMsg(MSG.HOLY_ITEM_SELECT_REFRESH);
      }
      refresh(sortType) {
          let bagItems = mgrHolyItem.getBagItems(sortType, this.ctrl_filter.selectedIndex ? true : false, this.typeFilter);
          let listData = [];
          for (let item of bagItems) {
              if (item != this.itemExcept && !mgrSmelter.isHolyItemQualityUping(item.holyitem))
                  listData.push(item);
          }
          this.listItem.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      onClickBagItem(content) {
          if (content.data) {
              let holyitem = content.data.holyitem;
              if (holyitem) {
                  if (!content.data.selected && this.itemExcept && this.itemExcept.prelvMax) {
                      mgrTip.showMsgTip("已达强化上限");
                  }
                  this.com_holyitem.refresh(content.data);
                  this.ctrl_detail.selectedIndex = 1;
                  if (!content.data.selected && holyitem.isEquiped()) {
                      let name = holyitem.getEquipTowerName();
                      mgrTip.alertPrompt("该圣物已被" + name + "所装备，是否【确认作为强化素材】？", "", () => {
                          content.data.selected = true;
                          this.refresh(mgrHolyItem.sortType);
                          this.onItemUseChange();
                      });
                      return true;
                  }
                  if (!content.data.selected && holyitem.isPreset()) {
                      mgrTip.alertPrompt("该圣物已被" + holyitem.getPresetNum() + "个方案预设，是否【确认作为强化素材】？", "", () => {
                          content.data.selected = true;
                          this.refresh(mgrHolyItem.sortType);
                          this.onItemUseChange();
                      });
                      return true;
                  }
                  if (holyitem.lock) {
                      mgrTip.alertPrompt("该圣物已被锁定，请解锁后再试");
                      return true;
                  }
              }
          }
          return false;
      }
      onFilterStateChange() {
          this.refresh(mgrHolyItem.sortType);
      }
      onHolyItemLock(uid) {
          let content = this.listItem.selectContent;
          if (content && content.data && content.data.holyitem && content.data.holyitem.getUID() == uid) {
              this.listItem.renderBagItem(content, content.data);
          }
          else {
              this.refresh(mgrHolyItem.sortType);
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_sort() {
      }
      on_click_button_filter_select() {
      }
      on_click_button_filter() {
          Director.openPanelWithSingleton("PanelHolyItemFilter");
      }
  }

  class PanelHolyItemChooseSmelter extends PanelHolyItemChoose {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem_lvup/PanelHolyItemChooseSmelter";
          this.exportNodeNames = {
              cc_choose: "fgui.GComponent",
              cc_button_close: "ScaleButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
              cc_list_sort: "fgui.GList",
              cc_com_holyitem: "CustomHolyItemInfoBag",
              cc_button_sort: "fgui.GButton",
              cc_button_filter_select: "fgui.GButton",
              cc_button_filter: "fgui.GButton",
              cc_ctrl_detail: "fgui.Controller",
              cc_ctrl_sort: "fgui.Controller",
              cc_ctrl_filter: "fgui.Controller",
              cc_ctrl_filter_show: "fgui.Controller",
          };
      }
      buildUi() {
          super.buildUi();
          this.ctrl_filter_show.selectedIndex = 0;
      }
      dispose() {
          super.dispose();
      }
      refresh(sortType) {
          let bagItems = mgrHolyItem.getBagItems4Feed(sortType, this.typeFilter, EQUIP_QUALITY.RED);
          let listData = [];
          for (let item of bagItems) {
              if (item != this.itemExcept && !mgrSmelter.isHolyItemQualityUping(item.holyitem) && mgrSmelter.checkItemCanPut(item.holyitem))
                  listData.push(item);
          }
          this.listItem.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      onItemUseChange(content, use) {
          Global.sendMsg(MSG.SMELTER_BAG_SELECT_ITEMS);
      }
      onClickBagItem(content) {
          if (content.data) {
              let holyitem = content.data.holyitem;
              if (holyitem) {
                  if (!content.data.selected) {
                      if (mgrSmelter.isSmeltPreExpFull()) {
                          mgrTip.showMsgTip("熔炼值已满！");
                          return true;
                      }
                  }
                  this.com_holyitem.refresh(content.data);
                  this.ctrl_detail.selectedIndex = 1;
                  if (!content.data.selected && holyitem.isEquiped()) {
                      let name = holyitem.getEquipTowerName();
                      mgrTip.alertPrompt("该圣物已被" + name + "所装备，是否【确认作为锻造素材】？", "", () => {
                          content.data.selected = true;
                          this.refresh(mgrHolyItem.sortType);
                          this.onItemUseChange();
                      });
                      return true;
                  }
                  if (!content.data.selected && holyitem.isPreset()) {
                      mgrTip.alertPrompt("该圣物已被" + holyitem.getPresetNum() + "个方案预设，是否【确认作为锻造素材】？", "", () => {
                          content.data.selected = true;
                          this.refresh(mgrHolyItem.sortType);
                          this.onItemUseChange();
                      });
                      return true;
                  }
                  if (holyitem.lock) {
                      mgrTip.alertPrompt("该圣物已被锁定，请解锁后再试");
                      return true;
                  }
              }
          }
          return false;
      }
      on_click_button_close() {
          super.on_click_button_close();
      }
      on_click_button_sort() {
          super.on_click_button_sort();
      }
      on_click_button_filter_select() {
      }
      on_click_button_filter() {
      }
  }

  class HolyItemListWash extends HolyItemList {
      renderBagItem(content, data) {
          content.select.selectedIndex = 0;
          content.equip.selectedIndex = 0;
          content.data = data;
          if (data.holyitem) {
              Level.updateRedPoint4Button(content.item, data.holyitem.new);
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
              content.item.refresh(data.holyitem);
              if (this.selectHolytem && this.selectHolytem == data) {
                  this.markSelect(content);
              }
              if (data.holyitem.isEquiped()) {
                  content.equip.selectedIndex = 1;
              }
              if (this.openUse) {
                  content.use.selectedIndex = data.selected ? 1 : 0;
              }
              content.lock.selectedIndex = data.holyitem.lock ? 1 : 0;
          }
          else {
              content.lock.selectedIndex = 0;
              if (this.openUse) {
                  content.use.selectedIndex = 0;
              }
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.EMPTY;
          }
      }
  }

  class PanelHolyItemChooseWash extends PanelHolyItemChoose {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://holyitem_lvup/PanelHolyItemChooseWash";
          this.exportNodeNames = {
              cc_choose: "fgui.GComponent",
              cc_button_close: "ScaleButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
              cc_list_sort: "fgui.GList",
              cc_com_holyitem: "CustomHolyItemInfoBag",
              cc_button_sort: "fgui.GButton",
              cc_button_filter_select: "fgui.GButton",
              cc_button_filter: "fgui.GButton",
              cc_ctrl_detail: "fgui.Controller",
              cc_ctrl_sort: "fgui.Controller",
              cc_ctrl_filter: "fgui.Controller",
              cc_ctrl_filter_show: "fgui.Controller",
          };
      }
      buildUi() {
          mgrHolyItem.clearBagSelect();
          this.itemExcept = this.context.itemExcept;
          this.typeFilter = this.context.typeFilter;
          this.initEvent();
          this.listSort = new ListView(this.list_sort, this, this.parseSortItem, this.renderSortItem);
          this.listSort.setOnClickItem(this, this.onClickSortItem);
          this.listSort.setListData([
              "默认排序",
              "品质排序",
              "强化等级排序",
              "种类排序",
          ]);
          this.listItem = new HolyItemListWash(this.list_item, this, this.onClickBagItem);
          this.listItem.setOnItemUseCallBack(this.onItemUseChange.bind(this));
          this.listItem.openUse = true;
          this.refresh(mgrHolyItem.sortType);
          this.com_holyitem.hideButton();
          this.label_title.text = "请选择洗炼的圣物";
      }
      dispose() {
          super.dispose();
          mgrHolyItem.clearBagSelect();
      }
      refresh(sortType) {
          let bagItems = mgrHolyItem.getBagItemsByQuality(sortType, EQUIP_QUALITY.RED, true);
          let listData = [];
          for (let item of bagItems) {
              if (item != this.itemExcept)
                  listData.push(item);
          }
          this.listItem.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      onItemUseChange(content, use) {
          if (content) {
              Global.sendMsg(MSG.WASH_SELECT_ITEM, content.data);
          }
      }
      onClickBagItem(content) {
          if (content.data) {
              let holyitem = content.data.holyitem;
              if (holyitem) {
                  let lastItem = this.com_holyitem.selectItem;
                  this.com_holyitem.refresh(content.data);
                  this.ctrl_detail.selectedIndex = 1;
                  if (lastItem && lastItem != content.data) {
                      lastItem.selected = false;
                      this.refresh(mgrHolyItem.sortType);
                  }
              }
          }
          return false;
      }
      on_click_button_close() {
          super.on_click_button_close();
      }
      on_click_button_sort() {
          super.on_click_button_sort();
      }
      on_click_button_filter_select() {
      }
      on_click_button_filter() {
      }
  }

  class PanelHolyItemLvup extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物升级";
          this.sourceName = "ui://holyitem_lvup/PanelHolyItemLvup";
          this.bAutoRemovePackage = true;
          this.panelStyle = 0;
          this.emptyItem = { item: null };
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_word: "fgui.GBasicTextField",
              cc_label_value_1: "fgui.GBasicTextField",
              cc_label_value_2: "fgui.GBasicTextField",
              cc_label_desc_2: "fgui.GBasicTextField",
              cc_button_lvup: "fgui.GButton",
              cc_com_item: "fgui.GComponent",
              cc_loder_item_icon: "fgui.GLoader",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_progress: "CustomProgressLvup",
              cc_button_put: "fgui.GButton",
              cc_com_attr: "CustomAttrHolyItem2",
              cc_button_filter: "fgui.GButton",
              cc_list_item: "fgui.GList",
              cc_list_quality: "fgui.GList",
              cc_ctrl_filter: "fgui.Controller",
              cc_ctrl_lvup_attr: "fgui.Controller",
              cc_ctrl_add_level: "fgui.Controller",
              cc_ctrl_max: "fgui.Controller",
          };
      }
      buildUi() {
          mgrHolyItem.clearBagSelect();
          this.item = this.context.item;
          this.listQualityFilter = new ListView(this.list_quality, this, this.parsetFilterItem, this.renderFilterItem);
          this.listQualityFilter.setOnClickItem(this, this.onClickFilterItem);
          this.listItem = new ListView(this.list_item, this, this.parseHolyItem, this.renderHolyItem);
          this.listItem.setOnClickItem(this, this.onClickHolyItem);
          this.refresh();
          this.refreshProgress();
          this.refreshFilter();
          this.refreshFilterSelect();
          this.refreshHolyItem();
          this.initEvent();
      }
      dispose() {
          Global.sendMsg(MSG.PANEL_HOLYITEM_LVUP_CLOSE);
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.HOLY_ITEM_SELECT_REFRESH]: this.onHolyItemSelectRefresh.bind(this),
              [MSG.HOLY_ITEM_FEED]: this.onHolyItemChange.bind(this),
          });
      }
      refresh() {
          let item = this.item.holyitem;
          if (item) {
              this.label_item_name.text = item.getName();
              this.label_desc.text = item.getDesc();
              this.label_word.text = item.itemDb.key_word;
              this.loder_item_icon.url = item.getIcon();
              this.ctrl_quality.selectedIndex = item.qualityDb.quality;
              this.label_value_1.text = item.getValue(true).toFixed(1) + "%";
              this.com_attr.refresh(item.attr);
          }
      }
      refreshProgress(add = 0) {
          let item = this.item.holyitem;
          if (item) {
              let isLvMax = item.isLevelMax();
              if (isLvMax) {
                  this.ctrl_max.selectedIndex = 1;
                  this.progress.setLv(item.level);
                  this.progress.setProgress(100, 0, 100);
                  this.progress.hideExpLabel();
                  this.item.prelvMax = true;
                  this.label_desc_2.text = "";
              }
              else {
                  this.ctrl_max.selectedIndex = 0;
                  let maxLevel = item.levelMax;
                  let addLevel = item.calcLvAdd(add);
                  let newLevel = item.level + addLevel;
                  if (newLevel > maxLevel) {
                      addLevel = maxLevel - item.level;
                  }
                  this.progress.setLv(item.level);
                  this.progress.setPreviewLvAdd(addLevel);
                  this.progress.setProgress(item.getExp(), add, item.getExpMax(null, 0));
                  this.ctrl_add_level.selectedIndex = addLevel > 0 ? 1 : 0;
                  let wordLvupCount = Math.floor((item.level % 4 + addLevel) / 4);
                  this.ctrl_lvup_attr.selectedIndex = wordLvupCount ? 1 : 0;
                  this.label_desc_2.text = "(将强化" + wordLvupCount + "次副词条)";
                  if (addLevel) {
                      this.label_value_2.text = item.getValueNext(addLevel, true).toFixed(1) + "%";
                  }
                  this.item.prelvMax = newLevel >= item.levelMax;
              }
          }
      }
      refreshFilter() {
          let listData = [];
          let qualistList = db.get_holy_item_quality_map();
          for (let item of qualistList) {
              listData.push(item);
          }
          listData.sort(this.sortQualityItem.bind(this));
          this.listQualityFilter.setListData(listData);
      }
      refreshFilterSelect() {
          let qualityDb = db.get_holy_item_quality(mgrHolyItem.getFilterQuality());
          if (qualityDb) {
              this.button_filter.title = qualityDb.name;
              this.button_filter.titleColor = qualityDb.color;
          }
      }
      sortQualityItem(a, b) {
          return b.index - a.index;
      }
      parsetFilterItem(content, object) {
          content.title = object.getChild("title").asLabel;
      }
      renderFilterItem(content, data) {
          content.data = data;
          content.title.text = data.name;
          content.title.color = data.color;
      }
      onClickFilterItem(content) {
          this.ctrl_filter.selectedIndex = 0;
          mgrHolyItem.setFilterQuality(content.data.quality);
          this.refreshFilterSelect();
      }
      parseHolyItem(content, object, index) {
          content.quality = object.getController("quality");
          content.state = object.getController("state");
          content.select = object.getController("select");
          content.coinUnlock = object.getChild("coin_unlock").asLabel;
          content.starUnlock = object.getChild("star_unlock").asLabel;
          content.levelUnlock = object.getChild("level_unlock").asLabel;
          content.item = object.getChild("item");
          if (index < 5) {
              object.getTransition("idle").play();
              object.getTransition("in").play(null, 1, 0.125 * index);
          }
      }
      renderHolyItem(content, data) {
          let item = data.item;
          if (item && item.holyitem) {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
              content.item.refresh(item.holyitem);
          }
          else {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ADD;
          }
          content.data = data;
      }
      onClickHolyItem(content) {
          if (mgrGuide.isGuiding)
              return;
          if (this.selectSlotContent) {
              this.selectSlotContent.select.selectedIndex = 0;
          }
          this.selectSlotContent = content;
          content.select.selectedIndex = 1;
          switch (content.state.selectedIndex) {
              case HOLY_ITEM_SLOT_STATE.ITEM:
              case HOLY_ITEM_SLOT_STATE.ADD:
                  Director.openPanel("PanelHolyItemChoose", { itemExcept: this.item });
                  break;
          }
      }
      refreshHolyItem(listItem = null) {
          listItem = listItem || mgrHolyItem.getBagItems();
          let listData = [];
          let expAdd = 0;
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  listData.push({ item: item });
                  expAdd += item.holyitem.getExpFeed();
              }
              else {
                  listData.push(this.emptyItem);
              }
          }
          listData.sort(this.sortListItem.bind(this));
          this.listItem.setListData(listData);
          this.refreshProgress(expAdd);
      }
      sortListItem(a, b) {
          let score_a = a.item ? 100 : 0;
          let score_b = b.item ? 100 : 0;
          return score_b - score_a;
      }
      onHolyItemSelectRefresh() {
          this.refreshHolyItem();
      }
      onHolyItemChange() {
          this.refreshHolyItem();
          this.refresh();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_lvup() {
          mgrNetwork.callByNetwork(() => {
              let listItem = mgrHolyItem.getBagItems();
              let listData = [];
              for (let i = 0; i < listItem.length; i++) {
                  let item = listItem[i];
                  if (item.holyitem && item.selected) {
                      listData.push(item);
                  }
              }
              let holyitem = this.item.holyitem;
              let attrOld = holyitem.buildAttr();
              let valueOld = holyitem.getValue(true);
              let isLevelAdd = mgrHolyItem.feedItem(this.item, listData);
              if (isLevelAdd) {
                  let attrNew = holyitem.buildAttr();
                  let valueNew = holyitem.getValue(true);
                  Director.openPanel("PanelHolyItemLvupSuc", { item: this.item, attrOld: attrOld, attrNew: attrNew, valueOld: valueOld, valueNew: valueNew });
              }
          });
      }
      on_click_button_put() {
          this.refreshHolyItem(mgrHolyItem.autoSelectByQuality(this.item));
      }
      on_click_button_filter() {
      }
  }

  class PanelHolyItemLvupSuc extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "圣物升级成功";
          this.sourceName = "ui://holyitem_lvup/PanelHolyItemLvupSuc";
          this.panelStyle = 0;
          this.exportNodeNames = {
              cc_layer_bg: "fgui.GComponent",
              cc_com_item: "fgui.GComponent",
              cc_loder_item_icon: "fgui.GLoader",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_label_word: "fgui.GBasicTextField",
              cc_label_value_1: "fgui.GBasicTextField",
              cc_label_value_2: "fgui.GBasicTextField",
              cc_label_level: "fgui.GBasicTextField",
              cc_list_attr: "fgui.GList",
              cc_effect_suc: "FguiEffect",
          };
      }
      buildUi() {
          this.item = this.context.item;
          this.listAttr = new ListView(this.list_attr, this, this.parseAttrItem, this.renderAttrItem);
          this.listAttr.setListData(this.context.attrOld);
          this.layer_bg.onClick(this, this.onClickBackground);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      parseAttrItem(content, object, index) {
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          content.valueAdd = object.getChild("valueAdd").asTextField;
          content.add = object.getController("add");
          content.quality = object.getController("quality");
          let trans_out = object.getTransition("idle");
          trans_out.play();
          let trans_in = object.getTransition("in");
          trans_in.play(null, 1, 1.1 + 0.05 * index);
      }
      renderAttrItem(content, data, index) {
          let v = data.v;
          let valueNew = this.context.attrNew[index].v;
          let valueAdd = valueNew - data.v;
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
          }
          let attrDb = db.get_holy_item_attr_base_map()[data.k];
          if (attrDb) {
              if (attrDb.percent_value) {
                  content.value.text = "+" + v.toFixed(1) + "%";
              }
              else {
                  content.value.text = "+" + v.toFixed(1);
              }
          }
          else {
              content.value.text = "+" + v.toFixed(1) + "%";
          }
          if (valueAdd) {
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.valueAdd.text = "+" + valueNew.toFixed(1) + "%";
                  }
                  else {
                      content.valueAdd.text = "+" + valueNew.toFixed(1);
                  }
              }
              else {
                  content.valueAdd.text = "+" + valueNew.toFixed(1) + "%";
              }
              content.add.selectedIndex = 1;
          }
          else {
              content.add.selectedIndex = 0;
          }
          content.quality.selectedIndex = data.q || 0;
      }
      refresh() {
          let item = this.item.holyitem;
          if (item) {
              this.label_item_name.text = item.getName();
              this.label_word.text = item.itemDb.key_word;
              this.loder_item_icon.url = item.getIcon();
              this.ctrl_quality.selectedIndex = item.qualityDb.quality;
              this.label_value_1.text = this.context.valueOld.toFixed(1) + "%";
              this.label_value_2.text = this.context.valueNew.toFixed(1) + "%";
              this.label_level.text = "+" + item.level;
          }
      }
      onClickBackground() {
          this.closeWithTransition();
      }
  }

  class CustomTowerIntro extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://icebreak/CustomTowerIntro";
          this.exportNodeNames = {
              cc_stage_tower: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(towerId) {
          let towerDb = db.get_tower_db(towerId);
          if (towerDb) {
              this.label_name.text = towerDb.name;
              this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
              let skin = new TowerSkin();
              skin.loadSkin(towerDb, true);
              this.skin = skin;
              this.stage_tower.displayObject.addChild(skin);
              this.skin.refreshQuality(towerDb.id);
              this.skin.syncShooterByDB(towerDb);
          }
      }
  }

  class PanelIceBreak extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "破冰奖励";
          this.sourceName = "ui://icebreak/PanelIceBreak";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_tower_ad: "CustomTowerIntro",
              cc_tower_normal: "CustomTowerIntro",
              cc_button_ad: "fgui.GButton",
              cc_button_normal: "fgui.GButton",
              cc_effect_node: "FguiEffect",
          };
      }
      buildUi() {
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.icebreak) {
                      this.getReward(db.game_cnf.icebreak_tower_id_ad);
                  }
              },
          });
          this.tower_normal.refresh(db.game_cnf.icebreak_tower_id_free);
          this.tower_ad.refresh(db.game_cnf.icebreak_tower_id_ad);
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.icebreak);
      }
      dispose() {
          super.dispose();
      }
      getReward(towerId) {
          mgrGame.getIceBreakReward(towerId);
          this.closeWithTransition();
      }
      on_click_button_ad() {
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.icebreak);
          });
      }
      on_click_button_normal() {
          mgrNetwork.callByNetwork(() => {
              this.getReward(db.game_cnf.icebreak_tower_id_free);
          });
      }
  }

  class CustomUnlockItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://intro/CustomUnlockItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_lable_desc: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.lable_desc.text = data.unlock_desc;
          this.loader_icon.url = data.unlock_icon;
      }
  }

  class PanelIntroBag extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "背包介绍";
          this.sourceName = "ui://intro/PanelIntroBag";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          if (this.context.msg) {
              Global.sendMsg(MSG.GUIDE_MSG_TRIGGER, this.context.msg);
          }
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroBoss extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "挑战模式介绍";
          this.sourceName = "ui://intro/PanelIntroBoss";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroChallenge extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "无尽挑战介绍";
          this.sourceName = "ui://intro/PanelIntroChallenge";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          Global.sendMsg(MSG.TOWER_ENDNESS_BEGIN);
          this.close();
      }
  }

  class PanelIntroGoal extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "战令介绍";
          this.sourceName = "ui://intro/PanelIntroGoal";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroPeace extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "和平模式介绍";
          this.sourceName = "ui://intro/PanelIntroPeace";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroPray extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "祈愿介绍";
          this.sourceName = "ui://intro/PanelIntroPray";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroStory extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "主线故事介绍";
          this.sourceName = "ui://intro/PanelIntroStory";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroSummon extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "召唤介绍";
          this.sourceName = "ui://intro/PanelIntroSummon";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "fgui.GButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_close() {
          this.close();
      }
  }

  class PanelIntroUnlock extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "成长之路";
          this.sourceName = "ui://intro/PanelIntroUnlock";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_label_condition: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
              cc_button_go: "fgui.GButton",
              cc_button_sure: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
          let unlock = this.context.unlock;
          let step = this.context.step || 0;
          this.ctrl_state.selectedIndex = unlock ? 1 : 0;
          let infos = mgrGame.calcStepUnlockInfo(step);
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.listItem.setListData(infos);
          let storyDb = mgrGame.findStoryDbByIndex(step);
          if (storyDb) {
              this.label_condition.text = "通关主线故事关卡" + storyDb.id + "-" + storyDb.lv + "即可解锁以上系统";
          }
      }
      dispose() {
          super.dispose();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_go() {
          this.closeWithTransition();
          Director.openPanelWithSingleton("PanelChallenge", { index: 0 });
      }
      on_click_button_sure() {
          this.closeWithTransition();
          let listData = this.listItem.getListData();
          if (listData.length) {
              let data = listData[0];
              if (data)
                  Director.openPanelWithSingleton(data.unlock_panel, { index: data.unlock_panel_index, page: data.unlock_panel_index });
          }
      }
  }

  class CustomGetItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://item_get/CustomGetItem";
          this.exportNodeNames = {
              cc_item: "CustomCommItem",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.item.refresh(data);
      }
      playTransIn(delay = 0) {
          this.item.playTransIn(delay);
      }
      playTransInWityEffect(delay = 0, scene3d, camera) {
          this.item.playTransIn(delay);
          Laya.timer.once(delay * 1000, this, () => {
              let effect = EffectFactory.create("166_ui_loop_gold_01", scene3d);
              effect.followFguiNode(camera, this.item);
          });
      }
      getItem() {
          return this.item;
      }
  }

  class CustomItemSelect extends CustomButton {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://item_get/CustomItemSelect";
          this.exportNodeNames = {
              cc_item: "CustomItem",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.item.refresh(data);
      }
      playTransIn(delay = 0) {
      }
      playTransInWityEffect(delay = 0, scene3d, camera) {
      }
  }

  class PanelItemGet extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "物品获得";
          this.sourceName = "ui://item_get/PanelItemGet";
          this.panelLayer = 4;
          this.isButtonBannerBottom = false;
          this.isButtonBannerRecover = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_ensure: "fgui.GButton",
              cc_button_lookad: "fgui.GButton",
              cc_list_item: "fgui.GList",
              cc_node_effect: "fgui.GLoader",
              cc_ctrl_banner: "fgui.Controller",
          };
      }
      create(callback) {
          Global.registerListeners(this, {
              [MSG.BANNER_SHOW]: this.onMsgBannerShow.bind(this),
              [MSG.BANNER_HIDE]: this.onMsgBannerHide.bind(this),
          });
          super.create(callback);
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          if (this.isButtonBannerBottom) {
              this.ctrl_banner.selectedIndex = 1;
          }
          if (this.isButtonBannerRecover) {
              if (db.cop_db.ui_itemget_button_banner_delay) {
                  Laya.timer.once(db.cop_db.ui_itemget_button_banner_delay * 1000, this, this.onButtonBannerDelay);
              }
              else {
                  this.ctrl_banner.selectedIndex = 0;
              }
          }
      }
      onButtonBannerDelay() {
          if (this.destroyed || !this.ctrl_banner)
              return;
          this.ctrl_banner.selectedIndex = 0;
          super.adaptBannerAdv();
      }
      onAwake() {
          this.createScene3DEffect();
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.refreshItem();
          let effect = EffectFactory.create("166_ui_loop_gxhd_01", this.scene3DEffect);
          effect.followFguiNode(this.cameraEffect, this.node_effect);
          mgrSound.playSound("item_get");
      }
      dispose() {
          Global.sendMsg(MSG.PANEL_ITEM_GET_CLOSE);
          super.dispose();
      }
      adaptBannerAdv() {
          if (this.isFocus) {
              let isShowBanner = true;
              if (db.cop_db.ui_itemget_button_banner_ratio) {
                  this.isButtonBannerBottom = true;
                  if (mgrTime.getOnlineTime() >= db.cop_db.ui_itemget_button_banner_wait && !CopHelper.isBannerRecoverCDing()) {
                      this.isButtonBannerRecover = Mathf.randomEnable(db.cop_db.ui_itemget_button_banner_ratio);
                  }
                  else {
                      this.isButtonBannerRecover = false;
                  }
                  if (this.isButtonBannerRecover) {
                      CopHelper.markBannerRecoverCDing();
                  }
                  isShowBanner = false;
              }
              if (isShowBanner) {
                  super.adaptBannerAdv();
              }
          }
          else {
              super.adaptBannerAdv();
          }
      }
      parseItem(content, object) {
          content.view = object;
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
          content.view.playTransInWityEffect(1 + index * 0.05, this.scene3DEffect, this.cameraEffect);
      }
      refreshItem() {
          let listData = this.context.items || [];
          this.listItem.setListData(listData);
      }
      onMsgBannerShow() {
          if (db.cop_db.b_show_banner_btn_switch[0]) {
              this.button_lookad.visible = true;
          }
      }
      onMsgBannerHide() {
          this.button_lookad.visible = false;
      }
      on_click_button_ensure() {
          this.closeWithTransition();
      }
      on_click_button_lookad() {
          Global.sendMsg(MSG.BANNER_CLICK_AD);
      }
  }

  class PanelItemSelect extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "物品选择";
          this.sourceName = "ui://item_get/PanelItemSelect";
          this.panelLayer = 4;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_ensure: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_node_effect: "fgui.GLoader",
              cc_label_title: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.refreshItem();
      }
      dispose() {
          super.dispose();
      }
      parseItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.25, 0.05);
      }
      renderItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshItem() {
          let dropDb = this.context.dropDb;
          if (dropDb) {
              let listData = [];
              let items = dropDb.items;
              for (let i = 0; i < items.length; i += 2) {
                  let itemId = items[i];
                  let itemCn = items[i + 1];
                  if (itemId && itemCn) {
                      listData.push({ itemId: itemId, count: itemCn });
                  }
              }
              this.listItem.setListData(listData);
              this.list_item.selectedIndex = 0;
          }
          let itemId = this.context.itemId;
          if (itemId) {
              this.label_title.text = mgrGame.getItemName(itemId);
          }
      }
      on_click_button_ensure() {
          let data = this.listItem.getSelectData();
          if (data) {
              mgrGame.addItem(data.itemId, data.count, 46);
          }
          let callback = this.context.callback;
          if (callback) {
              callback();
          }
          this.closeWithTransition();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelLoading extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "首页加载";
          this.sourceName = "ui://load/PanelLoading";
          this.panelStyle = 1;
          this.loadTipArr = [
              { percent: 0, tip: "初次加载请耐心等待" },
              { percent: 30, tip: "加载中..." },
              { percent: 50, tip: "正在进入游戏" },
              { percent: 80, tip: "马上进入游戏" },
          ];
          this.stepCur = 0;
          this.stepPer = 100 / 2;
          this.exportNodeNames = {
              cc_label_progress: "fgui.GBasicTextField",
              cc_label_tip: "fgui.GBasicTextField",
              cc_progress_bar: "fgui.GProgressBar",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      onPanelCreate() {
          this.loadSpine();
      }
      buildUi() {
          this.resNode.makeFullScreen();
          Global.registerListeners(this, {
              [BASE_MSG.RES_LOAD_PROGRESS]: this.onProgress.bind(this),
              [MSG.SDK_INIT]: this.onSdkInit.bind(this),
              [UPDATER_UI_MSG.DOWNLOAD_BEGIN]: this.onDownLoadBegin.bind(this),
              [UPDATER_UI_MSG.GET_VERSION]: this.onGetVerison.bind(this),
              [UPDATER_UI_MSG.DOWNLOAD_SUCCESS]: this.onDownloadSuccess.bind(this),
              [UPDATER_UI_MSG.ENTER_NEXT_SCENE]: this.onEnterNextScene.bind(this),
          });
      }
      dispose() {
          super.dispose();
          this.unloadSpine();
      }
      hide() {
          this.close();
      }
      loadSpine() {
      }
      unloadSpine() {
      }
      onGetVerison() {
      }
      onDownLoadBegin() {
          this.ctrl_state.selectedIndex = 1;
          this.progress_bar.tweenValue(100, 5);
      }
      onDownloadSuccess() {
      }
      onEnterNextScene() {
          console.log("PanelLoading.onEnterNextScene");
      }
      getTipMsg(percent) {
          for (let i = this.loadTipArr.length - 1; i >= 0; i--) {
              let item = this.loadTipArr[i];
              if (item && percent >= item.percent) {
                  return item.tip;
              }
          }
          return "资源加载中";
      }
      onProgress(percent) {
          if (percent >= 1)
              this.stepCur++;
          let value = Math.ceil(this.stepPer * this.stepCur + percent * this.stepPer);
          this.progress_bar.value = value;
          this.label_progress.text = value + "%";
          this.label_tip.text = this.getTipMsg(value);
      }
      onSdkInit() {
          this.adaptStatisDuration();
      }
  }

  class PanelLoadingGame extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://load/PanelLoadingGame";
          this.panelStyle = 1;
          this.stepCur = 0;
          this.stepPer = 100 / 2;
          this.exportNodeNames = {
              cc_progress_bar: "fgui.GProgressBar",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          Global.registerListeners(this, {
              [BASE_MSG.RES_LOAD_PROGRESS]: this.onProgress.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      hide() {
          this.close();
      }
      onProgress(percent) {
          if (percent >= 1)
              this.stepCur++;
          this.progress_bar.value = this.stepPer * this.stepCur + percent * this.stepPer;
      }
  }

  class PanelWait extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://load/PanelWait";
          this.panelLayer = 8;
          this.panelStyle = 1;
          this.exportNodeNames = {
              cc_circle: "fgui.GComponent",
              cc_loadSprite: "fgui.GImage",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
  }

  class CustomMainSkillItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://main_hero/CustomMainSkillItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_loader_name: "fgui.GLoader",
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_name: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(skillId) {
          let skillDb = db.get_skill_db(skillId);
          if (skillDb) {
              this.label_desc.text = skillDb.desc;
              this.loader_icon.url = skillDb.icon;
              this.label_name.text = skillDb.name;
          }
      }
  }

  class PanelMainHeroUnlock extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "主塔英雄解锁";
          this.sourceName = "ui://main_hero/PanelMainHeroUnlock";
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_dialog: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
          };
      }
      buildUi() {
          this.heroId = this.context;
          let heroDb = db.get_main_hero(this.heroId - 1);
          if (heroDb) {
              this.label_dialog.text = "是否解锁【" + heroDb.name + "】？";
              this.button_ensure.title = heroDb.cost.toString();
          }
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.unlock_main_hero) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.unlock_main_hero);
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      dispose() {
          super.dispose();
      }
      tryUnlock(force = false) {
          if (mgrTower.tryUnlockMainHero(this.heroId, force)) {
              this.close();
          }
      }
      watchAdSuccess() {
          this.tryUnlock(true);
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_ensure() {
          this.tryUnlock();
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.unlock_main_hero);
      }
      on_click_button_giveupad() {
          this.closeWithTransition();
      }
  }

  var UNLOCK_STATE;
  (function (UNLOCK_STATE) {
      UNLOCK_STATE[UNLOCK_STATE["UNLOCK"] = 0] = "UNLOCK";
      UNLOCK_STATE[UNLOCK_STATE["LOCK"] = 1] = "LOCK";
  })(UNLOCK_STATE || (UNLOCK_STATE = {}));
  class PanelTowerMainHero extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "主塔英雄";
          this.sourceName = "ui://main_hero/PanelTowerMainHero";
          this.bAutoRemovePackage = true;
          this.selectHeroId = 0;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_hero: "fgui.GList",
              cc_skill1: "CustomMainSkillItem",
              cc_skill2: "CustomMainSkillItem",
              cc_button_ensure: "fgui.GButton",
              cc_ctrl_select: "fgui.Controller",
          };
      }
      buildUi() {
          this.selectHeroId = mgrTower.getMainHeroId();
          this.listHero = new ListView(this.list_hero, this, this.parseHeroItem, this.renderHeroItem, false, false);
          this.listHero.setOnClickItem(this, this.onClickHeroItem);
          this.initEvent();
          this.refresh();
          this.refreshSkill();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.MAIN_HERO_UNLOCK]: this.onMainHeroUnlock.bind(this),
          });
      }
      refresh() {
          let listData = db.get_main_hero_map();
          this.listHero.setListData(listData);
      }
      refreshSkill() {
          let heroDb = db.get_main_hero(this.selectHeroId - 1);
          if (heroDb) {
              this.skill1.refresh(heroDb.skill_id);
              this.skill2.refresh(heroDb.super_id);
          }
          this.button_ensure.enabled = this.selectHeroId != mgrTower.getMainHeroId();
      }
      parseHeroItem(content, object, index) {
          content.button = object;
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asLoader;
          content.label_name = object.getChild("label_name").asTextField;
          content.select = object.getController("select");
          content.lock = object.getController("lock");
          content.cost = object.getChild("cost").asLabel;
          let idle = object.getTransition("idle");
          idle.play();
          let tIn = object.getTransition("in");
          tIn.play(null, 1, 0.5 + 0.05 * index);
      }
      renderHeroItem(content, data) {
          content.label_name.text = data.name;
          content.icon.url = data.icon;
          content.name.url = data.icon_name;
          content.data = data;
          content.lock.selectedIndex = (data.unlock || mgrTower.isMainHeroUnlock(data.id)) ? UNLOCK_STATE.UNLOCK : UNLOCK_STATE.LOCK;
          content.cost.text = data.cost.toString();
          content.data = data;
          if (data.id == this.selectHeroId) {
              content.select.selectedIndex = 1;
              this.selectContent = content;
          }
          else {
              content.select.selectedIndex = 0;
          }
      }
      onClickHeroItem(content) {
          if (content.lock.selectedIndex == UNLOCK_STATE.UNLOCK) {
              if (this.selectContent) {
                  this.selectContent.select.selectedIndex = 0;
                  this.selectContent = null;
              }
              this.selectContent = content;
              this.selectContent.select.selectedIndex = 1;
              this.selectHeroId = content.data.id;
              this.refreshSkill();
          }
          else {
              Director.openPanelWithSingleton("PanelMainHeroUnlock", content.data.id);
          }
      }
      onMainHeroUnlock(id) {
          this.selectHeroId = id;
          this.refresh();
          this.refreshSkill();
      }
      changeSkill() {
          mgrTower.changeMainHero(this.selectHeroId);
          this.closeWithTransition("click");
      }
      on_click_button_close() {
          this.closeWithTransition("out");
      }
      on_click_button_ensure() {
          this.changeSkill();
      }
  }

  class CustomNewyearShop1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomNewyearShop1";
          this.exportNodeNames = {
              cc_label_name: "fgui.GBasicTextField",
              cc_button_buy: "fgui.GButton",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_soldout: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(exchangeDb) {
          if (!exchangeDb)
              return;
          this.exchangeDb = exchangeDb;
          let itemDb = db.get_item_db(exchangeDb.item_id);
          if (itemDb) {
              this.label_name.text = itemDb.name;
              if (itemDb.quality < this.ctrl_quality.pageCount)
                  this.ctrl_quality.selectedIndex = itemDb.quality;
              this.button_buy.title = exchangeDb.price_item_cost.toString();
          }
          this.ctrl_soldout.selectedIndex = mgrExchange.canExchangeByDB(exchangeDb) ? 0 : 1;
      }
      on_click_button_buy() {
          if (this.exchangeDb)
              mgrExchange.tryExchangeShop(this.exchangeDb);
      }
  }

  class CustomNewyearShopItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomNewyearShopItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_buy: "fgui.GButton",
              cc_label_shop_name: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_ctrl_soldout: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.shopDb = data;
          this.item.refreshById(data.item_id, data.item_num);
          this.label_shop_name.text = mgrGame.getItemName(data.item_id);
          this.label_left.text = mgrExchange.getExchangeLeftCountByDB(data) + "/" + data.limit;
          this.button_buy.title = data.price_item_cost.toString();
          this.button_buy.icon = mgrGame.getItemIcon(data.price_item_id);
          this.ctrl_soldout.selectedIndex = mgrExchange.canExchangeByDB(data) ? 0 : 1;
      }
      on_click_button_buy() {
          if (this.shopDb && mgrHolyItem.notEnoughEmptyByItemId(this.shopDb.item_id, this.shopDb.item_num))
              return;
          mgrExchange.tryExchangeShop(this.shopDb);
      }
  }

  class CustomTaskItemNewyear extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomTaskItemNewyear";
          this.exportNodeNames = {
              cc_progress_task: "fgui.GProgressBar",
              cc_button_reward: "fgui.GButton",
              cc_label_desc: "fgui.GBasicTextField",
              cc_task_state: "fgui.Controller",
          };
      }
      onCreate() {
          this.label_progress = this.progress_task.getChild("text").asTextField;
      }
      dispose() {
          super.dispose();
      }
      onClickWithButton(caller, func, args) {
          this.button_reward.onClick(caller, func, args);
      }
      refresh(data) {
          let task = data.task;
          let curt = mgrTask.getTaskCountByDB(task);
          let need = mgrTask.getTaskNeed(task);
          if (curt > need)
              curt = need;
          if (mgrNewyear.isTaskAndFBValid()) {
              if (mgrTask.isTaskAward(task.id)) {
                  this.task_state.setSelectedIndex(2);
              }
              else {
                  if (mgrTask.isTaskCompleteByDB(task)) {
                      this.task_state.setSelectedIndex(1);
                  }
                  else {
                      this.task_state.setSelectedIndex(0);
                  }
              }
          }
          else {
              this.task_state.setSelectedIndex(3);
          }
          this.label_desc.text = Utils.sprintf(task.desc, need);
          this.label_progress.text = curt + "/" + need;
          this.progress_task.value = curt / need * 100;
      }
      on_click_button_reward() {
      }
  }

  class CustomSignItemNewyear extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomSignItemNewyear";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_fix: "fgui.GButton",
              cc_label_day: "fgui.GBasicTextField",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.signDb = data;
          this.label_day.text = data.name;
          this.item.refreshById(data.item_id, data.item_num);
          let day = mgrNewyear.day;
          if (mgrNewyear.isSigned(data.day)) {
              this.ctrl_state.selectedIndex = 3;
          }
          else {
              if (data.day == day) {
                  this.ctrl_state.selectedIndex = 1;
              }
              else if (data.day < day) {
                  this.ctrl_state.selectedIndex = 2;
              }
              else {
                  this.ctrl_state.selectedIndex = 0;
              }
          }
          if (!mgrNewyear.dataShowAdStatis[data.day]) {
              if (mgrGame.statisVideoShowByButton(this.button_fix, db.ADV_DB_ADVNAME.newyear_sign_fix_ad)) {
                  mgrNewyear.dataShowAdStatis[data.day] = true;
              }
          }
      }
      checkBagSize(scale) {
          let signDb = this.signDb;
          if (signDb) {
              return mgrHolyItem.notEnoughEmptyByItemId(signDb.item_id, signDb.item_num * scale);
          }
          return false;
      }
      on_click_button_fix() {
          if (this.checkBagSize(1))
              return;
          if (this.signDb) {
              mgrNetwork.callByNetwork(() => {
                  mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.newyear_sign_fix_ad, this.signDb.day);
              });
          }
      }
  }

  class CustomNewyearPage1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomNewyearPage1";
          this.bInited = false;
          this.exportNodeNames = {
              cc_button_sign: "fgui.GButton",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          this.initEvent();
          this.listItem = [];
          for (let i = 0; i < this.numChildren; i++) {
              let child = this.getChildAt(i);
              if (child instanceof CustomSignItemNewyear) {
                  this.listItem.push(child);
              }
          }
          this.refreshList();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.NEWYEAR_SIGN_UPDATE]: this.onSignUpdate.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.newyear_sign_fix_ad) {
                      mgrNewyear.sign(e.params, 1);
                  }
              },
          });
      }
      onSignUpdate() {
          this.refreshList();
      }
      refreshList() {
          for (let i = 0; i < this.listItem.length; i++) {
              let data = db.get_newyear_sign_db(i);
              let item = this.listItem[i];
              if (item && data) {
                  item.refresh(data);
              }
          }
          this.button_sign.enabled = mgrNewyear.canSign(mgrNewyear.day);
      }
      getReward(scale = 1) {
          mgrNewyear.sign(mgrNewyear.day, scale);
      }
      checkBagSize(scale) {
          let signDb = mgrNewyear.findSignDbByDay(mgrNewyear.day);
          if (signDb) {
              return mgrHolyItem.notEnoughEmptyByItemId(signDb.item_id, signDb.item_num * scale);
          }
          return false;
      }
      on_click_button_sign() {
          if (this.checkBagSize(1))
              return;
          mgrNetwork.callByNetwork(() => {
              this.getReward();
          });
      }
  }

  class CustomNewyearPage2 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomNewyearPage2";
          this.bInited = false;
          this.exportNodeNames = {
              cc_button_exchange: "fgui.GButton",
              cc_list_task: "fgui.GList",
              cc_label_curt: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_enough: "fgui.Controller",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          FguiHelper.playTransition(this, "in");
          this.listTask = new ListView(this.list_task, this, this.parseTaskItem, this.renderTaskItem);
          this.refreshTask();
          this.refreshInfo();
          this.initEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.onItemChange.bind(this),
          });
      }
      onItemChange() {
          this.refreshInfo();
      }
      parseTaskItem(content, view, index) {
          content.view = view;
          view.onClickWithButton(this, this.onClickTaskItem, [content]);
          if (index < 6) {
              FguiHelper.playIdleAndIn(view, index, 0.25, 0.1);
          }
      }
      renderTaskItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickTaskItem(content) {
          if (mgrTask.getTaskRewardByDB(content.data.task)) {
              this.refreshTask();
          }
      }
      refreshTask() {
          let listTask = mgrTask.getNewyearTask();
          let listTaskWrap = [];
          for (let task of listTask) {
              let curt = mgrTask.getTaskCountByDB(task);
              let need = mgrTask.getTaskNeed(task);
              if (curt > need)
                  curt = need;
              listTaskWrap.push({ task: task, progress: curt * 100 / need });
          }
          listTaskWrap.sort(this.sortTask);
          this.listTask.setListData(listTaskWrap);
      }
      sortTask(a, b) {
          let score_a = (mgrTask.isTaskAward(a.task.id) ? -1 : a.progress) * 100 + a.task.index;
          let score_b = (mgrTask.isTaskAward(b.task.id) ? -1 : b.progress) * 100 + b.task.index;
          return score_b - score_a;
      }
      refreshInfo() {
          let curt = mgrGame.getItemCount(1024);
          let need = db.game_cnf.newyear_firecracker_cost_fu;
          this.label_curt.text = curt.toString();
          this.label_max.text = "/" + need;
          this.ctrl_enough.selectedIndex = curt >= need ? 0 : 1;
      }
      on_click_button_exchange() {
          mgrNewyear.costFu2Firecracker();
      }
  }

  class StageGameNewyear extends StageGame {
      onStart() {
          this.refresh();
          this.enemyWave.clear();
      }
      refresh() {
          this.loadTowerGround();
          this.world.remAllUnit();
          this.focusSceneInit();
          this.loadTowers();
          mgrSound.playMusic("sBg");
      }
      dropItemByProb(prob, unit, skin) {
      }
      enemyDropByLevel(unit, skin, coin, show) {
      }
      onMsgTowerEndnessBegin() {
          this.enemyWave.openModeNewyear(db.get_fb_custom_db(db.FB_CUSTOM_DB_ID.NEWYEAR));
          this.onBattleStart();
      }
  }

  class SceneGameNewyear extends SceneGame {
      addResLoader(loader) {
          loader.addFguiPackage("res/fgui/newyear_game");
          loader.addFguiPackage("res/fgui/newyear_game_result");
          loader.addFguiPackage("res/fgui/dailydamage_ad");
      }
      onSceneGameCreate(scene) {
          this.scene2d = scene;
          scene.addComponent(StageGameNewyear);
      }
      onEnter(withLoad) {
          Director.disposeAllPanel();
          Director.openPanelWithSingleton("PanelNewyearGame");
      }
  }

  class CustomNewyearPage3 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomNewyearPage3";
          this.bInited = false;
          this.exportNodeNames = {
              cc_label_curt: "fgui.GBasicTextField",
              cc_label_damage: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_max: "fgui.Controller",
              cc_button_go: "fgui.GButton",
              cc_ctrl_fb: "fgui.Controller",
          };
      }
      init() {
          if (this.bInited) {
              return;
          }
          FguiHelper.playTransition(this, "in");
          this.bInited = true;
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          this.label_max.text = "/" + mgrNewyear.getRewardNumtTodayMax();
          this.label_curt.text = mgrNewyear.rewardNumToday.toString();
          this.label_damage.text = StageTool.formatDailyDamage(mgrNewyear.damageHistory);
          this.ctrl_fb.selectedIndex = mgrNewyear.isTaskAndFBValid() ? 0 : 1;
          this.ctrl_max.selectedIndex = mgrNewyear.isRewardNumMax() ? 1 : 0;
      }
      on_click_button_go() {
          Director.runScene(SceneGameNewyear, "PanelLoadingGame");
      }
  }

  class CustomNewyearPage4 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear/CustomNewyearPage4";
          this.bInited = false;
          this.exportNodeNames = {
              cc_button_role1: "fgui.GButton",
              cc_button_role2: "fgui.GButton",
              cc_button_role3: "fgui.GButton",
              cc_top1: "CustomNewyearShop1",
              cc_top2: "CustomNewyearShop1",
              cc_top3: "CustomNewyearShop1",
              cc_list_shop: "fgui.GList",
          };
      }
      init() {
          if (this.bInited)
              return;
          this.bInited = true;
          FguiHelper.playTransition(this, "in");
          this.listShop = new ListView(this.list_shop, this, this.parseShopItem, this.renderShopItem);
          this.refresh();
          Global.registerListeners(this, {
              [MSG.EXCHANGE_SHOP_REFRESH]: this.onExchangeShopRefresh.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      onExchangeShopRefresh() {
          this.refresh();
      }
      refresh() {
          let listData = [];
          let shopList = db.get_shop_exchange_db_map();
          for (let k in shopList) {
              let shop = db.get_shop_exchange_db(k);
              if (shop.type == 4) {
                  listData.push(shop);
              }
          }
          this.top1.refresh(listData[0]);
          this.top2.refresh(listData[1]);
          this.top3.refresh(listData[2]);
          this.refreshShopList();
      }
      parseShopItem(content, view, index) {
          content.view = view;
          if (index < 4) {
              FguiHelper.playIdleAndIn(view, index, 0.15, 0.1);
          }
          else {
              FguiHelper.playIdleAndIn(view, index - 4, 0.25, 0.1);
          }
      }
      renderShopItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshShopList() {
          let listData = [];
          let shopList = db.get_shop_exchange_db_map();
          for (let k in shopList) {
              let shop = db.get_shop_exchange_db(k);
              if (shop.type == 3) {
                  listData.push(shop);
              }
          }
          this.listShop.setListData(listData);
      }
      on_click_button_role1() {
          mgrCollect.showDetailByTowerId(this.button_role1.data);
      }
      on_click_button_role2() {
          mgrCollect.showDetailByTowerId(this.button_role2.data);
      }
      on_click_button_role3() {
          mgrCollect.showDetailByTowerId(this.button_role3.data);
      }
  }

  const DAY_SECOND$1 = 24 * 3600;
  class PanelNewyear extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "新年庆典";
          this.sourceName = "ui://newyear/PanelNewyear";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_button_question: "ScaleButton",
              cc_page1: "CustomNewyearPage1",
              cc_page2: "CustomNewyearPage2",
              cc_page3: "CustomNewyearPage3",
              cc_page4: "CustomNewyearPage4",
              cc_button01: "fgui.GButton",
              cc_button02: "fgui.GButton",
              cc_button03: "fgui.GButton",
              cc_button04: "fgui.GButton",
              cc_item_bar: "CustomBarItem",
              cc_label_left_time: "fgui.GBasicTextField",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.item_bar.setItemId(1025);
          this.ctrl_page.selectedIndex = this.context.index || 0;
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.onStateChange();
          this.refreshLeftTime();
          this.initTimer();
          this.refreshRedPoint();
          mgrGame.tryOpenPanelIntroNoCOP("PanelNewyearIntro");
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.refreshLeftTime);
      }
      removeTimer() {
          Laya.timer.clear(this, this.refreshLeftTime);
      }
      onStateChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.page1.init();
                  break;
              case 1:
                  this.page2.init();
                  break;
              case 2:
                  this.page3.init();
                  break;
              case 3:
                  this.page4.init();
                  break;
          }
      }
      refreshLeftTime() {
          let second = mgrNewyear.calcLeftTime();
          let day = Math.floor(second / DAY_SECOND$1);
          second = second % DAY_SECOND$1;
          if (day) {
              let hour = Math.floor(second / 3600);
              this.label_left_time.text = day + "天" + hour + "小时";
          }
          else {
              this.label_left_time.text = Utils.cdTimeFormat(second);
          }
      }
      refreshRedPoint() {
          StageTool.updateRedPoint4Button(this.button04, mgrNewyear.haveRedPoint());
      }
      on_click_button01() {
      }
      on_click_button02() {
      }
      on_click_button03() {
      }
      on_click_button04() {
          mgrNewyear.unlockRedPoint();
          this.refreshRedPoint();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_question() {
          Director.openPanelWithSingleton("PanelNewyearIntro");
      }
  }

  class PanelNewyearIntro extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "新年庆典介绍";
          this.sourceName = "ui://newyear/PanelNewyearIntro";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_sure: "fgui.GButton",
              cc_button_close: "ScaleButton",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
      }
      dispose() {
          super.dispose();
      }
      on_click_button_sure() {
          this.closeWithTransition();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class CustomNewyearBar extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://newyear_game/CustomNewyearBar";
          this.exportNodeNames = {
              cc_label_damage: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      updatePerSecond() {
          this.label_damage.text = StageTool.formatDailyDamage(StageGameStatis.getDamageAll());
      }
  }

  class PanelNewyearGame extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "驱逐年兽-游戏中";
          this.sourceName = "ui://newyear_game/PanelNewyearGame";
          this.panelStyle = 1;
          this.bMask = false;
          this.bAutoRemovePackage = true;
          this.isRunning = true;
          this.exportNodeNames = {
              cc_layer_fit: "CustomLayerFit",
              cc_button_setting: "fgui.GButton",
              cc_money_coin: "CustomMoneyBar",
              cc_bottom: "fgui.GComponent",
              cc_button_giveup: "ScaleButton",
              cc_hand: "CustomGameHand",
              cc_button_hand: "fgui.GButton",
              cc_button_auto_skill: "fgui.GButton",
              cc_damage_bar: "CustomNewyearBar",
              cc_button_start: "fgui.GButton",
              cc_button_exit: "ScaleButton",
              cc_button_ad: "ScaleButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_hand: "fgui.Controller",
              cc_trans_out: "fgui.Transition",
          };
      }
      buildUi() {
          this.layer_fit.fit();
          this.damage_bar.updatePerSecond();
          this.resNode.makeFullScreen();
          this.initEvent();
          this.initTimer();
          this.refresh();
          this.showAD();
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_RUSH_END_FOCUS]: this.onTowrRushERndFocus.bind(this),
              [MSG.TOWER_RUSH_END]: this.onTowrRushEnd.bind(this),
              [MSG.TOWER_DEPLOY]: this.onTowerChange.bind(this),
              [MSG.TOWER_TAKEOFF]: this.onTowerChange.bind(this),
              [MSG.TOWER_DEAD]: this.onTowerDead.bind(this),
              [MSG.TOWER_MAIN_SKILL_CHANGE]: this.onTowerMainSkillChange.bind(this),
          });
      }
      onTowrRushERndFocus() {
          this.isRunning = false;
          this.trans_out.play();
      }
      onTowrRushEnd(win) {
          this.exitBattle(win);
      }
      onUpdatePerSecond() {
          if (this.isRunning)
              this.damage_bar.updatePerSecond();
      }
      refreshGameHand() {
          if (this.ctrl_hand.selectedIndex == 1) {
              this.hand.refresh(true);
          }
      }
      onTowerDead() {
          this.refreshGameHand();
      }
      onTowerMainSkillChange() {
          this.refreshGameHand();
      }
      onTowerChange() {
          this.refreshGameHand();
      }
      showAD() {
          Director.openPanelWithSingleton("PanelDailyDamageAD");
      }
      refresh() {
          this.button_auto_skill.selected = !StageConfig.handSuperSkill;
      }
      beginBattle() {
          this.ctrl_state.selectedIndex = 1;
          Global.sendMsg(MSG.TOWER_ENDNESS_BEGIN);
      }
      exitBattle(win) {
          if (win) {
              Director.runScene(SceneGame, "PanelLoadingGame", { openPanel: "PanelNewyear", context: { index: 2 } });
          }
          else {
              Director.runScene(SceneGame, "PanelLoadingGame");
          }
      }
      on_click_button_setting() {
          Director.openPanelWithSingleton("PanelSetting");
      }
      on_click_button_giveup() {
          mgrTip.alertPrompt("确定要退出驱逐年兽么？", null, () => {
              this.exitBattle(false);
          });
      }
      on_click_button_hand() {
          if (this.ctrl_hand.selectedIndex)
              this.hand.openHand();
          else
              this.hand.closeHand();
      }
      on_click_button_auto_skill() {
          StageConfig.handSuperSkill = !this.button_auto_skill.selected;
      }
      on_click_button_start() {
          this.beginBattle();
      }
      on_click_button_exit() {
          this.exitBattle(true);
      }
      on_click_button_ad() {
          this.showAD();
      }
  }

  class PanelNewyearGameResult extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "驱逐年兽-伤害结算";
          this.sourceName = "ui://newyear_game_result/PanelNewyearGameResult";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_label_item_cur: "fgui.GBasicTextField",
              cc_label_item_max: "fgui.GBasicTextField",
              cc_label_damage: "fgui.GBasicTextField",
              cc_label_history: "fgui.GBasicTextField",
              cc_item_reward: "CustomItem",
              cc_button_quit: "fgui.GButton",
              cc_button_get: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_ctrl_max: "fgui.Controller",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      buildUi() {
          Global.registerListeners(this, {
              [MSG.PANEL_ITEM_GET_CLOSE]: this.closeWithTransition.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.newyear_game_more) {
                      this.getReward(2);
                  }
              },
          });
          this.refresh();
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.newyear_game_more);
      }
      dispose() {
          Global.sendMsg(MSG.TOWER_RUSH_END, [true, WaveMode.NEWYEAR]);
          super.dispose();
      }
      refresh() {
          this.label_damage.text = StageTool.formatDailyDamage(mgrNewyear.damageLast);
          this.label_history.text = StageTool.formatDailyDamage(mgrNewyear.damageHistory);
          this.label_item_max.text = "/" + mgrNewyear.getRewardNumtTodayMax().toString() + ")";
          let reward = mgrNewyear.rewardConfig;
          if (reward) {
              this.item_reward.refreshById(reward.item_id, mgrNewyear.rewardNum, true);
              this.label_item_cur.text = mgrNewyear.rewardNumToday.toString();
              let adRewardNum = mgrNewyear.rewardNum * 2;
              if (adRewardNum > 0 && adRewardNum <= mgrNewyear.getRewardNumLeft()) {
                  this.ctrl_reward.selectedIndex = 0;
              }
              else {
                  this.ctrl_reward.selectedIndex = mgrNewyear.rewardNum > 0 ? 1 : 2;
              }
          }
          else {
              this.ctrl_reward.selectedIndex = 1;
          }
          this.ctrl_max.selectedIndex = mgrNewyear.isRewardNumMax() ? 1 : 0;
      }
      getReward(scale = 1) {
          if (mgrNewyear.getDamageReward(scale)) {
              this.closeWithTransition();
          }
      }
      on_click_button_quit() {
          this.getReward();
      }
      on_click_button_get() {
          this.getReward();
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.newyear_game_more);
      }
  }

  class mgrSubscription extends Manager {
      static onStart() {
          Global.registerListeners(this, {
              [BASE_MSG.SDK_GET_SUBSCRIBE_STATE_RESULT]: this.onGetSubScribeStateResult.bind(this),
              [BASE_MSG.SDK_ADD_SUBSCRIBE_RESULT]: this.onAddSubscribeResult.bind(this),
          });
          if (!db.cop_db.isSupportSubscription)
              return;
          for (let k in db.SUBSCRIPTION_DB_NAME) {
              this.getSubscribeState(db.SUBSCRIPTION_DB_NAME[k]);
          }
      }
      static onGetSubScribeStateResult(data) {
          if (data.code) {
              this.id2subscrition[data.subscribeId] = true;
          }
          Global.sendMsg(MSG.SUBSCRIPTION_UPDATE);
      }
      static onAddSubscribeResult(data) {
          if (data.code) {
              this.id2subscrition[data.subscribeId] = true;
              let subDb = this.findSubscritionDbById(data.subscribeId);
              if (subDb) {
                  mgrStatis.statisCommonEvent(subDb.statis_id, 1);
              }
          }
          mgrTip.showMsgTip(data.msg);
          Global.sendMsg(MSG.SUBSCRIPTION_UPDATE);
      }
      static findSubscritionDbById(id) {
          let dataMap = db.get_subscription_db_map();
          for (let k in dataMap) {
              let data = db.get_subscription_db(k);
              if (data.id == id) {
                  return data;
              }
          }
          return null;
      }
      static isSubscribed(name) {
          let subDb = db.get_subscription_db(name);
          if (subDb) {
              return this.id2subscrition[subDb.id];
          }
          else {
              return false;
          }
      }
      static getSubscribeState(name) {
          let subDb = db.get_subscription_db(name);
          if (subDb) {
              mgrSdk.getSubscribeState(subDb.id);
          }
      }
      static addSubscribe(name) {
          let subDb = db.get_subscription_db(name);
          if (subDb) {
              let id = subDb.id;
              mgrSdk.addSubscribe(id, name);
              if (GameGlobal.isDebug) {
                  Global.sendMsg(BASE_MSG.SDK_ADD_SUBSCRIBE_RESULT, { code: 1, subscribeId: id, msg: "订阅成功" });
              }
          }
      }
  }
  mgrSubscription.id2subscrition = {};

  class PanelNextDayReward extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "次日奖励";
          this.sourceName = "ui://next_day/PanelNextDayReward";
          this.bAutoRemovePackage = true;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_tip: "fgui.GBasicTextField",
              cc_label_cd: "fgui.GBasicTextField",
              cc_list_reward: "fgui.GList",
              cc_button_reward: "fgui.GButton",
              cc_button_subcription: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_sub: "fgui.Controller",
          };
      }
      buildUi() {
          Global.registerListeners(this, {
              [MSG.NEXT_DAY_REWARD]: this.onNextDayReward.bind(this),
              [BASE_MSG.SDK_ADD_SUBSCRIBE_RESULT]: this.refreshSubscription.bind(this),
          });
          this.listReward = new ListView(this.list_reward, this, this.parseItem, this.renderItem);
          this.initTimer();
          this.refreshCD();
          this.refreshReward();
          this.refreshSubscription();
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      onNextDayReward() {
          let data = mgrSign.getNextDayRewardDB();
          if (!data) {
              this.closeWithTransition();
              return;
          }
          this.refreshReward();
      }
      refreshSubscription() {
          if (db.cop_db.isSupportSubscription && !mgrSubscription.isSubscribed(db.SUBSCRIPTION_DB_NAME.NEXTDAY)) {
              this.ctrl_sub.selectedIndex = 1;
          }
          else {
              this.ctrl_sub.selectedIndex = 0;
          }
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      onUpdatePerSecond() {
          this.refreshCD();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, info) {
          content.view.refresh(info);
      }
      refreshReward() {
          let data = mgrSign.getNextDayRewardDB();
          if (!data)
              return;
          let listData = [];
          for (let i = 0; i < data.reward_ids.length; i += 2) {
              let itemId = data.reward_ids[i];
              let itemCt = data.reward_ids[i + 1];
              if (itemId && itemCt) {
                  listData.push({ itemId: itemId, count: itemCt });
              }
          }
          this.listReward.setListData(listData);
          this.label_tip.text = data.desc;
      }
      refreshCD() {
          let leftTime = mgrSign.calcNextDayLeftTime();
          if (leftTime > 0) {
              this.label_cd.text = Utils.cdTimeFormat(leftTime) + " 后可领取";
              this.ctrl_state.selectedIndex = 0;
          }
          else {
              this.ctrl_state.selectedIndex = 1;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_reward() {
          mgrSign.getNextDayReward();
      }
      on_click_button_subcription() {
          this.closeWithTransition();
          mgrSubscription.addSubscribe(db.SUBSCRIPTION_DB_NAME.NEXTDAY);
      }
  }

  class ListViewItem {
      constructor(list, childPath) {
          this.childPath = "";
          this.childPath = childPath;
          this.listView = new ListView(list, this, this.parseItem, this.renderItem);
      }
      parseItem(content, view) {
          if (this.childPath) {
              content.view = view.getChild(this.childPath);
          }
          else {
              content.view = view;
          }
      }
      renderItem(content, item) {
          content.data = item;
          content.view.refresh(item);
      }
      setData(listData) {
          this.listView.setListData(listData);
      }
      setDataByItemIds(itemIds) {
          let listData = [];
          for (let i = 0; i < itemIds.length; i += 2) {
              let itemId = itemIds[i];
              let itemCn = itemIds[i + 1];
              if (itemId && itemCn) {
                  listData.push({ itemId: itemId, count: itemCn });
              }
          }
          this.listView.setListData(listData);
      }
  }

  class PanelNotice extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "公告";
          this.sourceName = "ui://notice/PanelNotice";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_labelContent: "fgui.GRichTextField",
              cc_button_close: "fgui.GButton",
              cc_button_subscription: "fgui.GButton",
              cc_com_subscription_reward: "fgui.GComponent",
              cc_list_subscription_reward: "fgui.GList",
              cc_ctrl_subscription: "fgui.Controller",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
          let cop_notice = db.cop_db.notice_content;
          cop_notice = cop_notice.replace(/\\n/g, "\n");
          this.labelContent.text = cop_notice;
          mgrGame.vNotice = db.cop_db.notice_version;
          this.listView = new ListViewItem(this.list_subscription_reward, "item");
          if (db.cop_db.isSupportSubscription) {
              Global.registerListeners(this, {
                  [MSG.SUBSCRIPTION_UPDATE]: this.onSubScriptionUpdate.bind(this),
                  [BASE_MSG.SDK_ADD_SUBSCRIBE_RESULT]: this.onAddSubscribeResult.bind(this),
              });
              this.onSubScriptionUpdate();
          }
      }
      dispose() {
          super.dispose();
      }
      onAddSubscribeResult(data) {
          if (data.userData == db.SUBSCRIPTION_DB_NAME.NOTICE) {
              if (data.code) {
                  Level.getRewardByItemIds(db.game_cnf.subscription_reward_notice, 73);
              }
              this.close();
          }
      }
      onSubScriptionUpdate() {
          this.ctrl_subscription.selectedIndex = mgrSubscription.isSubscribed(db.SUBSCRIPTION_DB_NAME.NOTICE) ? 0 : 1;
          if (this.ctrl_subscription.selectedIndex) {
              this.listView.setDataByItemIds(db.game_cnf.subscription_reward_notice);
          }
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_subscription() {
          mgrSubscription.addSubscribe(db.SUBSCRIPTION_DB_NAME.NOTICE);
      }
  }

  class CustomOfflineItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://offline/CustomOfflineItem";
          this.exportNodeNames = {
              cc_load_icon: "fgui.GLoader",
              cc_label_title: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemId, count) {
          this.load_icon.url = mgrGame.getItemIcon(itemId);
          this.label_title.text = "x" + count;
      }
  }

  class PanelOffline extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "离线奖励";
          this.sourceName = "ui://offline/PanelOffline";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.passTimeAutoAD = 0;
          this.isAutoAD = false;
          this.isAutoADOpen = false;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_item_1: "CustomOfflineItem",
              cc_item_2: "CustomOfflineItem",
              cc_button_get: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
          };
      }
      buildUi() {
          this.initTimer();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.offline_ad) {
                      this.watchAdSuccess();
                  }
              },
          });
          let rewardData = mgrOffline.getRewardData();
          if (rewardData) {
              this.item_1.refresh(1001, rewardData.coin);
              this.item_2.refresh(1000, rewardData.diamond);
          }
          else {
              this.item_1.refresh(1001, 0);
              this.item_2.refresh(1000, 0);
          }
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.offline_ad);
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      onSubScriptionUpdate(data) {
      }
      initTimer() {
          this.checkAutoADOpen();
          Laya.timer.loop(1000, this, this.updatePerSecond);
          this.updatePerSecond();
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      checkAutoADOpen() {
          if (db.cop_db.auto_open_ad_cd) {
              let curtTime = Timer.time;
              if (!StageTool.checkAutoOpenCD(curtTime)) {
                  StageTool.beginAutoOpenCD(curtTime);
                  this.isAutoADOpen = true;
              }
          }
      }
      updatePerSecond() {
          if (this.isFocus) {
              if (this.isAutoADOpen && !this.isAutoAD) {
                  let leftTimeAutoAD = db.cop_db.auto_open_ad_cd - this.passTimeAutoAD;
                  if (leftTimeAutoAD > 0) {
                      this.button_ad.titleFontSize = 20;
                      this.button_ad.title = leftTimeAutoAD + "秒后双倍";
                      this.passTimeAutoAD++;
                  }
                  else {
                      this.isAutoAD = true;
                      this.button_ad.title = "双倍领取";
                      this.on_click_button_ad();
                  }
              }
          }
      }
      getReworad(scale = 1) {
          mgrOffline.getReward(scale);
          Global.sendMsg(MSG.OFFLINE_GET_REWARD);
          this.close();
      }
      watchAdSuccess() {
          this.getReworad(2);
      }
      on_click_button_get() {
          this.getReworad(1);
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.offline_ad);
      }
      on_click_button_close() {
          this.close();
          Global.sendMsg(MSG.OFFLINE_SHOW_BUTTON);
      }
      on_click_button_giveupad() {
          this.on_click_button_close();
      }
  }

  class PanelOfflineSubscription extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "离线奖励订阅";
          this.sourceName = "ui://offline/PanelOfflineSubscription";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_ensure: "fgui.GButton",
              cc_button_cancel: "fgui.GButton",
              cc_com_subscription_reward: "fgui.GComponent",
              cc_list_subscription_reward: "fgui.GList",
              cc_label_dialog: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.listView = new ListViewItem(this.list_subscription_reward, "item");
          this.listView.setDataByItemIds(db.game_cnf.subscription_reward_offline);
          Global.registerListeners(this, {
              [BASE_MSG.SDK_ADD_SUBSCRIBE_RESULT]: this.onAddSubscribeResult.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      onAddSubscribeResult(data) {
          if (data.code) {
              Level.getRewardByItemIds(db.game_cnf.subscription_reward_offline, 73);
          }
          this.closeWithTransition();
      }
      on_click_button_ensure() {
          mgrSubscription.addSubscribe(db.SUBSCRIPTION_DB_NAME.OFFLINE);
      }
      on_click_button_cancel() {
          this.closeWithTransition();
      }
  }

  class CustomPrayBox extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://pray/CustomPrayBox";
          this.exportNodeNames = {
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_lefttime: "fgui.GBasicTextField",
              cc_item_1: "CustomPrayBoxItem",
              cc_item_2: "CustomPrayBoxItem",
              cc_item_3: "CustomPrayBoxItem",
              cc_item_4: "CustomPrayBoxItem",
              cc_item_5: "CustomPrayBoxItem",
              cc_item_6: "CustomPrayBoxItem",
              cc_progress_cd: "fgui.GProgressBar",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
              cc_button_reward: "fgui.GButton",
              cc_loader_box: "fgui.GLoader",
              cc_lable_tip_main: "fgui.GRichTextField",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      onCreate() {
          this.itemArr = [];
          for (let i = 1; i <= 6; i++) {
              let item = this["item_" + i];
              if (item) {
                  this.itemArr.push(item);
              }
          }
          this.initTimer();
          this.initEvent();
          this.refresh();
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      show() {
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.box_open_now);
      }
      dispose() {
          this.destroyBoxEffect();
          this.removeTimer();
          super.dispose();
      }
      clearTip() {
          for (let i = 0; i < this.itemArr.length; i++) {
              let item = this.itemArr[i];
              if (item) {
                  item.clearTip();
              }
          }
      }
      refreshBoxes() {
          let boxes = mgrPrayBox.getBoxes();
          for (let i = 0; i < this.itemArr.length; i++) {
              let item = this.itemArr[i];
              let box = boxes[i];
              if (item && box) {
                  item.setBox(box.box);
                  item.clearTip();
              }
          }
      }
      createBoxEffect(effect) {
          this.destroyBoxEffect();
          let view = this.parent;
          if (view instanceof PanelBase3D) {
              this.effectBox = EffectFactory.create(effect, view.scene3DEffect);
              this.effectBox.followFguiNode(view.cameraEffect, this.loader_box);
          }
          else {
              let data = Director.getScene3DLayer(3);
              this.effectBox = EffectFactory.create(effect, data.scene3d);
              this.effectBox.followFguiNode(data.camera, this.loader_box);
          }
      }
      destroyBoxEffect() {
          if (this.effectBox) {
              this.effectBox.clear();
              this.effectBox = null;
          }
      }
      refresh() {
          this.refreshBoxes();
          this.label_desc.text = db.game_cnf.pray_box_desc;
          let boxOpen = mgrPrayBox.getBoxOpen();
          switch (boxOpen.box.state) {
              case PRAY_BOX_STATE.OPEN:
                  this.ctrl_reward.selectedIndex = 1;
                  break;
              case PRAY_BOX_STATE.OPEN_COMPLETE:
                  this.ctrl_reward.selectedIndex = 2;
                  break;
              default:
                  this.ctrl_reward.selectedIndex = 0;
                  break;
          }
          if (boxOpen.boxDb) {
              this.loader_box.url = boxOpen.boxDb.icon;
              this.lable_tip_main.text = boxOpen.boxDb.tip;
              this.createBoxEffect(boxOpen.boxDb.effect);
          }
          this.onUpdatePerSecond();
          if (!mgrPrayBox.findOpeningBox() && mgrPrayBox.findBornCompleteBox()) {
              if (this.item_1.box.state == PRAY_BOX_STATE.BORN_COMPLETE) {
                  this.moveBoxToOpen(this.item_1);
              }
          }
          this.refreshRedPoint();
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_reward, mgrPrayBox.haveRedPoint());
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.PRAY_BOX_REFRESH]: this.refresh.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.box_open_now) {
                      this.watchAdSuccess();
                  }
              },
          });
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      watchAdSuccess() {
          mgrPrayBox.makeOpenComplete();
          this.refresh();
      }
      moveBoxToOpen(target) {
          let item = fgui.UIPackage.createObjectFromURL("ui://pray/CustomPrayBoxItem");
          this.addChild(item);
          item.x = target.x;
          item.y = target.y;
          item.setBox(target.box);
          target.letEmpty();
          Laya.Tween.to(item, { x: this.loader_box.x, y: this.loader_box.y }, 500, null, Laya.Handler.create(this, this.onMoveBoxToOpenEnd, [item]));
      }
      onMoveBoxToOpenEnd(item) {
          item.dispose();
          mgrPrayBox.openBox();
          this.refresh();
      }
      onUpdatePerSecond() {
          for (let item of this.itemArr) {
              item.onUpdatePerSecond();
          }
          let warp = mgrPrayBox.getBoxOpen();
          if (warp.box.state == PRAY_BOX_STATE.OPEN) {
              let leftTime = warp.boxDb.time - warp.box.time_pass;
              if (leftTime < 0)
                  leftTime = 0;
              if (leftTime >= 3600) {
                  this.label_lefttime.text = Utils.dateFormat(leftTime, "H:i:s");
              }
              else {
                  this.label_lefttime.text = Utils.dateFormat(leftTime, "i:s");
              }
              let percent = 100 - leftTime / warp.boxDb.time * 100;
              this.progress_cd.value = percent;
          }
      }
      on_click_button_ad() {
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.box_open_now);
      }
      on_click_button_reward() {
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrPrayBox.getOpenBoxReward();
              this.refresh();
          });
      }
      on_click_button_giveupad() {
          Global.sendMsg(MSG.PANEL_PRAY_CLOSE);
      }
  }

  class CustomPrayBoxItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://pray/CustomPrayBoxItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_cd: "fgui.GBasicTextField",
              cc_lable_tip: "fgui.GRichTextField",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_pos: "fgui.Controller",
              cc_ctrl_tip: "fgui.Controller",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickItem);
      }
      dispose() {
          super.dispose();
      }
      setBox(box) {
          this.box = box;
          this.boxDb = db.get_pray_box_db_map()[box.id];
          this.refresh();
      }
      letEmpty() {
          this.boxDb = null;
          this.ctrl_state.selectedIndex = 0;
      }
      refresh() {
          if (!this.box)
              return;
          this.refreshStatic();
          switch (this.box.state) {
              case PRAY_BOX_STATE.BORN:
                  let leftTime = db.game_cnf.pray_box_interval - this.box.time_pass;
                  if (leftTime < 0)
                      leftTime = 0;
                  this.label_cd.text = Utils.dateFormat(leftTime, "H:i:s");
                  break;
              default:
                  break;
          }
      }
      clearTip() {
          this.ctrl_tip.selectedIndex = 0;
      }
      refreshStatic() {
          switch (this.box.state) {
              case PRAY_BOX_STATE.BORN:
                  this.ctrl_state.selectedIndex = 1;
                  break;
              case PRAY_BOX_STATE.BORN_COMPLETE:
                  this.ctrl_state.selectedIndex = 2;
                  break;
              default:
                  this.ctrl_state.selectedIndex = 0;
                  break;
          }
          if (this.boxDb) {
              this.lable_tip.text = this.boxDb.tip;
              this.loader_icon.url = this.boxDb.icon;
          }
      }
      setTipDown(value) {
          if (value)
              this.ctrl_pos.selectedIndex = 1;
          else
              this.ctrl_pos.selectedIndex = 0;
      }
      onClickItem() {
          if (!this.box) {
              this.ctrl_tip.selectedIndex = 0;
              return;
          }
          if (this.box.state == PRAY_BOX_STATE.EMPTY || this.box.state == PRAY_BOX_STATE.BORN) {
              this.ctrl_tip.selectedIndex = 0;
              return;
          }
          if (this.ctrl_tip.selectedIndex) {
              this.ctrl_tip.selectedIndex = 0;
          }
          else {
              this.ctrl_tip.selectedIndex = 1;
          }
      }
      onUpdatePerSecond() {
          this.refresh();
      }
  }

  class CustomPrayCoin extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://pray/CustomPrayCoin";
          this.exportNodeNames = {
              cc_label_desc: "fgui.GBasicTextField",
              cc_label_time: "fgui.GBasicTextField",
              cc_label_num: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_button_normal: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_cding: "fgui.Controller",
          };
      }
      onCreate() {
          this.initEvent();
          this.refresh();
          this.refreshRedPoint();
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      show() {
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.mine_deep);
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          this.label_desc.text = mgrPrayCoin.getDesc();
          this.label_num.text = "当前数量：" + mgrPrayCoin.getRewardCount().toString();
          this.refreshCDTime();
      }
      refreshCDTime() {
          let leftTime = mgrPrayCoin.getLeftTime();
          if (leftTime <= 0) {
              this.label_left.text = "今日普通祈愿已用完，每日00：00刷新祈愿次数";
              this.ctrl_state.setSelectedIndex(1);
          }
          else {
              if (mgrPrayCoin.checkFreeCD()) {
                  this.label_left.text = "今日剩余：" + leftTime;
                  this.ctrl_state.setSelectedIndex(0);
                  this.ctrl_cding.setSelectedIndex(0);
              }
              else {
                  this.label_left.text = "祈愿冷却中" + Utils.dateFormat(mgrPrayCoin.getFreeCDLeftTime(), "i:s");
                  this.ctrl_cding.setSelectedIndex(1);
              }
          }
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.PRAY_COIN_REFRESH]: this.refresh.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.mine_deep) {
                      this.watchAdSuccess();
                  }
              },
          });
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeEvent() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_normal, mgrPrayCoin.canDigFree());
      }
      watchAdSuccess() {
          this.digDeep();
      }
      updatePerSecond() {
          this.refreshCDTime();
      }
      digDeep() {
          mgrPrayCoin.digDeep();
          this.refreshRedPoint();
      }
      on_click_button_normal() {
          if (mgrPrayCoin.canDigFree()) {
              mgrPrayCoin.digFree();
              this.refreshRedPoint();
          }
          else {
              mgrTip.showMsgTip("祈愿正在冷却中");
          }
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.mine_deep);
      }
      on_click_button_giveupad() {
          Global.sendMsg(MSG.PANEL_PRAY_CLOSE);
      }
  }

  class PanelPray extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "祈愿";
          this.sourceName = "ui://pray/PanelPray";
          this.panelStyle = 0;
          this.panelLayer = 4;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_com_coin: "CustomPrayCoin",
              cc_com_box: "CustomPrayBox",
              cc_button_coin: "fgui.GButton",
              cc_button_box: "fgui.GButton",
              cc_money_bar: "CustomMoneyBar",
              cc_button_close: "ScaleButton",
              cc_effect_box: "FguiEffect",
              cc_effect_coin: "FguiEffect",
              cc_ctrl_page: "fgui.Controller",
              cc_trans_in_box: "fgui.Transition",
              cc_trans_in_coin: "fgui.Transition",
          };
      }
      buildUi() {
          this.resNode.makeFullScreen();
          this.createScene3DEffect(100);
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          let page = this.context.page || 1;
          this.ctrl_page.selectedIndex = page;
          switch (page) {
              case 1:
                  this.trans_in_box.play();
                  break;
              case 2:
                  this.trans_in_coin.play();
                  break;
          }
          this.refreshRedPoint();
          this.initEvent();
          mgrGame.tryOpenPanelIntro("PanelIntroPray");
      }
      dispose() {
          super.dispose();
      }
      onStateChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 1:
                  this.com_box.show();
                  break;
              case 2:
                  this.com_coin.show();
                  break;
          }
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.REFRESH_RED_POINT]: this.refreshRedPoint.bind(this),
              [MSG.PANEL_PRAY_CLOSE]: this.onPanelPrayClose.bind(this),
          });
      }
      onPanelPrayClose() {
          this.closeWithTransition();
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_coin, mgrPrayCoin.haveRedPoint());
          Level.updateRedPoint4Button(this.button_box, mgrPrayBox.haveRedPoint());
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_coin() {
          this.com_box.clearTip();
      }
      on_click_button_box() {
          this.com_box.clearTip();
      }
  }

  class PanelSecretDailyReward extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://rush_reward/PanelSecretDailyReward";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_need: "fgui.GBasicTextField",
              cc_label_layer: "fgui.GBasicTextField",
              cc_list_reward: "fgui.GList",
              cc_button_get: "fgui.GButton",
              cc_ctrl_next: "fgui.Controller",
          };
      }
      buildUi() {
          this.label_layer.text = mgrSecret.layerId.toString();
          this.listReward = new ListView(this.list_reward, this, this.parseRewardItem, this.renderRewardItem);
          this.refreshReward();
      }
      dispose() {
          super.dispose();
      }
      parseRewardItem(content, object) {
          content.view = object.getChild("item");
      }
      renderRewardItem(content, item) {
          content.data = item;
          content.view.refresh(item);
      }
      refreshReward() {
          let listData = [];
          let rewardDb = Level.calcSecretDailyReward(mgrSecret.layerId);
          let reward_ids = rewardDb.reward_ids;
          for (let i = 0; i < reward_ids.length; i += 2) {
              listData.push({ itemId: reward_ids[i], count: reward_ids[i + 1] });
          }
          this.listReward.setListData(listData);
          let rewardDbNext = db.get_secret_daily_reward_map()[rewardDb.id];
          if (rewardDbNext) {
              let need = rewardDb.level + 1 - mgrSecret.layerId;
              this.label_need.text = need.toString();
              this.ctrl_next.selectedIndex = 1;
          }
          else {
              this.ctrl_next.selectedIndex = 0;
          }
          let canReward = mgrSecret.canGetDailyReward();
          this.button_get.visible = canReward;
      }
      getReward(scale = 1) {
          Level.getSecretDailyReward(scale);
          this.close();
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_get() {
          mgrNetwork.callByNetwork(() => {
              this.getReward();
          });
      }
  }

  class PanelTowerRushReward extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "无尽奖励";
          this.sourceName = "ui://rush_reward/PanelTowerRushReward";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_need: "fgui.GBasicTextField",
              cc_label_layer: "fgui.GBasicTextField",
              cc_list_reward: "fgui.GList",
              cc_button_get: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_ctrl_next: "fgui.Controller",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      buildUi() {
          this.label_layer.text = mgrGame.levelId.toString();
          this.listReward = new ListView(this.list_reward, this, this.parseRewardItem, this.renderRewardItem);
          this.refreshReward();
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.endness_reward);
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.endness_reward) {
                      this.watchAdSuccess();
                  }
              },
          });
      }
      dispose() {
          super.dispose();
      }
      watchAdSuccess() {
          this.getRewardAD();
      }
      parseRewardItem(content, object) {
          content.view = object.getChild("item");
      }
      renderRewardItem(content, item) {
          content.data = item;
          content.view.refresh(item);
      }
      refreshReward() {
          let listData = [];
          let rewardDb = Level.calcTowerRushReward(mgrGame.levelId);
          let reward_ids = rewardDb.reward_ids;
          for (let i = 0; i < reward_ids.length; i += 2) {
              listData.push({ itemId: reward_ids[i], count: reward_ids[i + 1] });
          }
          this.listReward.setListData(listData);
          let rewardDbNext = db.get_tower_rush_reward_map()[rewardDb.id];
          if (rewardDbNext) {
              let need = rewardDb.level + 1 - mgrGame.levelId;
              this.label_need.text = need.toString();
              this.ctrl_next.selectedIndex = 1;
          }
          else {
              this.ctrl_next.selectedIndex = 0;
          }
          let canReward = Level.canGetTowerRushReward();
          this.ctrl_reward.selectedIndex = canReward ? 0 : 1;
      }
      getReward(scale = 1) {
          Level.getTowerTushRewardDaily(scale);
          this.close();
      }
      getRewardAD() {
          Level.getTowerTushRewardDailyAD();
          this.close();
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_get() {
          if (Level.notEnoughEmptyByRewardIds())
              return;
          mgrNetwork.callByNetwork(() => {
              this.getReward();
          });
      }
      on_click_button_ad() {
          if (Level.notEnoughEmptyByRewardIds(2))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.endness_reward);
          });
      }
  }

  class CustomSecretShopItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretShopItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_buy: "fgui.GButton",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_ctrl_soldout: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.shopDb = data;
          this.item.refreshById(data.item_id, data.item_num);
          this.label_title.text = mgrGame.getItemName(data.item_id);
          this.label_left.text = mgrExchange.getExchangeLeftCountByDB(data) + "/" + data.limit;
          this.button_buy.title = data.price_item_cost.toString();
          this.button_buy.icon = mgrGame.getItemIcon(data.price_item_id);
          this.ctrl_soldout.selectedIndex = mgrExchange.canExchangeByDB(data) ? 0 : 1;
      }
      on_click_button_buy() {
          if (this.shopDb && mgrHolyItem.notEnoughEmptyByItemId(this.shopDb.item_id, this.shopDb.item_num))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrExchange.tryExchangeShop(this.shopDb);
          });
      }
  }

  class CustomSecretShopItemTop extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretShopItemTop";
          this.exportNodeNames = {
              cc_exchange: "fgui.GComponent",
              cc_label_exchange: "fgui.GBasicTextField",
              cc_button_exchange: "fgui.GButton",
              cc_button_info: "fgui.GButton",
              cc_ctrl_exchange: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refersh(data) {
          this.shopDb = data;
          this.label_exchange.text = mgrExchange.getExchangeLeftCountByDB(data) + "/" + data.limit;
          this.button_exchange.title = data.price_item_cost.toString();
          this.button_exchange.icon = mgrGame.getItemIcon(data.price_item_id);
          this.ctrl_exchange.selectedIndex = mgrExchange.canExchangeByDB(data) ? 0 : 1;
      }
      on_click_button_exchange() {
          mgrExchange.tryExchangeShop(this.shopDb);
      }
      on_click_button_info() {
          mgrCollect.showDetailByTowerId(this.data);
      }
  }

  class CustomSecretTowerItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretTowerItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_up: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          let quality = mgrTower.getTowerQualityByDB(data);
          this.loader_icon.icon = data.icon_small;
          this.ctrl_quality.selectedIndex = quality;
          this.ctrl_up.selectedIndex = quality == EQUIP_QUALITY.ORANGE ? 1 : 0;
      }
  }

  class CustomSecretWord extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretWord";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_title: "fgui.GBasicTextField",
              cc_label_layer: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_ctrl_active: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(id, layer, selecLayerId) {
          let isActive = layer <= selecLayerId;
          let word = db.get_secret_word_db(id);
          if (word) {
              this.loader_icon.url = word.icon;
              this.label_title.text = word.title;
              if (isActive) {
                  this.label_desc.text = Utils.sprintf(word.desc, Math.floor(word.value * 100));
              }
              else {
                  this.label_desc.text = "第" + layer + "层出现新的干扰";
              }
          }
          this.label_layer.text = "第" + layer + "层生效";
          this.ctrl_active.selectedIndex = isActive ? 1 : 0;
      }
  }

  class CustomSelectLayer extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSelectLayer";
          this.exportNodeNames = {
              cc_label_title: "fgui.GBasicTextField",
              cc_ctrl_valid: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.label_title.text = data.name;
          this.ctrl_valid.selectedIndex = data.id <= mgrSecret.layerId ? 0 : 1;
      }
  }

  class CustomSecretCard extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretCard";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_level: "fgui.GBasicTextField",
              cc_com_star: "fgui.GComponent",
              cc_ctrl_card_quality: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data, quality) {
          let com_star = this.com_star;
          let type = com_star.getController("type");
          let star = com_star.getController("star");
          type.selectedIndex = data.type;
          star.selectedIndex = mgrTower.getTowerStar(data.id);
          if (quality >= 0 && quality < this.ctrl_card_quality.pageCount)
              this.ctrl_card_quality.selectedIndex = quality;
          this.loader_icon.url = data.icon;
          this.label_level.text = "Lv." + mgrTower.getTowerLv(data.id);
      }
  }

  class CustomSecretChallenge extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretChallenge";
          this.selectId = 1;
          this.inited = false;
          this.exportNodeNames = {
              cc_label_level_cur: "fgui.GBasicTextField",
              cc_lable_level_max: "fgui.GBasicTextField",
              cc_label_left: "fgui.GBasicTextField",
              cc_button_daily: "ScaleButton",
              cc_button_add: "ScaleButton",
              cc_list_reward: "fgui.GList",
              cc_list_word: "fgui.GList",
              cc_button_select_layer: "fgui.GButton",
              cc_button_challenge: "fgui.GButton",
              cc_ctrl_first: "fgui.Controller",
          };
      }
      init() {
          if (this.inited)
              return;
          this.inited = true;
          this.selectId = mgrSecret.selectId;
          this.listReward = new ListView(this.list_reward, this, this.parseRewardItem, this.renderRewardItem);
          this.listWord = new ListView(this.list_word, this, this.parseWordItem, this.renderWordItem);
          this.refresh();
          Global.registerListeners(this, {
              [MSG.SECRET_SELECT_LAYER]: this.onSecretSelectLayer.bind(this),
              [BASE_MSG.ITEM_CHANGE]: this.onItemChange.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      onSecretSelectLayer(data) {
          this.selectId = data.id;
          this.refresh();
      }
      onItemChange() {
          this.refreshItem();
      }
      getSecretLevel() {
          return db.get_secret_level_map()[this.selectId - 1];
      }
      refreshItem() {
          this.label_left.text = mgrGame.getItemCount(1013).toString();
      }
      refresh() {
          this.label_level_cur.text = this.selectId.toString();
          this.lable_level_max.text = mgrSecret.getMaxLv().toString();
          this.refreshItem();
          let secretLevel = this.getSecretLevel();
          if (secretLevel) {
              this.refreshReward(secretLevel);
          }
          this.refreshWordList();
      }
      parseRewardItem(content, object, index) {
          content.view = object;
          if (index < 3)
              FguiHelper.playIdleAndIn(content.view, index, 0.25, 0.1);
      }
      renderRewardItem(content, item) {
          content.data = item;
          content.view.refresh(item);
      }
      refreshReward(data) {
          let rewardIds = null;
          if (mgrSecret.getPassCount(data.id) > 0) {
              this.ctrl_first.selectedIndex = 0;
              rewardIds = data.drop_id;
          }
          else {
              this.ctrl_first.selectedIndex = 1;
              rewardIds = data.first_reward_ids;
          }
          let listData = [];
          for (let i = 0; i < rewardIds.length; i += 2) {
              listData.push({ itemId: rewardIds[i], count: rewardIds[i + 1] });
          }
          this.listReward.setListData(listData);
      }
      parseWordItem(content, object, index) {
          content.view = object;
          FguiHelper.playIdleAndIn(object, index, 0.3, 0.1);
      }
      renderWordItem(content, data) {
          content.data = data;
          content.view.refresh(data.id, data.lv, this.selectId);
      }
      refreshWordList() {
          let listData = [];
          let week = mgrSecret.getWeekCfg();
          for (let i = 0; i < week.word_ids.length; i++) {
              let id = week.word_ids[i];
              let lv = week.word_levels[i];
              listData.push({ id: id, lv: lv });
          }
          this.listWord.setListData(listData);
      }
      on_click_button_daily() {
          Director.openPanelWithSingleton("PanelSecretDailyReward");
      }
      on_click_button_add() {
          Director.openPanelWithSingleton("PanelSecretKeyAdd");
      }
      on_click_button_select_layer() {
          Director.openPanelWithSingleton("PanelSecretSelectLayer");
      }
      on_click_button_challenge() {
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          if (!mgrGame.checkItem(1013, 1)) {
              return;
          }
          let cfg = this.getSecretLevel();
          if (cfg) {
              Global.sendMsg(MSG.TOWER_SECRET, cfg);
              Global.sendMsg(MSG.PANEL_SECRET_CLOSE);
          }
      }
  }

  class CustomSecretShop extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretShop";
          this.inited = false;
          this.exportNodeNames = {
              cc_list_shop: "fgui.GList",
              cc_item01: "CustomSecretShopItemTop",
              cc_item02: "CustomSecretShopItemTop",
              cc_item03: "CustomSecretShopItemTop",
          };
      }
      init() {
          if (this.inited)
              return;
          this.inited = true;
          this.listShop = new ListView(this.list_shop, this, this.parseShopItem, this.renderShopItem);
          Global.registerListeners(this, {
              [MSG.EXCHANGE_SHOP_REFRESH]: this.onExchangeShopRefresh.bind(this),
          });
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onExchangeShopRefresh() {
          this.refresh();
      }
      refresh() {
          this.item01.refersh(db.get_shop_exchange_db(db.game_cnf.secret_shop_exchange_ids[0]));
          this.item02.refersh(db.get_shop_exchange_db(db.game_cnf.secret_shop_exchange_ids[1]));
          this.item03.refersh(db.get_shop_exchange_db(db.game_cnf.secret_shop_exchange_ids[2]));
          this.refreshShopList();
      }
      parseShopItem(content, view, index) {
          content.view = view;
          if (index < 4) {
              FguiHelper.playIdleAndIn(view, index, 0, 0.1);
          }
          else {
              FguiHelper.playIdleAndIn(view, index - 4, 0.1, 0.1);
          }
      }
      renderShopItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      refreshShopList() {
          let listData = [];
          let shopList = db.get_shop_exchange_db_map();
          for (let k in shopList) {
              let shop = db.get_shop_exchange_db(k);
              if (shop.type == 1) {
                  listData.push(shop);
              }
          }
          this.listShop.setListData(listData);
      }
  }

  class CustomSecretTowerPrice extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretTowerPrice";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_cur: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_enough: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemId, need) {
          if (itemId && need) {
              let curt = mgrGame.getItemCount(itemId);
              this.label_cur.text = curt.toString();
              this.label_max.text = "/" + need;
              this.loader_icon.url = mgrGame.getItemIcon(itemId);
              this.ctrl_enough.selectedIndex = curt >= need ? 0 : 1;
          }
      }
  }

  class CustomSecretTowerUp extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretTowerUp";
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_loader_tower: "fgui.GComponent",
              cc_button_up: "fgui.GButton",
              cc_price1: "CustomSecretTowerPrice",
              cc_price2: "CustomSecretTowerPrice",
              cc_node_effect: "fgui.GLoader",
              cc_button_switch: "ScaleButton",
              cc_ctrl_secret_quality: "fgui.Controller",
          };
      }
      onCreate() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.onItemChange.bind(this),
          });
      }
      dispose() {
          super.dispose();
      }
      createEffect(scene3D, camera) {
          let effect = EffectFactory.create("166_ui_loop_star_04", scene3D);
          effect.followFguiNode(camera, this.node_effect);
          this.effect = effect;
      }
      destroyEffect() {
          if (this.effect) {
              this.effect.clear();
              this.effect = null;
          }
      }
      onItemChange() {
          this.refreshMoney();
      }
      refresh(data) {
          this.towerDb = data;
          this.loadSkin();
          this.ctrl_secret_quality.selectedIndex = mgrTower.getTowerQualityByDB(data);
          ;
          this.refreshMoney();
      }
      refreshMoney() {
          let qualityDb = db.get_tower_quality(mgrTower.getTowerQualityByDB(this.towerDb));
          if (qualityDb) {
              let itemId1 = qualityDb.item_ids[0] || 0;
              let itemCount1 = qualityDb.item_ids[1] || 0;
              let itemId2 = qualityDb.item_ids[2] || 0;
              let itemCount2 = qualityDb.item_ids[3] || 0;
              this.price1.refresh(itemId1, itemCount1);
              this.price2.refresh(itemId2, itemCount2);
          }
      }
      loadSkin() {
          this.clearSkin();
          let skin = new TowerSkin();
          skin.loadSkin(this.towerDb, true);
          this.skin = skin;
          this.loader_tower.displayObject.addChild(skin);
          this.skin.refreshQuality(this.towerDb.id);
          if (this.towerDb.main) {
              this.skin.refreshSkillByDB(this.towerDb);
          }
          else {
              this.skin.syncShooterByDB(this.towerDb);
          }
      }
      clearSkin() {
          if (this.skin) {
              this.skin.removeSelf();
              this.skin = null;
          }
      }
      on_click_button_up() {
          if (mgrTower.tryLvupTowerQualityByDB(this.towerDb)) {
              Global.sendMsg(MSG.SECRET_TOWER_BREAK_UP);
              Director.openPanelWithSingleton("PanelSecretTowerUpSuc", { towerDb: this.towerDb });
          }
      }
      on_click_button_switch() {
          Director.openPanelWithSingleton("PanelSecretSelectTower");
      }
  }

  class CustomSecretUp extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://secret/CustomSecretUp";
          this.inited = false;
          this.exportNodeNames = {
              cc_button_add: "ScaleButton",
              cc_tower: "CustomSecretTowerUp",
              cc_ctrl_up_state: "fgui.Controller",
          };
      }
      init(panel, towerDb) {
          if (this.inited)
              return;
          this.inited = true;
          this.panel = panel;
          if (towerDb && !mgrTower.isTowerQualityMax(mgrTower.getTowerQualityByDB(towerDb))) {
              this.onSecretSelectTower(towerDb);
          }
          Global.registerListeners(this, {
              [MSG.SECRET_SELECT_TOWER]: this.onSecretSelectTower.bind(this),
              [MSG.SECRET_TOWER_BREAK_UP]: this.onSecretTowerBreakUp.bind(this),
          });
          this.ctrl_up_state.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
      }
      dispose() {
          this.clearEffect();
          super.dispose();
      }
      clearEffect() {
          this.tower.destroyEffect();
      }
      updateEffect() {
          this.onStateChange();
      }
      onSecretSelectTower(data) {
          if (data) {
              this.ctrl_up_state.selectedIndex = 1;
              this.tower.refresh(data);
          }
      }
      onSecretTowerBreakUp() {
          this.ctrl_up_state.selectedIndex = 0;
      }
      onStateChange() {
          switch (this.ctrl_up_state.selectedIndex) {
              case 0:
                  this.tower.destroyEffect();
                  break;
              case 1:
                  if (this.panel) {
                      this.tower.createEffect(this.panel.scene3DEffect, this.panel.cameraEffect);
                  }
                  break;
          }
      }
      on_click_button_add() {
          Director.openPanelWithSingleton("PanelSecretSelectTower");
      }
  }

  class PanelSecret extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "逾越挑战";
          this.sourceName = "ui://secret/PanelSecret";
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_challenge: "CustomSecretChallenge",
              cc_shop: "CustomSecretShop",
              cc_up: "CustomSecretUp",
              cc_button_challenge: "fgui.GButton",
              cc_button_shop: "fgui.GButton",
              cc_button_up: "fgui.GButton",
              cc_stone_bar: "CustomBarStone",
              cc_button_close: "ScaleButton",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          Global.registerListeners(this, {
              [MSG.PANEL_SECRET_CLOSE]: this.closeWithTransition.bind(this),
          });
          let index = this.context.index || 0;
          if (index < this.ctrl_page.pageCount)
              this.ctrl_page.selectedIndex = index;
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStageChange);
      }
      dispose() {
          super.dispose();
      }
      onAwake() {
          this.createScene3DEffect(99);
          this.onStageChange();
      }
      onStageChange() {
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.up.clearEffect();
                  this.challenge.init();
                  break;
              case 1:
                  this.up.clearEffect();
                  this.shop.init();
                  break;
              case 2:
                  this.up.init(this, this.context.towerDb);
                  this.up.updateEffect();
                  break;
          }
      }
      on_click_button_challenge() {
      }
      on_click_button_shop() {
      }
      on_click_button_up() {
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelSecretKeyAdd extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "逾越购买次数";
          this.sourceName = "ui://secret/PanelSecretKeyAdd";
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_button_ad: "fgui.GButton",
              cc_button_close: "fgui.GButton",
              cc_label_left: "fgui.GBasicTextField",
              cc_ctrl_buy: "fgui.Controller",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.refresh();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.secret_add) {
                      this.addSecretCount();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.secret_add);
      }
      dispose() {
          super.dispose();
      }
      addSecretCount() {
          mgrGame.addItem(1015, 1, 20, false);
          mgrGame.addItem(1013, 1, 20, false);
          this.closeWithTransition();
      }
      refresh() {
          this.label_left.text = mgrSecret.getBuyChallengeLeftCount().toString();
          this.ctrl_buy.selectedIndex = mgrSecret.canBuyChallengeCount() ? 0 : 1;
      }
      onClickBackground() {
          this.closeWithTransition();
      }
      on_click_button_ad() {
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.secret_add);
          });
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class PanelSecretSelectLayer extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "逾越选择层级";
          this.sourceName = "ui://secret/PanelSecretSelectLayer";
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_list_layer: "fgui.GList",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.listLayer = new ListView(this.list_layer, this, this.parseLayerItem, this.renderLayerItem);
          this.listLayer.setOnClickItem(this, this.onClickLayerItem);
          this.refreshLayerList();
      }
      dispose() {
          super.dispose();
      }
      parseLayerItem(content, view, index) {
          content.view = view;
          if (index < 9)
              FguiHelper.playIdleAndIn(content.view, index, 0, 0.1);
      }
      renderLayerItem(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickLayerItem(content) {
          if (content.data.id <= mgrSecret.layerId) {
              Global.sendMsg(MSG.SECRET_SELECT_LAYER, content.data);
              this.closeWithTransition();
          }
      }
      refreshLayerList() {
          let listData = db.get_secret_level_map();
          this.listLayer.setListData(listData);
      }
      onClickBackground() {
          this.closeWithTransition();
      }
  }

  class PanelSecretSelectTower extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "逾越选择塔";
          this.sourceName = "ui://secret/PanelSecretSelectTower";
          this.bMask = false;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_list_tower: "fgui.GList",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.listTower = new ListView(this.list_tower, this, this.parseTowerItem, this.renderTowerItem);
          this.listTower.setOnClickItem(this, this.onClickTowerItem);
          this.refreshTowerList();
      }
      dispose() {
          super.dispose();
      }
      parseTowerItem(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(content.view, index, 0.25, 0);
      }
      renderTowerItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickTowerItem(content) {
          if (!mgrTower.isTowerQualityMax(mgrTower.getTowerQualityByDB(content.data))) {
              Global.sendMsg(MSG.SECRET_SELECT_TOWER, content.data);
              this.closeWithTransition();
          }
      }
      refreshTowerList() {
          let towerDbMap = db.get_tower_db_map();
          let listData = [];
          for (let key in towerDbMap) {
              let data = db.get_tower_db(key);
              if (data.main || mgrTower.getTowerAmount(key)) {
                  listData.push(data);
              }
          }
          listData.sort(this.sortCard);
          this.listTower.setListData(listData);
      }
      sortCard(a, b) {
          let score_a = mgrTower.calcTowerScoreSecret(a.id);
          let score_b = mgrTower.calcTowerScoreSecret(b.id);
          return score_b - score_a;
      }
      onClickBackground() {
          this.closeWithTransition();
      }
  }

  class PanelSecretTowerUpSuc extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "逾越成功";
          this.sourceName = "ui://secret/PanelSecretTowerUpSuc";
          this.timeOpen = 0;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_card_2: "CustomSecretCard",
              cc_card_1: "CustomSecretCard",
              cc_loader_tower: "fgui.GComponent",
              cc_node_effect: "fgui.GLoader",
              cc_label_tip: "fgui.GBasicTextField",
              cc_label_name: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.towerDb = this.context.towerDb;
          this.timeOpen = Utils.getTime();
          this.refresh();
      }
      dispose() {
          Laya.timer.clearAll(this);
          super.dispose();
      }
      onAwake() {
          this.createScene3DEffect(this.resNode.getChildIndex(this.node_effect));
          let effectId = "166_ui_loop_star_02";
          switch (this.ctrl_quality.selectedIndex) {
              case 0:
                  effectId = "166_ui_loop_star_02_green";
                  break;
              case 1:
                  effectId = "166_ui_loop_star_02_blue";
                  break;
              case 2:
                  effectId = "166_ui_loop_star_02_purple";
                  break;
              case 3:
                  effectId = "166_ui_loop_star_02";
                  break;
          }
          let effect1 = EffectFactory.create(effectId, this.scene3DEffect);
          effect1.followFguiNode(this.cameraEffect, this.node_effect);
          Laya.timer.once(1000, this, this.onCreateCardEffect);
      }
      onCreateCardEffect() {
          if (this.destroyed)
              return;
          let effectId = "166_ui_kapai_pzsj";
          switch (this.ctrl_quality.selectedIndex) {
              case 0:
                  effectId = "166_ui_kapai_pzsj_green";
                  break;
              case 1:
                  effectId = "166_ui_kapai_pzsj_blue";
                  break;
              case 2:
                  effectId = "166_ui_kapai_pzsj_purple";
                  break;
              case 3:
                  effectId = "166_ui_kapai_pzsj";
                  break;
          }
          let effect2 = EffectFactory.create(effectId, this.scene3DEffect);
          effect2.followFguiNode(this.cameraEffect, this.card_2, true, this.card_2.width / 2, this.card_2.height / 2);
      }
      refresh() {
          let skin = new TowerSkin();
          skin.loadSkin(this.towerDb, true);
          this.skin = skin;
          this.loader_tower.displayObject.addChild(skin);
          this.skin.refreshQuality(this.towerDb.id);
          if (this.towerDb.main) {
              this.skin.refreshSkillByDB(this.towerDb);
          }
          else {
              this.skin.syncShooterByDB(this.towerDb);
          }
          let quality = mgrTower.getTowerQualityByDB(this.towerDb);
          this.label_name.text = this.towerDb.name;
          this.ctrl_quality.selectedIndex = quality;
          this.ctrl_type.selectedIndex = this.towerDb.type;
          this.card_1.refresh(this.towerDb, quality - 1);
          this.card_2.refresh(this.towerDb, quality);
      }
      onClickBackground() {
          let passTime = Utils.getTime() - this.timeOpen;
          if (passTime >= 1000) {
              this.closeWithTransition();
          }
      }
  }

  class SceneSplash extends SceneBase {
      constructor() {
          super();
      }
      getTaskManager() {
          let taskManager = new TaskManager();
          taskManager.addCall(this.initBaseRes.bind(this));
          this.taskManager = taskManager;
          return taskManager;
      }
      initBaseRes(resolve) {
          let loader = new TaskManager();
          loader.setParent(this.taskManager);
          loader.setLoadingCallback(resolve);
          loader.addFguiPackage("res/fgui/splash");
          loader.loadAll();
      }
      onEnter(withLoad) {
          Director.openPanelWithSingleton("PanelSplash");
      }
      onExit() {
      }
  }

  class PanelCheckNetworkFail extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "检测网络失败";
          this.sourceName = "ui://setting/PanelCheckNetworkFail";
          this.panelLayer = 8;
          this.exportNodeNames = {
              cc_button_back: "fgui.GButton",
          };
      }
      buildUi() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_back() {
          Director.disposeAllPanel();
          Director.runScene(SceneSplash, "PanelLoadingGame");
      }
  }

  class DebugHelper {
      static begin() {
          this.debugCode = "";
          this.initEvent();
          this.screedMidX = Laya.stage.width / 2;
      }
      static end() {
          this.removeEvent();
      }
      static initEvent() {
          if (mgrGame.isWhiteUser)
              Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onClickDeug);
      }
      static removeEvent() {
          if (mgrGame.isWhiteUser)
              Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onClickDeug);
      }
      static onClickDeug() {
          let halfW = Laya.stage.width / 2;
          let halfH = Laya.stage.height / 2;
          let x = Laya.stage.mouseX;
          let y = Laya.stage.mouseY;
          if (y >= halfH) {
              if (x <= halfW) {
                  this.onClickDebugLeft();
              }
              else {
                  this.onClickDebugRight();
              }
          }
      }
      static onClickDebugLeft() {
          this.debugCode += "l";
          this.checkDebugCode();
      }
      static onClickDebugRight() {
          this.debugCode += "r";
          this.checkDebugCode();
      }
      static checkDebugCode() {
          if (this.debugCode == GameGlobal.DEBUG_CODE) {
              this.onDebugCodeCorrect();
          }
          if (this.debugCode.length >= GameGlobal.DEBUG_CODE.length) {
              this.debugCode = "";
          }
      }
      static onDebugCodeCorrect() {
          if (mgrGame.isWhiteUser) {
              fgui.UIPackage.loadPackage("res/fgui/test", Laya.Handler.create(this, () => {
                  UIManager.getInstance().openDebug();
              }));
          }
      }
  }
  DebugHelper.debugCode = "";

  class PanelSetting extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "设置";
          this.sourceName = "ui://setting/PanelSetting";
          this.panelLayer = 4;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_btn_vibrate: "fgui.GButton",
              cc_btn_music: "fgui.GButton",
              cc_btn_sound: "fgui.GButton",
              cc_button_privacy: "fgui.GButton",
              cc_btn_damage: "fgui.GButton",
              cc_btn_ensure_cdk: "fgui.GButton",
              cc_button_qq: "fgui.GButton",
              cc_btn_effect: "fgui.GButton",
              cc_btn_idle: "fgui.GButton",
              cc_btn_target_nearest: "fgui.GButton",
              cc_btn_target_hpless: "fgui.GButton",
              cc_btn_target_nearest_lock: "fgui.GButton",
              cc_btn_record: "fgui.GButton",
              cc_button_close: "ScaleButton",
              cc_labelKefu: "fgui.GBasicTextField",
              cc_label_cdk: "fgui.GBasicTextField",
              cc_input_cdk: "fgui.GTextInput",
              cc_label_user_id: "fgui.GBasicTextField",
              cc_com_record: "fgui.GGroup",
              cc_ctrl_target: "fgui.Controller",
              cc_ctrl_privacy_style: "fgui.Controller",
              cc_ctrl_record: "fgui.Controller",
          };
      }
      buildUi() {
          this.ctrlSound = this.resNode.getController("sound");
          this.ctrlMusic = this.resNode.getController("music");
          this.ctrlAdvAnced = this.resNode.getController("advanced");
          this.ctrlKefu = this.resNode.getController("kefu");
          this.ctrlVibrate = this.resNode.getController("vibrate");
          this.ctrlDamage = this.resNode.getController("damage");
          this.ctrlEffect = this.resNode.getController("effect");
          this.ctrlSound.on(fgui.Events.STATE_CHANGED, this, this.refreshState);
          this.ctrlMusic.on(fgui.Events.STATE_CHANGED, this, this.refreshState);
          this.ctrlVibrate.on(fgui.Events.STATE_CHANGED, this, this.refreshState);
          this.ctrlDamage.on(fgui.Events.STATE_CHANGED, this, this.refreshState);
          this.ctrlEffect.on(fgui.Events.STATE_CHANGED, this, this.refreshState);
          this.ctrl_target.on(fgui.Events.STATE_CHANGED, this, this.refreshState);
          this.initState();
          this.refreshRecord();
          CopHelper.updateControllerVisible(this.resNode.getController("email"), CopHelper.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_kefu_email), 1, 0);
          CopHelper.updateControllerVisible(this.resNode.getController("record"), CopHelper.getSubCopValue(db.SUB_COP_SUBCOPKEY.b_record_video), 0, 1);
          CopHelper.updateControllerVisible(this.resNode.getController("cdk"), db.cop_db.b_cdk > 0, 1, 0);
          CopHelper.updateControllerVisible(this.ctrlAdvAnced, db.cop_db.b_advanced_setting, 1, 0);
          CopHelper.updateButtonVisible(this.button_qq, mgrSdk.numQQGroup);
          CopHelper.updateControllerVisible(this.ctrl_record, db.cop_db.isSupportUserCloudStorage && !mgrNative.isHtml5Platform(), true, false);
          if (db.cop_db.advanced_game_style < this.ctrl_privacy_style.pageCount)
              this.ctrl_privacy_style.selectedIndex = db.cop_db.advanced_game_style;
          DebugHelper.begin();
          this.initTimer();
          Global.registerListeners(this, {
              [BASE_MSG.SDK_LOGIN_RESULT]: this.refreshRecord.bind(this),
              ["MSG_SDK_SET_USER_CLOUD_STORAGE_REAULT"]: this.onSdkSetUserCloudStorageResult.bind(this),
          });
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.onUpdatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.onUpdatePerSecond);
      }
      onUpdatePerSecond() {
          this.label_cdk.visible = this.input_cdk.text.length == 0;
      }
      initState() {
          this.ctrlSound.setSelectedIndex(mgrSound.soundEnabled ? 0 : 1);
          this.ctrlMusic.setSelectedIndex(mgrSound.musicEnabled ? 0 : 1);
          this.ctrlVibrate.setSelectedIndex(mgrGame.vibrateEnable ? 0 : 1);
          this.ctrlAdvAnced.setSelectedIndex(db.cop_db.b_open_advancedSetting != 1 ? 0 : 1);
          this.ctrlDamage.setSelectedIndex(mgrGame.dmgFontEnable ? 0 : 1);
          this.ctrlEffect.setSelectedIndex(mgrGame.enableGameEffect ? 0 : 1);
          let type = mgrGame.towerTargetSearchType;
          if (type < this.ctrl_target.pageCount)
              this.ctrl_target.selectedIndex = type;
          let kefu = db.cop_db.s_kefu_text;
          this.labelKefu.text = kefu || "";
          this.ctrlKefu.setSelectedIndex((!kefu || kefu == "0") ? 0 : 1);
          console.log("PanelSetting.initState", mgrSound.soundEnabled, mgrSound.musicEnabled);
      }
      refreshState() {
          mgrSound.soundEnabled = this.ctrlSound.selectedIndex == 0 ? true : false;
          mgrSound.musicEnabled = this.ctrlMusic.selectedIndex == 0 ? true : false;
          mgrGame.vibrateEnable = this.ctrlVibrate.selectedIndex == 0 ? true : false;
          mgrGame.dmgFontEnable = this.ctrlDamage.selectedIndex == 0 ? true : false;
          mgrGame.enableGameEffect = this.ctrlEffect.selectedIndex == 0 ? true : false;
          mgrGame.towerTargetSearchType = this.ctrl_target.selectedIndex;
          StageConfig.enableGameEffect = mgrGame.enableGameEffect;
          StageConfig.towerTargetSearchType = mgrGame.towerTargetSearchType;
          console.log("PanelSetting.refreshState", mgrSound.soundEnabled, mgrSound.musicEnabled);
      }
      refreshRecord() {
          this.ctrl_record.setSelectedIndex(db.cop_db.isSupportUserCloudStorage ? 1 : 0);
          this.label_user_id.text = FileRecord.getUserId() || "尚未登录";
      }
      dispose() {
          this.removeTimer();
          super.dispose();
          DebugHelper.end();
      }
      onSdkSetUserCloudStorageResult(data) {
          if (data.msg) {
              if (data.bSuccess) {
                  mgrTip.showMsgTip("上传成功");
                  this.markUploadRecordSucTime();
              }
              else {
                  mgrTip.showMsgTip("上传失败");
              }
          }
      }
      cdTimeFormat(seconds) {
          if (seconds >= 3600) {
              return Math.floor(seconds / 3600) + "小时";
          }
          else if (seconds >= 60) {
              return Math.floor(seconds / 60) + "分钟";
          }
          else {
              return seconds + "秒";
          }
      }
      tryUploadRecord() {
          let curtTime = mgrTime.curtTime();
          let lastTime = mgrGame.timeUploadRecord;
          if (lastTime > 0 && lastTime > curtTime) {
              let leftTime = lastTime - curtTime;
              let formatTime = this.cdTimeFormat(leftTime);
              mgrTip.alertTip(formatTime + "后可再次上传云存档", "提示", "确定");
              return;
          }
          FileRecord.sendCloudRecord(null, true, "showtip");
      }
      markUploadRecordSucTime() {
          mgrGame.timeUploadRecord = mgrTime.curtTime() + 3600 * db.game_cnf.cd_record_upload_hand;
      }
      on_click_btn_sound() {
      }
      on_click_btn_music() {
      }
      on_click_btn_vibrate() {
      }
      on_click_button_privacy() {
          mgrSdk.openAdvancedSetting();
      }
      on_click_btn_damage() {
      }
      on_click_btn_ensure_cdk() {
          if (mgrTower.getMainTowerLv() < db.game_cnf.cdk_main_lv_limit) {
              mgrTip.showMsgTip("主塔升级到" + db.game_cnf.cdk_main_lv_limit + "级才可使用兑换码功能哦！");
              return;
          }
          if (mgrHolyItem.notEnoughEmpty(8))
              return;
          let cdk = this.input_cdk.text;
          if (cdk)
              mgrSdk.sendCDK(cdk);
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_qq() {
          mgrSdk.joinQqGroup();
      }
      on_click_btn_effect() {
      }
      on_click_btn_idle() {
          this.close();
          Director.openPanelWithSingleton("PanelIdle");
      }
      on_click_btn_target_nearest() {
      }
      on_click_btn_target_hpless() {
      }
      on_click_btn_target_nearest_lock() {
      }
      on_click_btn_record() {
          if (!!FileRecord.getUserId()) {
              this.tryUploadRecord();
          }
          else {
              mgrSdk.login();
          }
      }
  }

  class mgrShop extends Manager {
      static onLoad() {
          super.onLoad();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.shop_ad) {
                      this.onAdvShowSuc(e.params);
                  }
              },
              [BASE_MSG.SDK_SERVER_TIME_CHANGE]: this.onServerTimeChange.bind(this),
              [MSG.TIME_DIFFERENT_DAY]: this.onDifferentDay.bind(this),
          });
      }
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static onAdvShowSuc(key) {
          this.getShopExtraReward(key);
      }
      static onServerTimeChange(data) {
          let curtTimeServer = Number(data.serverTime);
          if (curtTimeServer <= 0)
              return;
          if (data.bChange) {
              return;
          }
          this.buildSupplyTime(curtTimeServer);
          this.calcSupplyExtraRefresh(curtTimeServer);
          this.calcBusinessmanRefresh(curtTimeServer);
          Global.sendMsg(MSG.SHOP_SERVER_TIME_REFRESH);
      }
      static onDifferentDay() {
          this.shopSupplyTimeShopId = 0;
      }
      static get lastUpdateTimeExtra() {
          return this.data.lastUpdateTimeExtra;
      }
      static set lastUpdateTimeExtra(time) {
          this.data.lastUpdateTimeExtra = time;
          this.saveRecord();
      }
      static get lastUpdateTimeBusiness() {
          return this.data.lastUpdateTimeBusiness;
      }
      static set lastUpdateTimeBusiness(time) {
          this.data.lastUpdateTimeBusiness = time;
          this.saveRecord();
      }
      static get timeBusinessHandRefresh() {
          return this.data.timeBusinessHandRefresh;
      }
      static set timeBusinessHandRefresh(time) {
          this.data.timeBusinessHandRefresh = time;
          this.saveRecord();
      }
      static get isHandRefreshBusiness() {
          return this.data.isHandRefreshBusiness;
      }
      static set isHandRefreshBusiness(time) {
          this.data.isHandRefreshBusiness = time;
          this.saveRecord();
      }
      static getShopExtraReward(key) {
          let record = this.getShopSupplyExtra(key);
          if (record && !record.reward) {
              let shopDb = this.getShopExtraDb(record.shopId);
              if (shopDb) {
                  mgrGame.addItem(shopDb.item_id, shopDb.item_num, 56, true);
              }
              this.markShopSupplyExtraReward(key);
              mgrTask.doEvent(db.TASK_EVENT_ID.GET_SHOP_ITEM);
              Global.sendMsg(MSG.SHOP_SUPPLY_EXTRA_REFRESH);
          }
      }
      static tryGetShopExtraReward(key) {
          let record = this.getShopSupplyExtra(key);
          if (record) {
              let shopDb = this.getShopExtraDb(record.shopId);
              if (shopDb) {
                  switch (shopDb.price_item_id) {
                      case 1010:
                          this.getShopExtraReward(key);
                          break;
                      case 1000:
                          if (mgrGame.subItem(shopDb.price_item_id, shopDb.price_item_cost, 56)) {
                              this.getShopExtraReward(key);
                          }
                          break;
                      case 1004:
                          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.shop_ad, key);
                          break;
                  }
              }
          }
      }
      static getShopExtraDb(shopId) {
          return db.get_shop_extra_db(shopId);
      }
      static getShopTimeDb(shopId) {
          return db.get_shop_time_db(shopId - 1);
      }
      static getShopSupplyExtra(key) {
          return this.data.shopSupplyExtra[key] || {};
      }
      static getShopSupplyExtraDB(key) {
          return this.getShopExtraDb(this.getShopSupplyExtra(key).shopId);
      }
      static isShopSupplyExtraReward(key) {
          return this.getShopSupplyExtra(key).reward;
      }
      static setShopSupplyExtra(key, shopId, reward) {
          let data = this.getShopSupplyExtra(key);
          data.shopId = shopId;
          data.reward = reward;
          this.data.shopSupplyExtra[key] = data;
          this.saveRecord();
      }
      static markShopSupplyExtraReward(key) {
          let data = this.getShopSupplyExtra(key);
          data.reward = true;
          this.data.shopSupplyExtra[key] = data;
          this.saveRecord();
      }
      static buildRandomSupplyExtra(type) {
          let shopExtraMap = db.get_shop_extra_db_map();
          let listData = [];
          for (let shopId in shopExtraMap) {
              let shopExtra = shopExtraMap[shopId];
              if (shopExtra.type == type) {
                  listData.push(shopExtra);
              }
          }
          let shopExtraDb = StageTool.calcWeightItem(listData);
          return shopExtraDb;
      }
      static buildShopSupplyExtraBySlots(key) {
          let slots = (db.get_shop_slot_db_map()[key] || []);
          for (let slot of slots) {
              let shopExtra = this.buildRandomSupplyExtra(slot.type);
              if (shopExtra) {
                  this.setShopSupplyExtra(slot.save_key, shopExtra.id, false);
              }
          }
      }
      static getShopSupplyExtraBySlots(key) {
          let slots = (db.get_shop_slot_db_map()[key] || []);
          let listData = [];
          for (let slot of slots) {
              let record = this.getShopSupplyExtra(slot.save_key);
              if (record) {
                  listData.push({ key: slot.save_key });
              }
          }
          return listData;
      }
      static calcCurrentSupplyTimeDb(curtTimeServer) {
          let date = mgrTime.getBeijingTime(curtTimeServer);
          let hour = date.getHours();
          let listData = db.get_shop_time_db_map();
          for (let i = 0; i < listData.length; i++) {
              let shop = listData[i];
              if (shop && hour < shop.hour) {
                  return shop;
              }
          }
          return listData[0];
      }
      static set shopSupplyTimeShopId(shopId) {
          this.data.shopSupplyTime.shopId = shopId;
          this.saveRecord();
      }
      static get shopSupplyTimeShopId() {
          return this.data.shopSupplyTime.shopId;
      }
      static isShopSupplyTimeReward() {
          return this.data.shopSupplyTime.reward;
      }
      static set shopSupplyTimeReward(value) {
          this.data.shopSupplyTime.reward = value;
          this.saveRecord();
      }
      static getCurrentSupplyTimeDb() {
          return this.getShopTimeDb(this.shopSupplyTimeShopId);
      }
      static tryGetSupplyTimeReward() {
          let supplyTimeDb = mgrShop.getCurrentSupplyTimeDb();
          if (supplyTimeDb && !this.isShopSupplyTimeReward()) {
              Level.getRewardByItemIds(supplyTimeDb.item_ids, 56);
              mgrTask.doEvent(db.TASK_EVENT_ID.GET_SHOP_ITEM);
              this.shopSupplyTimeReward = true;
              return true;
          }
          return false;
      }
      static buildSupplyTime(curtTimeServer) {
          let shopDb = this.calcCurrentSupplyTimeDb(curtTimeServer);
          if (this.shopSupplyTimeShopId != shopDb.id) {
              this.shopSupplyTimeReward = false;
              this.shopSupplyTimeShopId = shopDb.id;
          }
          console.log("计算额外补给 是否刷新", shopDb.id, shopDb.desc);
      }
      static buildSupplyExtra() {
          this.buildShopSupplyExtraBySlots("supply_extra");
      }
      static buildBusinessman() {
          this.buildShopSupplyExtraBySlots("business");
          if (!this.isHandRefreshBusiness) {
              this.timeBusinessHandRefresh = 0;
          }
          this.isHandRefreshBusiness = false;
      }
      static getSupplyExtraList() {
          return this.getShopSupplyExtraBySlots("supply_extra");
      }
      static getBusinessmanList() {
          return this.getShopSupplyExtraBySlots("business");
      }
      static calcSupplyExtraRefresh(curtTime) {
          let lastUpdateTimeExtra = this.lastUpdateTimeExtra;
          let passTime = 0;
          let maxxTime = db.game_cnf.shop_extra_cd * 1000;
          if (lastUpdateTimeExtra) {
              passTime = curtTime - lastUpdateTimeExtra;
          }
          else {
              passTime = maxxTime;
          }
          if (passTime >= maxxTime) {
              this.buildSupplyExtra();
              this.lastUpdateTimeExtra = curtTime;
          }
          console.log("计算额外补给 是否刷新", (maxxTime - passTime) / 1000);
      }
      static calcBusinessmanRefresh(curtTime) {
          let lastUpdateTimeBusiness = this.lastUpdateTimeBusiness;
          let passTime = 0;
          let maxxTime = db.game_cnf.shop_businessman_cd * 1000;
          if (lastUpdateTimeBusiness) {
              passTime = curtTime - lastUpdateTimeBusiness;
          }
          else {
              passTime = maxxTime;
          }
          if (this.isHandRefreshBusiness || passTime >= maxxTime) {
              this.buildBusinessman();
              this.lastUpdateTimeBusiness = curtTime;
          }
          console.log("计算圣物商人 是否刷新", (maxxTime - passTime) / 1000);
      }
      static tryGetServerTime(force = false) {
          let time = Date.now();
          if (!force && this.lastGetServerTime > time)
              return;
          this.lastGetServerTime = time + 5000;
          if (db.cop_db.is4399Watermark) {
              Global.sendMsg(BASE_MSG.SDK_SERVER_TIME_CHANGE, { bChange: false, serverTime: Date.now().toString() });
          }
          else {
              mgrSdk.checkTimeChange();
          }
          console.log("商店：请求服务器时间");
      }
      static calcSupplyTimeLefttime() {
          let date = mgrTime.getBeijingTime(Date.now());
          let hour = date.getHours();
          let minute = date.getMinutes();
          let second = date.getSeconds();
          let data = this.getCurrentSupplyTimeDb();
          let leftTime = data.hour * 3600 - hour * 3600 - minute * 60 - second;
          if (leftTime < 0)
              leftTime = 0;
          if (leftTime <= 0)
              this.tryGetServerTime();
          return leftTime;
      }
      static calcSupplyExtraLefttime() {
          let curtTime = Date.now();
          let lastUpdateTimeExtra = this.lastUpdateTimeExtra;
          let passTime = 0;
          let maxxTime = db.game_cnf.shop_extra_cd * 1000;
          if (lastUpdateTimeExtra) {
              passTime = curtTime - lastUpdateTimeExtra;
          }
          else {
              passTime = maxxTime;
          }
          let leftTime = Math.floor((maxxTime - passTime) / 1000);
          if (leftTime < 0) {
              leftTime = 0;
          }
          if (leftTime <= 0)
              this.tryGetServerTime();
          return leftTime;
      }
      static calcBusinessLefttime() {
          let curtTime = Date.now();
          let lastUpdateTimeBusiness = this.lastUpdateTimeBusiness;
          let passTime = 0;
          let maxxTime = db.game_cnf.shop_businessman_cd * 1000;
          if (lastUpdateTimeBusiness) {
              passTime = curtTime - lastUpdateTimeBusiness;
          }
          else {
              passTime = maxxTime;
          }
          let leftTime = Math.floor((maxxTime - passTime) / 1000);
          if (leftTime < 0) {
              leftTime = 0;
          }
          if (this.isHandRefreshBusiness || leftTime <= 0)
              this.tryGetServerTime();
          return leftTime;
      }
      static getBusinessHandRefreshPirce() {
          return db.game_cnf.shop_businessman_refresh_cost * Math.pow(2, this.timeBusinessHandRefresh);
      }
      static handRefreshBusiness() {
          let cost = this.getBusinessHandRefreshPirce();
          if (!this.isHandRefreshBusiness && mgrGame.subItem(1000, cost, 56)) {
              this.timeBusinessHandRefresh += 1;
              this.isHandRefreshBusiness = true;
              this.tryGetServerTime(true);
          }
      }
  }
  mgrShop.RECORD_KEY = "game166_shop_v1.0";
  mgrShop.dataDefault = {
      shopSupplyTime: { shopId: 0, reward: false },
      shopSupplyExtra: {},
      lastUpdateTimeExtra: 0,
      lastUpdateTimeBusiness: 0,
      timeBusinessHandRefresh: 0,
      isHandRefreshBusiness: false,
  };
  mgrShop.lastGetServerTime = 0;

  class CustomShopItemExtra extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://shop/CustomShopItemExtra";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_get: "fgui.GButton",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      onCreate() {
          this.ctrlType = this.button_get.getController("type");
          this.ctrlType.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
      }
      dispose() {
          super.dispose();
      }
      onStateChange() {
          switch (this.ctrlType.selectedIndex) {
              case 2:
                  mgrGame.statisVideoShow(db.ADV_DB_ADVNAME.shop_ad);
                  break;
          }
      }
      refresh(shop) {
          this.shop = shop;
          let data = mgrShop.getShopSupplyExtraDB(shop.key);
          if (data) {
              let itemInfo = { itemId: data.item_id, count: data.item_num };
              this.item.refresh(itemInfo);
              this.button_get.title = data.price_item_cost.toString();
              switch (data.price_item_id) {
                  case 1010:
                      this.ctrlType.selectedIndex = 0;
                      break;
                  case 1000:
                      this.ctrlType.selectedIndex = 1;
                      break;
                  case 1004:
                      this.ctrlType.selectedIndex = 2;
                      break;
              }
          }
          this.ctrl_reward.selectedIndex = mgrShop.isShopSupplyExtraReward(shop.key) ? 1 : 0;
      }
      on_click_button_get() {
          if (mgrHolyItem.notEnoughEmpty(1))
              return;
          let data = this.shop;
          if (data) {
              mgrNetwork.callByNetwork(() => {
                  mgrShop.tryGetShopExtraReward(this.shop.key);
              });
          }
      }
  }

  class CustomShopItemBusiness extends CustomShopItemExtra {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://shop/CustomShopItemBusiness";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_get: "fgui.GButton",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      onCreate() {
          super.onCreate();
      }
      dispose() {
          super.dispose();
      }
      on_click_button_get() {
          super.on_click_button_get();
      }
  }

  class CustomShopBusinessman extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://shop/CustomShopBusinessman";
          this.inited = false;
          this.exportNodeNames = {
              cc_list_business: "fgui.GList",
              cc_label_refresh_price: "fgui.GBasicTextField",
              cc_label_extra_desc: "fgui.GBasicTextField",
              cc_button_refresh: "fgui.GButton",
              cc_loader_refresh_price: "fgui.GLoader",
              cc_trans_in: "fgui.Transition",
              cc_trans_idle: "fgui.Transition",
          };
      }
      onCreate() {
          this.listSupplyExtra = new ListView(this.list_business, this, this.parseSupplyExtra, this.renderSupplyExtra);
          this.initEvent();
      }
      refresh() {
          this.refreshList();
          this.refreshLeftTime();
          this.refreshPrice();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.SHOP_SUPPLY_EXTRA_REFRESH]: this.onShopSupplyExtraRefresh.bind(this),
              [MSG.SHOP_SERVER_TIME_REFRESH]: this.onShopServerTimeRefresh.bind(this),
          });
      }
      in() {
          if (this.inited)
              return;
          this.inited = true;
          this.trans_in.play();
          this.refresh();
      }
      onShopSupplyExtraRefresh() {
          this.listSupplyExtra.refresh();
      }
      onShopServerTimeRefresh() {
          this.refresh();
      }
      updatePerSecond() {
          this.refreshLeftTime();
      }
      parseSupplyExtra(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(content.view, index, 0.3, 0.1);
      }
      renderSupplyExtra(content, data, index) {
          content.view.refresh(data);
      }
      refreshList() {
          let listData = mgrShop.getBusinessmanList();
          this.listSupplyExtra.setListData(listData);
      }
      refreshLeftTime() {
          this.label_extra_desc.text = Utils.cdTimeFormat(mgrShop.calcBusinessLefttime());
      }
      refreshPrice() {
          this.label_refresh_price.text = mgrShop.getBusinessHandRefreshPirce().toString();
      }
      on_click_button_refresh() {
          mgrNetwork.callByNetwork(() => {
              mgrShop.handRefreshBusiness();
          });
      }
  }

  class CustomShopSupply extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://shop/CustomShopSupply";
          this.inited = false;
          this.exportNodeNames = {
              cc_label_time_title: "fgui.GBasicTextField",
              cc_label_time_desc: "fgui.GBasicTextField",
              cc_label_time_left: "fgui.GBasicTextField",
              cc_label_extra_desc: "fgui.GBasicTextField",
              cc_list_time: "fgui.GList",
              cc_list_extra: "fgui.GList",
              cc_button_time_reward: "fgui.GButton",
              cc_ctrl_state_time: "fgui.Controller",
              cc_trans_in: "fgui.Transition",
              cc_trans_idle: "fgui.Transition",
          };
      }
      onCreate() {
          this.listSupplyTime = new ListView(this.list_time, this, this.parseSupplyTime, this.rednerSupplyTime);
          this.listSupplyExtra = new ListView(this.list_extra, this, this.parseSupplyExtra, this.renderSupplyExtra);
          this.initEvent();
      }
      refresh() {
          this.refreshSupplyTime();
          this.refreshSupplyExtra();
          this.refreshLeftTime();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.SHOP_SUPPLY_EXTRA_REFRESH]: this.onShopSupplyExtraRefresh.bind(this),
              [MSG.SHOP_SERVER_TIME_REFRESH]: this.onShopServerTimeRefresh.bind(this),
          });
      }
      in() {
          if (this.inited)
              return;
          this.inited = true;
          this.trans_in.play();
          this.refresh();
      }
      onShopSupplyExtraRefresh() {
          this.listSupplyExtra.refresh();
      }
      onShopServerTimeRefresh() {
          this.refresh();
      }
      updatePerSecond() {
          this.refreshLeftTime();
      }
      refreshLeftTime() {
          if (this.ctrl_state_time.selectedIndex) {
              this.label_time_left.text = Utils.cdTimeFormat(mgrShop.calcSupplyTimeLefttime()) + "后可领取";
          }
          this.label_extra_desc.text = "下次刷新还剩" + Utils.cdTimeFormat(mgrShop.calcSupplyExtraLefttime());
      }
      refreshSupplyTime() {
          let supplyTimeDb = mgrShop.getCurrentSupplyTimeDb();
          if (!supplyTimeDb)
              return;
          let reward_ids = supplyTimeDb.item_ids;
          let listData = [];
          for (let i = 0; i < reward_ids.length; i += 2) {
              listData.push({ itemId: reward_ids[i], count: reward_ids[i + 1] });
          }
          this.listSupplyTime.setListData(listData);
          this.label_time_title.text = supplyTimeDb.title;
          this.label_time_desc.text = supplyTimeDb.desc;
          this.ctrl_state_time.selectedIndex = mgrShop.isShopSupplyTimeReward() ? 1 : 0;
      }
      parseSupplyTime(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(content.view, index, 0.35, 0.1);
      }
      rednerSupplyTime(content, item, index) {
          content.view.refresh(item);
      }
      refreshSupplyExtra() {
          let listData = mgrShop.getSupplyExtraList();
          this.listSupplyExtra.setListData(listData);
      }
      parseSupplyExtra(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(content.view, index, 0.35, 0.1);
      }
      renderSupplyExtra(content, data, index) {
          content.view.refresh(data);
      }
      on_click_button_time_reward() {
          if (mgrHolyItem.notEnoughEmpty(4))
              return;
          mgrNetwork.callByNetwork(() => {
              if (mgrShop.tryGetSupplyTimeReward()) {
                  this.refreshSupplyTime();
              }
          });
      }
  }

  class PanelShop extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "商店";
          this.sourceName = "ui://shop/PanelShop";
          this.panelLayer = 4;
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_supply: "CustomShopSupply",
              cc_businessman: "CustomShopBusinessman",
              cc_button_shop_supply: "fgui.GButton",
              cc_button_shop_businessman: "fgui.GButton",
              cc_layer_bar: "fgui.GComponent",
              cc_money_bar: "CustomMoneyBar",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      buildUi() {
          this.layer_bar.makeFullScreen();
          this.ctrl_type.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.initTimer();
          this.onStateChange();
      }
      dispose() {
          this.removeTimer();
          super.dispose();
      }
      initTimer() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
      }
      removeTimer() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      onStateChange() {
          switch (this.ctrl_type.selectedIndex) {
              case 0:
                  this.supply.in();
                  break;
              case 1:
                  this.businessman.in();
                  break;
          }
      }
      updatePerSecond() {
          this.supply.updatePerSecond();
          this.businessman.updatePerSecond();
      }
      on_click_button_shop_supply() {
      }
      on_click_button_shop_businessman() {
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
  }

  class CustomSignItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://sign/CustomSignItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_button_fix: "fgui.GButton",
              cc_label_day: "fgui.GBasicTextField",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          if (!data)
              return;
          this.signDb = data;
          this.label_day.text = data.name;
          this.item.refreshById(data.item_id, data.item_num);
          let day = mgrSign.day;
          if (mgrSign.isSigned(data.day)) {
              this.ctrl_state.selectedIndex = 3;
          }
          else {
              if (data.day == day) {
                  this.ctrl_state.selectedIndex = 1;
              }
              else if (data.day < day) {
                  this.ctrl_state.selectedIndex = 2;
              }
              else {
                  this.ctrl_state.selectedIndex = 0;
              }
          }
          if (!mgrSign.dataShowAdStatis[data.day]) {
              if (mgrGame.statisVideoShowByButton(this.button_fix, db.ADV_DB_ADVNAME.sign_fix_ad)) {
                  mgrSign.dataShowAdStatis[data.day] = true;
              }
          }
      }
      checkBagSize(scale) {
          let signDb = this.signDb;
          if (signDb) {
              return mgrHolyItem.notEnoughEmptyByItemId(signDb.item_id, signDb.item_num * scale);
          }
          return false;
      }
      on_click_button_fix() {
          if (this.checkBagSize(1))
              return;
          if (this.signDb) {
              mgrNetwork.callByNetwork(() => {
                  mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.sign_fix_ad, this.signDb.day);
              });
          }
      }
  }

  class CustomSignItemBig extends CustomSignItem {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://sign/CustomSignItemBig";
          this.exportNodeNames = {
              cc_label_day: "fgui.GBasicTextField",
              cc_item: "CustomItem",
              cc_button_fix: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      on_click_button_fix() {
          super.on_click_button_fix();
      }
  }

  class CustomSignWeek extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://sign/CustomSignWeek";
          this.exportNodeNames = {
              cc_label_week: "fgui.GBasicTextField",
              cc_item_1: "CustomSignItem",
              cc_item_2: "CustomSignItem",
              cc_item_3: "CustomSignItem",
              cc_item_4: "CustomSignItem",
              cc_item_5: "CustomSignItem",
              cc_item_6: "CustomSignItem",
              cc_item_7: "CustomSignItemBig",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(datas) {
          let data = datas[0];
          if (data) {
              this.label_week.text = data.week_name;
          }
          let index = 0;
          this.item_1.refresh(datas[index++]);
          this.item_2.refresh(datas[index++]);
          this.item_3.refresh(datas[index++]);
          this.item_4.refresh(datas[index++]);
          this.item_5.refresh(datas[index++]);
          this.item_6.refresh(datas[index++]);
          this.item_7.refresh(datas[index++]);
      }
  }

  class PanelSign extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "签到";
          this.sourceName = "ui://sign/PanelSign";
          this.bOpenAndCloseAnim = true;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_day_cur: "fgui.GBasicTextField",
              cc_label_day_fix: "fgui.GBasicTextField",
              cc_list_week: "fgui.GList",
              cc_button_get: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
              cc_ctrl_can_sign: "fgui.Controller",
          };
      }
      buildUi() {
          mgrSign.dataShowAdStatis = {};
          this.listWeek = new ListView(this.list_week, this, this.parsSignWeek, this.renderSignWeek);
          this.refreshList();
          this.initEvent();
          this.refresh();
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.sign_ad);
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.SIGN_UDPATE]: this.onSignUpdate.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.sign_ad) {
                      this.watchAdSuccess();
                  }
                  else if (e.advName == db.ADV_DB_ADVNAME.sign_fix_ad) {
                      mgrSign.sign(e.params, 1);
                  }
              },
          });
      }
      onSignUpdate() {
          this.refresh();
          this.listWeek.refresh();
      }
      refresh() {
          this.ctrl_can_sign.selectedIndex = mgrSign.canSign(mgrSign.day) ? 0 : 1;
          this.label_day_cur.text = mgrSign.day.toString();
          this.label_day_fix.text = mgrSign.calcNeedFixCount() + "天";
      }
      parsSignWeek(content, view) {
          content.view = view;
      }
      renderSignWeek(content, datas) {
          content.view.refresh(datas);
      }
      refreshList() {
          this.listWeek.setListData(db.get_sign_db_map());
          let signDb = mgrSign.findSignDbByDay(mgrSign.day);
          if (signDb) {
              this.listWeek.scrollToView(signDb.week - 1);
          }
      }
      getReward(scale = 1) {
          mgrSign.sign(mgrSign.day, scale);
      }
      watchAdSuccess() {
          this.getReward(2);
      }
      checkBagSize(scale) {
          let signDb = mgrSign.findSignDbByDay(mgrSign.day);
          if (signDb) {
              return mgrHolyItem.notEnoughEmptyByItemId(signDb.item_id, signDb.item_num * scale);
          }
          return false;
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_get() {
          if (this.checkBagSize(1))
              return;
          mgrNetwork.callByNetwork(() => {
              this.getReward();
          });
      }
      on_click_button_ad() {
          if (this.checkBagSize(2))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.sign_ad);
          });
      }
      on_click_button_giveupad() {
          this.closeWithTransition();
      }
  }

  class CustomSmelterHolyItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://smelter/CustomSmelterHolyItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.loader_icon.url = data.icon;
      }
  }

  class CustomSmelterPrice extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://smelter/CustomSmelterPrice";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_cur: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_enough: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemId, need) {
          if (itemId && need) {
              let curt = mgrGame.getItemCount(itemId);
              this.label_cur.text = curt.toString();
              this.label_max.text = "/" + need;
              this.loader_icon.url = mgrGame.getItemIcon(itemId);
              this.ctrl_enough.selectedIndex = curt >= need ? 0 : 1;
          }
      }
  }

  class CustomSmelterPrice1 extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://smelter/CustomSmelterPrice1";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_cur: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_enough: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemId, need) {
          if (itemId && need) {
              let curt = mgrGame.getItemCount(itemId);
              this.label_cur.text = curt.toString();
              this.label_max.text = "/" + need;
              this.loader_icon.url = mgrGame.getItemIcon(itemId);
              this.ctrl_enough.selectedIndex = curt >= need ? 0 : 1;
          }
      }
  }

  class CustomlSmelterForge extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "锻造";
          this.sourceName = "ui://smelter/CustomlSmelterForge";
          this.emptyItem = { item: null };
          this.lastSmeltTime = 0;
          this.exportNodeNames = {
              cc_item: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_button_item_1: "fgui.GButton",
              cc_button_item_2: "fgui.GButton",
              cc_feed: "fgui.GComponent",
              cc_progress_forge: "fgui.GProgressBar",
              cc_button_filter: "fgui.GButton",
              cc_button_put: "fgui.GButton",
              cc_button_smelt: "fgui.GButton",
              cc_lable_forge: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
              cc_list_quality: "fgui.GList",
              cc_ctrl_filter: "fgui.Controller",
              cc_forge: "fgui.GComponent",
              cc_price_1: "CustomSmelterPrice",
              cc_price_2: "CustomSmelterPrice",
              cc_button_start: "fgui.GButton",
              cc_button_cancel_forge: "ScaleButton",
              cc_button_auto_put: "ScaleButton",
              cc_node_effect: "fgui.GLoader",
              cc_forge_state: "fgui.Controller",
              cc_ctrl_auto: "fgui.Controller",
          };
      }
      onCreate() {
          mgrHolyItem.clearBagSelect();
          this.ctrlItem1Have = this.button_item_1.getController("item");
          this.ctrlItem2Have = this.button_item_2.getController("item");
          this.listQualityFilter = new ListView(this.list_quality, this, this.parsetFilterItem, this.renderFilterItem);
          this.listQualityFilter.setOnClickItem(this, this.onClickFilterItem);
          this.listItem = new ListView(this.list_item, this, this.parseHolyItem, this.renderHolyItem);
          this.listItem.setOnClickItem(this, this.onClickHolyItem);
          if (mgrSmelter.isSmeltExpFull()) {
              mgrSmelter.autoPutForge = false;
          }
          this.initEvent();
          this.refresh();
          this.refreshFilter();
          this.refreshFilterSelect();
          this.refreshHolyItem();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.SMELTER_SELECT_ITEM]: this.onSmelterSelectItem.bind(this),
              [MSG.SMELTER_BAG_SELECT_ITEMS]: this.onHolyItemSelectRefresh.bind(this),
              [MSG.SMELTER_FEED_ITEM]: this.onHolyItemChange.bind(this),
              [MSG.SMELTER_ITEM_SUC]: this.onSmelterItemSuc.bind(this),
              [BASE_MSG.ITEM_CHANGE]: this.onItemChange.bind(this),
              [MSG.SMELTER_AUTO_PUT_UPDATE]: this.refreshAutoPut.bind(this),
          });
      }
      setScene3DEffect(scene3d, camera) {
          this.scene3d = scene3d;
          this.camera = camera;
      }
      createEffect(scene3d, camera) {
          if (scene3d && camera) {
              let effectId = "166_ui_dz_glow";
              let effect = EffectFactory.create(effectId, scene3d);
              effect.followFguiNode(camera, this.node_effect, true);
          }
      }
      onItemChange() {
          this.refreshPrice();
      }
      onSmelterSelectItem(data) {
          switch (data.index) {
              case 1:
                  this.onSelectItemMain(data.itemDb);
                  break;
              case 2:
                  this.onSelectItemVice(data.itemDb);
                  break;
          }
      }
      onHolyItemSelectRefresh() {
          this.refreshHolyItem();
      }
      onHolyItemChange() {
          this.refreshHolyItem();
          this.refresh();
      }
      onSmelterItemSuc() {
          this.refresh();
      }
      parsetFilterItem(content, object) {
          content.title = object.getChild("title").asLabel;
      }
      renderFilterItem(content, data) {
          content.data = data;
          content.title.text = data.name;
          content.title.color = data.color;
      }
      onClickFilterItem(content) {
          this.ctrl_filter.selectedIndex = 0;
          mgrHolyItem.setFilterQuality(content.data.quality);
          this.refreshFilterSelect();
      }
      refreshFilter() {
          let listData = [];
          let qualistList = db.get_holy_item_quality_map();
          for (let item of qualistList) {
              listData.push(item);
          }
          listData.sort(this.sortQualityItem.bind(this));
          this.listQualityFilter.setListData(listData);
      }
      sortQualityItem(a, b) {
          return b.index - a.index;
      }
      refreshFilterSelect() {
          let qualityDb = db.get_holy_item_quality(mgrHolyItem.getFilterQuality());
          if (qualityDb) {
              this.button_filter.title = qualityDb.name;
              this.button_filter.titleColor = qualityDb.color;
          }
      }
      parseHolyItem(content, object, index) {
          content.quality = object.getController("quality");
          content.state = object.getController("state");
          content.select = object.getController("select");
          content.coinUnlock = object.getChild("coin_unlock").asLabel;
          content.starUnlock = object.getChild("star_unlock").asLabel;
          content.levelUnlock = object.getChild("level_unlock").asLabel;
          content.item = object.getChild("item");
          if (index < 5) {
              object.getTransition("idle").play();
              object.getTransition("in").play(null, 1, 0.125 * index);
          }
      }
      renderHolyItem(content, data) {
          let item = data.item;
          if (item && item.holyitem) {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
              content.item.refresh(item.holyitem);
          }
          else {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ADD;
          }
          content.data = data;
      }
      onClickHolyItem(content) {
          if (this.selectSlotContent) {
              this.selectSlotContent.select.selectedIndex = 0;
          }
          this.selectSlotContent = content;
          content.select.selectedIndex = 1;
          switch (content.state.selectedIndex) {
              case HOLY_ITEM_SLOT_STATE.ITEM:
              case HOLY_ITEM_SLOT_STATE.ADD:
                  Director.openPanel("PanelHolyItemChooseSmelter", { typeFilter: mgrSmelter.getItemTypeFilter() });
                  break;
          }
      }
      refreshHolyItem(listItem = null) {
          listItem = listItem || mgrHolyItem.getBagItems();
          let listData = [];
          let expAdd = 0;
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  listData.push({ item: item });
                  expAdd += item.holyitem.getExpSmelt();
              }
              else {
                  listData.push(this.emptyItem);
              }
          }
          listData.sort(this.sortListItem.bind(this));
          this.listItem.setListData(listData);
          this.refreshProgress(expAdd);
      }
      refreshAutoPut() {
          this.ctrl_auto.selectedIndex = mgrSmelter.autoPutForge ? 1 : 0;
      }
      sortListItem(a, b) {
          let score_a = a.item ? 100 : 0;
          let score_b = b.item ? 100 : 0;
          return score_b - score_a;
      }
      onSelectItemMain(itemDb) {
          mgrSmelter.IdMain = itemDb.id;
          this.refresh();
      }
      onSelectItemVice(itemDb) {
          mgrSmelter.IdVice = itemDb.id;
          this.refresh();
      }
      refresh() {
          let itemDbMain = db.get_holy_item_db_map()[mgrSmelter.IdMain];
          let itemDbVice = db.get_holy_item_db_map()[mgrSmelter.IdVice];
          if (itemDbMain) {
              this.button_item_1.icon = itemDbMain.icon;
              this.loader_icon.icon = mgrHolyItem.getHolyItemQualityIcon(EQUIP_QUALITY.RED);
              this.ctrlItem1Have.selectedIndex = 1;
          }
          else {
              this.ctrlItem1Have.selectedIndex = 0;
              this.loader_icon.icon = "";
          }
          if (itemDbVice) {
              this.button_item_2.icon = itemDbVice.icon;
              this.ctrlItem2Have.selectedIndex = 1;
          }
          else {
              this.ctrlItem2Have.selectedIndex = 0;
          }
          this.refreshProgress();
          this.forge_state.selectedIndex = mgrSmelter.isRunning() ? 1 : 0;
          this.refreshAutoPut();
          if (mgrSmelter.isSmeltExpFull()) {
              this.button_smelt.text = "锻 造";
          }
          else {
              this.button_smelt.text = "投 入";
          }
          this.refreshPrice();
      }
      refreshPrice() {
          let items = mgrSmelter.getSmeltItemNeed();
          this.price_1.refresh(items[0], items[1]);
          this.price_2.refresh(items[2], items[3]);
      }
      refreshProgress(expAdd = 0) {
          let percent = mgrSmelter.getSmletProgress(expAdd) * 100;
          if (percent <= 0) {
              this.progress_forge.value = percent;
          }
          else {
              this.progress_forge.tweenValue(percent, 0.1);
          }
          this.lable_forge.text = percent.toFixed(2) + "%";
      }
      checkCanChangeItem() {
          if (mgrSmelter.canChangeItemId()) {
              return false;
          }
          else {
              mgrTip.showMsgTip("熔炉已启动，不能更换圣物");
              return true;
          }
      }
      resetSmelt() {
          mgrSmelter.resetSmelt();
          this.refresh();
          this.refreshProgress();
      }
      feedItem() {
          let listItem = mgrHolyItem.getBagItems();
          let listData = [];
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  listData.push(item);
              }
          }
          mgrSmelter.feedItem(listData);
          return listData.length > 0;
      }
      onPageEnter() {
          this.refreshHolyItem();
      }
      on_click_button_cancel_forge() {
          mgrTip.alertPrompt("取消锻造将清空熔炼值，且不会退还【已投入熔炼的圣物】、【开启熔炉所需资源】，是否确认取消锻造？", null, () => {
              mgrNetwork.callByNetwork(() => {
                  this.resetSmelt();
              });
          });
      }
      on_click_button_item_1() {
          if (this.checkCanChangeItem())
              return;
          Director.openPanelWithSingleton("PanelSmelterSelectItem", { index: 1, selectId: mgrSmelter.IdVice });
      }
      on_click_button_item_2() {
          if (this.checkCanChangeItem())
              return;
          Director.openPanelWithSingleton("PanelSmelterSelectItem", { index: 2, selectId: mgrSmelter.IdMain });
      }
      on_click_button_start() {
          if (mgrSmelter.startSmelt()) {
              this.refresh();
          }
      }
      on_click_button_filter() {
      }
      on_click_button_put() {
          this.refreshHolyItem(mgrHolyItem.smelterAutoSelectByQuality(mgrSmelter.getSmeltExpNeed()));
      }
      on_click_button_smelt() {
          let curtTime = Utils.getTime();
          if (this.lastSmeltTime <= 0)
              this.lastSmeltTime = curtTime;
          if (curtTime < this.lastSmeltTime) {
              return;
          }
          mgrNetwork.callByNetwork(() => {
              if (mgrSmelter.isSmeltPreExpFull()) {
                  this.lastSmeltTime = curtTime + 1000;
                  this.createEffect(this.scene3d, this.camera);
                  Laya.timer.once(1000, this, this.feedItem);
              }
              else {
                  if (this.feedItem()) {
                      this.createEffect(this.scene3d, this.camera);
                  }
              }
          });
      }
      on_click_button_auto_put() {
          Director.openPanelWithSingleton("PanelSmelterAutoPut", { type: "forge" });
      }
  }

  class PanelHolyItemChooseSmelterLvup extends PanelHolyItemChoose {
      buildUi() {
          mgrHolyItem.clearBagSelect();
          this.itemExcept = this.context.itemExcept;
          this.typeFilter = this.context.typeFilter;
          this.initEvent();
          this.listSort = new ListView(this.list_sort, this, this.parseSortItem, this.renderSortItem);
          this.listSort.setOnClickItem(this, this.onClickSortItem);
          this.listSort.setListData([
              "默认排序",
              "品质排序",
              "强化等级排序",
              "种类排序",
          ]);
          this.listItem = new HolyItemListWash(this.list_item, this, this.onClickBagItem);
          this.listItem.setOnItemUseCallBack(this.onItemUseChange.bind(this));
          this.listItem.openUse = true;
          this.refresh(mgrHolyItem.sortType);
          this.com_holyitem.hideButton();
          this.label_title.text = "请选择升品的圣物";
      }
      dispose() {
          super.dispose();
          mgrHolyItem.clearBagSelect();
      }
      refresh(sortType) {
          let bagItems = mgrHolyItem.getBagItems4Lvup(sortType);
          let listData = [];
          for (let item of bagItems) {
              if (item != this.itemExcept)
                  listData.push(item);
          }
          this.listItem.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      onItemUseChange(content, use) {
          if (content) {
              Global.sendMsg(MSG.ITEM_QUALITY_LVUP_SELECT, content.data);
          }
      }
      onClickBagItem(content) {
          if (content.data) {
              let holyitem = content.data.holyitem;
              if (holyitem) {
                  let lastItem = this.com_holyitem.selectItem;
                  this.com_holyitem.refresh(content.data);
                  this.ctrl_detail.selectedIndex = 1;
                  if (lastItem && lastItem != content.data) {
                      lastItem.selected = false;
                      this.refresh(mgrHolyItem.sortType);
                  }
              }
          }
          return false;
      }
  }

  class PanelHolyItemChooseSmelterLvupFeed extends PanelHolyItemChoose {
      buildUi() {
          super.buildUi();
          this.ctrl_filter_show.selectedIndex = 0;
      }
      refresh(sortType) {
          let bagItems = mgrHolyItem.getBagItems4Feed(sortType, this.typeFilter);
          let listData = [];
          for (let item of bagItems) {
              if (item != this.itemExcept)
                  listData.push(item);
          }
          this.listItem.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      onItemUseChange(content, use) {
          Global.sendMsg(MSG.ITEM_QUALITY_LVUP_BAG_SELECT_ITEMS);
      }
      onClickBagItem(content) {
          if (content.data) {
              let holyitem = content.data.holyitem;
              if (holyitem) {
                  if (!content.data.selected) {
                      if (mgrSmelter.isSmeltLvupExpFull()) {
                          mgrTip.showMsgTip("熔炼值已满！");
                          return true;
                      }
                  }
                  this.com_holyitem.refresh(content.data);
                  this.ctrl_detail.selectedIndex = 1;
                  if (!content.data.selected && holyitem.isEquiped()) {
                      let name = holyitem.getEquipTowerName();
                      mgrTip.alertPrompt("该圣物已被" + name + "所装备，是否【确认作为锻造素材】？", "", () => {
                          content.data.selected = true;
                          this.refresh(mgrHolyItem.sortType);
                          this.onItemUseChange();
                      });
                      return true;
                  }
                  if (!content.data.selected && holyitem.isPreset()) {
                      mgrTip.alertPrompt("该圣物已被" + holyitem.getPresetNum() + "个方案预设，是否【确认作为锻造素材】？", "", () => {
                          content.data.selected = true;
                          this.refresh(mgrHolyItem.sortType);
                          this.onItemUseChange();
                      });
                      return true;
                  }
                  if (holyitem.lock) {
                      mgrTip.alertPrompt("该圣物已被锁定，请解锁后再试");
                      return true;
                  }
              }
          }
          return false;
      }
  }

  class CustomlSmelterLvup extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "升品";
          this.sourceName = "ui://smelter/CustomlSmelterLvup";
          this.emptyItem = { item: null };
          this.lastSmeltTime = 0;
          this.exportNodeNames = {
              cc_button_cancel_forge: "ScaleButton",
              cc_button_auto_put: "ScaleButton",
              cc_item: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_button_add: "fgui.GButton",
              cc_feed: "fgui.GComponent",
              cc_progress_forge: "fgui.GProgressBar",
              cc_button_filter: "fgui.GButton",
              cc_button_put: "fgui.GButton",
              cc_button_smelt: "fgui.GButton",
              cc_lable_forge: "fgui.GBasicTextField",
              cc_list_item: "fgui.GList",
              cc_list_quality: "fgui.GList",
              cc_ctrl_filter: "fgui.Controller",
              cc_lvup: "fgui.GComponent",
              cc_price_1: "CustomSmelterPrice",
              cc_price_2: "CustomSmelterPrice",
              cc_button_start: "fgui.GButton",
              cc_button_switch: "ScaleButton",
              cc_list_word: "fgui.GList",
              cc_have_item2: "fgui.Controller",
              cc_node_effect: "fgui.GLoader",
              cc_lvup_state: "fgui.Controller",
              cc_have_item: "fgui.Controller",
              cc_ctrl_auto: "fgui.Controller",
          };
      }
      onCreate() {
          this.initEvent();
          if (mgrSmelter.isSmeltLvupExpFull()) {
              mgrSmelter.autoPutLvup = false;
          }
          this.listAttr = new ListView(this.list_word, this, this.parseAttrItem, this.renderAttrItem);
          this.listQualityFilter = new ListView(this.list_quality, this, this.parsetFilterItem, this.renderFilterItem);
          this.listQualityFilter.setOnClickItem(this, this.onClickFilterItem);
          this.listItem = new ListView(this.list_item, this, this.parseHolyItem, this.renderHolyItem);
          this.listItem.setOnClickItem(this, this.onClickHolyItem);
          this.item.onClick(this, this.onClickSelectItem);
          this.refreshPrice();
          this.refresh(mgrSmelter.getLvupHolyItem());
          this.refreshFilter();
          this.refreshFilterSelect();
          this.refreshHolyItem();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.ITEM_QUALITY_LVUP_SELECT]: this.onItemQualityLvupSelect.bind(this),
              [MSG.ITEM_QUALITY_LVUP_SUC]: this.onItemQualityLvupSuc.bind(this),
              [MSG.ITEM_QUALITY_LVUP_BAG_SELECT_ITEMS]: this.onHolyItemSelectRefresh.bind(this),
              [MSG.ITEM_QUALITY_LVUP_FEED_ITEM]: this.onHolyItemQualityUpFeedItem.bind(this),
              [MSG.SMELTER_AUTO_PUT_UPDATE]: this.refreshAutoPut.bind(this),
          });
      }
      onItemQualityLvupSelect(data) {
          if (data && data.selected && data.holyitem) {
              this.refresh(data);
          }
          else {
              this.refresh(null);
          }
      }
      onItemQualityLvupSuc() {
          this.selectItem = null;
          this.refresh(this.selectItem);
          this.refreshHolyItem();
      }
      onHolyItemSelectRefresh() {
          this.refreshHolyItem();
      }
      onHolyItemQualityUpFeedItem() {
          this.refreshHolyItem();
      }
      parseAttrItem(content, object) {
          content.root = object;
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          content.quality = object.getController("quality");
          content.perfect = object.getChild("perfect").asTextField;
      }
      renderAttrItem(content, data, index) {
          FguiHelper.playIdleAndIn(content.root, index, 0, 0.05);
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
              let v = data.v.toFixed(1);
              let attrDb = db.get_holy_item_attr_base_map()[data.k];
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.value.text = "+" + v + "%";
                  }
                  else {
                      content.value.text = "+" + v;
                  }
              }
              else {
                  content.value.text = "+" + v + "%";
              }
              content.quality.selectedIndex = data.q || 0;
              let wordDb = mgrSmelter.findWordDb(data.k);
              if (wordDb) {
                  let values = wordDb["v" + (data.q + 1)] || [];
                  let max = values[1] || 0;
                  content.perfect.text = "(" + Math.floor(data.v_base / max * 100) + "%)";
              }
          }
      }
      refreshAttr(attr) {
          this.listAttr.setListData(attr);
      }
      setScene3DEffect(scene3d, camera) {
          this.scene3d = scene3d;
          this.camera = camera;
      }
      createEffect(scene3d, camera) {
          if (scene3d && camera) {
              let effectId = "166_ui_xl_glow";
              let effect = EffectFactory.create(effectId, scene3d);
              effect.followFguiNode(camera, this.node_effect, true);
          }
      }
      parsetFilterItem(content, object) {
          content.title = object.getChild("title").asLabel;
      }
      renderFilterItem(content, data) {
          content.data = data;
          content.title.text = data.name;
          content.title.color = data.color;
      }
      onClickFilterItem(content) {
          this.ctrl_filter.selectedIndex = 0;
          mgrHolyItem.setFilterQuality(content.data.quality);
          this.refreshFilterSelect();
      }
      refreshFilter() {
          let listData = [];
          let qualistList = db.get_holy_item_quality_map();
          for (let item of qualistList) {
              if (item.quality <= EQUIP_QUALITY.ORANGE)
                  listData.push(item);
          }
          listData.sort(this.sortQualityItem.bind(this));
          this.listQualityFilter.setListData(listData);
      }
      sortQualityItem(a, b) {
          return b.index - a.index;
      }
      refreshFilterSelect() {
          let qualityDb = db.get_holy_item_quality(mgrHolyItem.getFilterQuality(EQUIP_QUALITY.ORANGE));
          if (qualityDb) {
              this.button_filter.title = qualityDb.name;
              this.button_filter.titleColor = qualityDb.color;
          }
      }
      parseHolyItem(content, object, index) {
          content.quality = object.getController("quality");
          content.state = object.getController("state");
          content.select = object.getController("select");
          content.coinUnlock = object.getChild("coin_unlock").asLabel;
          content.starUnlock = object.getChild("star_unlock").asLabel;
          content.levelUnlock = object.getChild("level_unlock").asLabel;
          content.item = object.getChild("item");
          if (index < 5) {
              object.getTransition("idle").play();
              object.getTransition("in").play(null, 1, 0.125 * index);
          }
      }
      renderHolyItem(content, data) {
          let item = data.item;
          if (item && item.holyitem) {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ITEM;
              content.item.refresh(item.holyitem);
          }
          else {
              content.state.selectedIndex = HOLY_ITEM_SLOT_STATE.ADD;
          }
          content.data = data;
      }
      onClickHolyItem(content) {
          if (this.selectSlotContent) {
              this.selectSlotContent.select.selectedIndex = 0;
          }
          this.selectSlotContent = content;
          content.select.selectedIndex = 1;
          switch (content.state.selectedIndex) {
              case HOLY_ITEM_SLOT_STATE.ITEM:
              case HOLY_ITEM_SLOT_STATE.ADD:
                  Director.openPanelByClass(PanelHolyItemChooseSmelterLvupFeed, "PanelHolyItemChooseSmelterLvupFeed", { itemExcept: this.selectItem, typeFilter: mgrSmelter.getQualityUpItemTypeFilter() });
                  break;
          }
      }
      onClickSelectItem() {
          if (this.selectItem && this.selectItem.holyitem) {
              Director.openPanelWithSingleton("PanelHolyitemInfo", { item: this.selectItem.holyitem, point: this.item.localToGlobal(this.item.width * 0.5, this.item.height * 0.5) });
          }
      }
      refreshHolyItem(listItem = null) {
          listItem = listItem || mgrHolyItem.getBagItems();
          let listData = [];
          let expAdd = 0;
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  listData.push({ item: item });
                  expAdd += item.holyitem.getExpSmelt();
              }
              else {
                  listData.push(this.emptyItem);
              }
          }
          listData.sort(this.sortListItem.bind(this));
          this.listItem.setListData(listData);
          this.refreshProgress(expAdd);
      }
      refreshProgress(expAdd = 0) {
          let percent = mgrSmelter.getSmeltQualityUpProgress(expAdd) * 100;
          if (percent <= 0) {
              this.progress_forge.value = percent;
          }
          else {
              this.progress_forge.tweenValue(percent, 0.1);
          }
          this.lable_forge.text = percent.toFixed(2) + "%";
      }
      sortListItem(a, b) {
          let score_a = a.item ? 100 : 0;
          let score_b = b.item ? 100 : 0;
          return score_b - score_a;
      }
      refresh(selectItem) {
          if (selectItem && selectItem.holyitem) {
              this.selectItem = selectItem;
              this.loader_icon.url = selectItem.holyitem.getIcon();
              this.have_item.selectedIndex = 1;
              this.refreshAttr(selectItem.holyitem.attr);
          }
          else {
              this.have_item.selectedIndex = 0;
          }
          this.have_item2.selectedIndex = this.have_item.selectedIndex;
          this.refreshPrice();
          this.refershState();
          this.refreshProgress();
          this.refreshAutoPut();
          if (mgrSmelter.isSmeltLvupExpFull()) {
              this.button_smelt.text = "升 品";
          }
          else {
              this.button_smelt.text = "投 入";
          }
      }
      refershState() {
          this.lvup_state.selectedIndex = mgrSmelter.isSmeltQualityUpRunning() ? 1 : 0;
      }
      refreshPrice() {
          let items = mgrSmelter.getSmeltQualityUpItemNeed();
          this.price_1.refresh(items[0], items[1]);
          this.price_2.refresh(items[2], items[3]);
      }
      refreshAutoPut() {
          this.ctrl_auto.selectedIndex = mgrSmelter.autoPutLvup ? 1 : 0;
      }
      openChoose() {
          Director.openPanelWithSingletonByClass(PanelHolyItemChooseSmelterLvup, "PanelHolyItemChooseSmelterLvup");
      }
      feedItem() {
          let listItem = mgrHolyItem.getBagItems();
          let listData = [];
          for (let i = 0; i < listItem.length; i++) {
              let item = listItem[i];
              if (item.holyitem && item.selected) {
                  listData.push(item);
              }
          }
          mgrSmelter.feedItem4Lvup(listData);
          return listData.length > 0;
      }
      resetSmeltQualityUp() {
          mgrHolyItem.clearBagSelect();
          this.selectItem = null;
          mgrSmelter.resetSmeltQualityUp();
          this.refresh(this.selectItem);
          this.refreshProgress();
          this.refreshHolyItem();
      }
      onPageEnter() {
          this.refreshHolyItem();
      }
      on_click_button_cancel_forge() {
          mgrTip.alertPrompt("取消升品将清空熔炼值，且不会退还【已投入熔炼的圣物】、【开启熔炉所需资源】，是否确认取消升品？", null, () => {
              mgrNetwork.callByNetwork(() => {
                  this.resetSmeltQualityUp();
              });
          });
      }
      on_click_button_filter() {
      }
      on_click_button_put() {
          this.refreshHolyItem(mgrHolyItem.smelterQualityUpAutoSelectByQuality(mgrSmelter.getSmeltLvupExpNeed(), this.selectItem));
      }
      on_click_button_smelt() {
          let curtTime = Utils.getTime();
          if (this.lastSmeltTime <= 0)
              this.lastSmeltTime = curtTime;
          if (curtTime < this.lastSmeltTime) {
              return;
          }
          mgrNetwork.callByNetwork(() => {
              if (mgrSmelter.isSmeltQualityPreExpFull()) {
                  this.lastSmeltTime = curtTime + 1000;
                  this.createEffect(this.scene3d, this.camera);
                  Laya.timer.once(1000, this, this.feedItem);
              }
              else {
                  if (this.feedItem()) {
                      this.createEffect(this.scene3d, this.camera);
                  }
              }
          });
      }
      on_click_button_start() {
          if (this.selectItem && mgrSmelter.startSmelt4QualiytUp(this.selectItem.holyitem)) {
              this.refershState();
          }
      }
      on_click_button_add() {
          this.openChoose();
      }
      on_click_button_switch() {
          this.openChoose();
      }
      on_click_button_auto_put() {
          Director.openPanelWithSingleton("PanelSmelterAutoPut", { type: "lvup" });
      }
  }

  class PanelHolyItemChooseSmelterRebuild extends PanelHolyItemChoose {
      buildUi() {
          mgrHolyItem.clearBagSelect();
          super.buildUi();
          this.ctrl_filter_show.selectedIndex = 0;
          this.label_title.text = "请选择重铸的圣物";
      }
      dispose() {
          super.dispose();
          mgrHolyItem.clearBagSelect();
      }
      refresh(sortType) {
          let bagItems = mgrHolyItem.getBagItemsByQuality(sortType, EQUIP_QUALITY.RED, false);
          let listData = [];
          for (let item of bagItems) {
              if (item != this.itemExcept)
                  listData.push(item);
          }
          this.listItem.setListData(listData);
          this.button_sort.title = this.listSort.getListData()[sortType];
      }
      onItemUseChange(content, use) {
          if (content) {
              Global.sendMsg(MSG.REBUILD_SELECT_ITEM, content.data);
          }
      }
      onClickBagItem(content) {
          if (content.data) {
              let holyitem = content.data.holyitem;
              if (holyitem) {
                  let lastItem = this.com_holyitem.selectItem;
                  this.com_holyitem.refresh(content.data);
                  this.ctrl_detail.selectedIndex = 1;
                  if (lastItem && lastItem != content.data) {
                      lastItem.selected = false;
                      this.refresh(mgrHolyItem.sortType);
                  }
              }
          }
          return false;
      }
  }

  class CustomlSmelterRebuild extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "重铸";
          this.sourceName = "ui://smelter/CustomlSmelterRebuild";
          this.exportNodeNames = {
              cc_button_switch: "ScaleButton",
              cc_item: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_price_1: "CustomSmelterPrice1",
              cc_price_2: "CustomSmelterPrice1",
              cc_button_wash: "fgui.GButton",
              cc_button_add: "fgui.GButton",
              cc_label_desc: "fgui.GBasicTextField",
              cc_list_attr: "fgui.GList",
              cc_node_effect: "fgui.GLoader",
              cc_have_item: "fgui.Controller",
              cc_trans_wash_item: "fgui.Transition",
          };
      }
      onCreate() {
          mgrHolyItem.clearBagSelect();
          this.have_item.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.listAttr = new ListView(this.list_attr, this, this.parseAttrItem, this.renderAttrItem);
          this.initEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.REBUILD_SELECT_ITEM]: this.onRebuildSelectItem.bind(this),
              [MSG.REBUILD_ITEM_SUC]: this.onRebuildItemSuc.bind(this),
          });
      }
      onRebuildSelectItem(data) {
          if (data) {
              this.refresh(data.holyitem);
          }
          this.have_item.selectedIndex = data.selected ? 1 : 0;
      }
      onRebuildItemSuc() {
      }
      onStateChange() {
          switch (this.have_item.selectedIndex) {
              case 1:
                  this.trans_wash_item.play();
                  break;
          }
      }
      setScene3DEffect(scene3d, camera) {
          this.scene3d = scene3d;
          this.camera = camera;
      }
      createEffect(scene3d, camera) {
          if (scene3d && camera) {
              let effectId = "166_ui_xl_glow";
              let effect = EffectFactory.create(effectId, scene3d);
              effect.followFguiNode(camera, this.node_effect, true);
          }
      }
      parseAttrItem(content, object, index) {
          content.root = object;
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          content.quality = object.getController("quality");
          content.perfect = object.getChild("perfect").asTextField;
          content.lock = object.getController("lock");
          FguiHelper.playIdleAndIn(content.root, index, 0, 0.05);
      }
      renderAttrItem(content, data, index) {
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
              let v = data.v.toFixed(1);
              let attrDb = db.get_holy_item_attr_base_map()[data.k];
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.value.text = "+" + v + "%";
                  }
                  else {
                      content.value.text = "+" + v;
                  }
              }
              else {
                  content.value.text = "+" + v + "%";
              }
              content.quality.selectedIndex = data.q || 0;
              content.lock.selectedIndex = data.q == EQUIP_QUALITY.RED ? 0 : 1;
              if (data.q == EQUIP_QUALITY.RED) {
                  FguiHelper.playIdleAndIn(content.root, 0, 0, 0.05);
              }
              let wordDb = mgrSmelter.findWordDb(data.k);
              if (wordDb) {
                  let values = wordDb["v" + (data.q + 1)] || [];
                  let max = values[1] || 0;
                  content.perfect.text = "(" + Math.floor(data.v_base / max * 100) + "%)";
              }
          }
      }
      refreshAttr(attr) {
          this.listAttr.setListData(attr);
      }
      refresh(holyitem) {
          if (!holyitem)
              return;
          this.holyitem = holyitem;
          this.loader_icon.url = holyitem.getIcon();
          this.label_desc.text = "        " + holyitem.getDesc();
          this.refreshAttr(holyitem.attr);
          this.refershPrice();
      }
      refershPrice() {
          let items = mgrSmelter.getRebuildItemNeed();
          this.price_1.refresh(items[0], items[1]);
          this.price_2.refresh(items[2], items[3]);
          let itemId3 = items[4];
          let itemCn3 = items[5];
          if (itemId3 && itemCn3) {
              this.button_wash.icon = mgrGame.getItemIcon(itemId3);
              this.button_wash.title = itemCn3.toString();
          }
      }
      openChoose() {
          Director.openPanelWithSingletonByClass(PanelHolyItemChooseSmelterRebuild, "PanelHolyItemChooseSmelterRebuild");
      }
      onPageEnter() {
      }
      on_click_button_switch() {
          this.openChoose();
      }
      on_click_button_wash() {
          if (this.holyitem) {
              mgrNetwork.callByNetwork(() => {
                  if (mgrSmelter.rebuildItem(this.holyitem)) {
                      this.createEffect(this.scene3d, this.camera);
                      this.refresh(this.holyitem);
                  }
              });
          }
      }
      on_click_button_add() {
          this.openChoose();
      }
  }

  class CustomlSmelterWash extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "洗炼";
          this.sourceName = "ui://smelter/CustomlSmelterWash";
          this.exportNodeNames = {
              cc_button_switch: "ScaleButton",
              cc_label_desc1: "fgui.GBasicTextField",
              cc_label_desc2: "fgui.GBasicTextField",
              cc_item: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_price_1: "CustomSmelterPrice1",
              cc_price_2: "CustomSmelterPrice1",
              cc_button_wash: "fgui.GButton",
              cc_button_add: "fgui.GButton",
              cc_list_attr: "fgui.GList",
              cc_node_effect: "fgui.GLoader",
              cc_forge_state: "fgui.Controller",
              cc_have_item: "fgui.Controller",
              cc_trans_wash_item: "fgui.Transition",
          };
      }
      onCreate() {
          mgrHolyItem.clearBagSelect();
          this.have_item.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.listAttr = new ListView(this.list_attr, this, this.parseAttrItem, this.renderAttrItem);
          this.initEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.WASH_SELECT_ITEM]: this.onWashSelectItem.bind(this),
              [MSG.WASH_ITEM_SUC]: this.onWashItemSuc.bind(this),
          });
      }
      onWashSelectItem(data) {
          if (data) {
              this.refresh(data.holyitem);
          }
          this.have_item.selectedIndex = data.selected ? 1 : 0;
      }
      onWashItemSuc() {
      }
      onStateChange() {
          switch (this.have_item.selectedIndex) {
              case 1:
                  this.trans_wash_item.play();
                  break;
          }
      }
      setScene3DEffect(scene3d, camera) {
          this.scene3d = scene3d;
          this.camera = camera;
      }
      createEffect(scene3d, camera) {
          if (scene3d && camera) {
              let effectId = "166_ui_xl_glow";
              let effect = EffectFactory.create(effectId, scene3d);
              effect.followFguiNode(camera, this.node_effect, true);
          }
      }
      parseAttrItem(content, object) {
          content.root = object;
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          content.quality = object.getController("quality");
          content.perfect = object.getChild("perfect").asTextField;
      }
      renderAttrItem(content, data, index) {
          FguiHelper.playIdleAndIn(content.root, index, 0, 0.05);
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
              let v = data.v.toFixed(1);
              let attrDb = db.get_holy_item_attr_base_map()[data.k];
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.value.text = "+" + v + "%";
                  }
                  else {
                      content.value.text = "+" + v;
                  }
              }
              else {
                  content.value.text = "+" + v + "%";
              }
              content.quality.selectedIndex = data.q || 0;
              let wordDb = mgrSmelter.findWordDb(data.k);
              if (wordDb) {
                  let values = wordDb["v" + (data.q + 1)] || [];
                  let max = values[1] || 0;
                  content.perfect.text = "(" + Math.floor(data.v_base / max * 100) + "%)";
              }
          }
      }
      refreshAttr(attr) {
          this.listAttr.setListData(attr);
      }
      refresh(holyitem) {
          if (!holyitem)
              return;
          this.holyitem = holyitem;
          this.loader_icon.url = holyitem.getIcon();
          this.label_desc1.text = "        " + holyitem.getDescMain();
          this.label_desc2.text = "        " + holyitem.getDescVice();
          this.refreshAttr(holyitem.attr);
          this.refershPrice();
      }
      refershPrice() {
          let items = mgrSmelter.getWashItemNeed();
          this.price_1.refresh(items[0], items[1]);
          this.price_2.refresh(items[2], items[3]);
          let itemId3 = items[4];
          let itemCn3 = items[5];
          if (itemId3 && itemCn3) {
              this.button_wash.icon = mgrGame.getItemIcon(itemId3);
              this.button_wash.title = itemCn3.toString();
          }
      }
      openChoose() {
          Director.openPanelWithSingleton("PanelHolyItemChooseWash");
      }
      onPageEnter() {
      }
      on_click_button_switch() {
          this.openChoose();
      }
      on_click_button_wash() {
          if (this.holyitem) {
              mgrNetwork.callByNetwork(() => {
                  if (mgrSmelter.waskItem(this.holyitem)) {
                      this.createEffect(this.scene3d, this.camera);
                      this.refresh(this.holyitem);
                  }
              });
          }
      }
      on_click_button_add() {
          this.openChoose();
      }
  }

  class PanelSmelter extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "造物熔炼";
          this.sourceName = "ui://smelter/PanelSmelter";
          this.panelStyle = 0;
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_com_forge: "CustomlSmelterForge",
              cc_com_wash: "CustomlSmelterWash",
              cc_com_lvup: "CustomlSmelterLvup",
              cc_com_rebuild: "CustomlSmelterRebuild",
              cc_button_forge: "fgui.GButton",
              cc_button_wash: "fgui.GButton",
              cc_button_lvup: "fgui.GButton",
              cc_button_rebuild: "fgui.GButton",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.ctrl_page.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.onStateChange();
      }
      dispose() {
          super.dispose();
      }
      onAwake() {
          this.createScene3DEffect(99);
          this.com_forge.setScene3DEffect(this.scene3DEffect, this.cameraEffect);
          this.com_wash.setScene3DEffect(this.scene3DEffect, this.cameraEffect);
          this.com_lvup.setScene3DEffect(this.scene3DEffect, this.cameraEffect);
          this.com_rebuild.setScene3DEffect(this.scene3DEffect, this.cameraEffect);
      }
      onStateChange() {
          mgrHolyItem.clearBagSelect();
          switch (this.ctrl_page.selectedIndex) {
              case 0:
                  this.com_forge.onPageEnter();
                  break;
              case 1:
                  this.com_wash.onPageEnter();
                  break;
              case 2:
                  this.com_lvup.onPageEnter();
                  break;
              case 3:
                  this.com_rebuild.onPageEnter();
                  break;
          }
      }
      on_click_button_forge() {
      }
      on_click_button_wash() {
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_lvup() {
      }
      on_click_button_rebuild() {
      }
  }

  class PanelSmelterAutoPut extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "自动投入";
          this.sourceName = "ui://smelter/PanelSmelterAutoPut";
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_button_start: "fgui.GButton",
              cc_button_stop: "fgui.GButton",
              cc_button_giveup: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
          };
      }
      buildUi() {
          mgrGame.statisVideoShowByButton(this.button_start, db.ADV_DB_ADVNAME.smelt_auto_put);
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.smelt_auto_put) {
                      this.start();
                  }
              },
          });
          this.refresh();
      }
      dispose() {
          super.dispose();
          Global.sendMsg(MSG.SMELTER_AUTO_PUT_UPDATE, this.context.type);
      }
      refresh() {
          switch (this.context.type) {
              case "forge":
                  this.ctrl_state.selectedIndex = mgrSmelter.autoPutForge ? 1 : 0;
                  break;
              case "lvup":
                  this.ctrl_state.selectedIndex = mgrSmelter.autoPutLvup ? 1 : 0;
                  break;
          }
      }
      start() {
          switch (this.context.type) {
              case "forge":
                  mgrSmelter.autoPutForge = true;
                  break;
              case "lvup":
                  mgrSmelter.autoPutLvup = true;
                  break;
          }
          this.closeWithTransition();
      }
      stop() {
          switch (this.context.type) {
              case "forge":
                  mgrSmelter.autoPutForge = false;
                  break;
              case "lvup":
                  mgrSmelter.autoPutLvup = false;
                  break;
          }
          this.closeWithTransition();
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_start() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.smelt_auto_put);
      }
      on_click_button_stop() {
          this.stop();
      }
      on_click_button_giveup() {
          this.closeWithTransition();
      }
  }

  class PanelSmelterQualityUpSuc extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "升品成功";
          this.sourceName = "ui://smelter/PanelSmelterQualityUpSuc";
          this.timeOpen = 0;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_list_word_old: "fgui.GList",
              cc_list_word_new: "fgui.GList",
              cc_node_effect: "fgui.GLoader",
              cc_loader_item: "fgui.GLoader",
          };
      }
      buildUi() {
          this.timeOpen = Utils.getTime();
          this.holyitem = this.context.holyItem;
          this.listAttrOld = new ListView(this.list_word_old, this, this.parseAttrItem, this.renderAttrItem);
          this.listAttrNew = new ListView(this.list_word_new, this, this.parseAttrItem, this.renderAttrItem);
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
      }
      dispose() {
          super.dispose();
      }
      onAwake() {
          this.createScene3DEffect(4);
          let effectId = "166_ui_loop_star_02_red";
          let effect = EffectFactory.create(effectId, this.scene3DEffect);
          effect.followFguiNode(this.cameraEffect, this.node_effect);
          this.refresh();
      }
      createEffect(node_effect) {
          if (node_effect) {
              let effectId = "166_ui_shengpin_glow";
              let effect = EffectFactory.create(effectId, this.scene3DEffect);
              effect.followFguiNode(this.cameraEffect, node_effect, true, node_effect.width / 2, node_effect.height / 2);
          }
      }
      parseAttrItem(content, object, index) {
          content.bg = object.getChild("bg").asLoader;
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          content.quality = object.getController("quality");
          FguiHelper.playIdleAndIn(object, index, 0.3, 0.05);
      }
      renderAttrItem(content, data) {
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
              let v = data.v.toFixed(1);
              let attrDb = db.get_holy_item_attr_base_map()[data.k];
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.value.text = "+" + v + "%";
                  }
                  else {
                      content.value.text = "+" + v;
                  }
              }
              else {
                  content.value.text = "+" + v + "%";
              }
              content.quality.selectedIndex = data.q || 0;
              if (content.quality.selectedIndex == EQUIP_QUALITY.RED) {
                  Laya.timer.once(500, this, this.createEffect, [content.bg]);
              }
          }
      }
      onClickBackground() {
          let passTime = Utils.getTime() - this.timeOpen;
          if (passTime >= 1000) {
              this.closeWithTransition();
          }
      }
      refresh() {
          let holyitem = this.holyitem;
          if (!this.holyitem)
              return;
          this.listAttrOld.setListData(this.context.oldAttr || []);
          this.listAttrNew.setListData(this.context.newAttr || []);
          this.loader_item.url = holyitem.getIcon();
      }
  }

  class PanelSmelterSelectItem extends PanelBase {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://smelter/PanelSmelterSelectItem";
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_list_item: "fgui.GList",
          };
      }
      buildUi() {
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.listItem = new ListView(this.list_item, this, this.parseHolyItem, this.renderHolyItem);
          this.listItem.setOnClickItem(this, this.onClickHolyItem);
          this.refreshItemList();
      }
      dispose() {
          super.dispose();
      }
      onClickBackground() {
          this.closeWithTransition();
      }
      parseHolyItem(content, view, index) {
          content.view = view;
      }
      renderHolyItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
      }
      onClickHolyItem(content) {
          Global.sendMsg(MSG.SMELTER_SELECT_ITEM, { index: this.context.index, itemDb: content.data });
          this.closeWithTransition();
      }
      refreshItemList() {
          let selectId = this.context.selectId;
          let towerDbMap = db.get_holy_item_db_map();
          let listData = [];
          for (let key in towerDbMap) {
              let data = db.get_holy_item_db(key);
              if (data.smelt && data.id != selectId) {
                  listData.push(data);
              }
          }
          this.listItem.setListData(listData);
      }
  }

  class PanelSmelterSuc extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "锻造成功";
          this.sourceName = "ui://smelter/PanelSmelterSuc";
          this.timeOpen = 0;
          this.exportNodeNames = {
              cc_layer_full: "fgui.GComponent",
              cc_node_effect: "fgui.GLoader",
              cc_loader_item: "fgui.GLoader",
              cc_label_desc1: "fgui.GBasicTextField",
              cc_label_desc2: "fgui.GBasicTextField",
              cc_list_word: "fgui.GList",
          };
      }
      buildUi() {
          this.timeOpen = Utils.getTime();
          this.holyitem = this.context;
          this.listAttr = new ListView(this.list_word, this, this.parseAttrItem, this.renderAttrItem);
          this.layer_full.makeFullScreen();
          this.layer_full.onClick(this, this.onClickBackground);
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      onAwake() {
          this.createScene3DEffect(0);
          let effectId = "166_ui_loop_star_02_red";
          let effect = EffectFactory.create(effectId, this.scene3DEffect);
          effect.followFguiNode(this.cameraEffect, this.node_effect);
      }
      loadEffect() {
      }
      parseAttrItem(content, object, index) {
          content.icon = object.getChild("icon").asLoader;
          content.name = object.getChild("name").asTextField;
          content.value = object.getChild("value").asTextField;
          content.quality = object.getController("quality");
          FguiHelper.playIdleAndIn(object, index, 0.3, 0.05);
      }
      renderAttrItem(content, data) {
          let baseAttrDb = db.get_attr_base(data.k);
          if (baseAttrDb) {
              content.icon.url = baseAttrDb.icon;
              content.name.text = baseAttrDb.name;
              let v = data.v.toFixed(1);
              let attrDb = db.get_holy_item_attr_base_map()[data.k];
              if (attrDb) {
                  if (attrDb.percent_value) {
                      content.value.text = "+" + v + "%";
                  }
                  else {
                      content.value.text = "+" + v;
                  }
              }
              else {
                  content.value.text = "+" + v + "%";
              }
              content.quality.selectedIndex = data.q || 0;
          }
      }
      refreshAttr(attr) {
          this.listAttr.setListData(attr);
      }
      onClickBackground() {
          let passTime = Utils.getTime() - this.timeOpen;
          if (passTime >= 1000) {
              this.closeWithTransition();
          }
      }
      refresh() {
          let holyitem = this.holyitem;
          if (!this.holyitem)
              return;
          this.label_desc1.text = "        " + holyitem.getDescMain();
          this.label_desc2.text = "        " + holyitem.getDescVice();
          this.refreshAttr(holyitem.attr);
          this.loader_item.url = holyitem.getIcon();
      }
  }

  class PanelSplash extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "splash界面";
          this.sourceName = "ui://splash/PanelSplash";
          this.panelStyle = 1;
          this.bAutoRemovePackage = true;
          this.ageTip = "";
          this.exportNodeNames = {
              cc_loader_spine: "fgui.GLoader",
              cc_label_licenceinfo: "fgui.GBasicTextField",
              cc_label_version: "fgui.GBasicTextField",
              cc_button_age_tips: "fgui.GButton",
              cc_button_setting: "fgui.GButton",
              cc_button_notice: "fgui.GButton",
              cc_button_qq: "fgui.GButton",
              cc_licenceInfo: "fgui.Controller",
          };
      }
      buildUi() {
          mgrTime.checkTime();
          this.resNode.makeFullScreen();
          this.resNode.onClick(this, this.onClickBackGround);
          if (mgrGame.vNotice != db.cop_db.notice_version) {
              Director.openPanelWithSingleton("PanelNotice");
          }
          CopHelper.updateButtonVisible(this.button_qq, mgrSdk.numQQGroup);
          CopHelper.updateButtonVisible(this.button_age_tips, !mgrNative.isHtml5Platform());
          Global.registerListeners(this, {
              [BASE_MSG.SDK_BASE_CHANNEL_INFO_CHANGED]: this.refreshLicenceInfo.bind(this),
          });
          this.refreshLicenceInfo();
          this.loadSpine();
          this.label_version.text = GameGlobal.version + "." + this.getPID();
      }
      getPID() {
          let path_info = window["PATCH_INFO"] || {};
          return path_info.P_ID || "0";
      }
      dispose() {
          this.clearSpine();
          super.dispose();
      }
      refreshLicenceInfo() {
          let baseChannelInfo = mgrSdk.getBaseChannelInfo();
          console.warn("PanelSplash.refreshLicenceInfo", baseChannelInfo);
          if (!baseChannelInfo) {
              this.licenceInfo && this.licenceInfo.setSelectedIndex(0);
          }
          else {
              if (baseChannelInfo.licenceInfo && baseChannelInfo.licenceInfo != "") {
                  this.licenceInfo && this.licenceInfo.setSelectedIndex(1);
                  this.label_licenceinfo.text = baseChannelInfo.licenceInfo;
              }
              else {
                  this.licenceInfo && this.licenceInfo.setSelectedIndex(0);
              }
              this.ageTip = baseChannelInfo.ageLevelInfo;
              CopHelper.updateButtonVisible(this.button_age_tips, baseChannelInfo.isShowAgeLevelInfo);
          }
      }
      onClickBackGround() {
          if (!mgrTime.isReady()) {
              GameStatistics.statisCommonEvent(1110);
              Director.openPanelWithSingleton("PanelDialogTip", { title: "提示", desc: "登录游戏失败，请保持网络通畅！", confirmText: "确定" });
              return;
          }
          if (mgrTime.isChangeTime()) {
              Director.openPanelWithSingleton("PanelDialogTip", { title: "提示", desc: "检测到时间修改，无法正常登录游戏！", confirmText: "确定" });
              return;
          }
          if (mgrGame.isPirate) {
              mgrGame.openPirateUI();
              return;
          }
          Director.runScene(SceneGame, "PanelLoadingGame");
      }
      loadSpine() {
          this.spine = Spine.create("fengmian");
          if (this.spine) {
              this.loader_spine.displayObject.addChild(this.spine);
              this.spine.playAnimation("come", false, () => {
                  this.spine.playAnimation("idle", true);
              });
          }
      }
      clearSpine() {
          if (this.spine) {
              this.spine.destroyAndClear();
              this.spine = null;
          }
      }
      on_click_button_age_tips() {
          Director.openPanelWithSingleton("PanelAgeTip8", { tip: this.ageTip });
      }
      on_click_button_setting() {
          Director.openPanelWithSingleton("PanelSetting");
      }
      on_click_button_notice() {
          Director.openPanelWithSingleton("PanelNotice");
      }
      on_click_button_qq() {
          mgrSdk.joinQqGroup();
      }
  }

  class CustomStatisItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://statis/CustomStatisItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_com_star: "fgui.GComponent",
              cc_ctrl_star: "fgui.Controller",
              cc_progress_dps: "fgui.GProgressBar",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_dps: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data, damageMax) {
          let towerDb = db.get_tower_db(data.id);
          if (towerDb) {
              this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
              this.ctrl_star.selectedIndex = mgrTower.getTowerStar(towerDb.id);
              this.loader_icon.icon = towerDb.icon_small;
              if (damageMax) {
                  this.progress_dps.value = data.damage / damageMax * 100;
              }
              else {
                  this.progress_dps.value = 0;
              }
              this.label_name.text = towerDb.name;
              this.com_star.visible = !towerDb.main;
          }
          this.label_dps.text = data.damage.toString();
      }
  }

  class PanelGameStatis extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "伤害统计";
          this.bAutoRemovePackage = true;
          this.sourceName = "ui://statis/PanelGameStatis";
          this.bOpenAndCloseAnim = true;
          this.damageMax = 0;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_list_history: "fgui.GList",
              cc_list_item: "fgui.GList",
              cc_ctrl_none: "fgui.Controller",
              cc_ctrl_page: "fgui.Controller",
          };
      }
      buildUi() {
          this.listHistory = new ListView(this.list_history, this, this.parseHistoryItem, this.renderHistoryItem);
          this.listItem = new ListView(this.list_item, this, this.parseItem, this.renderItem);
          this.listHistory.setOnClickItem(this, this.onClickHistoryItem);
          this.refreshHistoryButton();
          this.refreshHistoryItem();
      }
      dispose() {
          super.dispose();
      }
      parseHistoryItem(content, button) {
          content.button = button;
      }
      renderHistoryItem(content, dataHistory) {
          content.data = dataHistory;
          switch (dataHistory.mode) {
              case WaveMode.TOWER_ENDNESS:
                  content.button.title = "无尽模式\n" + dataHistory.id;
                  break;
              case WaveMode.TOWER_MAIN_STORY:
                  content.button.title = "主线挑战\n" + dataHistory.id;
                  break;
              case WaveMode.TOWER_CHALLENGE:
                  content.button.title = "挑战模式\n" + dataHistory.id;
                  break;
              default:
                  content.button.title = dataHistory.id;
                  break;
          }
      }
      onClickHistoryItem(content) {
          this.refreshHistoryItem();
      }
      parseItem(content, view) {
          content.view = view;
      }
      renderItem(content, data) {
          content.data = data;
          content.view.refresh(data, this.damageMax);
      }
      refreshHistoryButton() {
          let listData = StageGameStatis.getHistoryData();
          this.ctrl_page.clearPages();
          for (let i = 0; i < listData.length; i++) {
              this.ctrl_page.addPage(i.toString());
          }
          this.listHistory.setListData(listData);
          this.ctrl_none.selectedIndex = listData.length == 0 ? 1 : 0;
          if (this.ctrl_page.pageCount)
              this.ctrl_page.selectedIndex = this.ctrl_page.pageCount - 1;
      }
      refreshHistoryItem() {
          let historyData = StageGameStatis.getHistoryData();
          let selectData = historyData[this.ctrl_page.selectedIndex];
          if (selectData) {
              let listData = [];
              let damageData = selectData.data;
              for (let id in damageData) {
                  listData.push({ id: id, damage: damageData[id] || 0 });
              }
              listData.sort(this.sortDamageData);
              let first = listData[0];
              if (first) {
                  this.damageMax = first.damage;
              }
              this.listItem.setListData(listData);
          }
          else {
              this.listItem.setListData([]);
          }
      }
      sortDamageData(a, b) {
          return b.damage - a.damage;
      }
      on_click_button_close() {
          this.close();
      }
  }

  class CustomTalentInfo extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://talent/CustomTalentInfo";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_level: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GRichTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.label_name.text = data.name;
          this.label_desc.text = mgrTalent.getTalentDesc(data);
          this.loader_icon.url = data.icon;
          let talentLv = mgrTalent.getTalentLv(data.id);
          if (data.lv_max)
              this.label_level.text = talentLv + "/" + data.lv_max;
          else
              this.label_level.text = talentLv.toString();
      }
  }

  class CustomTalentItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://talent/CustomTalentItem";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_level: "fgui.GBasicTextField",
              cc_ctrl_select: "fgui.Controller",
              cc_ctrl_acitve: "fgui.Controller",
              cc_trans_in: "fgui.Transition",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          let talentLv = mgrTalent.getTalentLv(data.id);
          this.label_name.text = data.name;
          if (data.lv_max)
              this.label_level.text = talentLv + "/" + data.lv_max;
          else
              this.label_level.text = talentLv.toString();
          this.ctrl_acitve.selectedIndex = talentLv > 0 ? 1 : 0;
          this.loader_icon.icon = data.icon;
      }
      select() {
          this.ctrl_select.selectedIndex = 1;
      }
      unselect() {
          this.ctrl_select.selectedIndex = 0;
      }
      playTransIn(delay = 0) {
          this.trans_in.play(null, 1, delay);
      }
  }

  class PanelTalent extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "天赋";
          this.sourceName = "ui://talent/PanelTalent";
          this.bAutoRemovePackage = true;
          this.panelStyle = 0;
          this.actionStep = 0;
          this.actionCount = 0;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_button_tip: "ScaleButton",
              cc_list_talent: "fgui.GList",
              cc_label_point: "fgui.GBasicTextField",
              cc_button_learn: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_talent_info: "CustomTalentInfo",
              cc_ctrl_info: "fgui.Controller",
              cc_ctrl_free: "fgui.Controller",
              cc_ctrl_runing: "fgui.Controller",
          };
      }
      buildUi() {
          this.initEvent();
          this.listTabletViewNor = [];
          this.listTabletViewMax = [];
          this.listTalent = new ListView(this.list_talent, this, this.parseTalentItem, this.renderTalentItem, false, false);
          this.listTalent.setOnClickItem(this, this.onClickTalentItem);
          this.talent_info.onClick(this, this.onClickTalentInfo);
          this.refresh();
          this.refreshPoint();
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.talent_ad);
          mgrTalent.doTaskEvent();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [BASE_MSG.ITEM_CHANGE]: this.onItemChange.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.talent_ad) {
                      this.watchAdSuccess();
                  }
              },
          });
      }
      parseTalentItem(content, object, index) {
          content.view = object;
          if (index < 14) {
              this.listTabletViewNor.push(object);
          }
          else {
              this.listTabletViewMax.push(object);
          }
          object.playTransIn(0.2 + index * 0.02);
      }
      renderTalentItem(content, data, index) {
          content.data = data;
          content.view.refresh(data);
          content.index = index;
          if (data == this.selectTablentDb) {
              this.selectItem(content.view);
          }
          else {
              content.view.unselect();
          }
      }
      onClickTalentItem(content) {
          if (this.clickTalentDb == content.data) {
              this.ctrl_info.selectedIndex = 0;
              this.clickTalentDb = null;
          }
          else {
              let index = content.index % 4;
              if (index == 0 || index == 1) {
                  this.talent_info.setPivot(0, 0, true);
              }
              else {
                  this.talent_info.setPivot(1, 0, true);
              }
              this.talent_info.y = this.list_talent.y + content.view.y;
              this.ctrl_info.selectedIndex = 1;
              this.talent_info.refresh(content.data);
              this.clickTalentDb = content.data;
          }
      }
      onClickTalentInfo() {
          this.ctrl_info.selectedIndex = 0;
      }
      refreshTalent() {
          let dataMap = db.get_talent_db_map();
          let listData = [];
          for (let k in dataMap) {
              let tablenDb = dataMap[k];
              if (tablenDb.unlock)
                  listData.push(tablenDb);
          }
          this.listTalent.setListData(listData);
      }
      refresh() {
          this.refreshTalent();
      }
      refreshPoint() {
          this.label_point.text = mgrGame.getItemCount(1007).toString();
          let isAllMax = mgrTalent.isAllTalentMax();
          if (isAllMax) {
              this.ctrl_free.selectedIndex = 2;
          }
          else {
              let freePoint = mgrGame.getItemCount(1008);
              this.ctrl_free.selectedIndex = freePoint > 0 ? 0 : 1;
              this.button_ad.title = freePoint.toString();
          }
          this.button_learn.title = db.game_cnf.talent_learn_cost.toString();
      }
      onItemChange() {
          this.refreshPoint();
      }
      clearSelect() {
          if (this.selectTalentItem)
              this.selectTalentItem.unselect();
      }
      selectItem(view) {
          this.clearSelect();
          view.select();
          this.selectTalentItem = view;
      }
      playAction(step) {
          if (step) {
              this.actionStep = step;
          }
          else {
              this.actionStep--;
          }
          let view = this.listTabletViewNor[this.actionCount++];
          if (view) {
              this.selectItem(view);
          }
          if (this.actionStep <= 0) {
              this.ctrl_runing.selectedIndex = 0;
              this.refresh();
              return;
          }
          Laya.timer.once(db.game_cnf.talent_action_interval, this, this.playAction);
      }
      playActionMax(step) {
          if (step) {
              this.actionStep = step;
          }
          else {
              this.actionStep--;
          }
          let view = this.listTabletViewMax[this.actionCount++];
          if (view) {
              this.selectItem(view);
          }
          if (this.actionStep <= 0) {
              this.ctrl_runing.selectedIndex = 0;
              this.refresh();
              return;
          }
          Laya.timer.once(db.game_cnf.talent_action_interval, this, this.playActionMax);
      }
      playRandomSelectActionNor() {
          this.clearSelect();
          this.actionCount = 0;
          Utils.randomSort(this.listTabletViewNor);
          this.playAction(5);
          this.ctrl_runing.selectedIndex = 1;
      }
      playRandomSelectActionMax() {
          this.clearSelect();
          this.actionCount = 0;
          Utils.randomSort(this.listTabletViewMax);
          this.playActionMax(2);
          this.ctrl_runing.selectedIndex = 1;
      }
      playRandom(talentDb) {
          if (!talentDb)
              return;
          if (talentDb.lv_max) {
              this.playRandomSelectActionNor();
          }
          else {
              this.playRandomSelectActionMax();
          }
      }
      watchAdSuccess() {
          if (mgrGame.subItem(1008, 1, 49)) {
              this.selectTablentDb = mgrTalent.randomLearn();
              this.playRandom(this.selectTablentDb);
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_learn() {
          mgrNetwork.callByNetwork(() => {
              if (mgrGame.subItem(1007, db.game_cnf.talent_learn_cost, 49)) {
                  this.selectTablentDb = mgrTalent.randomLearn();
                  this.playRandom(this.selectTablentDb);
              }
          });
      }
      on_click_button_ad() {
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.talent_ad);
          });
      }
      on_click_button_tip() {
          Director.openPanelWithSingleton("PanelDialogTip", { title: "巅峰灵石", desc: db.game_cnf.tip_talent_desc });
      }
  }

  class CustomGoalItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://task/CustomGoalItem";
          this.heightProgress = 0;
          this.exportNodeNames = {
              cc_image_progress: "fgui.GImage",
              cc_image_cursor: "fgui.GImage",
              cc_image_ad: "fgui.GImage",
              cc_label_id: "fgui.GBasicTextField",
              cc_item: "CustomItem",
              cc_item_ad: "CustomItem",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_reward: "fgui.Controller",
              cc_ctrl_reward_ad: "fgui.Controller",
          };
      }
      onCreate() {
          this.heightProgress = 131;
          this.item.setOnClickCallback(this.onClickItem.bind(this));
          this.item_ad.setOnClickCallback(this.onClickItemAD.bind(this));
      }
      dispose() {
          super.dispose();
      }
      onClickItem() {
          console.log("点击普通物品");
          if (this.goalDb && this.ctrl_state.selectedIndex == 0) {
              if (mgrHolyItem.notEnoughEmpty(8))
                  return true;
              mgrNetwork.callByNetwork(() => {
                  this.ctrl_reward.selectedIndex = 1;
                  mgrTask.getGoalNormalReward(this.goalDb);
              });
              return true;
          }
          return false;
      }
      onClickItemAD() {
          console.log("点击广告物品");
          if (this.goalDb && this.ctrl_state.selectedIndex == 0) {
              if (mgrHolyItem.notEnoughEmpty(8))
                  return true;
              mgrNetwork.callByNetwork(() => {
                  mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.goal_ad, this.goalDb.id);
              });
              return true;
          }
          return false;
      }
      refresh(warp, curtGoal, isLast = false, renderItem = true) {
          if (isLast) {
              this.ctrl_state.selectedIndex = 3;
              return;
          }
          let data = warp.data;
          let scoreMin = warp.scoreMin;
          let scoreMax = warp.scoreMax;
          this.goalDb = data;
          let score = mgrTask.goalScore;
          if (score < scoreMin) {
              this.ctrl_state.selectedIndex = 2;
              this.image_progress.height = this.heightProgress;
          }
          else if (score >= scoreMin && score < scoreMax) {
              this.ctrl_state.selectedIndex = 1;
              let scoreCurt = score - scoreMin;
              let scoreDelta = scoreMax - scoreMin;
              this.image_progress.height = scoreCurt / scoreDelta * this.heightProgress;
          }
          else {
              this.ctrl_state.selectedIndex = 0;
              this.image_progress.height = this.heightProgress;
          }
          this.label_id.text = data.id.toString();
          if (mgrTask.isGoalComplete(data.id)) {
              this.ctrl_reward.selectedIndex = 1;
          }
          else {
              this.ctrl_reward.selectedIndex = 0;
          }
          if (mgrAdv.checkActive(db.ADV_DB_ADVNAME.goal_ad)) {
              if (mgrTask.isGoalCompleteAD(data.id)) {
                  this.ctrl_reward_ad.selectedIndex = 1;
              }
              else {
                  this.ctrl_reward_ad.selectedIndex = 0;
              }
          }
          else {
              this.ctrl_reward_ad.selectedIndex = 2;
          }
          if (renderItem) {
              this.item.refreshById(data.item_id, data.item_amount);
              this.item_ad.refreshById(data.item_id_ad, data.item_amount_ad);
          }
          else {
          }
      }
      getImageAD() {
          return this.image_ad;
      }
      getItemAD() {
          return this.item_ad;
      }
  }

  class CustomGoalScoreFly extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://task/CustomGoalScoreFly";
          this.exportNodeNames = {};
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      flyTo(x, y) {
          Laya.Tween.to(this, { x: x, y: y }, 400, null, Laya.Handler.create(this, this.recover));
      }
      recover() {
          this.removeFromParent();
          FguiHelper.putItem("ui://task/CustomGoalScoreFly", this);
      }
      static create() {
          let item = FguiHelper.getItem("ui://task/CustomGoalScoreFly");
          if (item) {
              item.touchable = false;
          }
          return item;
      }
      static clear() {
          FguiHelper.clearItem("ui://task/CustomGoalScoreFly");
      }
  }

  class CustomTaskGoal extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "战令";
          this.sourceName = "ui://task/CustomTaskGoal";
          this.isRenderItem = false;
          this.lastIndex = 0;
          this.exportNodeNames = {
              cc_button_question: "ScaleButton",
              cc_progress_goal: "fgui.GProgressBar",
              cc_label_goal: "fgui.GBasicTextField",
              cc_label_step: "fgui.GBasicTextField",
              cc_label_ad: "fgui.GBasicTextField",
              cc_list_goal: "fgui.GList",
          };
      }
      onCreate() {
          this.listGoal = new ListView(this.list_goal, this, this.parseGoalItem, this.renderGoalItem);
          this.initEvent();
          this.initData();
          this.refresh();
          CopHelper.updateAdvButtonState(this.label_ad, db.ADV_DB_ADVNAME.goal_ad);
          CopHelper.updateAdvButtonState(this.button_question.guiNode, db.ADV_DB_ADVNAME.goal_ad);
          Laya.timer.once(100, this, this.refreshListSilence);
      }
      dispose() {
          Laya.timer.clearAll(this);
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.GOAL_SCORE_UDPATE]: this.onGoalScoreUpdate.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.goal_ad) {
                      this.watchAdSuccess(e.params);
                  }
              },
          });
      }
      initData() {
          let score = mgrTask.goalScore;
          let listData = db.get_goal_db_map();
          this.lastIndex = listData.length - 1;
          let listDataWarp = [];
          let scoreCount = 0;
          let curtGoal = null;
          for (let i = 0; i < listData.length; i++) {
              let data = listData[i];
              let scoreMin = scoreCount;
              scoreCount += data.score_need;
              let warp = {
                  data: data,
                  scoreMin: scoreMin,
                  scoreMax: scoreCount,
                  index: i,
              };
              if (!curtGoal && score < warp.scoreMax) {
                  curtGoal = warp;
              }
              listDataWarp.push(warp);
          }
          if (!curtGoal) {
              curtGoal = listDataWarp[listDataWarp.length - 2];
          }
          this.listDataWarp = listDataWarp;
          this.curtGoal = curtGoal;
      }
      refresh() {
          this.refreshCurtGoal(this.curtGoal);
          this.listGoal.setListData(this.listDataWarp);
          this.listGoal.scrollToView(this.curtGoal.index, false);
      }
      refreshList() {
          let curtGoal;
          let listDataWarp = this.listDataWarp;
          let score = mgrTask.goalScore;
          for (let i = 0; i < listDataWarp.length; i++) {
              let warp = listDataWarp[i];
              if (score < warp.scoreMax) {
                  curtGoal = warp;
                  break;
              }
          }
          if (!curtGoal) {
              curtGoal = listDataWarp[listDataWarp.length - 2];
          }
          this.curtGoal = curtGoal;
          this.refreshCurtGoal(curtGoal);
          this.listGoal.refresh();
      }
      refreshListSilence() {
          this.isRenderItem = true;
          this.listGoal.refresh();
      }
      parseGoalItem(content, object, index) {
          content.view = object;
          content.trans_in = object.getTransition("in");
          content.trans_idle = object.getTransition("idle");
      }
      renderGoalItem(content, data, index) {
          content.data = data;
          content.view.refresh(data, this.curtGoal, this.lastIndex == index, this.isRenderItem);
          if (!content.isShowAD) {
              if (mgrGame.statisVideoShowByButton(content.view.getItemAD(), db.ADV_DB_ADVNAME.goal_ad)) {
                  content.isShowAD = true;
              }
          }
      }
      onGoalScoreUpdate() {
          this.refreshList();
      }
      watchAdSuccess(goalId) {
          let goalDb = db.get_goal_db(goalId - 1);
          if (goalDb) {
              mgrTask.getGoalADReward(goalDb);
              this.listGoal.refresh();
          }
      }
      refreshCurtGoal(curtGoal) {
          let score = mgrTask.goalScore;
          let scoreMax = curtGoal.scoreMax;
          if (score > curtGoal.scoreMax) {
              score = curtGoal.scoreMax;
          }
          score -= curtGoal.scoreMin;
          scoreMax -= curtGoal.scoreMin;
          this.label_step.text = (curtGoal.data.id - 1).toString();
          this.label_goal.text = score + "/" + scoreMax;
          this.progress_goal.value = score / scoreMax * 100;
          return curtGoal;
      }
      on_click_button_question() {
          Director.openPanelWithSingleton("PanelIntroGoal");
      }
  }

  class CustomTaskTask extends CustomComponent {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "任务";
          this.sourceName = "ui://task/CustomTaskTask";
          this.statisTask = {};
          this.exportNodeNames = {
              cc_label_main: "fgui.GBasicTextField",
              cc_label_cding: "fgui.GBasicTextField",
              cc_progress_main: "fgui.GProgressBar",
              cc_button_main: "fgui.GButton",
              cc_item_main: "CustomCommItem",
              cc_button_achievement: "fgui.GButton",
              cc_button_daily: "fgui.GButton",
              cc_button_get_all: "fgui.GButton",
              cc_list_task: "fgui.GList",
              cc_loader_score_point: "fgui.GLoader",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_mini: "fgui.Controller",
          };
      }
      onCreate() {
          this.ctrl_state.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.ctrl_mini.on(fgui.Events.STATE_CHANGED, this, this.onMiniStateChange);
          this.listTask = new ListView(this.list_task, this, this.parseTaskItem, this.renderTaskItem);
          this.refreshTask();
          this.refreshMiniTask();
          this.initEvent();
          mgrGame.statisVideoShowByButton(this.button_main, db.ADV_DB_ADVNAME.task_reward_now);
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Laya.timer.loop(1000, this, this.updatePerSecond);
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.task_reward_now) {
                      this.getMiniTaskRewardNow();
                  }
              },
          });
      }
      removeEvent() {
          Laya.timer.clear(this, this.updatePerSecond);
      }
      updatePerSecond() {
          this.refreshMiniTask();
      }
      parseTaskItem(content, object, index) {
          content.state = object.getController("state");
          content.desc = object.getChild("desc").asTextField;
          content.progress = object.getChild("progress").asProgress;
          content.label_progress = content.progress.getChild("text").asTextField;
          content.button = object.getChild("reward").asButton;
          content.item = object.getChild("item");
          content.button.onClick(this, this.onClickTaskItem, [content]);
          content.score = object.getChild("score").asTextField;
          content.icon_score = object.getChild("icon_score").asImage;
          content.trans_in = object.getTransition("in");
          content.trans_idle = object.getTransition("idle");
          if (index < 5) {
              content.trans_idle.play();
              content.trans_in.play(null, 1, index * 0.05);
          }
      }
      renderTaskItem(content, data, index) {
          content.data = data.task;
          let task = data.task;
          let curt = mgrTask.getTaskCountByDB(task);
          let need = mgrTask.getTaskNeed(task);
          if (curt > need)
              curt = need;
          if (task.type == TASK_TYPE.ARCHIEVEMENT) {
              if (mgrTask.isTaskCompleteByDB(data.task)) {
                  content.state.setSelectedIndex(1);
              }
              else {
                  content.state.setSelectedIndex(0);
              }
          }
          else {
              if (mgrTask.isTaskAward(task.id)) {
                  content.state.setSelectedIndex(2);
              }
              else {
                  if (mgrTask.isTaskCompleteByDB(data.task)) {
                      content.state.setSelectedIndex(1);
                  }
                  else {
                      content.state.setSelectedIndex(0);
                  }
              }
          }
          if (!this.statisTask[task.id]) {
              this.statisTask[task.id] = true;
              mgrTask.statisTaskShow(task);
          }
          content.desc.text = Utils.sprintf(task.desc, need);
          content.label_progress.text = curt + "/" + need;
          content.progress.value = data.progress;
          content.score.text = "+" + task.goal_score;
          content.item.refreshById(1000, task.coin);
      }
      onClickTaskItem(content) {
          if (mgrTask.getTaskRewardByDB(content.data)) {
              this.flyGoalScore(content.icon_score);
              this.refreshTask();
          }
      }
      flyGoalScore(object) {
          let goalScoreFly = CustomGoalScoreFly.create();
          if (goalScoreFly) {
              this.addChild(goalScoreFly);
              let gPoint = object.localToGlobal();
              let lPoint = this.globalToLocal(gPoint.x, gPoint.y);
              goalScoreFly.x = lPoint.x;
              goalScoreFly.y = lPoint.y;
              goalScoreFly.flyTo(this.loader_score_point.x, this.loader_score_point.y);
          }
      }
      getAllTaskReward() {
          let listTask = [];
          switch (this.ctrl_state.selectedIndex) {
              case 0:
                  listTask = mgrTask.getDailyTask();
                  break;
              case 1:
                  listTask = mgrTask.getArchievementTask();
                  break;
          }
          let totalCoin = 0;
          let totalScore = 0;
          while (true) {
              let isAnyReward = false;
              for (let task of listTask) {
                  if (mgrTask.isTaskCompleteByDB(task)) {
                      isAnyReward = true;
                      totalCoin += task.coin;
                      totalScore += task.goal_score;
                      mgrTask.markTaskComplete(task.id);
                  }
              }
              if (!isAnyReward) {
                  break;
              }
          }
          if (totalScore) {
              mgrTask.addGoalScore(totalScore);
          }
          if (totalCoin) {
              mgrGame.addItem(1000, totalCoin, 50);
          }
          this.refreshTask();
      }
      refreshTask() {
          let listTask = [];
          switch (this.ctrl_state.selectedIndex) {
              case 0:
                  listTask = mgrTask.getDailyTask();
                  break;
              case 1:
                  listTask = mgrTask.getArchievementTask();
                  break;
          }
          let listTaskWrap = [];
          for (let task of listTask) {
              let curt = mgrTask.getTaskCountByDB(task);
              let need = mgrTask.getTaskNeed(task);
              if (curt > need)
                  curt = need;
              listTaskWrap.push({ task: task, progress: curt * 100 / need });
          }
          switch (this.ctrl_state.selectedIndex) {
              case 0:
                  listTaskWrap.sort(this.sortTask);
                  break;
              case 1:
                  listTaskWrap.sort(this.sortTaskArchievement);
                  break;
          }
          this.listTask.setListData(listTaskWrap);
          this.refreshRedPoint();
      }
      sortTask(a, b) {
          let score_a = (mgrTask.isTaskAward(a.task.id) ? -1 : a.progress) * 100 + a.task.index;
          let score_b = (mgrTask.isTaskAward(b.task.id) ? -1 : b.progress) * 100 + b.task.index;
          return score_b - score_a;
      }
      sortTaskArchievement(a, b) {
          let score_a = a.progress * 100 + a.task.index;
          let score_b = b.progress * 100 + b.task.index;
          return score_b - score_a;
      }
      refreshMiniTask() {
          let task = mgrTask.getMiniTask();
          if (task) {
              let curt = mgrTask.getTaskCountByDB(task);
              let need = mgrTask.getTaskNeed(task);
              if (curt > need)
                  curt = need;
              this.label_main.text = Utils.sprintf(task.desc, need);
              this.progress_main.value = curt * 100 / need;
              let label_progress = this.progress_main.getChild("text").asTextField;
              label_progress.text = curt + "/" + need;
              this.ctrl_mini.setSelectedIndex(0);
              let item = mgrTask.getMiniTaskRewardItem();
              if (item)
                  this.item_main.refresh(item);
          }
          else {
              this.label_cding.text = mgrTask.getMiniCDLeftTime() + "秒后出现新任务!";
              this.ctrl_mini.setSelectedIndex(1);
          }
      }
      onStateChange() {
          this.refreshMiniTask();
          this.refreshTask();
      }
      onMiniStateChange() {
          this.refreshMiniTask();
      }
      refreshRedPoint() {
          this.button_daily.getChild("red").visible = mgrTask.isAnyDailyCanReward();
          this.button_achievement.getChild("red").visible = mgrTask.isAnyArchieveCanReward();
      }
      getMiniTaskRewardNow() {
          let task = mgrTask.getMiniTask();
          if (task) {
              mgrTask.getTaskRewardByDB(task, true);
              this.flyGoalScore(this.button_main);
              this.refreshMiniTask();
          }
      }
      on_click_button_main() {
          if (mgrHolyItem.notEnoughEmpty(1))
              return;
          mgrNetwork.callByNetwork(() => {
              mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.task_reward_now);
          });
      }
      on_click_button_achievement() {
      }
      on_click_button_daily() {
      }
      on_click_button_get_all() {
          this.getAllTaskReward();
      }
  }

  class PanelTask extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "任务";
          this.sourceName = "ui://task/PanelTask";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_com_task: "fgui.GComponent",
              cc_button_close: "ScaleButton",
              cc_button_task: "fgui.GButton",
              cc_button_goal: "fgui.GButton",
              cc_com_node: "fgui.GComponent",
              cc_ctrl_type: "fgui.Controller",
          };
      }
      buildUi() {
          let index = this.context.index || 0;
          this.ctrl_type.on(fgui.Events.STATE_CHANGED, this, this.onStateChange);
          this.ctrl_type.selectedIndex = index;
          this.onStateChange();
      }
      dispose() {
          CustomGoalScoreFly.clear();
          super.dispose();
      }
      onStateChange() {
          switch (this.ctrl_type.selectedIndex) {
              case 0:
                  if (!this.task) {
                      this.task = fgui.UIPackage.createObjectFromURL("ui://task/CustomTaskTask");
                      if (this.task)
                          this.com_node.addChild(this.task);
                  }
                  if (this.task)
                      this.task.visible = true;
                  if (this.goal)
                      this.goal.visible = false;
                  StageTool.updateRedPoint4Button(this.button_task, false);
                  StageTool.updateRedPoint4Button(this.button_goal, mgrTask.isAnyGoalCanReward());
                  break;
              case 1:
                  if (!this.goal) {
                      this.goal = fgui.UIPackage.createObjectFromURL("ui://task/CustomTaskGoal");
                      if (this.goal)
                          this.com_node.addChild(this.goal);
                  }
                  if (this.task)
                      this.task.visible = false;
                  if (this.goal)
                      this.goal.visible = true;
                  StageTool.updateRedPoint4Button(this.button_goal, false);
                  StageTool.updateRedPoint4Button(this.button_task, mgrTask.isAnyTaskCanReward());
                  break;
          }
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_task() {
      }
      on_click_button_goal() {
          if (this.goal) {
              this.goal.refresh();
          }
      }
  }

  class CustomSevenDayItem extends CustomButton {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://task_seven/CustomSevenDayItem";
          this.exportNodeNames = {
              cc_label_day: "fgui.GBasicTextField",
              cc_label_day_lock: "fgui.GBasicTextField",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.sevenTaskDb = data;
          this.label_day.text = data.name;
          this.label_day_lock.text = data.name;
          let day = data.day - 1;
          if (day <= mgrTaskSeven.curtDay) {
              this.ctrl_unlock.selectedIndex = 1;
              StageTool.updateRedPoint4Button(this, mgrTaskSeven.isAnyTaskCanRewardByDay(data));
          }
          else {
              this.ctrl_unlock.selectedIndex = 0;
          }
      }
      click(selectDb) {
          if (this.sevenTaskDb) {
          }
      }
  }

  class CustomTaskSevenItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://task_seven/CustomTaskSevenItem";
          this.exportNodeNames = {
              cc_label_desc: "fgui.GBasicTextField",
              cc_item_reward: "CustomItem",
              cc_label_task_score: "fgui.GBasicTextField",
              cc_progress_task: "fgui.GProgressBar",
              cc_button_reward: "fgui.GButton",
              cc_ctrl_state: "fgui.Controller",
              cc_ctrl_unlock: "fgui.Controller",
          };
      }
      onCreate() {
          this.label_progress = this.progress_task.getChild("text").asTextField;
      }
      dispose() {
          super.dispose();
      }
      refresh(task, unlock) {
          this.task = task;
          let curt = mgrTask.getTaskCountByDB(task);
          let need = mgrTask.getTaskNeed(task);
          if (curt > need)
              curt = need;
          let progress = curt / need * 100;
          if (mgrTask.isTaskAward(task.id)) {
              this.ctrl_state.setSelectedIndex(2);
          }
          else {
              if (mgrTask.isTaskCompleteByDB(task)) {
                  this.ctrl_state.setSelectedIndex(1);
              }
              else {
                  this.ctrl_state.setSelectedIndex(0);
              }
          }
          this.ctrl_unlock.selectedIndex = unlock ? 1 : 0;
          this.label_desc.text = Utils.sprintf(task.desc, need);
          this.label_progress.text = curt + "/" + need;
          this.progress_task.value = progress;
          this.item_reward.refreshById(task.items[0], task.items[1]);
      }
      on_click_button_reward() {
          if (!this.task)
              return;
          if (mgrHolyItem.notEnoughEmptyByRewardIds(this.task.items)) {
              return;
          }
          if (mgrTask.getTaskRewardByDB(this.task)) {
              Global.sendMsg(MSG.TASK_SEVEN_REFRESH);
          }
      }
  }

  class CustomTaskSevenScoreItem extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://task_seven/CustomTaskSevenScoreItem";
          this.exportNodeNames = {
              cc_item: "CustomItem",
              cc_label_score: "fgui.GBasicTextField",
              cc_ctrl_reward: "fgui.Controller",
          };
      }
      onCreate() {
          this.item.setOnClickCallback(this.onClickItem.bind(this));
      }
      dispose() {
          super.dispose();
      }
      refresh(data) {
          this.sevenScoreDb = data;
          this.label_score.text = data.score.toString();
          this.item.refreshById(data.item_id, data.item_count);
          if (!mgrTaskSeven.isScoreReward(data.id)) {
              if (mgrTaskSeven.curtScore >= data.score) {
                  this.ctrl_reward.selectedIndex = 1;
              }
              else {
                  this.ctrl_reward.selectedIndex = 0;
              }
          }
          else {
              this.ctrl_reward.selectedIndex = 2;
          }
      }
      onClickItem() {
          if (this.sevenScoreDb) {
              return mgrTaskSeven.getScoreReward(this.sevenScoreDb);
          }
          return false;
      }
  }

  class PanelTaskSeven extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "七日挑战";
          this.sourceName = "ui://task_seven/PanelTaskSeven";
          this.bAutoRemovePackage = true;
          this.selectDay = 0;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_score: "fgui.GBasicTextField",
              cc_progress_score: "fgui.GProgressBar",
              cc_progress_total: "fgui.GProgressBar",
              cc_item_today: "CustomItem",
              cc_ctrl_total: "fgui.Controller",
              cc_button_ad: "fgui.GButton",
              cc_list_score: "fgui.GList",
              cc_list_task: "fgui.GList",
              cc_list_day: "fgui.GList",
              cc_ctrl_again: "fgui.Controller",
          };
      }
      buildUi() {
          this.selectDay = mgrTaskSeven.curtDay;
          this.labelProgressToday = this.progress_total.getChild("text").asTextField;
          this.listTask = new ListView(this.list_task, this, this.parseTask, this.renderTask);
          this.listDay = new ListView(this.list_day, this, this.parseDay, this.renderDay);
          this.listScore = new ListView(this.list_score, this, this.parseScore, this.renderScore);
          this.listDay.setOnClickItem(this, this.clickDay);
          this.initEvent();
          this.refreshDay();
          this.refreshScore();
          this.refreshTask();
          this.item_today.setOnClickCallback(this.onClickItemToday.bind(this));
          this.ctrl_again.on(fgui.Events.STATE_CHANGED, this, this.onCtrlAgainAdChange);
          this.onCtrlAgainAdChange();
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TASK_SEVEN_REFRESH]: this.onTaskSevenRefresh.bind(this),
              [MSG.TASK_SEVEN_SCORE]: this.onTaskSevenScore.bind(this),
              [MSG.TASK_SEVEN_SCORE_REWARD]: this.onTaskSevenRefresh.bind(this),
              [MSG.TASK_SEVEN_TODAY_MAX_REWARD]: this.onTaskSevenRefresh.bind(this),
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.seven_again) {
                      this.onWatchAdSuc();
                  }
              },
          });
      }
      onCtrlAgainAdChange() {
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.seven_again);
      }
      onTaskSevenRefresh() {
          this.refreshTask();
          this.listDay.refresh();
      }
      onTaskSevenScore() {
          this.refreshScoreInfo();
      }
      onClickItemToday() {
          return mgrTaskSeven.getDayMaxReward(db.get_seven_task_db(this.selectDay));
      }
      onWatchAdSuc() {
          mgrTaskSeven.getDayMaxRewardAD(db.get_seven_task_db(this.selectDay));
      }
      parseTask(content, view, index) {
          content.view = view;
          FguiHelper.playIdleAndIn(view, index, 0.25, 0.05, 5);
      }
      renderTask(content, data) {
          content.view.refresh(data, this.selectDay <= mgrTaskSeven.curtDay);
      }
      refreshTask() {
          let taskSevenDb = db.get_seven_task_db(this.selectDay);
          if (!taskSevenDb)
              return;
          let tasks = mgrTaskSeven.getTasksByDay(this.selectDay);
          let taskComplete = 0;
          let taskMaxCount = tasks.length;
          for (let task of tasks) {
              if (mgrTask.isTaskAward(task.id)) {
                  taskComplete++;
              }
          }
          tasks.sort(this.sortTask);
          this.listTask.setListData(tasks);
          this.refreshScoreInfo();
          this.item_today.refreshById(taskSevenDb.item_id, taskSevenDb.item_count);
          this.labelProgressToday.text = taskComplete + "/" + taskMaxCount;
          this.progress_total.value = taskComplete / taskMaxCount * 100;
          let flag = mgrTaskSeven.getDayId2Reward(this.selectDay);
          if (!flag) {
              if (taskComplete >= taskMaxCount) {
                  this.ctrl_total.selectedIndex = 1;
              }
              else {
                  this.ctrl_total.selectedIndex = 0;
              }
              this.ctrl_again.selectedIndex = 0;
          }
          else {
              if (flag == 1) {
                  this.ctrl_again.selectedIndex = 1;
              }
              else {
                  this.ctrl_again.selectedIndex = 0;
              }
              this.ctrl_total.selectedIndex = 2;
          }
      }
      refreshScoreInfo() {
          let curt = mgrTaskSeven.curtScore;
          let maxx = mgrTaskSeven.getScoreMax();
          this.label_score.text = curt.toString();
          this.progress_score.max = maxx;
          this.progress_score.value = curt;
          this.listScore.refresh();
      }
      sortTask(a, b) {
          let score_a = (mgrTask.isTaskAward(a.id) ? -1 : mgrTask.getTaskProgress(a)) * 100 + a.index;
          let score_b = (mgrTask.isTaskAward(b.id) ? -1 : mgrTask.getTaskProgress(b)) * 100 + b.index;
          return score_b - score_a;
      }
      parseDay(content, view) {
          content.view = view;
      }
      renderDay(content, data) {
          content.data = data;
          content.view.refresh(data);
      }
      clickDay(content) {
          this.selectDay = this.list_day.selectedIndex;
          this.refreshTask();
      }
      refreshDay() {
          let days = db.get_seven_task_db_map();
          this.listDay.setListData(days);
          if (this.selectDay < days.length)
              this.list_day.selectedIndex = this.selectDay;
      }
      parseScore(content, view) {
          content.view = view;
      }
      renderScore(content, data) {
          content.view.refresh(data);
      }
      refreshScore() {
          let datas = db.get_seven_score_db_map();
          this.listScore.setListData(datas);
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.seven_again);
      }
  }

  class CustomHolyItemInfo extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_info/CustomHolyItemInfo";
          this.exportNodeNames = {
              cc_loader_sell_icon: "fgui.GLoader",
              cc_loader_tower_head: "fgui.GLoader",
              cc_com_item: "CustomHolyItem",
              cc_label_item_desc: "CustomHolyItemDesc",
              cc_com_attr: "CustomAttrHolyItem",
              cc_button_item_change: "fgui.GButton",
              cc_button_item_sell: "fgui.GButton",
              cc_button_item_lvup: "fgui.GButton",
              cc_button_lock: "fgui.GButton",
              cc_label_item_name: "fgui.GBasicTextField",
              cc_label_item_level: "fgui.GBasicTextField",
              cc_label_sell_price: "fgui.GBasicTextField",
              cc_ctrl_title_quality: "fgui.Controller",
              cc_ctrl_equip: "fgui.Controller",
              cc_ctrl_equip_by_tower: "fgui.Controller",
          };
      }
      onCreate() {
          this.initEvent();
          this.com_item.touchable = false;
      }
      dispose() {
          super.dispose();
      }
      initEvent() {
      }
      onHolyItemFeed() {
      }
      bindListener(funcItemChange, funcItemChangeLvup) {
          this.funcOnClickButtonItemChange = funcItemChange;
          this.funcOnClickButtonItemLvup = funcItemChangeLvup;
      }
      getEquipController() {
          return this.ctrl_equip;
      }
      haveItem() {
          return this.selectItem && this.selectItem.holyitem && this.selectItem.holyitem.valid;
      }
      refresh(item) {
          let holyitem = item.holyitem;
          if (holyitem) {
              this.label_item_name.text = holyitem.getName();
              this.label_item_level.text = holyitem.getLevelDesc();
              this.label_item_desc.refresh(holyitem);
              this.com_item.refresh(holyitem, false);
              this.com_attr.refresh(holyitem.attr);
              this.ctrl_title_quality.selectedIndex = holyitem.qualityDb.quality;
              this.button_lock.selected = holyitem.lock;
              let isEquiped = holyitem.isEquiped();
              this.ctrl_equip_by_tower.selectedIndex = isEquiped ? 1 : 0;
              this.button_item_sell.title = mgrHolyItem.getHolyItemSellPrice(holyitem).toString();
              this.loader_tower_head.url = holyitem.getHead();
          }
          this.selectItem = item;
          let holyItem = item.holyitem;
          if (holyItem) {
              this.label_sell_price.text = mgrHolyItem.getHolyItemSellPrice(holyItem).toString();
          }
      }
      hideButton() {
          this.button_item_lvup.visible = false;
          this.button_item_sell.visible = false;
      }
      on_click_button_lock() {
          if (this.selectItem) {
              this.selectItem.holyitem.lock = this.button_lock.selected;
          }
      }
      on_click_button_item_lvup() {
          if (this.funcOnClickButtonItemLvup)
              this.funcOnClickButtonItemLvup();
      }
      on_click_button_item_sell() {
          if (this.selectItem) {
              let holyitem = this.selectItem.holyitem;
              mgrHolyItem.sellHolyItem(holyitem, true);
          }
      }
      on_click_button_item_change() {
          if (this.funcOnClickButtonItemChange)
              this.funcOnClickButtonItemChange(this.ctrl_equip.selectedIndex);
      }
  }

  class CustomLvBreakPrice extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_info/CustomLvBreakPrice";
          this.exportNodeNames = {
              cc_loader_icon: "fgui.GLoader",
              cc_label_cur: "fgui.GBasicTextField",
              cc_label_max: "fgui.GBasicTextField",
              cc_ctrl_enough: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(itemId, need) {
          if (itemId && need) {
              let curt = mgrGame.getItemCount(itemId);
              this.label_cur.text = StageTool.formatNumUI(curt);
              this.label_max.text = "/" + need;
              this.loader_icon.url = mgrGame.getItemIcon(itemId);
              this.ctrl_enough.selectedIndex = curt >= need ? 0 : 1;
          }
      }
  }

  class CustomTowerSkillInfo extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_info/CustomTowerSkillInfo";
          this.exportNodeNames = {
              cc_label_name: "fgui.GBasicTextField",
              cc_progress_star: "fgui.GProgressBar",
              cc_button_skill_normal: "fgui.GButton",
              cc_button_skill_super: "fgui.GButton",
              cc_com_tower_star: "fgui.GComponent",
              cc_ctrl_star: "fgui.Controller",
              cc_button_lvup_quality: "fgui.GButton",
              cc_button_change_skill: "fgui.GButton",
              cc_ctrl_main: "fgui.Controller",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_type: "fgui.Controller",
              cc_ctrl_star_max: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb) {
          this.towerDb = towerDb;
          if (towerDb.main) {
              this.ctrl_main.selectedIndex = 1;
          }
          else {
              this.ctrl_main.selectedIndex = 0;
          }
          this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
          this.ctrl_star.selectedIndex = mgrTower.getTowerStar(towerDb.id);
          this.ctrl_type.selectedIndex = towerDb.type;
          this.ctrl_star_max.selectedIndex = mgrTower.isTowerStarFull(towerDb.id) ? 1 : 0;
          this.label_name.text = towerDb.name;
          mgrTower.refreshStarLvupBar(this.progress_star, towerDb.id);
          this.button_skill_normal.icon = mgrTower.getSkillIcon(mgrTower.getTowerSkillId(towerDb.id));
          this.button_skill_super.icon = mgrTower.getSkillIcon(mgrTower.getTowerSuperId(towerDb.id));
          this.refreshRedPoint();
      }
      hideStarLvupMenu() {
          this.progress_star.visible = false;
          this.button_lvup_quality.visible = false;
          this.button_change_skill.visible = false;
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_lvup_quality, mgrTower.canLvupTowerStar(this.towerDb.id));
      }
      on_click_button_lvup_quality() {
          Director.openPanel("PanelTowerStar", { towerDb: this.towerDb });
      }
      on_click_button_change_skill() {
          Director.openPanel("PanelTowerMainHero");
      }
      on_click_button_skill_normal() {
          let skillId = this.towerDb.skill_id;
          if (this.towerDb.main) {
              skillId = mgrTower.getMainSkillId();
          }
          Global.sendMsg(MSG.SHOW_TOWER_SKILL_DETAIL, skillId);
      }
      on_click_button_skill_super() {
          let skillId = this.towerDb.super_skill_id;
          if (this.towerDb.main) {
              skillId = mgrTower.getMainSuperId();
          }
          Global.sendMsg(MSG.SHOW_TOWER_SKILL_DETAIL, skillId);
      }
  }

  class PanelAddPointFinalWar extends PanelAddPoint {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_info/PanelAddPointFinalWar";
          this.exportNodeNames = {
              cc_layer_bg: "fgui.GComponent",
              cc_com_add: "fgui.GComponent",
              cc_button_add_1: "fgui.GButton",
              cc_button_add_half: "fgui.GButton",
              cc_button_add_all: "fgui.GButton",
          };
      }
      buildUi() {
          super.buildUi();
      }
      dispose() {
          super.dispose();
      }
      addPoint(add = 1) {
          switch (this.context.type) {
              case PanelAddPoint.TYPE_ADD_BASE:
                  mgrFinalWar.assignTowerPointBase(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_POWER:
                  mgrFinalWar.assignTowerPointPower(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_MANA:
                  mgrFinalWar.assignTowerPointMana(this.towerId, add);
                  break;
          }
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD);
      }
      addPointQuick(add = 1) {
          switch (this.context.type) {
              case PanelAddPoint.TYPE_ADD_BASE:
                  mgrFinalWar.assignTowerPointBase(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_POWER:
                  mgrFinalWar.assignTowerPointPower(this.towerId, add);
                  break;
              case PanelAddPoint.TYPE_ADD_MANA:
                  mgrFinalWar.assignTowerPointMana(this.towerId, add);
                  break;
          }
          Global.sendMsg(MSG.PANEL_ADD_POINT_ADD_QUICK);
      }
      on_click_button_add_1() {
          this.addPoint();
      }
      on_click_button_add_half() {
          this.addPoint(mgrFinalWar.calcTowerPointLeftHalf(this.towerId));
      }
      on_click_button_add_all() {
          this.addPoint(mgrFinalWar.calcTowerPointLeft(this.towerId));
      }
  }

  class PanelHolyitemSlotUnlock extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "解锁圣物插槽";
          this.sourceName = "ui://tower_info/PanelHolyitemSlotUnlock";
          this.panelStyle = 0;
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_label_dialog: "fgui.GBasicTextField",
              cc_label_title: "fgui.GBasicTextField",
              cc_button_ensure: "fgui.GButton",
              cc_button_ad: "fgui.GButton",
              cc_button_giveupad: "fgui.GButton",
          };
      }
      buildUi() {
          this.towerId = this.context;
          let cost = mgrTower.getUnlocklTowerSlotCost(this.towerId);
          this.button_ensure.title = cost.toString();
          Global.registerListeners(this, {
              [BASE_MSG.ADV_SHOW_SUC]: (e) => {
                  if (e.advName == db.ADV_DB_ADVNAME.unlock_item_slot) {
                      this.watchAdSuccess();
                  }
              },
          });
          mgrGame.statisVideoShowByButton(this.button_ad, db.ADV_DB_ADVNAME.unlock_item_slot);
          mgrChannel.updateADGiveupButton(this.button_giveupad);
      }
      dispose() {
          super.dispose();
      }
      tryUnlock(force = false) {
          if (mgrTower.tryUnlcokTowerSlotByCoin(this.towerId, force)) {
              this.close();
          }
      }
      watchAdSuccess() {
          this.tryUnlock(true);
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_ensure() {
          this.tryUnlock();
      }
      on_click_button_ad() {
          mgrGame.dispatchAdv(db.ADV_DB_ADVNAME.unlock_item_slot);
      }
      on_click_button_giveupad() {
          this.closeWithTransition();
      }
  }

  class PanelTowerLvBreak extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "塔突破等级";
          this.sourceName = "ui://tower_info/PanelTowerLvBreak";
          this.bOpenAndCloseAnim = true;
          this.exportNodeNames = {
              cc_loader_bg: "fgui.GLoader",
              cc_button_close: "ScaleButton",
              cc_tower: "fgui.GComponent",
              cc_loader_icon: "fgui.GLoader",
              cc_label_level: "fgui.GBasicTextField",
              cc_com_star: "fgui.GComponent",
              cc_ctrl_quality: "fgui.Controller",
              cc_item1: "CustomLvBreakPrice",
              cc_item2: "CustomLvBreakPrice",
              cc_item3: "CustomLvBreakPrice",
              cc_button_ensure: "fgui.GButton",
              cc_label_curt: "fgui.GBasicTextField",
              cc_label_next: "fgui.GBasicTextField",
          };
      }
      buildUi() {
          this.loader_bg.url = "res/ui/bg_comm_01.png";
          this.towerDb = this.context.towerDb;
          this.listItem = [];
          this.listItem.push(this.item1);
          this.listItem.push(this.item2);
          this.listItem.push(this.item3);
          this.refresh(this.towerDb);
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb) {
          this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(towerDb);
          this.loader_icon.url = towerDb.icon;
          let type = this.com_star.getController("type");
          let star = this.com_star.getController("star");
          type.selectedIndex = towerDb.type;
          star.selectedIndex = mgrTower.getTowerStar(towerDb.id);
          let limit = mgrTower.getTowerLvLimit(towerDb.id);
          this.label_curt.text = limit.toString();
          this.label_next.text = (limit + db.game_cnf.tower_lv_break_add).toString();
          this.label_level.text = "Lv." + mgrTower.getTowerLv(towerDb.id).toString();
          let itemIds = db.game_cnf.tower_lv_break_items;
          let index = 0;
          for (let i = 0; i < itemIds.length; i += 2) {
              let id = itemIds[i];
              let cn = itemIds[i + 1];
              if (id && cn) {
                  let item = this.listItem[index++];
                  if (item) {
                      item.refresh(id, cn);
                  }
              }
          }
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_ensure() {
          mgrNetwork.callByNetwork(() => {
              if (mgrTower.tryBreakTowerLvLimit(this.towerDb.id)) {
                  this.close();
              }
          });
      }
  }

  class PanelTowerNew extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "新获得塔";
          this.sourceName = "ui://tower_new/PanelTowerNew";
          this.panelLayer = 4;
          this.timeOpen = 0;
          this.bAutoRemovePackage = true;
          this.detailSkillId = null;
          this.exportNodeNames = {
              cc_layer_touch: "fgui.GComponent",
              cc_loader_tower: "fgui.GComponent",
              cc_button_skill_1: "fgui.GButton",
              cc_button_skill_2: "fgui.GButton",
              cc_skill_info: "CustomSkillDetail",
              cc_node_effect: "fgui.GLoader",
              cc_label_name: "fgui.GBasicTextField",
              cc_label_tip: "fgui.GBasicTextField",
              cc_label_desc: "fgui.GBasicTextField",
              cc_ctrl_quality: "fgui.Controller",
              cc_ctrl_type: "fgui.Controller",
              cc_ctrl_skill: "fgui.Controller",
          };
      }
      buildUi() {
          this.towerDb = db.get_tower_db(this.context.towerId || "1");
          this.timeOpen = Utils.getTime();
          this.layer_touch.onClick(this, this.onClickBackgroud);
          this.refresh();
      }
      onAwake() {
          this.createScene3DEffect(0);
          let effectId = "166_ui_loop_star_02";
          switch (this.ctrl_quality.selectedIndex) {
              case 0:
                  effectId = "166_ui_loop_star_02_green";
                  break;
              case 1:
                  effectId = "166_ui_loop_star_02_blue";
                  break;
              case 2:
                  effectId = "166_ui_loop_star_02_purple";
                  break;
              case 3:
                  effectId = "166_ui_loop_star_02";
                  break;
          }
          let effect = EffectFactory.create(effectId, this.scene3DEffect);
          effect.followFguiNode(this.cameraEffect, this.node_effect);
      }
      dispose() {
          super.dispose();
      }
      onClickBackgroud() {
          if (this.ctrl_skill.selectedIndex) {
              this.ctrl_skill.selectedIndex = 0;
              return;
          }
          let passTime = Utils.getTime() - this.timeOpen;
          if (passTime >= 1000) {
              this.onClickEnd();
          }
      }
      onClickEnd() {
          this.close();
      }
      refresh() {
          let skin = new TowerSkin();
          skin.loadSkin(this.towerDb, true);
          this.skin = skin;
          this.loader_tower.displayObject.addChild(skin);
          this.skin.refreshQuality(this.towerDb.id);
          if (this.towerDb.main) {
              this.skin.refreshSkillByDB(this.towerDb);
          }
          else {
              this.skin.syncShooterByDB(this.towerDb);
          }
          this.label_desc.text = this.towerDb.desc;
          this.label_tip.text = this.towerDb.tip;
          this.label_name.text = this.towerDb.name;
          this.button_skill_1.icon = mgrTower.getSkillIcon(mgrTower.getTowerSkillId(this.towerDb.id));
          this.button_skill_2.icon = mgrTower.getSkillIcon(mgrTower.getTowerSuperId(this.towerDb.id));
          this.ctrl_quality.selectedIndex = mgrTower.getTowerQualityByDB(this.towerDb);
          this.ctrl_type.selectedIndex = this.towerDb.type;
      }
      onShowTowerSkillDetail(skillId) {
          if (skillId) {
              if (skillId != this.detailSkillId) {
                  this.ctrl_skill.selectedIndex = 1;
                  this.skill_info.refresh(skillId);
              }
              else {
                  if (this.ctrl_skill.selectedIndex)
                      this.ctrl_skill.selectedIndex = 0;
                  else
                      this.ctrl_skill.selectedIndex = 1;
              }
          }
          else {
              this.ctrl_skill.selectedIndex = 0;
          }
          this.detailSkillId = skillId;
      }
      on_click_button_skill_1() {
          this.onShowTowerSkillDetail(this.towerDb.skill_id);
      }
      on_click_button_skill_2() {
          this.onShowTowerSkillDetail(this.towerDb.super_skill_id);
      }
  }

  class CustomMapTower extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_show/CustomMapTower";
          this.exportNodeNames = {
              cc_progress_star: "fgui.GProgressBar",
              cc_loader_tower: "fgui.GLoader",
              cc_ctrl_tower: "fgui.Controller",
              cc_ctrl_fight: "fgui.Controller",
              cc_ctrl_star_max: "fgui.Controller",
          };
      }
      onCreate() {
          this.onClick(this, this.onClickTower);
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb) {
          this.towerDb = towerDb;
          if (this.skin) {
              this.skin.destroy();
          }
          let skin = new TowerSkin();
          skin.loadSkin(towerDb, true);
          this.skin = skin;
          this.loader_tower.displayObject.addChild(skin);
          this.ctrl_fight.selectedIndex = mgrTower.isTowerEquip(towerDb.id) ? 1 : 0;
          this.ctrl_tower.selectedIndex = towerDb.main ? 0 : 1;
          this.ctrl_star_max.selectedIndex = mgrTower.isTowerStarFull(towerDb.id) ? 1 : 0;
          mgrTower.refreshStarLvupBar(this.progress_star, towerDb.id);
      }
      refreshStarLvupBar() {
          if (this.towerDb) {
              mgrTower.refreshStarLvupBar(this.progress_star, this.towerDb.id);
          }
      }
      refreshTowerStar() {
          this.refreshStarLvupBar();
          if (this.skin && this.towerDb) {
              this.skin.refreshQuality(this.towerDb.id);
          }
      }
      onClickTower() {
          if (this.towerDb) {
              Director.openPanel("PanelTowerInfo", { towerDb: this.towerDb });
          }
      }
  }

  class CustomMoverDialog extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_show/CustomMoverDialog";
          this.exportNodeNames = {
              cc_label_dialog: "fgui.GBasicTextField",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      show(dialog) {
          this.label_dialog.text = dialog;
          this.visible = true;
      }
      hide() {
          this.visible = false;
      }
  }

  var MY_TOWER_MAP_FLAG;
  (function (MY_TOWER_MAP_FLAG) {
      MY_TOWER_MAP_FLAG[MY_TOWER_MAP_FLAG["NONE"] = 0] = "NONE";
      MY_TOWER_MAP_FLAG[MY_TOWER_MAP_FLAG["PATH"] = 1] = "PATH";
      MY_TOWER_MAP_FLAG[MY_TOWER_MAP_FLAG["BARRIER"] = 16] = "BARRIER";
  })(MY_TOWER_MAP_FLAG || (MY_TOWER_MAP_FLAG = {}));
  class MyTowerMap {
      constructor() {
          this.tileW = 32;
          this.tileH = 32;
          this.tempPos = { x: 0, y: 0 };
          this.offsetQueue = [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: -1, y: 0 }, { x: 0, y: -1 }];
          this.width = 0;
          this.height = 0;
          this.pointsPath = [];
          this.pointsTarget = [];
      }
      drawStep(x, y) {
          if (this.funcDrawStep)
              this.funcDrawStep(x, y);
      }
      initGrid(width, height, tileW = 32, tileH = 32) {
          this.width = width;
          this.height = height;
          this.tileW = tileW;
          this.tileH = tileH;
          this.gridFlag = [];
          for (let w = 0; w < width; w++) {
              let flag = [];
              for (let h = 0; h < height; h++) {
                  flag.push(0);
              }
              this.gridFlag[w] = flag;
          }
          this.initAstar();
          console.log("MyTowerMap.initGrid", this.gridFlag);
      }
      initAstar() {
          this.astar = new Astar(true);
          this.astar.setMap(this.width, this.height);
          this.astar.setBarrierCheckCallback(this.onBarrierCheck.bind(this));
      }
      onBarrierCheck(gx, gy, flag = MY_TOWER_MAP_FLAG.PATH) {
          return !this.checkFlag(gx, gy, flag);
      }
      checkFlag(x, y, flag) {
          return this.gridFlag[x][y] & flag;
      }
      addFlag(x, y, flag) {
          this.gridFlag[x][y] |= flag;
      }
      remFlag(x, y, flag) {
          this.gridFlag[x][y] ^= flag;
      }
      clearFlag(x, y) {
          this.gridFlag[x][y] = 0;
      }
      findPath(fx, fy, tx, ty, flag) {
          return this.astar.findPath(fx, fy, tx, ty, flag);
      }
      convertGridPosToRealPos(x, y, rand = true) {
          if (rand) {
              this.tempPos.x = x * this.tileW + Utils.random(0, this.tileW);
              this.tempPos.y = y * this.tileH + Utils.random(0, this.tileH);
          }
          else {
              this.tempPos.x = x * this.tileW + this.tileW / 2;
              this.tempPos.y = y * this.tileH + this.tileH / 2;
          }
          return this.tempPos;
      }
      checkPos(x, y) {
          let row = this.gridFlag[x];
          if (!row)
              return false;
          return row[y] != null;
      }
      findCirleByRange(x, y, range, flag) {
          let step = Math.floor(range) * 2;
          let posList = [];
          while (step > 0) {
              let offsetCurt = null;
              let halfs = step / 2;
              let fromx = x - halfs;
              let fromy = y - halfs;
              let offsetx = 0;
              let offsety = 0;
              for (let i = 0; i < this.offsetQueue.length; i++) {
                  offsetCurt = this.offsetQueue[i];
                  for (let j = 1; j <= step; j++) {
                      offsetx += offsetCurt.x;
                      offsety += offsetCurt.y;
                      let tx = fromx + offsetx;
                      let ty = fromy + offsety;
                      if (this.checkPos(tx, ty) && this.checkFlag(tx, ty, flag)) {
                          posList.push({ x: tx, y: ty });
                      }
                  }
              }
              step -= 2;
              if (step < 0) {
                  break;
              }
          }
          return posList;
      }
  }

  var MOVE_STATE$1;
  (function (MOVE_STATE) {
      MOVE_STATE[MOVE_STATE["NONE"] = 0] = "NONE";
      MOVE_STATE[MOVE_STATE["IDLE"] = 1] = "IDLE";
      MOVE_STATE[MOVE_STATE["THINK"] = 2] = "THINK";
      MOVE_STATE[MOVE_STATE["MOVETO"] = 3] = "MOVETO";
  })(MOVE_STATE$1 || (MOVE_STATE$1 = {}));
  var DIALOG_STATE;
  (function (DIALOG_STATE) {
      DIALOG_STATE[DIALOG_STATE["IDLE"] = 0] = "IDLE";
      DIALOG_STATE[DIALOG_STATE["WAIT"] = 1] = "WAIT";
      DIALOG_STATE[DIALOG_STATE["SHOW"] = 2] = "SHOW";
  })(DIALOG_STATE || (DIALOG_STATE = {}));
  class TowerShowMover extends Laya.Sprite {
      constructor() {
          super(...arguments);
          this.gx = 0;
          this.gy = 0;
          this.mx = 0;
          this.my = 0;
          this.factorFlip = 1;
          this.factorFlip2 = 0.5;
      }
      onAwake() {
          this.move = this.addComponent(StateMover);
      }
      setPos(mx, my) {
          this.mx = mx;
          this.my = my;
          let pos = this.map.convertGridPosToRealPos(mx, my, false);
          this.x = pos.x;
          this.y = pos.y;
          this.zOrder = pos.y;
          this.setGrid(Math.round(mx), Math.round(my));
      }
      setGrid(gx, gy) {
          this.gx = gx;
          this.gy = gy;
      }
      play(name) {
          if (this.spine) {
              this.spine.playAnimation(name);
          }
      }
      setSkillId(skillId) {
          this.skillId = skillId;
      }
      loadSpine(name = "ta_01", factorFlip = 0) {
          this.factorFlip = factorFlip;
          let spine = Spine.create(name);
          spine.playAnimation("move");
          this.addChild(spine);
          spine.scale(this.factorFlip2, this.factorFlip2);
          this.spine = spine;
          return spine;
      }
      setFlip(flip) {
          this.spine.scaleX = flip * this.factorFlip * this.factorFlip2;
      }
      setMap(map) {
          this.map = map;
      }
      createDialog(dialogs) {
          this.dialogs = dialogs;
          this.clearDilaog();
          let dialog = FguiHelper.getItem("ui://tower_show/CustomMoverDialog");
          if (dialog) {
              dialog.y = -50;
              this.addChild(dialog.displayObject);
              this.uiDialog = dialog;
              this.uiDialog.hide();
          }
      }
      randowDialog() {
          if (this.dialogs && this.uiDialog) {
              let dialog = Utils.randomItem(this.dialogs);
              if (dialog) {
                  this.uiDialog.show(dialog.word);
              }
          }
      }
      hideDialog() {
          if (this.uiDialog) {
              this.uiDialog.hide();
          }
      }
      clearDilaog() {
          if (this.uiDialog) {
              this.uiDialog.displayObject.removeSelf();
              this.uiDialog.dispose();
              this.uiDialog = null;
          }
      }
      onDestroy() {
          this.clearDilaog();
          super.onDestroy();
      }
  }
  class StateMover extends StateMachine2D {
      constructor() {
          super(...arguments);
          this.mSpeed = 1;
          this.timePass = 0;
          this.timeWait = 0;
          this.dialogTimePass = 0;
          this.dialogTimeWait = 0;
          this.dialogState = DIALOG_STATE.IDLE;
          this.mPathIndex = 0;
          this.mMoveDir = new LogicPoint;
          this.mMoveDistance = 0;
      }
      onAwake() {
          this.isRunning = true;
          this.node = this.owner;
          this.registerState(MOVE_STATE$1.IDLE, "Idle");
          this.registerState(MOVE_STATE$1.THINK, "Think");
          this.registerState(MOVE_STATE$1.MOVETO, "MoveTo");
          this.setState(MOVE_STATE$1.IDLE);
      }
      update(dt) {
          super.update(dt);
          this.updateDialog(dt);
      }
      updateDialog(dt) {
          this.dialogTimePass += dt;
          switch (this.dialogState) {
              case DIALOG_STATE.IDLE:
                  this.dialogTimeWait = Utils.random(7, 35);
                  this.dialogState = DIALOG_STATE.WAIT;
                  break;
              case DIALOG_STATE.WAIT:
                  if (this.dialogTimePass >= this.dialogTimeWait) {
                      this.node.randowDialog();
                      this.dialogTimeWait = Utils.random(3, 6);
                      this.dialogTimePass = 0;
                      this.dialogState = DIALOG_STATE.SHOW;
                  }
                  break;
              case DIALOG_STATE.SHOW:
                  if (this.dialogTimePass >= this.dialogTimeWait) {
                      this.dialogTimeWait = 0;
                      this.dialogTimePass = 0;
                      this.node.hideDialog();
                      this.dialogState = DIALOG_STATE.IDLE;
                  }
                  break;
          }
      }
      findPath() {
          let points = this.node.map.findCirleByRange(this.node.gx, this.node.gy, 6, MY_TOWER_MAP_FLAG.PATH);
          let point = Utils.randomItem(points);
          this.mPath = this.node.map.findPath(this.node.gx, this.node.gy, point.x, point.y);
          this.mPathIndex = 0;
      }
      moveTo(tx, ty) {
          if (this.getState() == MOVE_STATE$1.MOVETO) {
              return;
          }
          let dx = tx - this.node.gx;
          let dy = ty - this.node.gy;
          this.mMoveDir.x = dx;
          this.mMoveDir.y = dy;
          this.mMoveDistance = this.mMoveDir.distance();
          this.mMoveDir.normalize();
          if (dx > 0) {
              this.node.setFlip(1);
          }
          else if (dx < 0) {
              this.node.setFlip(-1);
          }
          this.setState(MOVE_STATE$1.MOVETO);
      }
      enterIdle() {
          this.timePass = 0;
          this.timeWait = Utils.random(2, 5);
          this.node.play("idle");
      }
      execIdle(t) {
          this.timePass += t;
          if (this.timePass >= this.timeWait) {
              this.node.play("move");
              this.setState(MOVE_STATE$1.THINK);
          }
      }
      exitIdle() {
      }
      enterThink() {
          if (!this.mPath && this.node && this.node.map) {
              this.findPath();
          }
          if (this.mPath) {
              let p = this.mPath[this.mPathIndex];
              if (p) {
                  this.moveTo(p.x, p.y);
              }
              else {
                  this.mPath = null;
                  this.setState(MOVE_STATE$1.IDLE);
              }
              this.mPathIndex++;
          }
      }
      enterMoveTo() {
      }
      execMoveTo(t) {
          let disMove = this.mSpeed * t;
          let mx = this.node.mx + this.mMoveDir.x * disMove;
          let my = this.node.my + this.mMoveDir.y * disMove;
          this.node.setPos(mx, my);
          this.mMoveDistance -= disMove;
          if (this.mMoveDistance <= 0) {
              this.setState(MOVE_STATE$1.THINK);
          }
      }
      exitMoveTo() {
      }
  }

  let DEBUG_PATH = false;
  class PanelTowerShow extends PanelBase {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "我的箭塔";
          this.sourceName = "ui://tower_show/PanelTowerShow";
          this.panelStyle = 1;
          this.bAutoRemovePackage = true;
          this.pointIndex = 0;
          this.exportNodeNames = {
              cc_layer_fit: "CustomLayerFit",
              cc_map: "fgui.GComponent",
              cc_button_close: "fgui.GButton",
              cc_money_bar: "CustomMoneyBar",
              cc_button_collect: "fgui.GButton",
              cc_button_grow: "fgui.GButton",
          };
      }
      buildUi() {
          this.layer_fit.fit();
          this.resNode.makeFullScreen();
          this.towerList = [];
          this.listTowerDb = [];
          this.moverList = [];
          for (let i = 0; i < this.map.numChildren; i++) {
              let child = this.map.getChildAt(i);
              if (child instanceof CustomMapTower) {
                  this.towerList.push(child);
              }
          }
          this.refresh();
          this.loadTileMap();
          this.initEvent();
          if (DEBUG_PATH) {
              let sp = new Laya.Sprite;
              this.map.displayObject.addChild(sp);
              this.graphicsDebug = sp.graphics;
          }
      }
      dispose() {
          this.saveMoverPos();
          super.dispose();
          Global.sendMsg(MSG.GAME_VIEW_RESTORE);
      }
      initEvent() {
          Global.registerListeners(this, {
              [MSG.TOWER_RUSH_BEGIN]: this.closeWithTransition.bind(this),
              [MSG.TOWER_LVUP_STAR]: this.onTowerLvupStar.bind(this),
          });
      }
      refresh() {
          let towerMap = db.get_tower_db_map();
          let countMap = 0;
          for (let k in towerMap) {
              let towerDb = db.get_tower_db(k);
              if (towerDb.main || mgrTower.getTowerAmount(k)) {
                  let towerUi = this.towerList[countMap++];
                  if (towerUi) {
                      this.listTowerDb.push(towerDb);
                      towerUi.refresh(towerDb);
                  }
              }
          }
      }
      loadTileMap() {
          let path = "res/tilemap/my_tower.json";
          Laya.loader.load(path, Laya.Handler.create(this, function () {
              let mapJson = Laya.loader.getRes(path);
              this.parseTileMap(mapJson);
          }), null, Laya.Loader.JSON);
      }
      parseTileMap(json) {
          if (this.destroyed)
              return;
          let layers = json.layers;
          for (let layer of layers) {
              switch (layer.name) {
                  case "path": {
                      this.tileMapPath = layer;
                      break;
                  }
                  case "point": {
                      this.tileMapPoint = layer;
                      break;
                  }
              }
          }
          console.log("箭塔地图路径数据", this.tileMapPath);
          console.log("箭塔地图目标数据", this.tileMapPoint);
          let mapGrid = new MyTowerMap();
          mapGrid.initGrid(this.tileMapPath.width, this.tileMapPath.height, 32, 32);
          this.mapGrid = mapGrid;
          mapGrid.funcDrawStep = this.drawStep.bind(this);
          mapGrid.pointsPath = [];
          mapGrid.pointsTarget = [];
          for (let w = 0; w < this.tileMapPath.width; w++) {
              for (let h = 0; h < this.tileMapPath.height; h++) {
                  if (this.isTileMapPoint(w, h)) {
                      mapGrid.addFlag(w, h, MY_TOWER_MAP_FLAG.PATH);
                      mapGrid.pointsPath.push({ x: w, y: h });
                  }
                  else if (this.isTileMapPath(w, h)) {
                      mapGrid.addFlag(w, h, MY_TOWER_MAP_FLAG.PATH);
                      mapGrid.pointsTarget.push({ x: w, y: h });
                  }
                  else {
                  }
              }
          }
          mapGrid.pointsPath.sort(function (a, b) {
              let score_a = a.y * 1000 + a.x;
              let score_b = b.y * 1000 + b.x;
              return score_a - score_b;
          });
          if (DEBUG_PATH) {
              this.drawGrid();
          }
          for (let i = 0; i < this.listTowerDb.length; i++) {
              this.createMover(i);
          }
      }
      createMover(i) {
          let towerDb = this.listTowerDb[i];
          if (towerDb) {
              let skill_id = towerDb.skill_id;
              if (towerDb.main) {
                  skill_id = mgrTower.getMainSkillId();
              }
              let skillDb = db.get_skill_db(skill_id);
              if (skillDb) {
                  let mover = new TowerShowMover;
                  mover.setSkillId(skillDb.id);
                  mover.loadSpine(skillDb.spine, skillDb.spine_flip);
                  mover.createDialog(db.get_tower_dialog_db_map()[skillDb.id]);
                  mover.setMap(this.mapGrid);
                  this.map.displayObject.addChild(mover);
                  this.moverList.push(mover);
                  let point = this.mapGrid.pointsPath[this.pointIndex];
                  this.pointIndex++;
                  point = mgrTower.getTowerShowMoverPos(skillDb.id) || point;
                  mover.setPos(point.x, point.y);
              }
          }
      }
      saveMoverPos() {
          if (this.moverList) {
              for (let mover of this.moverList) {
                  mgrTower.setTowerShowMovePos(mover.skillId, { x: mover.gx, y: mover.gy });
              }
          }
      }
      isTileMapPath(x, y) {
          return this.tileMapPath.data[x + y * this.tileMapPath.width] || 0;
      }
      isTileMapPoint(x, y) {
          return this.tileMapPoint.data[x + y * this.tileMapPoint.width] || 0;
      }
      drawGrid(tileW = 32, tileH = 32) {
          this.graphicsDebug.clear();
          for (let w = 0; w < this.tileMapPath.width; w++) {
              for (let h = 0; h < this.tileMapPath.height; h++) {
                  if (this.isTileMapPoint(w, h)) {
                      this.graphicsDebug.drawRect(tileW * w, tileH * h, tileW, tileH, "#aa000055", "#00000055");
                  }
                  else if (this.isTileMapPath(w, h)) {
                      this.graphicsDebug.drawRect(tileW * w, tileH * h, tileW, tileH, "#00aa0055", "#00000055");
                  }
              }
          }
      }
      drawStep(x, y, color = "#abcd0055") {
          let tileW = 32;
          let tileH = 32;
          if (this.graphicsDebug)
              this.graphicsDebug.drawRect(tileW * x, tileH * y, tileW, tileH, color, "#00aa0055");
      }
      onTowerLvupStar(towerId) {
          for (let tower of this.towerList) {
              if (tower.towerDb && tower.towerDb.id == towerId) {
                  tower.refreshTowerStar();
              }
              else {
                  tower.refreshStarLvupBar();
              }
          }
      }
      on_click_button_close() {
          this.close();
      }
      on_click_button_collect() {
          Director.openPanelWithSingleton("PanelCollect");
      }
      on_click_button_grow() {
          Director.openPanelWithSingleton("PanelGrow");
      }
  }

  class CustomTowerShow extends CustomComponent {
      constructor() {
          super(...arguments);
          this.sourceName = "ui://tower_star/CustomTowerShow";
          this.exportNodeNames = {
              cc_loader_tower: "fgui.GComponent",
              cc_ctrl_star: "fgui.Controller",
          };
      }
      onCreate() {
      }
      dispose() {
          super.dispose();
      }
      refresh(towerDb, star) {
          if (this.skin) {
              this.skin.destroy();
          }
          let skin = new TowerSkin();
          skin.loadSkinByStar(towerDb, true, star);
          this.skin = skin;
          this.loader_tower.displayObject.addChild(skin);
          this.ctrl_star.selectedIndex = star;
          if (towerDb.main) {
              this.skin.refreshSkillByDB(towerDb, false, star);
          }
          else {
              this.skin.syncShooterByDB(towerDb, star);
          }
      }
  }

  class PanelTowerStar extends PanelBase3D {
      constructor() {
          super(...arguments);
          this.PANEL_NAME = "阶级提升";
          this.sourceName = "ui://tower_star/PanelTowerStar";
          this.bAutoRemovePackage = true;
          this.exportNodeNames = {
              cc_button_close: "ScaleButton",
              cc_button_tip_up: "ScaleButton",
              cc_button_tip: "ScaleButton",
              cc_button_star_lvup: "fgui.GButton",
              cc_tower1: "CustomTowerShow",
              cc_tower2: "CustomTowerShow",
              cc_progress_star: "fgui.GProgressBar",
              cc_label_piece: "fgui.GBasicTextField",
              cc_ctrl_max: "fgui.Controller",
              cc_ctrl_tower_star: "fgui.Controller",
              cc_trans_suc: "fgui.Transition",
          };
      }
      buildUi() {
          this.createScene3DEffect(100);
          this.towerDb = this.context.towerDb;
          this.refresh();
      }
      dispose() {
          super.dispose();
      }
      refresh() {
          let towerId = this.towerDb.id;
          let star = mgrTower.getTowerStar(this.towerDb.id);
          if (mgrTower.isTowerStarFull(this.towerDb.id)) {
              this.tower1.refresh(this.towerDb, star);
              this.ctrl_max.selectedIndex = 1;
          }
          else {
              this.tower1.refresh(this.towerDb, star);
              this.tower2.refresh(this.towerDb, star + 1);
              this.ctrl_max.selectedIndex = 0;
          }
          this.ctrl_tower_star.selectedIndex = star;
          this.label_piece.text = Utils.numberFormat(mgrGame.getItemCount(1006), 1).toString();
          mgrTower.refreshStarLvupBar(this.progress_star, towerId);
          this.refreshRedPoint();
      }
      onLvupStarSuc() {
          this.trans_suc.stop();
          if (mgrTower.isTowerStarFull(this.towerDb.id)) {
              this.refresh();
              Laya.timer.once(100, this, this.onPlayEffect1);
          }
          else {
              this.trans_suc.play();
              Laya.timer.once(700, this, this.onPlayEffect2);
          }
      }
      onPlayEffect1() {
          let effect = EffectFactory.create("166_ui_star_levp", this.scene3DEffect);
          effect.setPosFguiNodePivot(this.cameraEffect, this.tower1);
      }
      onPlayEffect2() {
          this.refresh();
          let effect = EffectFactory.create("166_ui_star_levp", this.scene3DEffect);
          effect.setPosFguiNodePivot(this.cameraEffect, this.tower2);
      }
      lvupTowerStar() {
          mgrNetwork.callByNetwork(() => {
              if (mgrTower.lvupTowerStar(this.towerDb.id, StageConfig.forceTowerLvupStar)) {
                  this.onLvupStarSuc();
              }
          });
      }
      refreshRedPoint() {
          Level.updateRedPoint4Button(this.button_star_lvup, mgrTower.canLvupTowerStar(this.towerDb.id));
      }
      on_click_button_close() {
          this.closeWithTransition();
      }
      on_click_button_star_lvup() {
          let needPiece = mgrTower.calcNeedPiece(this.towerDb.id);
          if (needPiece > 0 && mgrGame.getItemCount(1006) >= needPiece) {
              mgrTip.alertPrompt("碎片不足，是否使用" + needPiece + "个" + mgrGame.getItemName(1006) + "进行升阶？", null, () => {
                  this.lvupTowerStar();
              });
          }
          else {
              this.lvupTowerStar();
          }
      }
      on_click_button_tip() {
          Director.openPanelWithSingleton("PanelDialogTip", { title: "万能碎片", desc: db.game_cnf.tip_piece_desc });
      }
      on_click_button_tip_up() {
          Director.openPanelWithSingleton("PanelDialogTip", { title: "英雄进阶", desc: db.game_cnf.tip_star_up_desc });
      }
  }

  function requireModule(name) {
      switch (name) {
          case "PanelAgeTip16":
              return PanelAgeTip16;
          case "PanelAgeTip8":
              return PanelAgeTip8;
          case "CustomAEPrice":
              return CustomAEPrice;
          case "CustomAEWordItem":
              return CustomAEWordItem;
          case "CustomTowerEquipItem":
              return CustomTowerEquipItem;
          case "PanelAllEquipInfo":
              return PanelAllEquipInfo;
          case "PanelAllTowerEquip":
              return PanelAllTowerEquip;
          case "CustomCommItem":
              return CustomCommItem;
          case "CustomItem":
              return CustomItem;
          case "CustomSkillDetail":
              return CustomSkillDetail;
          case "CustomGuideDialogLeft":
              return CustomGuideDialogLeft;
          case "CustomGuideDialogRight":
              return CustomGuideDialogRight;
          case "CustomAttrHolyItem":
              return CustomAttrHolyItem;
          case "CustomAttrHolyItem2":
              return CustomAttrHolyItem2;
          case "CustomAttrHolyItem3":
              return CustomAttrHolyItem3;
          case "CustomHolyItem":
              return CustomHolyItem;
          case "CustomHolyItemDesc":
              return CustomHolyItemDesc;
          case "CustomHolyitemDescItem":
              return CustomHolyitemDescItem;
          case "CustomHolyItemInfoBag":
              return CustomHolyItemInfoBag;
          case "CustomHolyItemInfoBagEx":
              return CustomHolyItemInfoBagEx;
          case "CustomBarItem":
              return CustomBarItem;
          case "CustomBarStone":
              return CustomBarStone;
          case "CustomBarTicket":
              return CustomBarTicket;
          case "CustomDamageText":
              return CustomDamageText;
          case "CustomDropItem":
              return CustomDropItem;
          case "CustomDropItemFly":
              return CustomDropItemFly;
          case "CustomH5ADDToDesk":
              return CustomH5ADDToDesk;
          case "CustomHolyItemIntro":
              return CustomHolyItemIntro;
          case "CustomHpBar":
              return CustomHpBar;
          case "CustomHpBarTower":
              return CustomHpBarTower;
          case "CustomHpBarTowerMain":
              return CustomHpBarTowerMain;
          case "CustomItemInfo":
              return CustomItemInfo;
          case "CustomLayerFit":
              return CustomLayerFit;
          case "CustomMoney":
              return CustomMoney;
          case "CustomMoneyBar":
              return CustomMoneyBar;
          case "CustomNodeEffect":
              return CustomNodeEffect;
          case "CustomTowerHead":
              return CustomTowerHead;
          case "PanelDialog":
              return PanelDialog;
          case "PanelDialogCD":
              return PanelDialogCD;
          case "PanelDialogTip":
              return PanelDialogTip;
          case "PanelGuide":
              return PanelGuide;
          case "PanelHolyitemInfo":
              return PanelHolyitemInfo;
          case "PanelItemInfo":
              return PanelItemInfo;
          case "PanelMoney":
              return PanelMoney;
          case "PanelSkillInfo":
              return PanelSkillInfo;
          case "PanelStoryDialog":
              return PanelStoryDialog;
          case "ViewTipItem":
              return ViewTipItem;
          case "CustomBoxrewardItem":
              return CustomBoxrewardItem;
          case "PanelBoxReward":
              return PanelBoxReward;
          case "CustomSummonProb":
              return CustomSummonProb;
          case "CustomSummon":
              return CustomSummon;
          case "CustomSummonCard":
              return CustomSummonCard;
          case "CustomSummonItem":
              return CustomSummonItem;
          case "CustomSummonItemSub":
              return CustomSummonItemSub;
          case "PanelSummon":
              return PanelSummon;
          case "CustomChallengeItem":
              return CustomChallengeItem;
          case "CustomTaskChapter":
              return CustomTaskChapter;
          case "CustomTaskStep":
              return CustomTaskStep;
          case "CustomChallengeBoss":
              return CustomChallengeBoss;
          case "CustomChallengeMain":
              return CustomChallengeMain;
          case "PanelChallenge":
              return PanelChallenge;
          case "PanelLocalBanner":
              return PanelLocalBanner;
          case "PanelLocalInterstitial":
              return PanelLocalInterstitial;
          case "PanelMoreGameOppo":
              return PanelMoreGameOppo;
          case "PanelMoreGameOppoDown":
              return PanelMoreGameOppoDown;
          case "PanelTryToPlay":
              return PanelTryToPlay;
          case "ViewBannerOtherGame":
              return ViewBannerOtherGame;
          case "ViewBannerOtherGameVertical":
              return ViewBannerOtherGameVertical;
          case "CustomCollectEnemy":
              return CustomCollectEnemy;
          case "CustomCollectHolyitem":
              return CustomCollectHolyitem;
          case "CustomCollectTower":
              return CustomCollectTower;
          case "PanelCollect":
              return PanelCollect;
          case "PanelCollectDetailEnemy":
              return PanelCollectDetailEnemy;
          case "PanelCollectDetailItem":
              return PanelCollectDetailItem;
          case "PanelCollectDetailTower":
              return PanelCollectDetailTower;
          case "CustomDailyDamageDesc":
              return CustomDailyDamageDesc;
          case "CustomDailyDmageHistoryItem":
              return CustomDailyDmageHistoryItem;
          case "PanelDailyDamage":
              return PanelDailyDamage;
          case "PanelDailyDamageHIstory":
              return PanelDailyDamageHIstory;
          case "PanelDailyDamageQuestion":
              return PanelDailyDamageQuestion;
          case "CustomDailyDamageADItem":
              return CustomDailyDamageADItem;
          case "PanelDailyDamageAD":
              return PanelDailyDamageAD;
          case "CustomDailyDamageBar":
              return CustomDailyDamageBar;
          case "PanelDailyDamageGame":
              return PanelDailyDamageGame;
          case "PanelDailyDamageReady":
              return PanelDailyDamageReady;
          case "PanelDamageResult":
              return PanelDamageResult;
          case "PanelDebug":
              return PanelDebug;
          case "PanelDebugEffect":
              return PanelDebugEffect;
          case "PanelDebugInput":
              return PanelDebugInput;
          case "PanelTest2d":
              return PanelTest2d;
          case "PanelTest3d":
              return PanelTest3d;
          case "CustomAttrList":
              return CustomAttrList;
          case "CustomTowerInfo":
              return CustomTowerInfo;
          case "PanelDeploy":
              return PanelDeploy;
          case "CustomScaleBar":
              return CustomScaleBar;
          case "PanelEditAnim":
              return PanelEditAnim;
          case "PanelEditBullet":
              return PanelEditBullet;
          case "PanelEditHIt":
              return PanelEditHIt;
          case "PanelEditSpine":
              return PanelEditSpine;
          case "PanelEditTrajectory":
              return PanelEditTrajectory;
          case "CustomExploreHead":
              return CustomExploreHead;
          case "CustomExploreHolyItem":
              return CustomExploreHolyItem;
          case "CustomExploreShopItem":
              return CustomExploreShopItem;
          case "CustomExploreTowerItem":
              return CustomExploreTowerItem;
          case "CustomExplorePage1":
              return CustomExplorePage1;
          case "CustomExplorePage2":
              return CustomExplorePage2;
          case "CustomExplorePage3":
              return CustomExplorePage3;
          case "PanelExplore":
              return PanelExplore;
          case "PanelExploreItemInfo":
              return PanelExploreItemInfo;
          case "PanelExploreKeyAdd":
              return PanelExploreKeyAdd;
          case "PanelExploreSelectHero":
              return PanelExploreSelectHero;
          case "CustomFBCoinItem":
              return CustomFBCoinItem;
          case "PanelFBCoin":
              return PanelFBCoin;
          case "PanelFBDoor":
              return PanelFBDoor;
          case "CustomFBItemItem":
              return CustomFBItemItem;
          case "PanelFBItem":
              return PanelFBItem;
          case "CustomFBItemShowItem1":
              return CustomFBItemShowItem1;
          case "CustomFBItemShowItem2":
              return CustomFBItemShowItem2;
          case "CustomFBItemShowLine1":
              return CustomFBItemShowLine1;
          case "CustomFBItemShowLine2":
              return CustomFBItemShowLine2;
          case "PanelFBItemShow":
              return PanelFBItemShow;
          case "CustomFianlWarItem":
              return CustomFianlWarItem;
          case "CustomHopelessWarItem":
              return CustomHopelessWarItem;
          case "PanelFinalWar":
              return PanelFinalWar;
          case "PanelFinalWarBegin3":
              return PanelFinalWarBegin3;
          case "PanelFinalWarBegin":
              return PanelFinalWarBegin;
          case "PanelFinalWarBegin2":
              return PanelFinalWarBegin2;
          case "PanelFinalWarGame":
              return PanelFinalWarGame;
          case "PanelFinalWarGame2":
              return PanelFinalWarGame2;
          case "CustomFinalWarShopItem":
              return CustomFinalWarShopItem;
          case "PanelFinaWarShop":
              return PanelFinaWarShop;
          case "PanelFinalWarWin":
              return PanelFinalWarWin;
          case "CustomBossCrazy":
              return CustomBossCrazy;
          case "CustomBoxReward":
              return CustomBoxReward;
          case "CustomBroadcast":
              return CustomBroadcast;
          case "CustomGuideTip":
              return CustomGuideTip;
          case "CustomH5Share":
              return CustomH5Share;
          case "CustomH5VideoRecord":
              return CustomH5VideoRecord;
          case "CustomHandSkill":
              return CustomHandSkill;
          case "CustomHandSkillBig":
              return CustomHandSkillBig;
          case "CustomIceBreak":
              return CustomIceBreak;
          case "CustomItemCast":
              return CustomItemCast;
          case "CustomMoneyPop":
              return CustomMoneyPop;
          case "CustomSuperCast":
              return CustomSuperCast;
          case "CustomTaskDesk":
              return CustomTaskDesk;
          case "CustomTowerOption":
              return CustomTowerOption;
          case "CustomTowerOptionDailyDamage":
              return CustomTowerOptionDailyDamage;
          case "CustomTowerOptionFinalWar":
              return CustomTowerOptionFinalWar;
          case "CustomWechatHutuiListVer":
              return CustomWechatHutuiListVer;
          case "CustomWechatHutuiSingle":
              return CustomWechatHutuiSingle;
          case "CustomBattleBar":
              return CustomBattleBar;
          case "CustomGameHand":
              return CustomGameHand;
          case "CustomGameHand2":
              return CustomGameHand2;
          case "PanelADFree":
              return PanelADFree;
          case "PanelComing":
              return PanelComing;
          case "PanelGame":
              return PanelGame;
          case "PanelGameDebug":
              return PanelGameDebug;
          case "PanelIdle":
              return PanelIdle;
          case "PanelPirate":
              return PanelPirate;
          case "PanelRewardFactor":
              return PanelRewardFactor;
          case "PanelTowerSlotUnlock":
              return PanelTowerSlotUnlock;
          case "PanelWarning":
              return PanelWarning;
          case "PanelBossComing":
              return PanelBossComing;
          case "PanelBossComing2":
              return PanelBossComing2;
          case "PanelMenuBuff":
              return PanelMenuBuff;
          case "PanelDropBoxAD":
              return PanelDropBoxAD;
          case "CustomWinItem":
              return CustomWinItem;
          case "PanelGameLose":
              return PanelGameLose;
          case "PanelGameWin":
              return PanelGameWin;
          case "PanelGameWinReward":
              return PanelGameWinReward;
          case "CustomGrowLvupItem":
              return CustomGrowLvupItem;
          case "CustomGrowPage1Item":
              return CustomGrowPage1Item;
          case "CustomGrowPage1SubItem":
              return CustomGrowPage1SubItem;
          case "CustomGrowPage2Item":
              return CustomGrowPage2Item;
          case "CustomGrowPage2SubItem":
              return CustomGrowPage2SubItem;
          case "CustomGrowPage3Item":
              return CustomGrowPage3Item;
          case "CustomGrowPage3SubItem":
              return CustomGrowPage3SubItem;
          case "CustomGrowPage4Item":
              return CustomGrowPage4Item;
          case "CustomGrowPage4SubItem":
              return CustomGrowPage4SubItem;
          case "CustomGrowQualityupItem":
              return CustomGrowQualityupItem;
          case "CustomGrowStarupItem":
              return CustomGrowStarupItem;
          case "CustomGrowPage1":
              return CustomGrowPage1;
          case "CustomGrowPage2":
              return CustomGrowPage2;
          case "CustomGrowPage3":
              return CustomGrowPage3;
          case "CustomGrowPage4":
              return CustomGrowPage4;
          case "PanelGrow":
              return PanelGrow;
          case "PanelGrowTip":
              return PanelGrowTip;
          case "PanelGrowPop":
              return PanelGrowPop;
          case "CustomHolyItemBuildItem":
              return CustomHolyItemBuildItem;
          case "CustomHolyItemCondition":
              return CustomHolyItemCondition;
          case "CustomHolyItemConditionBuild":
              return CustomHolyItemConditionBuild;
          case "CustomHolyItemConditionSell":
              return CustomHolyItemConditionSell;
          case "CustomHolyItemFilterItem":
              return CustomHolyItemFilterItem;
          case "CustomSubCondition":
              return CustomSubCondition;
          case "PanelBagEx":
              return PanelBagEx;
          case "PanelHolyItemAutoSell":
              return PanelHolyItemAutoSell;
          case "PanelHolyItemBag":
              return PanelHolyItemBag;
          case "PanelHolyItemBuilder":
              return PanelHolyItemBuilder;
          case "PanelHolyItemBuilderBox":
              return PanelHolyItemBuilderBox;
          case "PanelHolyItemFilter":
              return PanelHolyItemFilter;
          case "CustomProgressLvup":
              return CustomProgressLvup;
          case "PanelHolyItemChoose":
              return PanelHolyItemChoose;
          case "PanelHolyItemChooseSmelter":
              return PanelHolyItemChooseSmelter;
          case "PanelHolyItemChooseWash":
              return PanelHolyItemChooseWash;
          case "PanelHolyItemLvup":
              return PanelHolyItemLvup;
          case "PanelHolyItemLvupSuc":
              return PanelHolyItemLvupSuc;
          case "CustomTowerIntro":
              return CustomTowerIntro;
          case "PanelIceBreak":
              return PanelIceBreak;
          case "CustomUnlockItem":
              return CustomUnlockItem;
          case "PanelIntroBag":
              return PanelIntroBag;
          case "PanelIntroBoss":
              return PanelIntroBoss;
          case "PanelIntroChallenge":
              return PanelIntroChallenge;
          case "PanelIntroGoal":
              return PanelIntroGoal;
          case "PanelIntroPeace":
              return PanelIntroPeace;
          case "PanelIntroPray":
              return PanelIntroPray;
          case "PanelIntroStory":
              return PanelIntroStory;
          case "PanelIntroSummon":
              return PanelIntroSummon;
          case "PanelIntroUnlock":
              return PanelIntroUnlock;
          case "CustomGetItem":
              return CustomGetItem;
          case "CustomItemSelect":
              return CustomItemSelect;
          case "PanelItemGet":
              return PanelItemGet;
          case "PanelItemSelect":
              return PanelItemSelect;
          case "PanelLoading":
              return PanelLoading;
          case "PanelLoadingGame":
              return PanelLoadingGame;
          case "PanelWait":
              return PanelWait;
          case "CustomMainSkillItem":
              return CustomMainSkillItem;
          case "PanelMainHeroUnlock":
              return PanelMainHeroUnlock;
          case "PanelTowerMainHero":
              return PanelTowerMainHero;
          case "CustomNewyearShop1":
              return CustomNewyearShop1;
          case "CustomNewyearShopItem":
              return CustomNewyearShopItem;
          case "CustomTaskItemNewyear":
              return CustomTaskItemNewyear;
          case "CustomNewyearPage1":
              return CustomNewyearPage1;
          case "CustomNewyearPage2":
              return CustomNewyearPage2;
          case "CustomNewyearPage3":
              return CustomNewyearPage3;
          case "CustomNewyearPage4":
              return CustomNewyearPage4;
          case "CustomSignItemNewyear":
              return CustomSignItemNewyear;
          case "PanelNewyear":
              return PanelNewyear;
          case "PanelNewyearIntro":
              return PanelNewyearIntro;
          case "CustomNewyearBar":
              return CustomNewyearBar;
          case "PanelNewyearGame":
              return PanelNewyearGame;
          case "PanelNewyearGameResult":
              return PanelNewyearGameResult;
          case "PanelNextDayReward":
              return PanelNextDayReward;
          case "PanelNotice":
              return PanelNotice;
          case "CustomOfflineItem":
              return CustomOfflineItem;
          case "PanelOffline":
              return PanelOffline;
          case "PanelOfflineSubscription":
              return PanelOfflineSubscription;
          case "CustomPrayBox":
              return CustomPrayBox;
          case "CustomPrayBoxItem":
              return CustomPrayBoxItem;
          case "CustomPrayCoin":
              return CustomPrayCoin;
          case "PanelPray":
              return PanelPray;
          case "PanelSecretDailyReward":
              return PanelSecretDailyReward;
          case "PanelTowerRushReward":
              return PanelTowerRushReward;
          case "CustomSecretShopItem":
              return CustomSecretShopItem;
          case "CustomSecretShopItemTop":
              return CustomSecretShopItemTop;
          case "CustomSecretTowerItem":
              return CustomSecretTowerItem;
          case "CustomSecretWord":
              return CustomSecretWord;
          case "CustomSelectLayer":
              return CustomSelectLayer;
          case "CustomSecretCard":
              return CustomSecretCard;
          case "CustomSecretChallenge":
              return CustomSecretChallenge;
          case "CustomSecretShop":
              return CustomSecretShop;
          case "CustomSecretTowerPrice":
              return CustomSecretTowerPrice;
          case "CustomSecretTowerUp":
              return CustomSecretTowerUp;
          case "CustomSecretUp":
              return CustomSecretUp;
          case "PanelSecret":
              return PanelSecret;
          case "PanelSecretKeyAdd":
              return PanelSecretKeyAdd;
          case "PanelSecretSelectLayer":
              return PanelSecretSelectLayer;
          case "PanelSecretSelectTower":
              return PanelSecretSelectTower;
          case "PanelSecretTowerUpSuc":
              return PanelSecretTowerUpSuc;
          case "PanelCheckNetworkFail":
              return PanelCheckNetworkFail;
          case "PanelSetting":
              return PanelSetting;
          case "CustomShopItemBusiness":
              return CustomShopItemBusiness;
          case "CustomShopItemExtra":
              return CustomShopItemExtra;
          case "CustomShopBusinessman":
              return CustomShopBusinessman;
          case "CustomShopSupply":
              return CustomShopSupply;
          case "PanelShop":
              return PanelShop;
          case "CustomSignItem":
              return CustomSignItem;
          case "CustomSignItemBig":
              return CustomSignItemBig;
          case "CustomSignWeek":
              return CustomSignWeek;
          case "PanelSign":
              return PanelSign;
          case "CustomSmelterHolyItem":
              return CustomSmelterHolyItem;
          case "CustomSmelterPrice":
              return CustomSmelterPrice;
          case "CustomSmelterPrice1":
              return CustomSmelterPrice1;
          case "CustomlSmelterForge":
              return CustomlSmelterForge;
          case "CustomlSmelterLvup":
              return CustomlSmelterLvup;
          case "CustomlSmelterRebuild":
              return CustomlSmelterRebuild;
          case "CustomlSmelterWash":
              return CustomlSmelterWash;
          case "PanelSmelter":
              return PanelSmelter;
          case "PanelSmelterAutoPut":
              return PanelSmelterAutoPut;
          case "PanelSmelterQualityUpSuc":
              return PanelSmelterQualityUpSuc;
          case "PanelSmelterSelectItem":
              return PanelSmelterSelectItem;
          case "PanelSmelterSuc":
              return PanelSmelterSuc;
          case "PanelSplash":
              return PanelSplash;
          case "CustomStatisItem":
              return CustomStatisItem;
          case "PanelGameStatis":
              return PanelGameStatis;
          case "CustomTalentInfo":
              return CustomTalentInfo;
          case "CustomTalentItem":
              return CustomTalentItem;
          case "PanelTalent":
              return PanelTalent;
          case "CustomGoalItem":
              return CustomGoalItem;
          case "CustomGoalScoreFly":
              return CustomGoalScoreFly;
          case "CustomTaskGoal":
              return CustomTaskGoal;
          case "CustomTaskTask":
              return CustomTaskTask;
          case "PanelTask":
              return PanelTask;
          case "CustomSevenDayItem":
              return CustomSevenDayItem;
          case "CustomTaskSevenItem":
              return CustomTaskSevenItem;
          case "CustomTaskSevenScoreItem":
              return CustomTaskSevenScoreItem;
          case "PanelTaskSeven":
              return PanelTaskSeven;
          case "CustomCrossBow":
              return CustomCrossBow;
          case "CustomHolyItemInfo":
              return CustomHolyItemInfo;
          case "CustomLvBreakPrice":
              return CustomLvBreakPrice;
          case "CustomTowerSkillInfo":
              return CustomTowerSkillInfo;
          case "PanelAddPoint":
              return PanelAddPoint;
          case "PanelAddPointFinalWar":
              return PanelAddPointFinalWar;
          case "PanelHolyitemSlotUnlock":
              return PanelHolyitemSlotUnlock;
          case "PanelTowerInfo":
              return PanelTowerInfo;
          case "PanelTowerLvBreak":
              return PanelTowerLvBreak;
          case "PanelTowerNew":
              return PanelTowerNew;
          case "CustomMapTower":
              return CustomMapTower;
          case "CustomMoverDialog":
              return CustomMoverDialog;
          case "PanelTowerShow":
              return PanelTowerShow;
          case "CustomTowerShow":
              return CustomTowerShow;
          case "PanelTowerStar":
              return PanelTowerStar;
          default:
              console.error("找不到面板:", name);
              return null;
      }
  }
  function registerClass() {
      fgui.UIObjectFactory.extensions["ui://alltower_equip/CustomAEPrice"] = CustomAEPrice;
      fgui.UIObjectFactory.extensions["ui://alltower_equip/CustomAEWordItem"] = CustomAEWordItem;
      fgui.UIObjectFactory.extensions["ui://alltower_equip/CustomTowerEquipItem"] = CustomTowerEquipItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomCommItem"] = CustomCommItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomItem"] = CustomItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomSkillDetail"] = CustomSkillDetail;
      fgui.UIObjectFactory.extensions["ui://base/CustomGuideDialogLeft"] = CustomGuideDialogLeft;
      fgui.UIObjectFactory.extensions["ui://base/CustomGuideDialogRight"] = CustomGuideDialogRight;
      fgui.UIObjectFactory.extensions["ui://base/CustomAttrHolyItem"] = CustomAttrHolyItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomAttrHolyItem2"] = CustomAttrHolyItem2;
      fgui.UIObjectFactory.extensions["ui://base/CustomAttrHolyItem3"] = CustomAttrHolyItem3;
      fgui.UIObjectFactory.extensions["ui://base/CustomHolyItem"] = CustomHolyItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomHolyItemDesc"] = CustomHolyItemDesc;
      fgui.UIObjectFactory.extensions["ui://base/CustomHolyitemDescItem"] = CustomHolyitemDescItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomHolyItemInfoBag"] = CustomHolyItemInfoBag;
      fgui.UIObjectFactory.extensions["ui://base/CustomHolyItemInfoBagEx"] = CustomHolyItemInfoBagEx;
      fgui.UIObjectFactory.extensions["ui://base/CustomBarItem"] = CustomBarItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomBarStone"] = CustomBarStone;
      fgui.UIObjectFactory.extensions["ui://base/CustomBarTicket"] = CustomBarTicket;
      fgui.UIObjectFactory.extensions["ui://base/CustomDamageText"] = CustomDamageText;
      fgui.UIObjectFactory.extensions["ui://base/CustomDropItem"] = CustomDropItem;
      fgui.UIObjectFactory.extensions["ui://base/CustomDropItemFly"] = CustomDropItemFly;
      fgui.UIObjectFactory.extensions["ui://base/CustomH5ADDToDesk"] = CustomH5ADDToDesk;
      fgui.UIObjectFactory.extensions["ui://base/CustomHolyItemIntro"] = CustomHolyItemIntro;
      fgui.UIObjectFactory.extensions["ui://base/CustomHpBar"] = CustomHpBar;
      fgui.UIObjectFactory.extensions["ui://base/CustomHpBarTower"] = CustomHpBarTower;
      fgui.UIObjectFactory.extensions["ui://base/CustomHpBarTowerMain"] = CustomHpBarTowerMain;
      fgui.UIObjectFactory.extensions["ui://base/CustomItemInfo"] = CustomItemInfo;
      fgui.UIObjectFactory.extensions["ui://base/CustomLayerFit"] = CustomLayerFit;
      fgui.UIObjectFactory.extensions["ui://base/CustomMoney"] = CustomMoney;
      fgui.UIObjectFactory.extensions["ui://base/CustomMoneyBar"] = CustomMoneyBar;
      fgui.UIObjectFactory.extensions["ui://base/CustomNodeEffect"] = CustomNodeEffect;
      fgui.UIObjectFactory.extensions["ui://base/CustomTowerHead"] = CustomTowerHead;
      fgui.UIObjectFactory.extensions["ui://boxreward/CustomBoxrewardItem"] = CustomBoxrewardItem;
      fgui.UIObjectFactory.extensions["ui://card/CustomSummonProb"] = CustomSummonProb;
      fgui.UIObjectFactory.extensions["ui://card/CustomSummon"] = CustomSummon;
      fgui.UIObjectFactory.extensions["ui://card/CustomSummonCard"] = CustomSummonCard;
      fgui.UIObjectFactory.extensions["ui://card/CustomSummonItem"] = CustomSummonItem;
      fgui.UIObjectFactory.extensions["ui://card/CustomSummonItemSub"] = CustomSummonItemSub;
      fgui.UIObjectFactory.extensions["ui://challenge/CustomChallengeItem"] = CustomChallengeItem;
      fgui.UIObjectFactory.extensions["ui://challenge/CustomTaskChapter"] = CustomTaskChapter;
      fgui.UIObjectFactory.extensions["ui://challenge/CustomTaskStep"] = CustomTaskStep;
      fgui.UIObjectFactory.extensions["ui://challenge/CustomChallengeBoss"] = CustomChallengeBoss;
      fgui.UIObjectFactory.extensions["ui://challenge/CustomChallengeMain"] = CustomChallengeMain;
      fgui.UIObjectFactory.extensions["ui://collect/CustomCollectEnemy"] = CustomCollectEnemy;
      fgui.UIObjectFactory.extensions["ui://collect/CustomCollectHolyitem"] = CustomCollectHolyitem;
      fgui.UIObjectFactory.extensions["ui://collect/CustomCollectTower"] = CustomCollectTower;
      fgui.UIObjectFactory.extensions["ui://dailydamage/CustomDailyDamageDesc"] = CustomDailyDamageDesc;
      fgui.UIObjectFactory.extensions["ui://dailydamage/CustomDailyDmageHistoryItem"] = CustomDailyDmageHistoryItem;
      fgui.UIObjectFactory.extensions["ui://dailydamage_ad/CustomDailyDamageADItem"] = CustomDailyDamageADItem;
      fgui.UIObjectFactory.extensions["ui://dailydamage_game/CustomDailyDamageBar"] = CustomDailyDamageBar;
      fgui.UIObjectFactory.extensions["ui://deploy/CustomAttrList"] = CustomAttrList;
      fgui.UIObjectFactory.extensions["ui://deploy/CustomTowerInfo"] = CustomTowerInfo;
      fgui.UIObjectFactory.extensions["ui://editor/CustomScaleBar"] = CustomScaleBar;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExploreHead"] = CustomExploreHead;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExploreHolyItem"] = CustomExploreHolyItem;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExploreShopItem"] = CustomExploreShopItem;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExploreTowerItem"] = CustomExploreTowerItem;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExplorePage1"] = CustomExplorePage1;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExplorePage2"] = CustomExplorePage2;
      fgui.UIObjectFactory.extensions["ui://explore/CustomExplorePage3"] = CustomExplorePage3;
      fgui.UIObjectFactory.extensions["ui://fb_coin/CustomFBCoinItem"] = CustomFBCoinItem;
      fgui.UIObjectFactory.extensions["ui://fb_item/CustomFBItemItem"] = CustomFBItemItem;
      fgui.UIObjectFactory.extensions["ui://fb_item_show/CustomFBItemShowItem1"] = CustomFBItemShowItem1;
      fgui.UIObjectFactory.extensions["ui://fb_item_show/CustomFBItemShowItem2"] = CustomFBItemShowItem2;
      fgui.UIObjectFactory.extensions["ui://fb_item_show/CustomFBItemShowLine1"] = CustomFBItemShowLine1;
      fgui.UIObjectFactory.extensions["ui://fb_item_show/CustomFBItemShowLine2"] = CustomFBItemShowLine2;
      fgui.UIObjectFactory.extensions["ui://finalwar/CustomFianlWarItem"] = CustomFianlWarItem;
      fgui.UIObjectFactory.extensions["ui://finalwar/CustomHopelessWarItem"] = CustomHopelessWarItem;
      fgui.UIObjectFactory.extensions["ui://finalwar_shop/CustomFinalWarShopItem"] = CustomFinalWarShopItem;
      fgui.UIObjectFactory.extensions["ui://game/CustomBossCrazy"] = CustomBossCrazy;
      fgui.UIObjectFactory.extensions["ui://game/CustomBoxReward"] = CustomBoxReward;
      fgui.UIObjectFactory.extensions["ui://game/CustomBroadcast"] = CustomBroadcast;
      fgui.UIObjectFactory.extensions["ui://game/CustomGuideTip"] = CustomGuideTip;
      fgui.UIObjectFactory.extensions["ui://game/CustomH5Share"] = CustomH5Share;
      fgui.UIObjectFactory.extensions["ui://game/CustomH5VideoRecord"] = CustomH5VideoRecord;
      fgui.UIObjectFactory.extensions["ui://game/CustomHandSkill"] = CustomHandSkill;
      fgui.UIObjectFactory.extensions["ui://game/CustomHandSkillBig"] = CustomHandSkillBig;
      fgui.UIObjectFactory.extensions["ui://game/CustomIceBreak"] = CustomIceBreak;
      fgui.UIObjectFactory.extensions["ui://game/CustomItemCast"] = CustomItemCast;
      fgui.UIObjectFactory.extensions["ui://game/CustomMoneyPop"] = CustomMoneyPop;
      fgui.UIObjectFactory.extensions["ui://game/CustomSuperCast"] = CustomSuperCast;
      fgui.UIObjectFactory.extensions["ui://game/CustomTaskDesk"] = CustomTaskDesk;
      fgui.UIObjectFactory.extensions["ui://game/CustomTowerOption"] = CustomTowerOption;
      fgui.UIObjectFactory.extensions["ui://game/CustomTowerOptionDailyDamage"] = CustomTowerOptionDailyDamage;
      fgui.UIObjectFactory.extensions["ui://game/CustomTowerOptionFinalWar"] = CustomTowerOptionFinalWar;
      fgui.UIObjectFactory.extensions["ui://game/CustomWechatHutuiListVer"] = CustomWechatHutuiListVer;
      fgui.UIObjectFactory.extensions["ui://game/CustomWechatHutuiSingle"] = CustomWechatHutuiSingle;
      fgui.UIObjectFactory.extensions["ui://game/CustomBattleBar"] = CustomBattleBar;
      fgui.UIObjectFactory.extensions["ui://game/CustomGameHand"] = CustomGameHand;
      fgui.UIObjectFactory.extensions["ui://game/CustomGameHand2"] = CustomGameHand2;
      fgui.UIObjectFactory.extensions["ui://game_result/CustomWinItem"] = CustomWinItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowLvupItem"] = CustomGrowLvupItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage1Item"] = CustomGrowPage1Item;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage1SubItem"] = CustomGrowPage1SubItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage2Item"] = CustomGrowPage2Item;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage2SubItem"] = CustomGrowPage2SubItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage3Item"] = CustomGrowPage3Item;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage3SubItem"] = CustomGrowPage3SubItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage4Item"] = CustomGrowPage4Item;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage4SubItem"] = CustomGrowPage4SubItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowQualityupItem"] = CustomGrowQualityupItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowStarupItem"] = CustomGrowStarupItem;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage1"] = CustomGrowPage1;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage2"] = CustomGrowPage2;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage3"] = CustomGrowPage3;
      fgui.UIObjectFactory.extensions["ui://grow/CustomGrowPage4"] = CustomGrowPage4;
      fgui.UIObjectFactory.extensions["ui://holyitem/CustomHolyItemBuildItem"] = CustomHolyItemBuildItem;
      fgui.UIObjectFactory.extensions["ui://holyitem/CustomHolyItemCondition"] = CustomHolyItemCondition;
      fgui.UIObjectFactory.extensions["ui://holyitem/CustomHolyItemConditionBuild"] = CustomHolyItemConditionBuild;
      fgui.UIObjectFactory.extensions["ui://holyitem/CustomHolyItemConditionSell"] = CustomHolyItemConditionSell;
      fgui.UIObjectFactory.extensions["ui://holyitem/CustomHolyItemFilterItem"] = CustomHolyItemFilterItem;
      fgui.UIObjectFactory.extensions["ui://holyitem/CustomSubCondition"] = CustomSubCondition;
      fgui.UIObjectFactory.extensions["ui://holyitem_lvup/CustomProgressLvup"] = CustomProgressLvup;
      fgui.UIObjectFactory.extensions["ui://icebreak/CustomTowerIntro"] = CustomTowerIntro;
      fgui.UIObjectFactory.extensions["ui://intro/CustomUnlockItem"] = CustomUnlockItem;
      fgui.UIObjectFactory.extensions["ui://item_get/CustomGetItem"] = CustomGetItem;
      fgui.UIObjectFactory.extensions["ui://item_get/CustomItemSelect"] = CustomItemSelect;
      fgui.UIObjectFactory.extensions["ui://main_hero/CustomMainSkillItem"] = CustomMainSkillItem;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomNewyearShop1"] = CustomNewyearShop1;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomNewyearShopItem"] = CustomNewyearShopItem;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomTaskItemNewyear"] = CustomTaskItemNewyear;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomNewyearPage1"] = CustomNewyearPage1;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomNewyearPage2"] = CustomNewyearPage2;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomNewyearPage3"] = CustomNewyearPage3;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomNewyearPage4"] = CustomNewyearPage4;
      fgui.UIObjectFactory.extensions["ui://newyear/CustomSignItemNewyear"] = CustomSignItemNewyear;
      fgui.UIObjectFactory.extensions["ui://newyear_game/CustomNewyearBar"] = CustomNewyearBar;
      fgui.UIObjectFactory.extensions["ui://offline/CustomOfflineItem"] = CustomOfflineItem;
      fgui.UIObjectFactory.extensions["ui://pray/CustomPrayBox"] = CustomPrayBox;
      fgui.UIObjectFactory.extensions["ui://pray/CustomPrayBoxItem"] = CustomPrayBoxItem;
      fgui.UIObjectFactory.extensions["ui://pray/CustomPrayCoin"] = CustomPrayCoin;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretShopItem"] = CustomSecretShopItem;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretShopItemTop"] = CustomSecretShopItemTop;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretTowerItem"] = CustomSecretTowerItem;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretWord"] = CustomSecretWord;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSelectLayer"] = CustomSelectLayer;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretCard"] = CustomSecretCard;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretChallenge"] = CustomSecretChallenge;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretShop"] = CustomSecretShop;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretTowerPrice"] = CustomSecretTowerPrice;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretTowerUp"] = CustomSecretTowerUp;
      fgui.UIObjectFactory.extensions["ui://secret/CustomSecretUp"] = CustomSecretUp;
      fgui.UIObjectFactory.extensions["ui://shop/CustomShopItemBusiness"] = CustomShopItemBusiness;
      fgui.UIObjectFactory.extensions["ui://shop/CustomShopItemExtra"] = CustomShopItemExtra;
      fgui.UIObjectFactory.extensions["ui://shop/CustomShopBusinessman"] = CustomShopBusinessman;
      fgui.UIObjectFactory.extensions["ui://shop/CustomShopSupply"] = CustomShopSupply;
      fgui.UIObjectFactory.extensions["ui://sign/CustomSignItem"] = CustomSignItem;
      fgui.UIObjectFactory.extensions["ui://sign/CustomSignItemBig"] = CustomSignItemBig;
      fgui.UIObjectFactory.extensions["ui://sign/CustomSignWeek"] = CustomSignWeek;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomSmelterHolyItem"] = CustomSmelterHolyItem;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomSmelterPrice"] = CustomSmelterPrice;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomSmelterPrice1"] = CustomSmelterPrice1;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomlSmelterForge"] = CustomlSmelterForge;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomlSmelterLvup"] = CustomlSmelterLvup;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomlSmelterRebuild"] = CustomlSmelterRebuild;
      fgui.UIObjectFactory.extensions["ui://smelter/CustomlSmelterWash"] = CustomlSmelterWash;
      fgui.UIObjectFactory.extensions["ui://statis/CustomStatisItem"] = CustomStatisItem;
      fgui.UIObjectFactory.extensions["ui://talent/CustomTalentInfo"] = CustomTalentInfo;
      fgui.UIObjectFactory.extensions["ui://talent/CustomTalentItem"] = CustomTalentItem;
      fgui.UIObjectFactory.extensions["ui://task/CustomGoalItem"] = CustomGoalItem;
      fgui.UIObjectFactory.extensions["ui://task/CustomGoalScoreFly"] = CustomGoalScoreFly;
      fgui.UIObjectFactory.extensions["ui://task/CustomTaskGoal"] = CustomTaskGoal;
      fgui.UIObjectFactory.extensions["ui://task/CustomTaskTask"] = CustomTaskTask;
      fgui.UIObjectFactory.extensions["ui://task_seven/CustomSevenDayItem"] = CustomSevenDayItem;
      fgui.UIObjectFactory.extensions["ui://task_seven/CustomTaskSevenItem"] = CustomTaskSevenItem;
      fgui.UIObjectFactory.extensions["ui://task_seven/CustomTaskSevenScoreItem"] = CustomTaskSevenScoreItem;
      fgui.UIObjectFactory.extensions["ui://tower/CustomCrossBow"] = CustomCrossBow;
      fgui.UIObjectFactory.extensions["ui://tower_info/CustomHolyItemInfo"] = CustomHolyItemInfo;
      fgui.UIObjectFactory.extensions["ui://tower_info/CustomLvBreakPrice"] = CustomLvBreakPrice;
      fgui.UIObjectFactory.extensions["ui://tower_info/CustomTowerSkillInfo"] = CustomTowerSkillInfo;
      fgui.UIObjectFactory.extensions["ui://tower_show/CustomMapTower"] = CustomMapTower;
      fgui.UIObjectFactory.extensions["ui://tower_show/CustomMoverDialog"] = CustomMoverDialog;
      fgui.UIObjectFactory.extensions["ui://tower_star/CustomTowerShow"] = CustomTowerShow;
  }

  var MAIL_STATE;
  (function (MAIL_STATE) {
      MAIL_STATE[MAIL_STATE["NEW"] = 0] = "NEW";
      MAIL_STATE[MAIL_STATE["READ"] = 1] = "READ";
      MAIL_STATE[MAIL_STATE["GET"] = 2] = "GET";
  })(MAIL_STATE || (MAIL_STATE = {}));
  class mgrMail extends Manager {
      static loadRecord() {
          this.data = FileRecord.getData(this.RECORD_KEY);
          if (!this.data) {
              this.data = this.dataDefault;
              this.saveRecord();
          }
          else {
              this.checkRecord(this.data, this.dataDefault);
          }
          console.log("mgrMail.loadRecord", this.data);
      }
      static saveRecord() {
          FileRecord.setData(this.RECORD_KEY, this.data);
      }
      static getUserEmail() {
          let config = ULConfig.getConfig();
          let cop_game_id = config.s_sdk_cop_game_id;
          let url = `http://common.ultralisk.cn/email/getUserEmail?gameId=${cop_game_id}&userId=${mgrSdk.uuid}`;
          let timeout = config.i_net_timeout;
          ULTools.httpGet({
              url: url,
              timeoutMillisecond: timeout,
              success: (responseText) => {
                  console.warn("O_O mgrMail.getUserEmail suc", responseText);
                  try {
                      this.onGetUserEmailResult(JSON.parse(responseText));
                  }
                  catch (error) {
                      console.error("mgrMail.getUserEmail: Json.parse error", error);
                  }
              },
              fail: (error) => {
                  console.error("O_O mgrMail.getUserEmail fail", error);
              },
          });
      }
      static onGetUserEmailResult(data) {
          if (!data)
              return;
          let mails = data.data;
          if (data.code == 0 && mails && mails instanceof Array) {
              this.dealNewMailsFromServer(mails);
          }
          else {
              console.error("mgrMail.onGetUserEmailResult error", data.msg, data.data);
          }
      }
      static dealNewMailsFromServer(mails) {
          if (!mails || mails.length == 0)
              return;
          for (let mail of mails) {
              this.saveMail(mail);
          }
      }
      static saveMail(mail) {
          if (mail && !this.findMailById(mail.id)) {
              mail.state = MAIL_STATE.NEW,
                  this.data.mails[mail.id] = mail;
              this.saveRecord();
          }
      }
      static delMailById(id) {
          let mail = this.data.mails[id];
          if (mail) {
              this.data.mails[id] = null;
              delete this.data.mails[id];
              this.saveRecord();
          }
      }
      static findMailById(id) {
          return this.data.mails[id];
      }
      static getMailRewardById(id, show = true) {
          let mail = this.findMailById(id);
          if (mail && mail.state != MAIL_STATE.GET) {
              let attachment = mail.attachment;
              if (attachment && attachment.length) {
                  let dropData = [];
                  for (let i = 0; i < attachment.length; i++) {
                      let itemData = attachment[i];
                      if (itemData) {
                          let itemId = itemData[0];
                          let amount = itemData[1];
                          if (itemId && amount) {
                              mgrGame.addItem(itemId, amount, 72, false, dropData);
                          }
                      }
                  }
                  if (show) {
                      Level.showItemGet(dropData);
                  }
                  mail.state = MAIL_STATE.GET;
                  this.saveRecord();
              }
          }
      }
      static checkMailExpiration() {
          for (let id in this.data.mails) {
              let mail = this.data.mails[id];
              if (mail && mail.id != null && mail.expiration != null) {
                  if (mail.expiration <= mgrTime.curtTime()) {
                      this.delMailById(mail.id);
                  }
              }
          }
      }
      static getMailList() {
          this.checkMailExpiration();
          let listData = [];
          for (let id in this.data.mails) {
              let mail = this.data.mails[id];
              if (mail) {
                  listData.push(mail);
              }
          }
          return listData;
      }
  }
  mgrMail.RECORD_KEY = "game166_mail_v1.0";
  mgrMail.dataDefault = {
      mails: {},
  };

  class UIDebug extends View {
      constructor() {
          super();
      }
      loadUI() {
          this.loadUIComponent("test", "debug");
      }
      parseUI() {
          this.list = this.uiRoot.getChild("list").asList;
          this.list.setVirtual();
          this.list.itemRenderer = Laya.Handler.create(this, this.renderListItem, null, false);
          this.list.on(fgui.Events.CLICK_ITEM, this, this.onClickItem);
          this.uiRoot.getChild("close").onClick(this, this.onClickClose);
      }
      onShow() {
      }
      showData(data, onClickListItem) {
          this.onClickListItem = onClickListItem;
          this.listData = data;
          this.list.numItems = data.length;
      }
      renderListItem(index, obj) {
          let itemData = this.listData[index];
          if (itemData) {
              obj.asCom.getChild("text").asTextField.text = itemData.name || itemData;
          }
          obj.data = index;
      }
      onClickItem(obj) {
          let index = obj.data;
          let itemData = this.listData[index];
          if (itemData && itemData.callback) {
              itemData.callback(this, itemData);
          }
          if (this.onClickListItem) {
              this.onClickListItem(this, itemData);
          }
      }
      onClickClose() {
          this.remove();
      }
  }

  class UIEditor extends View {
      constructor() {
          super();
      }
      loadUI() {
          this.loadUIComponent("test", "editor");
      }
      parseUI() {
          this.list = this.uiRoot.getChild("list").asList;
          this.listview = new ListView(this.list, this, this.parseItem, this.renderItem);
          this.listview.setOnClickItem(this, this.onClickItem);
          this.uiRoot.getChild("close").onClick(this, this.onClickClose);
      }
      parseItem(content, object) {
          content.text = object.getChild("text").asTextField;
          content.input = object.getChild("input").asTextInput;
          content.add = object.getChild("add").asButton;
          content.sub = object.getChild("sub").asButton;
          content.input.on(Laya.Event.INPUT, this, this.onTextChange, [content]);
          content.add.onClick(this, this.onClickAdd, [content]);
          content.sub.onClick(this, this.onClickSub, [content]);
      }
      renderItem(content, data) {
          content.data = data;
          content.text.text = data.name;
          if (data.owner && data.ownerKey && data.owner[data.ownerKey]) {
              content.input.text = data.owner[data.ownerKey].toString();
          }
      }
      onTextChange(content) {
          let data = content.data;
          let textInput = content.input.text;
          let numInput = Number(textInput);
          if (numInput && data.owner && data.ownerKey) {
              data.owner[data.ownerKey] = numInput;
              this.save();
          }
      }
      onClickAdd(content) {
          let data = content.data;
          if (data.owner && data.ownerKey) {
              data.owner[data.ownerKey]++;
              this.save();
          }
          this.renderItem(content, content.data);
      }
      onClickSub(content) {
          let data = content.data;
          if (data.owner && data.ownerKey) {
              data.owner[data.ownerKey]--;
              this.save();
          }
          this.renderItem(content, content.data);
      }
      save() {
          if (this.callbackSave) {
              this.callbackSave();
          }
      }
      onShow() {
      }
      showData(data, callbackSave) {
          this.callbackSave = callbackSave;
          this.listview.setListData(data);
      }
      onClickItem(content) {
      }
      onClickClose() {
          this.remove();
      }
  }

  let gridW$2 = Level.gridW;
  let gridH$2 = Level.gridH;
  let tileW$2 = Level.tileW;
  let tileH$2 = Level.tileH;
  let gridCenterX$2 = Math.floor(gridW$2 / 2) - 1;
  let gridCenterY$2 = Math.floor(gridH$2 / 2) - 1;
  class StageGameDebug extends StageGame {
      constructor() {
          super(...arguments);
          this.seletTowerId = "0";
      }
      onStart() {
          StageConfig.enableEnemyWave = false;
          this.refresh();
      }
      refresh() {
          this.world.remAllUnit();
          this.loadTowerByIdAndSlotId(this.seletTowerId, 1);
          let pList = this.world.map.findCirleByRangeAndDegree2(gridCenterX$2 - 7, gridCenterY$2, gridCenterX$2, gridCenterY$2, 10);
          for (let p of pList) {
              this.world.addEnemy(EnemyIdle, p.x, p.y, "1");
          }
      }
      onTowerDebugChange(id) {
          this.seletTowerId = id;
          this.refresh();
      }
  }

  class SceneGameDebug extends SceneGame {
      onSceneGameCreate(scene) {
          Laya.Stat.hide();
          this.scene2d = scene;
          scene.addComponent(StageGameDebug);
          Director.disposeAllPanel();
          Director.openPanelWithSingleton("PanelGameDebug");
      }
  }

  class GameRegister {
      static regist() {
          this.registManager();
          this.registScene();
          this.registView();
          this.registValue();
          this.registComponent();
      }
      static registComponent() {
      }
      static registScene() {
      }
      static registView() {
          UIManager.getInstance()
              .registUIClas("debug", UIDebug, true)
              .registUIClas("editor", UIEditor, true);
          UIManager.getInstance();
          UIManager.getInstance().registDebugMenu([
              {
                  name: "切换调试场景",
                  callback: (view) => {
                      view.remove();
                      Director.runScene(SceneGameDebug);
                  }
              },
              {
                  name: "切换塔",
                  callback: (view) => {
                      view.remove();
                      let towerDbMap = db.get_tower_db_map();
                      let listData = [];
                      for (let key in towerDbMap) {
                          let data = db.get_tower_db(key);
                          if (data.show) {
                              listData.push({
                                  name: data.name,
                                  data: data,
                              });
                          }
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          Global.sendMsg(MSG.TOWER_DEBUG_CHANGE, data.data.id);
                      });
                  }
              },
              {
                  name: "FPS面板",
                  callback: (view) => {
                      GameConfig.stat = !GameConfig.stat;
                      StageConfig.showFPS = GameConfig.stat;
                      if (GameConfig.stat)
                          Laya.Stat.show();
                      else
                          Laya.Stat.hide();
                  }
              },
              {
                  name: "清除存档",
                  callback: (view) => {
                      view.remove();
                      Laya.LocalStorage.clear();
                      if (Laya.Browser.window)
                          Laya.Browser.window.location.reload(true);
                  }
              },
              {
                  name: "周四重置",
                  callback: (view) => {
                      view.remove();
                      mgrSecret.onResetSecret();
                  }
              },
              {
                  name: "年兽奖励",
                  callback: (view) => {
                      view.remove();
                      let listData = db.get_newyear_fb_reward_map();
                      let listNum = [];
                      for (let item of listData) {
                          listNum.push(item.damage);
                      }
                      UIManager.getInstance().showDebugList(listNum, (view, damage) => {
                          view.remove();
                          mgrNewyear.markDamage(damage);
                          Director.openPanelWithSingleton("PanelNewyearGameResult");
                      });
                  }
              },
              {
                  name: "请求邮件",
                  callback: (view) => {
                      view.remove();
                      mgrMail.getUserEmail();
                  }
              },
              {
                  name: "时间信息",
                  callback: (view) => {
                      view.remove();
                      let info = "";
                      mgrTime.updateOnlineTime();
                      if (mgrTime.dataServerTimeChange) {
                          info = JSON.stringify(mgrTime.dataServerTimeChange);
                          info += "\n计算:" + mgrTime.getDateNumBySecond(Number(mgrTime.dataServerTimeChange.serverTime));
                          info += "\n在线:" + mgrTime.onlineTime / 1000;
                          info += "\n当前周数:" + mgrTime.getYearWeek(-3);
                      }
                      else {
                          info = "没有获取到服务器时间";
                      }
                      for (let i = 1; i <= 30; i++) {
                          console.log("-->", i + "号", mgrTime.getYearWeekTest(2022, 7, i));
                      }
                      let dateNum = mgrTime.getDateNumBySecond(Number(mgrTime.dataServerTimeChange.serverTime));
                      mgrTime.getDateByDateNum(dateNum);
                      mgrTip.alertPrompt(info);
                  }
              },
              {
                  name: "切换点击放置怪物",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      let enemyMap = db.get_role_db_map();
                      for (let k in enemyMap) {
                          let enemyDb = enemyMap[k];
                          listData.push({
                              name: enemyDb.name,
                              enemyId: enemyDb.id,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          StageConfig.configTouchEnemy.enable = true;
                          StageConfig.configTouchEnemy.enemyId = data.enemyId;
                      });
                  }
              },
              {
                  name: "游戏中调试界面",
                  callback: (view) => {
                      view.remove();
                      Director.openPanel("PanelGameDebug");
                  },
              },
              {
                  name: "立刻完成次日豪礼",
                  callback: (view) => {
                      view.remove();
                      mgrSign.nextdayTime -= 24 * 3600 * 1000;
                  }
              },
              {
                  name: "设置掉落倍率",
                  callback: (view) => {
                      view.remove();
                      let listData = [1, 10, 100, 1000];
                      UIManager.getInstance().showDebugList(listData, (view, scale) => {
                          view.remove();
                          StageConfig.scaleProbDropItem = scale;
                      });
                  }
              },
              {
                  name: "寻宝历练",
                  callback: (view) => {
                      view.remove();
                      let listData = [
                          {
                              name: "重置地图",
                              callback: (view) => {
                                  view.remove();
                                  mgrExplore.buildMapId(true);
                              }
                          },
                          {
                              name: "立刻完成",
                              callback: (view) => {
                                  view.remove();
                                  mgrExplore.allComplete();
                              }
                          },
                      ];
                      UIManager.getInstance().showDebugList(listData);
                  }
              },
              {
                  name: "新年庆典",
                  callback: (view) => {
                      view.remove();
                      let listData = [
                          {
                              name: "立刻完成任务",
                              callback: (view) => {
                                  view.remove();
                                  let tasks = mgrTask.getNewyearTask();
                                  for (let task of tasks) {
                                      mgrTask.setEvent(task.event_id, task.event_need[0]);
                                  }
                              }
                          },
                      ];
                      UIManager.getInstance().showDebugList(listData);
                  }
              },
              {
                  name: "7日任务",
                  callback: (view) => {
                      view.remove();
                      let listData = [
                          {
                              name: "设置天数",
                              callback: (view) => {
                                  view.remove();
                                  let listData = [0, 1, 2, 3, 4, 5, 6];
                                  UIManager.getInstance().showDebugList(listData, (view, day) => {
                                      view.remove();
                                      mgrTaskSeven.curtDay = day;
                                  });
                              }
                          },
                          {
                              name: "立刻完成任务",
                              callback: (view) => {
                                  view.remove();
                                  let tasks = mgrTaskSeven.getCurtTasks();
                                  for (let task of tasks) {
                                      mgrTask.setEvent(task.event_id, task.event_need[0]);
                                  }
                              }
                          },
                          {
                              name: "设置积分",
                              callback: (view) => {
                                  view.remove();
                                  let listData = [];
                                  let scoreMap = db.get_seven_score_db_map();
                                  for (let score of scoreMap) {
                                      listData.push(score.score);
                                  }
                                  UIManager.getInstance().showDebugList(listData, (view, score) => {
                                      view.remove();
                                      mgrTaskSeven.curtScore = score;
                                      Global.sendMsg(MSG.TASK_SEVEN_SCORE);
                                  });
                              }
                          },
                      ];
                      UIManager.getInstance().showDebugList(listData);
                  }
              },
              {
                  name: "设置熔岩武具等级",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      for (let i = 0; i <= 20; i++) {
                          listData.push(i);
                      }
                      UIManager.getInstance().showDebugList(listData, (view, level) => {
                          view.remove();
                          let itemMap = db.get_all_tower_equip_map();
                          for (let k in itemMap) {
                              mgrAllEquip.setEquipLv(k, level);
                          }
                      });
                  }
              },
              {
                  name: "设置歼灭战层级",
                  callback: (view) => {
                      view.remove();
                      let listData = [1, 10, 20, 30, 50, 100, 250, 500, 1000];
                      UIManager.getInstance().showDebugList(listData, (view, level) => {
                          view.remove();
                          let itemList = db.get_finalwar_db_map();
                          for (let item of itemList) {
                              mgrFinalWar.setFinalWarLevel(item.id, level);
                          }
                      });
                  }
              },
              {
                  name: "歼灭战扫荡",
                  callback: (view) => {
                      view.remove();
                      let itemList = db.get_finalwar_db_map();
                      UIManager.getInstance().showDebugList(itemList, (view, finalWarDb) => {
                          view.remove();
                          mgrFinalWar.sweep(finalWarDb);
                      });
                  }
              },
              {
                  name: "设置怪物层级",
                  callback: (view) => {
                      view.remove();
                      let listData = [1, 10, 20, 30, 50, 100, 250, 500, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000];
                      UIManager.getInstance().showDebugList(listData, (view, level) => {
                          view.remove();
                          mgrGame.levelId = level;
                          Level.load();
                      });
                  }
              },
              {
                  name: "设置塔的等级",
                  callback: (view) => {
                      view.remove();
                      let listData = [1, 10, 20, 30, 50, 100, 600, 999, 1000, 1500, 2000, 3000, 4000, 5000, 6000, 7000, 8000];
                      UIManager.getInstance().showDebugList(listData, (view, level) => {
                          view.remove();
                          mgrTower.setAllTowerLv(level);
                      });
                  }
              },
              {
                  name: "指定塔的等级",
                  callback: (view) => {
                      view.remove();
                      let itemMap = db.get_tower_db_map();
                      let listData = [];
                      for (let key in itemMap) {
                          let data = db.get_tower_db(key);
                          listData.push({
                              name: data.name,
                              id: data.id,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          let listData = [1, 10, 20, 30, 50, 100, 600, 999, 1000, 1500];
                          UIManager.getInstance().showDebugList(listData, (view, level) => {
                              view.remove();
                              mgrTower.setTowerLv(data.id, level);
                          });
                      });
                  }
              },
              {
                  name: "选择冲塔ID",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      let dataMap = db.get_rush_wave_db_map();
                      for (let id in dataMap) {
                          listData.push(id);
                      }
                      UIManager.getInstance().showDebugList(listData, (view, id) => {
                          view.remove();
                          Level.rushWaveId = id;
                          Global.sendMsg(MSG.TOWER_ENDNESS_BEGIN);
                      });
                  }
              },
              {
                  name: "主线故事解锁",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      let dataMap = db.get_main_story_map_map();
                      for (let id in dataMap) {
                          let cfgList = db.get_main_story_level_map()[id];
                          if (cfgList) {
                              for (let cfg of cfgList) {
                                  listData.push({
                                      name: cfg.id + "-" + cfg.lv,
                                      data: cfg,
                                  });
                              }
                          }
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          mgrGame.addLevelStoryAward(data.data.index);
                      });
                  }
              },
              {
                  name: "调试开关",
                  callback: (view) => {
                      view.remove();
                      let listData = [
                          {
                              name: "打印存档",
                              callback: (view) => {
                                  view.remove();
                                  let record = FileRecord.record;
                                  console.log("///////////////////////////存档数据");
                                  console.log(JSON.stringify(record));
                                  console.log("///////////////////////////存档数据");
                              }
                          },
                          {
                              name: "打印字体信息",
                              callback: (view) => {
                                  view.remove();
                                  let info = "";
                                  let textRender = Laya.Context._textRender;
                                  for (var f in textRender.mapFont) {
                                      var fontsz = textRender.getFontSizeInfo(f);
                                      var offx = fontsz >> 24;
                                      var offy = (fontsz >> 16) & 0xff;
                                      var fw = (fontsz >> 8) & 0xff;
                                      var fh = fontsz & 0xff;
                                      info += ('    ' + f + ' off:' + offx + "," + offy + ' size:' + fw + ", " + fh);
                                  }
                                  mgrTip.alertPrompt(info);
                              }
                          },
                          {
                              name: "打印圣物信息",
                              callback: (view) => {
                                  view.remove();
                                  let listData = [];
                                  let items = mgrHolyItem.getBagItems();
                                  for (let i = 0; i < items.length; i++) {
                                      let item = items[i];
                                      if (item && item.holyitem) {
                                          let data = item.holyitem.data;
                                          listData.push(data.id + "|" + data.lv);
                                      }
                                  }
                                  UIManager.getInstance().showDebugList(listData, (view, data) => {
                                      view.remove();
                                  });
                              }
                          },
                          {
                              name: "一键解锁塔位置",
                              callback: (view) => {
                                  view.remove();
                                  let slotMap = db.get_tower_pos_map()[mgrTower.defaultPosGid];
                                  for (let k in slotMap) {
                                      let slot = slotMap[k];
                                      mgrTower.tryUnlockSlot(slot.id - 1, true);
                                  }
                              }
                          },
                          {
                              name: "获得所有的塔",
                              callback: (view) => {
                                  view.remove();
                                  let towerDbMap = db.get_tower_db_map();
                                  for (let key in towerDbMap) {
                                      let data = db.get_tower_db(key);
                                      mgrGame.addItem(data.item_id, 1, 21, false);
                                  }
                              }
                          },
                          {
                              name: "天赋拉满",
                              callback: (view) => {
                                  view.remove();
                                  let dataMap = db.get_talent_db_map();
                                  for (let key in dataMap) {
                                      let data = db.get_talent_db(key);
                                      if (data.lv_max) {
                                          mgrTalent.setTalentLv(data.id, data.lv_max);
                                          Global.sendMsg(MSG.TOWER_ATTR_UPDATE_MAIN);
                                      }
                                  }
                              }
                          },
                          {
                              name: StageConfig.useLocalTime ? "使用服务器时间" : "使用本地时间",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.useLocalTime = !StageConfig.useLocalTime;
                                  mgrGame.saveStageConfig();
                              }
                          },
                          {
                              name: Skill.DEBUG_HIT_RANGE ? "关闭击中范围" : "显示击中范围",
                              callback: (view) => {
                                  view.remove();
                                  Skill.DEBUG_HIT_RANGE = !Skill.DEBUG_HIT_RANGE;
                              }
                          },
                          {
                              name: StageConfig.forceTowerLvupStar ? "关闭星级直升" : "打开星级直升",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.forceTowerLvupStar = !StageConfig.forceTowerLvupStar;
                              }
                          },
                          {
                              name: StageConfig.keepSuperSkill ? "关闭一直大招" : "开启一直大招",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.keepSuperSkill = !StageConfig.keepSuperSkill;
                              }
                          },
                          {
                              name: StageConfig.enableEnemyWave ? "关闭关卡刷怪" : "开启关卡刷怪",
                              callback: (view) => {
                                  view.remove();
                                  if (StageConfig.enableEnemyWave) {
                                      Level.stage.world.remAllUnit(LogicCamp.ENEMY);
                                  }
                                  StageConfig.enableEnemyWave = !StageConfig.enableEnemyWave;
                              }
                          },
                          {
                              name: StageConfig.configTouchEnemy.enable ? "关闭点击刷怪" : "打开点击刷怪",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.configTouchEnemy.enable = !StageConfig.configTouchEnemy.enable;
                              }
                          },
                          {
                              name: StageConfig.enableTowerAttack ? "关闭塔攻击" : "打开塔攻击",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.enableTowerAttack = !StageConfig.enableTowerAttack;
                              }
                          },
                          {
                              name: StageConfig.configTouchEnemy.attack ? "关闭怪攻击" : "打开怪攻击",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.configTouchEnemy.attack = !StageConfig.configTouchEnemy.attack;
                              }
                          },
                          {
                              name: StageConfig.enableEnemyTouchRemove ? "关闭点击删怪" : "打开点击删怪",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.enableEnemyTouchRemove = !StageConfig.enableEnemyTouchRemove;
                              }
                          },
                          {
                              name: StageConfig.showCollisionArea ? "隐藏碰撞范围" : "显示碰撞范围",
                              callback: (view) => {
                                  view.remove();
                                  StageConfig.showCollisionArea = !StageConfig.showCollisionArea;
                              }
                          },
                          {
                              name: "保存配置",
                              callback: (view) => {
                                  view.remove();
                                  mgrGame.saveStageConfig();
                              }
                          },
                          {
                              name: "清除配置",
                              callback: (view) => {
                                  view.remove();
                                  mgrGame.clearStageConfig();
                              }
                          },
                      ];
                      UIManager.getInstance().showDebugList(listData);
                  }
              },
              {
                  name: "每日试炼",
                  callback: (view) => {
                      view.remove();
                      let listData = db.get_daily_damage_db_map();
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          mgrDailyDamage.setConfig(data.id);
                          Director.runScene(SceneGameDailyDamage, "PanelLoadingGame");
                      });
                  }
              },
              {
                  name: "金币副本",
                  callback: (view) => {
                      view.remove();
                      Director.openPanel("PanelFBCoin");
                  }
              },
              {
                  name: "大秘境",
                  callback: (view) => {
                      view.remove();
                      let listData = db.get_secret_level_map();
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          Global.sendMsg(MSG.TOWER_SECRET, data);
                      });
                  }
              },
              {
                  name: "圣物副本",
                  callback: (view) => {
                      view.remove();
                      Director.openPanel("PanelFBItem");
                  }
              },
              {
                  name: "编辑器",
                  callback: (view) => {
                      view.remove();
                      UIManager.getInstance().showDebugList([
                          {
                              name: "动画编辑",
                              callback: (view) => {
                                  view.remove();
                                  Director.disposeAllPanel();
                                  Director.openPanel("PanelEditAnim");
                              }
                          },
                          {
                              name: "Spine编辑",
                              callback: (view) => {
                                  view.remove();
                                  Director.disposeAllPanel();
                                  Director.openPanel("PanelEditSpine");
                              }
                          },
                          {
                              name: "特效预览",
                              callback: (view) => {
                                  view.remove();
                                  Director.disposeAllPanel();
                                  Director.openPanel("PanelDebugEffect");
                              }
                          },
                          {
                              name: "子弹编辑",
                              callback: (view) => {
                                  view.remove();
                                  Director.disposeAllPanel();
                                  Director.openPanel("PanelEditBullet");
                              }
                          },
                          {
                              name: "范围编辑",
                              callback: (view) => {
                                  view.remove();
                                  Director.disposeAllPanel();
                                  Director.openPanel("PanelEditHIt");
                              }
                          },
                          {
                              name: "弹道编辑",
                              callback: (view) => {
                                  view.remove();
                                  Director.disposeAllPanel();
                                  Director.openPanel("PanelEditTrajectory");
                              }
                          },
                      ]);
                  }
              },
              {
                  name: "圣物",
                  callback: (view) => {
                      view.remove();
                      UIManager.getInstance().showDebugList([
                          {
                              name: "掉落测试",
                              callback: (view) => {
                                  let countWord = {};
                                  let countQuality = {};
                                  for (let i = 0; i < 100000; i++) {
                                      let item = HolyItemMaker.buildHolyItemByOption();
                                      for (let data of item.data.words) {
                                          let count = countWord[data.id] || 0;
                                          count++;
                                          countWord[data.id] = count;
                                          let quality = countQuality[data.quality] || 0;
                                          quality++;
                                          countQuality[data.quality] = quality;
                                      }
                                  }
                                  console.log("#################################");
                                  console.log("ID统计", countWord);
                                  console.log("品质统计", countQuality);
                                  console.log("#################################");
                              }
                          },
                          {
                              name: "随机添加",
                              callback: (view) => {
                                  mgrHolyItem.addHolyItem(HolyItemMaker.buildHolyItemByOption());
                              }
                          },
                          {
                              name: "指定添加",
                              callback: (view) => {
                                  let itemMap = db.get_holy_item_db_map();
                                  let listData = [];
                                  for (let key in itemMap) {
                                      let data = db.get_holy_item_db(key);
                                      listData.push({
                                          name: data.name,
                                          data: data,
                                      });
                                  }
                                  UIManager.getInstance().showDebugList(listData, (view, data) => {
                                      mgrHolyItem.addHolyItem(HolyItemMaker.buildHolyItemByOption({ itemIds: [data.data.id], itemIdsWight: [] }));
                                  });
                              }
                          },
                          {
                              name: "全部添加",
                              callback: (view) => {
                                  view.remove();
                                  let itemMap = db.get_holy_item_db_map();
                                  for (let key in itemMap) {
                                      let data = db.get_holy_item_db(key);
                                      mgrHolyItem.addHolyItem(HolyItemMaker.buildHolyItemByOption({ itemIds: [data.id] }));
                                  }
                              }
                          },
                          {
                              name: "随机泰坦立方",
                              callback: (view) => {
                                  let itemDb = HolyItemMaker.makeHolyItemClassRandom();
                                  let itemDbSub = HolyItemMaker.makeHolyItemClassRandom(itemDb.id);
                                  let holyItem = HolyItemMaker.buildHolyItemByOption({ quality: EQUIP_QUALITY.RED, itemDb: itemDb, itemDbSub: itemDbSub });
                                  mgrHolyItem.addHolyItem(holyItem);
                                  Director.openPanelWithSingleton("PanelSmelterSuc", holyItem);
                              }
                          },
                          {
                              name: "随机红色圣物",
                              callback: (view) => {
                                  let holyItem = HolyItemMaker.buildHolyItemByOption({ itemDb: HolyItemMaker.makeHolyItemClassRandom(), quality: EQUIP_QUALITY.RED, wordQuality: [4, 3, 3, 3] });
                                  mgrHolyItem.addHolyItem(holyItem);
                                  Director.openPanelWithSingleton("PanelSmelterSuc", holyItem);
                              }
                          },
                          {
                              name: "随机橙色(4橙词条)",
                              callback: (view) => {
                                  let holyItem = HolyItemMaker.buildHolyItemByOption({ quality: EQUIP_QUALITY.ORANGE, wordQuality: [3, 3, 3, 3] });
                                  mgrHolyItem.addHolyItem(holyItem);
                              }
                          },
                      ]);
                  }
              },
              {
                  name: "天赋",
                  callback: (view) => {
                      view.remove();
                      let itemMap = db.get_talent_db_map();
                      let listData = [];
                      for (let key in itemMap) {
                          let data = db.get_talent_db(key);
                          data.id;
                          listData.push({
                              name: data.name + "+1",
                              data: data,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          mgrTalent.addTalentLv(data.data.id, 1);
                      });
                  }
              },
              {
                  name: "离线时间",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      for (let i = 0; i < 24; i++) {
                          listData.push({
                              name: "过去" + i + "小时",
                              data: i,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          Global.sendMsg(MSG.TIME_OFFLINE_TIME, data.data * 60 * 60);
                      });
                  }
              },
              {
                  name: "获得指定塔",
                  callback: (view) => {
                      view.remove();
                      let towerDbMap = db.get_tower_db_map();
                      let listData = [];
                      for (let key in towerDbMap) {
                          let data = db.get_tower_db(key);
                          listData.push({
                              name: data.name,
                              data: data,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          mgrTower.addTowerByAmount(data.data, 1, 21);
                      });
                  }
              },
              {
                  name: "抽卡测试(10000次)",
                  callback: (view) => {
                      let countId = {};
                      for (let i = 0; i < 10000; i++) {
                          let dropData = [];
                          Level.summonCard(null, dropData);
                          for (let drop of dropData) {
                              switch (drop.type) {
                                  case DROP_TYPE.HOLY_ITEM:
                                      {
                                          let infoItem = drop.data;
                                          let key = "圣物:" + infoItem.itemId;
                                          let count = countId[key] || 0;
                                          count++;
                                          countId[key] = count;
                                      }
                                      break;
                                  case DROP_TYPE.TOWER:
                                      {
                                          let infoTower = drop.data;
                                          let key = "塔:" + infoTower.towerDb.id;
                                          let count = countId[key] || 0;
                                          count++;
                                          countId[key] = count;
                                      }
                                      break;
                              }
                          }
                      }
                      console.log("#################################");
                      console.log("ID统计", countId);
                      console.log("#################################");
                  }
              },
              {
                  name: "掉落",
                  callback: (view) => {
                      view.remove();
                      let itemMap = db.get_drop_db_map();
                      let listData = [];
                      for (let key in itemMap) {
                          let data = db.get_drop_db(key);
                          listData.push({
                              name: data.id,
                              data: data,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          Level.dropItemByDropId(data.data.id, true);
                      });
                  }
              },
              {
                  name: "引导",
                  callback: (view) => {
                      view.remove();
                      let itemMap = db.get_guide_db_map();
                      let listData = [];
                      for (let key in itemMap) {
                          let data = itemMap[key];
                          listData.push({
                              name: key,
                              data: data,
                          });
                      }
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          let guides = data.data;
                          let listGuide = [];
                          for (let guide of guides) {
                              listGuide.push({
                                  name: guide.id,
                                  guide: guide,
                              });
                          }
                          UIManager.getInstance().showDebugList(listGuide, (sv, gd) => {
                              sv.remove();
                              let guide = gd.guide;
                              mgrGuide.execGuideByIdNoPanel(guide.group, guide.id);
                          });
                      });
                  }
              },
              {
                  name: "切换渠道",
                  callback: (view) => {
                      view.remove();
                      let listData = [
                          { channel: "weixin", name: "微信" },
                          { channel: "toutiao", name: "头条" },
                          { channel: "oppoqg", name: "OPPO" },
                      ];
                      UIManager.getInstance().showDebugList(listData, (view, data) => {
                          view.remove();
                          mgrSdk.h5_channel = data.channel;
                      });
                  }
              },
              {
                  name: "界面测试",
                  callback: (view) => {
                      view.remove();
                      UIManager.getInstance().showDebugList([
                          {
                              name: "物品选择",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelItemSelect");
                              }
                          },
                          {
                              name: "神秘矿石",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelDropBoxAD");
                              }
                          },
                          {
                              name: "锻造",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelSmelter");
                              }
                          },
                          {
                              name: "锻造成功",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelSmelterSuc");
                              }
                          },
                          {
                              name: "破冰",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelIceBreak");
                              }
                          },
                          {
                              name: "警告",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelWarning");
                              }
                          },
                          {
                              name: "省电模式",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelIdle");
                              }
                          },
                          {
                              name: "省电模式",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelIdle");
                              }
                          },
                          {
                              name: "剧情对话",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelStoryDialog");
                              }
                          },
                          {
                              name: "对话框",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelDialog");
                              }
                          },
                          {
                              name: "首领入侵",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelBossComing");
                              }
                          },
                          {
                              name: "首领手动技能",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelGameHand");
                              }
                          },
                          {
                              name: "技能标题",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelSkill01");
                              }
                          },
                          {
                              name: "物品获得",
                              callback: (view) => {
                                  view.remove();
                                  let item = { itemId: 1001, count: 1000 };
                                  Director.openPanel("PanelItemGet", { items: [{ data: item }] });
                              }
                          },
                          {
                              name: "圣物强化",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanelWithSingleton("PanelHolyItemLvup");
                              }
                          },
                          {
                              name: "胜利界面",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelGameWin");
                              }
                          },
                          {
                              name: "失败界面",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelGameLose");
                              }
                          },
                          {
                              name: "分享界面",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelShare");
                              }
                          },
                          {
                              name: "原生插屏",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelLocalInterstitial", { nativeData: { url: "", title: "标题测试标题测试标题测试标题测试标题测试标题测试标题测试", desc: "描述测试" } });
                              }
                          },
                          {
                              name: "原生Banner",
                              callback: (view) => {
                                  view.remove();
                                  Director.openPanel("PanelLocalBanner", { nativeData: { url: "", title: "标题测试", desc: "描述测试" } });
                              }
                          },
                      ]);
                  }
              },
              {
                  name: "定制物品",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      let itemMap = db.get_item_db_map();
                      for (let k in itemMap) {
                          let itemDb = itemMap[k];
                          if (itemDb.type == 6) {
                              listData.push({
                                  name: itemDb.name,
                                  data: itemDb,
                              });
                          }
                      }
                      UIManager.getInstance().showDebugList(listData, (sv, gd) => {
                          sv.remove();
                          let itemDb = gd.data;
                          mgrGame.addItem(itemDb.id, 1, 21, false);
                      });
                  }
              },
              {
                  name: "添加物品",
                  callback: (view) => {
                      view.remove();
                      let listData = [];
                      let itemMap = db.get_item_db_map();
                      for (let k in itemMap) {
                          let itemDb = itemMap[k];
                          if (itemDb.type == 1 || itemDb.type == 5) {
                              listData.push({
                                  name: itemDb.name,
                                  data: itemDb,
                              });
                          }
                      }
                      UIManager.getInstance().showDebugList(listData, (sv, gd) => {
                          sv.remove();
                          let itemDb = gd.data;
                          mgrGame.addItem(itemDb.id, 1000000, 21, false);
                      });
                  }
              },
              {
                  name: "添加物品2",
                  callback: (view) => {
                      view.remove();
                      UIManager.getInstance().showDebugList([
                          {
                              name: "添加钻石",
                              callback: (view) => {
                                  view.remove();
                                  mgrGame.addItem(1000, 1000000, 20, false);
                              }
                          },
                          {
                              name: "万能碎片",
                              callback: (view) => {
                                  view.remove();
                                  mgrGame.addItem(1006, 10000, 20, false);
                              }
                          },
                          {
                              name: "天赋点数",
                              callback: (view) => {
                                  view.remove();
                                  mgrGame.addItem(1007, 100, 20, false);
                              }
                          },
                      ]);
                  }
              },
              {
                  name: "第二天",
                  callback: (view) => {
                      view.remove();
                      Global.sendMsg(MSG.TIME_DIFFERENT_DAY);
                  }
              },
              {
                  name: "H5_TEST",
                  callback: (view) => {
                      view.remove();
                      Global.H5_TEST = true;
                  }
              },
              {
                  name: "调试模式",
                  callback: (view) => {
                      view.remove();
                      GameGlobal.isDebug = true;
                      db.cop_db.isSupportSubscription = true;
                      let data = db.cop_db;
                      data.ad_ui_show = 1;
                      data.isSupportSubscription = true;
                  }
              },
              {
                  name: "ADV调试",
                  callback: (view) => {
                      view.remove();
                      mgrAdv.openLogTip();
                  }
              },
              {
                  name: "退出游戏",
                  callback: (view) => {
                      view.remove();
                      mgrSdk.exitGame();
                  }
              },
          ]);
      }
      static registValue() {
      }
      static registManager() {
      }
      static fixDrawToCanas() {
          let Sprite = Laya.Sprite;
          let RenderSprite = Laya.RenderSprite;
          let HTMLCanvas = Laya.HTMLCanvas;
          let Context = Laya.Context;
          Sprite.drawToCanvas = function (sprite, _renderType, canvasWidth, canvasHeight, offsetX, offsetY) {
              offsetX -= sprite.x;
              offsetY -= sprite.y;
              offsetX |= 0;
              offsetY |= 0;
              canvasWidth |= 0;
              canvasHeight |= 0;
              var ctx = new Context();
              ctx.size(canvasWidth, canvasHeight);
              ctx.asBitmap = true;
              ctx._targets.start();
              ctx._targets.clear(0, 0, 0, 0);
              RenderSprite.renders[_renderType]._fun(sprite, ctx, offsetX, offsetY);
              ctx.flush();
              ctx._targets.end();
              ctx._targets.restore();
              var dt = ctx._targets.getData(0, 0, canvasWidth, canvasHeight);
              ctx.destroy();
              var imgdata = null;
              if (window.ImageData) {
                  imgdata = new ImageData(canvasWidth, canvasHeight);
              }
              else {
                  imgdata = { data: new Uint8Array(canvasWidth * canvasHeight * 4), width: canvasWidth, height: canvasHeight };
              }
              var lineLen = canvasWidth * 4;
              var dst = imgdata.data;
              var y = canvasHeight - 1;
              var off = y * lineLen;
              var srcoff = 0;
              for (; y >= 0; y--) {
                  dst.set(dt.subarray(srcoff, srcoff + lineLen), off);
                  off -= lineLen;
                  srcoff += lineLen;
              }
              var canv = new HTMLCanvas(true);
              canv.size(canvasWidth, canvasHeight);
              var ctx2d = canv.getContext('2d');
              ctx2d.putImageData(imgdata, 0, 0);
              return canv;
          };
      }
      static fixSpritedrawToTexture() {
          let Texture = Laya.Texture;
          let Sprite = Laya.Sprite;
          let RenderSprite = Laya.RenderSprite;
          let Context = Laya.Context;
          Sprite.drawToTexture2 = function (sprite, _renderType, canvasWidth, canvasHeight, offsetX, offsetY, rt = null) {
              if (!Sprite.drawtocanvCtx) {
                  Sprite.drawtocanvCtx = new Context();
              }
              offsetX -= sprite.x;
              offsetY -= sprite.y;
              offsetX |= 0;
              offsetY |= 0;
              canvasWidth |= 0;
              canvasHeight |= 0;
              var ctx = rt ? Sprite.drawtocanvCtx : new Context();
              ctx.clear();
              ctx.size(canvasWidth, canvasHeight);
              if (rt) {
                  ctx._targets = rt;
              }
              else {
                  ctx.asBitmap = true;
              }
              ctx.scale(1, -1);
              ctx.translate(0, -canvasHeight);
              ctx._targets.start();
              ctx._targets.clear(0, 0, 0, 0);
              RenderSprite.renders[_renderType]._fun(sprite, ctx, offsetX, offsetY);
              ctx.flush();
              ctx._targets.end();
              ctx._targets.restore();
              if (!rt) {
                  var rtex = new Texture(ctx._targets, Texture.INV_UV);
                  ctx.destroy(true);
                  return rtex;
              }
              sprite._repaint = 0;
              return rt;
          };
      }
      static fixFgui() {
          let GProgressBar = fgui.GProgressBar;
          GProgressBar.prototype.setFillAmount = function (bar, percent) {
              if (((bar instanceof fgui.GImage) || (bar instanceof fgui.GLoader)) && bar.fillMethod != fgui.FillMethod.None) {
                  if (percent == 0) {
                      bar.visible = false;
                  }
                  else {
                      bar.fillAmount = percent;
                      if (!bar.visible)
                          bar.visible = true;
                  }
                  return true;
              }
              else
                  return false;
          };
      }
  }

  let merged_cfg = true;
  let compress_cfg = true;
  class CfgLoader {
      static init(callback) {
          let onCallback = (suc) => {
              this.loaded = true;
              Global.sendMsg(BASE_MSG.CFG_LOAD_FINISH);
              callback && callback(suc);
          };
          if (this.loaded) {
              onCallback(true);
              return;
          }
          if (merged_cfg) {
              if (compress_cfg) {
                  this.loadFromText(onCallback);
              }
              else {
                  this.loadFromJson(onCallback);
              }
          }
          else {
              console.error("暂时未接入非合并配置表的读取方式!!!");
          }
          this.loaded = true;
          Global.sendMsg(BASE_MSG.CFG_LOAD_FINISH);
      }
      static loadFromJson(callback) {
          ResLoader.loadRes("res/cfg/allCfgDb.json", Laya.Loader.JSON, (res) => {
              if (res) {
                  this.initCfg(res);
              }
              callback(!!res);
          });
      }
      static loadFromText(callback) {
          ResLoader.loadRes("res/cfg/allCfgDb.txt", Laya.Loader.TEXT, (res) => {
              if (res) {
                  let compressArr = Base64.toUint8Array(res);
                  let jsonStr = Tools.decompressArrToStr(compressArr);
                  let allCfgDb = JSON.parse(jsonStr);
                  this.initCfg(allCfgDb);
              }
              callback(!!res);
          });
      }
      static initCfg(allCfgDb) {
          db.setAllDbs(allCfgDb);
      }
  }
  CfgLoader.loaded = false;

  class mgrDebug extends Manager {
      static onLoad() {
          super.onLoad();
          Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDown);
      }
      static onStart() {
          console.log("mgrDebug.onStart");
      }
      static onKeyDown(e) {
          if (!this.openDebug) {
              return;
          }
          switch (e.keyCode) {
              default:
                  break;
          }
      }
  }
  mgrDebug.KEY_RESET_RECORD = "DEBUG_RECORD_v1.0.1";
  mgrDebug.openDebug = false;

  var EditorType$1;
  (function (EditorType) {
      EditorType[EditorType["color"] = 0] = "color";
      EditorType[EditorType["slider"] = 1] = "slider";
      EditorType[EditorType["num"] = 2] = "num";
      EditorType[EditorType["vec4"] = 3] = "vec4";
      EditorType[EditorType["option"] = 4] = "option";
      EditorType[EditorType["texture2d"] = 5] = "texture2d";
  })(EditorType$1 || (EditorType$1 = {}));
  var EDITOR_MES;
  (function (EDITOR_MES) {
  })(EDITOR_MES || (EDITOR_MES = {}));

  var Material = Laya.Material;
  var VertexMesh = Laya.VertexMesh;
  var Shader3D = Laya.Shader3D;
  var SubShader = Laya.SubShader;
  var BlinnPhongMaterial = Laya.BlinnPhongMaterial;
  class HeightFogMaterial extends Material {
      constructor() {
          super();
          this.setShaderName("CT_BLINNPHONG");
          var sv = this._shaderValues;
          sv.setVector(BlinnPhongMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          sv.setVector(BlinnPhongMaterial.MATERIALSPECULAR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          sv.setNumber(BlinnPhongMaterial.SHININESS, 0.078125);
          sv.setNumber(Material.ALPHATESTVALUE, 0.5);
          sv.setVector(BlinnPhongMaterial.TILINGOFFSET, new Laya.Vector4(1.0, 1.0, 0.0, 0.0));
          this.renderMode = BlinnPhongMaterial.RENDERMODE_OPAQUE;
          sv.setNumber(HeightFogMaterial.SHADOWRANGE, 0.002);
          sv.setNumber(HeightFogMaterial.SHADOWINTENSITY, 0.3);
          sv.setVector(HeightFogMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
          sv.setNumber(HeightFogMaterial.SHADOWBOUNDARY, 0.015);
          sv.setNumber(HeightFogMaterial.SPECULARRANGE, 0.99);
          sv.setNumber(HeightFogMaterial.SPECULARINTENSITY, 0.5);
          sv.setVector(HeightFogMaterial.SPECULARCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
      }
      static initShader() {
          var attributeMap = {
              'a_Position': VertexMesh.MESH_POSITION0,
              'a_Color': VertexMesh.MESH_COLOR0,
              'a_Normal': VertexMesh.MESH_NORMAL0,
              'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
              'a_MvpMatrix': VertexMesh.MESH_MVPMATRIX_ROW0,
              'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0
          };
          var uniformMap = {
              'u_AlbedoIdentity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Bones': Shader3D.PERIOD_CUSTOM,
              'u_DiffuseTexture': Shader3D.PERIOD_MATERIAL,
              'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
              'u_DiffuseColor': Shader3D.PERIOD_MATERIAL,
              'u_MaterialSpecular': Shader3D.PERIOD_MATERIAL,
              'u_Shininess': Shader3D.PERIOD_MATERIAL,
              'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
              'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowBoundary': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_WorldMat': Shader3D.PERIOD_SPRITE,
              'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
              'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
              'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
              'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Shader3D.PERIOD_CAMERA,
              'u_ViewProjection': Shader3D.PERIOD_CAMERA,
              'u_FogStart': Shader3D.PERIOD_SCENE,
              'u_FogRange': Shader3D.PERIOD_SCENE,
              'u_FogColor': Shader3D.PERIOD_SCENE,
              'u_DirationLightCount': Shader3D.PERIOD_SCENE,
              'u_LightBuffer': Shader3D.PERIOD_SCENE,
              'u_LightClusterBuffer': Shader3D.PERIOD_SCENE,
              'u_AmbientColor': Shader3D.PERIOD_SCENE,
              'u_ShadowBias': Shader3D.PERIOD_SCENE,
              'u_ShadowLightDirection': Shader3D.PERIOD_SCENE,
              'u_ShadowMap': Shader3D.PERIOD_SCENE,
              'u_ShadowParams': Shader3D.PERIOD_SCENE,
              'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE,
              'u_ShadowMatrices': Shader3D.PERIOD_SCENE,
              'u_ShadowMapSize': Shader3D.PERIOD_SCENE,
              'u_SpotShadowMap': Shader3D.PERIOD_SCENE,
              'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE,
              'u_ShadowLightPosition': Shader3D.PERIOD_SCENE,
              'u_AmbientSHAr': Shader3D.PERIOD_SCENE,
              'u_AmbientSHAg': Shader3D.PERIOD_SCENE,
              'u_AmbientSHAb': Shader3D.PERIOD_SCENE,
              'u_AmbientSHBr': Shader3D.PERIOD_SCENE,
              'u_AmbientSHBg': Shader3D.PERIOD_SCENE,
              'u_AmbientSHBb': Shader3D.PERIOD_SCENE,
              'u_AmbientSHC': Shader3D.PERIOD_SCENE,
              'u_DirectionLight.color': Shader3D.PERIOD_SCENE,
              'u_DirectionLight.direction': Shader3D.PERIOD_SCENE,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
          };
          var stateMap = {
              's_Cull': Shader3D.RENDER_STATE_CULL,
              's_Blend': Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var shader = Shader3D.add("CT_BLINNPHONG");
          var subShader = new SubShader(attributeMap, uniformMap);
          shader.addSubShader(subShader);
          subShader.addShaderPass(MeshBlinnPhongVS, MeshBlinnPhongPS, stateMap, "Forward");
          subShader.addShaderPass(MeshBlinnPhongShadowCasterVS, MeshBlinnPhongShadowCasterPS, stateMap, "ShadowCaster");
      }
      get albedoTexture() {
          return this._shaderValues.getTexture(BlinnPhongMaterial.ALBEDOTEXTURE);
      }
      set albedoTexture(value) {
          this._shaderValues.setTexture(BlinnPhongMaterial.ALBEDOTEXTURE, value);
      }
      get albedoColor() {
          return this._shaderValues.getVector(HeightFogMaterial.ALBEDOCOLOR);
      }
      set albedoColor(value) {
          if (value.x != 1 || value.y != 1 || value.z != 1 || value.w != 1) {
              this._defineDatas.add(HeightFogMaterial.SHADERDEFINE_ALBEDO_COLOR);
          }
          else {
              this._defineDatas.remove(HeightFogMaterial.SHADERDEFINE_ALBEDO_COLOR);
          }
          this._shaderValues.setVector(HeightFogMaterial.ALBEDOCOLOR, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(BlinnPhongMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(BlinnPhongMaterial.DEPTH_WRITE, value);
      }
      get cull() {
          return this._shaderValues.getInt(BlinnPhongMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(BlinnPhongMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(BlinnPhongMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(BlinnPhongMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(BlinnPhongMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(BlinnPhongMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(BlinnPhongMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(BlinnPhongMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(BlinnPhongMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(BlinnPhongMaterial.DEPTH_TEST, value);
      }
      get renderMode() {
          return this.__render_mode__;
      }
      set renderMode(value) {
          this.__render_mode__ = value;
          switch (value) {
              case HeightFogMaterial.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case HeightFogMaterial.RENDERMODE_OPAQUE_CULL_NONE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case HeightFogMaterial.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case HeightFogMaterial.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case HeightFogMaterial.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case HeightFogMaterial.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              default:
                  this.renderQueue = value;
          }
      }
      get shadowColor() {
          return this._shaderValues.getVector(HeightFogMaterial.SHADOWCOLOR);
      }
      set shadowColor(value) {
          this._shaderValues.setVector(HeightFogMaterial.SHADOWCOLOR, value);
      }
      get shadowRange() {
          return this._shaderValues.getNumber(HeightFogMaterial.SHADOWRANGE);
      }
      set shadowRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(HeightFogMaterial.SHADOWRANGE, value);
      }
      get shadowIntensity() {
          return this._shaderValues.getNumber(HeightFogMaterial.SHADOWINTENSITY);
      }
      set shadowIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(HeightFogMaterial.SHADOWINTENSITY, value);
      }
      get shadowBoundary() {
          return this._shaderValues.getNumber(HeightFogMaterial.SHADOWBOUNDARY);
      }
      set shadowBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(HeightFogMaterial.SHADOWBOUNDARY, value);
      }
      get specularRange() {
          return this._shaderValues.getNumber(HeightFogMaterial.SPECULARRANGE);
      }
      set specularRange(value) {
          value = Math.max(0, Math.min(1.0, value));
          this._shaderValues.setNumber(HeightFogMaterial.SPECULARRANGE, value);
      }
      set specularIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(HeightFogMaterial.SPECULARINTENSITY, value);
      }
      get specularIntensity() {
          return this._shaderValues.getNumber(HeightFogMaterial.SPECULARINTENSITY);
      }
      get specularColor() {
          return this._shaderValues.getVector(HeightFogMaterial.SPECULARCOLOR);
      }
      set specularColor(value) {
          this._shaderValues.setVector(HeightFogMaterial.SPECULARCOLOR, value);
      }
      getCanEditorParamList() {
          let normals = [];
          let allDbs = {};
          for (const id in allDbs) {
              normals.push({ desc: id, value: allDbs[id].resPath });
          }
          return [
              {
                  name: "renderMode", desc: "裁剪模式", type: EditorType$1.option, options: [
                      { desc: "OPAQUE", value: 1 },
                      { desc: "CUTOUT", value: 2 },
                      { desc: "CUTOUT_CULL_NONE", value: 3 },
                      { desc: "TRANSPARENT", value: 4 },
                      { desc: "TRANSPARENT_CULL_NONE", value: 5 },
                      { desc: "OPAQUE_CULL_NONE", value: 6 },
                  ]
              },
              { name: `shadowRange`, desc: `阴影范围`, type: EditorType$1.slider, range: [0, 1] },
              { name: `shadowIntensity`, desc: `阴影强度`, type: EditorType$1.slider, range: [0, 1] },
              { name: `shadowColor`, desc: `阴影颜色`, type: EditorType$1.color },
              { name: `shadowBoundary`, desc: `阴影边界`, type: EditorType$1.slider, range: [0, 1] },
              { name: `specularRange`, desc: `高亮范围`, type: EditorType$1.slider, range: [0, 1] },
              { name: `specularIntensity`, desc: `高亮强度`, type: EditorType$1.slider, range: [0, 1] },
              { name: `specularColor`, desc: `高亮颜色`, type: EditorType$1.color },
          ];
      }
  }
  HeightFogMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  HeightFogMaterial.SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_ShadowRange");
  HeightFogMaterial.SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_ShadowIntensity");
  HeightFogMaterial.SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_ShadowBoundary");
  HeightFogMaterial.SPECULARRANGE = Laya.Shader3D.propertyNameToID("u_SpecularRange");
  HeightFogMaterial.SPECULARINTENSITY = Laya.Shader3D.propertyNameToID("u_SpecularIntensity");
  HeightFogMaterial.SPECULARCOLOR = Laya.Shader3D.propertyNameToID("u_SpecularColor");
  HeightFogMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  HeightFogMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  HeightFogMaterial.SHADERDEFINE_ALBEDO_COLOR = Laya.Shader3D.getDefineByName("ALBEDO_COLOR");
  HeightFogMaterial.RENDERMODE_OPAQUE = 0;
  HeightFogMaterial.RENDERMODE_OPAQUE_CULL_NONE = 1;
  HeightFogMaterial.RENDERMODE_CUTOUT = 2;
  HeightFogMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  HeightFogMaterial.RENDERMODE_TRANSPARENT = 4;
  HeightFogMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  let MeshBlinnPhongVS = `
#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理，而我们的解析是不认内置宏的，导致被删掉，所以改成 if defined 了
	precision highp float;
	precision highp int;
#else
	precision mediump float;
	precision mediump int;
#endif
#include "Lighting.glsl";
#include "Shadow.glsl";

attribute vec4 a_Position;

#ifdef GPU_INSTANCE
	attribute mat4 a_MvpMatrix;
#else
	uniform mat4 u_MvpMatrix;
#endif

attribute vec2 a_Texcoord0;
varying vec2 v_Texcoord0;

#ifdef COLOR
	attribute vec4 a_Color;
	varying vec4 v_Color;
#endif

#ifdef BONE
	const int c_MaxBoneCount = 24;
	attribute vec4 a_BoneIndices;
	attribute vec4 a_BoneWeights;
	uniform mat4 u_Bones[c_MaxBoneCount];
#endif

attribute vec3 a_Normal;
varying vec3 v_Normal; 

uniform vec3 u_CameraPos;
varying vec3 v_ViewDir; 

#ifdef GPU_INSTANCE
	attribute mat4 a_WorldMat;
#else
	uniform mat4 u_WorldMat;
#endif

#if (defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))
	varying vec3 v_PositionWorld;
#endif

#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
	varying vec4 v_ShadowCoord;
#endif

#ifdef TILINGOFFSET
	uniform vec4 u_TilingOffset;
#endif

#ifdef SIMPLEBONE
	#ifdef GPU_INSTANCE
		attribute vec4 a_SimpleTextureParams;
	#else
		uniform vec4 u_SimpleAnimatorParams;
	#endif
	uniform sampler2D u_SimpleAnimatorTexture;

	uniform float u_SimpleAnimatorTextureSize; 
#endif


#ifdef SIMPLEBONE
mat4 loadMatFromTexture(float FramePos,int boneIndices,float offset)
{
	vec2 uv;
	float PixelPos = FramePos+float(boneIndices)*4.0;
	float halfOffset = offset * 0.5;
	float uvoffset = PixelPos/u_SimpleAnimatorTextureSize;
	uv.y = floor(uvoffset)*offset+halfOffset;
	uv.x = mod(float(PixelPos),u_SimpleAnimatorTextureSize)*offset+halfOffset;
	vec4 mat0row = texture2D(u_SimpleAnimatorTexture,uv);
	uv.x+=offset;
	vec4 mat1row = texture2D(u_SimpleAnimatorTexture,uv);
	uv.x+=offset;
	vec4 mat2row = texture2D(u_SimpleAnimatorTexture,uv);
	uv.x+=offset;
	vec4 mat3row = texture2D(u_SimpleAnimatorTexture,uv);
	mat4 m =mat4(mat0row.x,mat0row.y,mat0row.z,mat0row.w,
			  mat1row.x,mat1row.y,mat1row.z,mat1row.w,
			  mat2row.x,mat2row.y,mat2row.z,mat2row.w,
			  mat3row.x,mat3row.y,mat3row.z,mat3row.w);
	return m;
}
#endif

varying float v_heightFogRatio;

void main()
{
	vec4 position;
	#ifdef BONE
		mat4 skinTransform;
	 	#ifdef SIMPLEBONE
			float currentPixelPos;
			#ifdef GPU_INSTANCE
				currentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;
			#else
				currentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;
			#endif
			float offset = 1.0/u_SimpleAnimatorTextureSize;
			skinTransform =  loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;
			skinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;
			skinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;
			skinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;
		#else
			skinTransform =  u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
			skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
			skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
			skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
		#endif
		position=skinTransform*a_Position;
	 #else
		position=a_Position;
	#endif

	#ifdef GPU_INSTANCE
		gl_Position = a_MvpMatrix * position;
	#else
		gl_Position = u_MvpMatrix * position;
	#endif
	
	mat4 worldMat;
	#ifdef GPU_INSTANCE
		worldMat = a_WorldMat;
	#else
		worldMat = u_WorldMat;
	#endif

	mat3 worldInvMat;
	#ifdef BONE
		worldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));
	#else
		worldInvMat=INVERSE_MAT(mat3(worldMat));
	#endif  
	v_Normal=normalize(a_Normal*worldInvMat);

    vec3 positionWS=(worldMat*position).xyz;
    v_ViewDir = u_CameraPos-positionWS;
    
    #if defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE)
        v_PositionWorld = positionWS;
    #endif

    #ifdef TILINGOFFSET
        v_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);
    #else
        v_Texcoord0=a_Texcoord0;
    #endif

	#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)
		v_Color=a_Color;
	#endif

	#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
		v_ShadowCoord =getShadowCoord(vec4(positionWS,1.0));
	#endif

	gl_Position=remapGLPositionZ(gl_Position);

    v_heightFogRatio = 1.0 - clamp(2.0 + positionWS.y/2.0, 0.0, 1.0);
}
`;
  let MeshBlinnPhongPS = `
#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理，而我们的解析是不认内置宏的，导致被删掉，所以改成 if defined 了
	precision highp float;
	precision highp int;
#else
	precision mediump float;
	precision mediump int;
#endif

#include "Lighting.glsl";
#include "Shadow.glsl"

uniform vec4 u_DiffuseColor;

#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)
	varying vec4 v_Color;
#endif

#ifdef ALPHATEST
	uniform float u_AlphaTestValue;
#endif

uniform sampler2D u_DiffuseTexture;
varying vec2 v_Texcoord0;

varying vec3 v_Normal;
varying vec3 v_ViewDir; 

uniform vec3 u_MaterialSpecular;
uniform float u_Shininess;

uniform DirectionLight u_DirectionLight;

#ifdef FOG
	uniform float u_FogStart;
	uniform float u_FogRange;
	uniform vec3 u_FogColor;
#endif

#if defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE)
	varying vec3 v_PositionWorld;
#endif


#include "GlobalIllumination.glsl";//"GlobalIllumination.glsl use uniform should at front of this

#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
	varying vec4 v_ShadowCoord;
#endif

uniform DirectionLight u_SunLight;
uniform vec4 u_ShadowColor;
uniform float u_ShadowRange;
uniform float u_ShadowIntensity;
uniform float u_ShadowBoundary;
uniform float u_SpecularRange;
uniform float u_SpecularIntensity;
uniform vec4 u_SpecularColor;

varying float v_heightFogRatio;

#ifdef ALBEDO_COLOR
    uniform float u_AlbedoIdentity;
    uniform vec4 u_AlbedoColor;
#endif

void main()
{
	vec3 normal;//light and SH maybe use normal
	normal = normalize(v_Normal);

	vec3 viewDir= normalize(v_ViewDir);

	LayaGIInput giInput;
	vec3 globalDiffuse=layaGIBase(giInput,1.0,normal);
	
	vec4 mainColor = u_DiffuseColor;
    vec4 difTexColor = texture2D(u_DiffuseTexture, v_Texcoord0);
    mainColor=mainColor*difTexColor;
	#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)
		mainColor=mainColor*v_Color;
	#endif 
    
	#ifdef ALPHATEST
		if(mainColor.a<u_AlphaTestValue)
			discard;
    #endif
    

    vec3 lightDir = normalize(u_SunLight.direction);

    //屏蔽掉卡通色转换, 使用模型原始颜色
	vec3 albedoColor = difTexColor.rgb;
    // 阴影计算部分计算
    // 1.0 -> 0.0
    float nl = max(dot(normal, -lightDir), 0.0);
    // +0.01是避免阴影边界等于0时 shadow_allin && shadow_partin 相同
    float shadow_boundary = u_ShadowBoundary + 0.01;
    float shadow_allin = step(nl, u_ShadowRange - shadow_boundary*0.5);
    float shadow_partin = step(nl, u_ShadowRange + shadow_boundary*0.5);
    //分析:  allin时:  shadow_allin == 1.0;  shadow_partin == 1.0;
    //      partin时: shadow_allin == 0.0; shadow_partin = 1.0;
    //      none时:   shadow_allin == 0.0; shadow_partin = 0.0;
    float shadow = shadow_allin + (u_ShadowRange + shadow_boundary*0.5 - nl)/shadow_boundary * (shadow_partin - shadow_allin);

    shadow *= u_ShadowIntensity;
    vec3 albedoAreaColor = (1.0 - shadow) * albedoColor;
    vec3 shadowAreaColor = shadow * albedoColor * u_ShadowColor.rgb;
    
    //高光部分计算
    // float specular = pow(nl, u_SpecularRange * 10.0);
    // vec3 speculAreaColor = (1.0 - shadow) * albedoColor * u_SpecularIntensity * specular * u_SpecularColor.rgb;

    #if defined(CALCULATE_SHADOWS)
        #ifdef SHADOW_CASCADE
            vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
        #else
            vec4 shadowCoord = v_ShadowCoord;
        #endif
        float shadowAttenuation = sampleShadowmap(shadowCoord);
        albedoAreaColor *= shadowAttenuation;
        // speculAreaColor *= shadowAttenuation;
    #endif

    //混合漫反射 + 高光 + 阴影
    vec3 finalColor = albedoAreaColor + shadowAreaColor;
    gl_FragColor = vec4(finalColor.rgb, difTexColor.a);

    #ifdef ALBEDO_COLOR
        //叠加全局颜色
        // gl_FragColor *= (u_AlbedoColor * (u_AlbedoIdentity+0.5));
        gl_FragColor *= u_AlbedoColor;
    #endif

    
	// 以下为原版
	// vec3 diffuse = vec3(0.0);
	// vec3 specular= vec3(0.0);
    // vec3 dif,spe;
    // vec3 gloss=vec3(difTexColor.a);
    // LayaAirBlinnPhongDiectionLight(u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,u_DirectionLight,dif,spe);
    // #if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined
    //     #ifdef SHADOW_CASCADE
    //         vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
    //     #else
    //         vec4 shadowCoord = v_ShadowCoord;
    //     #endif
    //     float shadowAttenuation=sampleShadowmap(shadowCoord);
    //     dif *= shadowAttenuation;
    //     spe *= shadowAttenuation;
    // #endif
    // diffuse+=dif;
    // specular+=spe;
	// gl_FragColor =vec4(mainColor.rgb*(globalDiffuse + diffuse), mainColor.a);
	// gl_FragColor.rgb += specular;
	  
	#ifdef FOG
		float lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);
		gl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);
        gl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,v_heightFogRatio);
	#endif
}

`;
  let MeshBlinnPhongShadowCasterVS = `
#include "ShadowCasterVS.glsl"

void main()
{
	vec4 positionCS =  shadowCasterVertex();
	gl_Position=remapGLPositionZ(positionCS);
}
`;
  let MeshBlinnPhongShadowCasterPS = `
#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理，而我们的解析是不认内置宏的，导致被删掉，所以改成 if defined 了
	precision highp float;
	precision highp int;
#else
	precision mediump float;
	precision mediump int;
#endif

#include "ShadowCasterFS.glsl"

void main()
{
	gl_FragColor=shadowCasterFragment();
}
`;

  class BagMaterial extends Laya.Material {
      constructor() {
          super();
          this.setShaderName("BagMaterial");
          this._shaderValues.setVector(BagMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
          this._shaderValues.setNumber(BagMaterial.SHADOWRANGE, 0.002);
          this._shaderValues.setNumber(BagMaterial.SHADOWINTENSITY, 0.98);
          this._shaderValues.setNumber(BagMaterial.SHADOWBOUNDARY, 0.015);
          this._shaderValues.setNumber(BagMaterial.SPECULARRANGE, 0.99);
          this._shaderValues.setNumber(BagMaterial.SPECULARINTENSITY, 0.09);
          this._shaderValues.setVector(BagMaterial.SPECULARCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this._shaderValues.setVector(BagMaterial.SECOND_SHADOWCOLOR, new Laya.Vector4(1, 1, 1, 1));
          this._shaderValues.setNumber(BagMaterial.SECOND_SHADOWRANGE, 0.00);
          this._shaderValues.setNumber(BagMaterial.SECOND_SHADOWINTENSITY, 0.98);
          this._shaderValues.setNumber(BagMaterial.SECOND_SHADOWBOUNDARY, 0.0);
          this._shaderValues.setVector(BagMaterial.EDGE_HIGHLIGHT_COLOR, new Laya.Vector4(0, 1, 0, 1));
          this._shaderValues.setNumber(BagMaterial.EDGE_HIGHLIGHT_RANGE, 0.00);
          this._shaderValues.setNumber(BagMaterial.EDGE_HIGHLIGHT_INTENSITY, 0.98);
          this._shaderValues.setNumber(BagMaterial.EDGE_HIGHLIGHT_BOUNDARY, 0.0);
          this._shaderValues.setNumber(BagMaterial.NORMAL_SCALE, 1.0);
          this._shaderValues.setNumber(BagMaterial.DETAIL_NORMAL_SCALE, 1.0);
          this.smoothness = 0.0;
          this.metallic = 0.0;
          this.FadeColor = new Laya.Vector4;
          this.FadeFactor = 0.0;
      }
      static __init__() {
          BagMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
          BagMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
          BagMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
          BagMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
          BagMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE = Laya.Shader3D.getDefineByName("DETAIL_NORMAL_TEXTURE");
          BagMaterial.SHADERDEFINE_MASK2_TEXTURE = Laya.Shader3D.getDefineByName("MASK1_TEXTURE");
          BagMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
          BagMaterial.SHADERDEFINE_LAYER2_TEXTURE = Laya.Shader3D.getDefineByName("LAYER2_TEXTURE");
          BagMaterial.SHADERDEFINE_LAYER1_COLOR = Laya.Shader3D.getDefineByName("LAYER1_COLOR");
          BagMaterial.SHADERDEFINE_REFLECT_CUBE = Laya.Shader3D.getDefineByName("REFLECT_CUBE");
          BagMaterial.SHADERDEFINE_FRESNEL_REFLECTION = Laya.Shader3D.getDefineByName("FRESNEL_REFLECTION");
          BagMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
          BagMaterial.SHADERDEFINE_DRAWING_MASK_ZERO = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK_ZERO");
      }
      static initShader() {
          BagMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Tangent0': Laya.VertexMesh.MESH_TANGENT0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
          };
          var uniformMap = {
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowBoundary': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalScale': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Metallic': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Smoothness': Laya.Shader3D.PERIOD_MATERIAL,
              'u_DetailNormalTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_DetailNormalTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_DetailNormalScale': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Bones': Laya.Shader3D.PERIOD_CUSTOM,
              'u_Second_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Second_ShadowRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Second_ShadowIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Second_ShadowBoundary': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Edge_HighlightColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Edge_HighlightRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Edge_HighlightIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Edge_HighlightBoundary': Laya.Shader3D.PERIOD_MATERIAL,
              'u_alpha': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpotLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.range': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.spot': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.position': Laya.Shader3D.PERIOD_SCENE,
              'u_reflection_cube': Laya.Shader3D.PERIOD_MATERIAL,
              'u_reflection_box_center': Laya.Shader3D.PERIOD_MATERIAL,
              'u_reflection_box_size': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintMask2Texture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              "u_PaintLayer1Color": Laya.Shader3D.PERIOD_MATERIAL,
              "u_fade_factor": Laya.Shader3D.PERIOD_MATERIAL,
              "u_fade_color": Laya.Shader3D.PERIOD_MATERIAL,
          };
          var BagMaterial3D = Laya.Shader3D.add("BagMaterial");
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          BagMaterial3D.addSubShader(subShader);
          var vs2 = `
		attribute vec4 a_Position; 
		attribute vec3 a_Normal;
		attribute vec2 a_Texcoord0;	
		attribute vec4 a_Tangent0;
		uniform mat4 u_MvpMatrix;
		uniform mat4 u_WorldMat;
		uniform vec3 u_CameraPos;	
		varying vec2 v_Texcoord0;
		varying vec3 v_Normal;
		varying vec3 v_PositionWorld;
		varying vec3 v_ViewDir;
		varying vec3 v_worldPos;
		varying float v_viewDistance;

		#if defined(CASTSHADOW)
			varying vec4 v_posView;
		#endif

		#ifdef BONE
			const int c_MaxBoneCount = 24;
			attribute vec4 a_BoneIndices;
			attribute vec4 a_BoneWeights;
			uniform mat4 u_Bones[c_MaxBoneCount];
		#endif

		#ifdef GRAPHICS_API_GLES3
			#define INVERSE_MAT(mat) inverse(mat)
		#else
			#define INVERSE_MAT(mat) inverseMat(mat)
		#endif

		varying vec3 T;
		varying vec3 B;
		
		void main()
		{
			#ifdef BONE
				//计算骨骼对位置的影响
				mat4 skinTransform=mat4(0.0);
				skinTransform += u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
				skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
				skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
				skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
				vec4 position = skinTransform * a_Position;
				
				gl_Position=u_MvpMatrix * position;
				mat3 worldMat=mat3(u_WorldMat * skinTransform);
			#else
				gl_Position=u_MvpMatrix * a_Position;
				mat3 worldMat=mat3(u_WorldMat);
			#endif

			//法线
			v_Normal=normalize(worldMat*a_Normal);//if no normalize will cause precision problem.

			//纹理贴图
			v_Texcoord0 = a_Texcoord0;		
			
			#ifdef BONE
				v_PositionWorld=(u_WorldMat*position).xyz;
			#else
				v_PositionWorld=(u_WorldMat*a_Position).xyz;
			#endif
			//eye vec
			v_ViewDir = u_CameraPos - v_PositionWorld;
			v_viewDistance = distance(u_CameraPos, v_PositionWorld);
			v_worldPos = v_PositionWorld.xyz;

			T = normalize(worldMat*a_Tangent0.xyz);
			B = cross(v_Normal,T)*a_Tangent0.w; 

			#if defined(CASTSHADOW)
				v_posView = gl_Position.xyzw;
			#endif
			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
		}`;
          var ps2 = `
		// #ifdef FSHIGHPRECISION
		// 	precision highp float;
		// #else
		// 	precision mediump float;
		// #endif
		precision lowp float;
		
		struct DirectionLight
		{
			vec3 color;
			vec3 direction;
		};
		uniform DirectionLight u_SunLight;

		#ifdef SPOTLIGHT
			struct SpotLight {
				vec3 color;
				vec3 position;
				float range;
				vec3 direction;
				float spot;
			};
			uniform SpotLight u_SpotLight;
		#endif

		#ifdef LAYER1_COLOR
			uniform vec4 u_PaintLayer1Color;
		#endif

		#ifdef NORMALTEXTURE
			uniform sampler2D u_NormalTexture; 
			uniform float u_NormalScale;
			uniform vec4 u_NormalTillingOffset;
		#endif
		varying vec3 T;
		varying vec3 B;
 
		#ifdef DETAIL_NORMAL_TEXTURE
			uniform sampler2D u_DetailNormalTexture;
			uniform vec4 u_DetailNormalTillingOffset;
			uniform float u_DetailNormalScale;
		#endif

		#ifdef REFLECT_CUBE
			uniform samplerCube u_reflection_cube;
			uniform float u_Smoothness;
			uniform float u_Metallic;
			uniform vec3 u_reflection_box_center;
			uniform vec3 u_reflection_box_size;
		#endif

		varying vec2 v_Texcoord0;
		varying vec3 v_Normal;
		varying vec3 v_PositionWorld;
		varying vec3 v_ViewDir;
		varying vec3 v_worldPos;
		#if defined(CASTSHADOW)
		varying vec4 v_posView;
		#endif
		varying float v_viewDistance;

		uniform vec4 u_ShadowColor;
		uniform float u_ShadowRange;
		uniform float u_ShadowIntensity;
		uniform float u_ShadowBoundary;
		uniform float u_SpecularRange;
		uniform float u_SpecularIntensity;
		uniform vec4 u_SpecularColor;
		//双重阴影参数
		uniform vec4 u_Second_ShadowColor;
		uniform float u_Second_ShadowRange;
		uniform float u_Second_ShadowIntensity;
		uniform float u_Second_ShadowBoundary;
		//边缘高亮参数
		uniform vec4 u_Edge_HighlightColor;
		uniform float u_Edge_HighlightRange;
		uniform float u_Edge_HighlightIntensity;
		uniform float u_Edge_HighlightBoundary;
	
		//喷绘相关
		uniform sampler2D u_PaintMask2Texture;
		uniform sampler2D u_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;
		uniform sampler2D u_PaintLayer2Texture;
		uniform vec4 u_PaintLayer2TilingOffset;

		#ifdef ALBEDOCOLOR
			uniform vec4 u_AlbedoColor;
		#endif

		uniform float u_fade_factor;
		uniform vec4 u_fade_color;
		

		#ifdef WHOLE_ALPHA
		uniform float u_alpha;
		#endif


		vec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {
            vec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);
            transTexcoord.y+=1.0;
            return transTexcoord;
		}
		
		mediump vec3 unpackScaleNormal(mediump vec3 packednormal, mediump float bumpScale)
		{
			mediump vec3 normal = packednormal.xyz * 2.0 - 1.0;
			normal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.
			normal.xy *= bumpScale;
			return normal;
		}

		mediump vec3 normalInTangentSpace(sampler2D tt2d, vec2 texcoords, float scale)
		{
			mediump vec3 normalTangent = unpackScaleNormal(texture2D(tt2d, texcoords).rgb,scale);
			return normalTangent;
		}

		/**
		 * - worldRefl 世界坐标系反射
		 * - worldPos 世界坐标系中的位置
		 * - cubemapCenter cubemap的中心
		 * - 
		 */
		vec3 BoxProjectedCubemapDirection(vec3 worldRefl, vec3 worldPos, vec3 cubemapCenter, vec3 boxMin, vec3 boxMax)
		{
			vec3 nrdir = normalize(worldRefl);
			vec3 rbmax = (boxMax.xyz - worldPos);
			vec3 rbmin = (boxMin.xyz - worldPos);
			
			vec3 select = step (vec3(0.0,0.0,0.0), nrdir);
			vec3 rbminmax = rbmax * select + rbmin * (1.0 - select);
			rbminmax /= nrdir;
			
			float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z);

			worldPos -= cubemapCenter.xyz;
			worldRefl = worldPos + nrdir * fa;
			return worldRefl;
		}
		#ifdef REFLECT_CUBE
			vec3 ReflectCubeMap(in vec3 viewDir, in vec3 normal, in vec3 worldPos, in vec3 center, in vec3 size){
				vec3 incident = -viewDir;
				vec3 reflectionVector = reflect(incident, normal);
				//限制在盒子内
				vec3 boxMin = center.xyz/2.0 - size.xyz/2.0;
				vec3 boxMax = center.xyz/2.0 + size.xyz/2.0;
				reflectionVector = BoxProjectedCubemapDirection(reflectionVector, worldPos, center.xyz, boxMin, boxMax);

				vec3 reflectionColor = textureCube(u_reflection_cube, vec3(-reflectionVector.x, reflectionVector.yz)).rgb;
				return reflectionColor;
			}
		#endif

		void main_castshadow(){
			#ifdef CASTSHADOW
				float z = v_posView.z/v_posView.w;
				z = z*0.5 + 0.5;
				gl_FragColor = vec4(0.0, 0, z, 1.0);
			#endif
		}

		void main_paint_mask(){
			#ifdef SHADERDEFINE_DRAWING_MASK_ZERO
				gl_FragColor = vec4(0.0,0.0,0.0,1.0);
			#else
				gl_FragColor = vec4(v_Texcoord0.xy,0.0,1.0);
			#endif
		}

		void main_normal(){
			mat3 TBN = mat3(T, B, v_Normal);
			vec3 normal;
			#ifdef NORMALTEXTURE
				vec2 normalTexcoord = TransformUV(v_Texcoord0, u_NormalTillingOffset);
				normal = normalInTangentSpace(u_NormalTexture, normalTexcoord, u_NormalScale);
				normal = TBN * normal;
			#else
				normal = normalize(v_Normal);
			#endif

			#ifdef DETAIL_NORMAL_TEXTURE
				vec2 detailNormalTexcoord = TransformUV(v_Texcoord0, u_DetailNormalTillingOffset);
				float minv = 0.5;//u_MinNormalScaleDistance;
				float maxv = 3.0;//u_MaxNormalScaleDistance;
				float distance = clamp(v_viewDistance, minv, maxv);
				float scalefactor = 1.0 - (distance - minv)/(maxv - minv);
				vec3 detailNormal = normalInTangentSpace(u_DetailNormalTexture, detailNormalTexcoord, scalefactor * u_DetailNormalScale);
				detailNormal = TBN * detailNormal;
				normal += detailNormal;

				normal /= 2.0;

				// tex2DNode60.xyz = TBN * tex2DNode60.xyz;
				// vec3 break95 = tex2DNode60.rgb;
				// vec3 appendResult78 = (vec3(( normal.r + break95.r ) , ( break95.g + normal.g ) , ( normal.b + tex2DNode60.b )));
				// vec3 normalizeResult85 = normalize( ( ( 2.0 * appendResult78 ) + -0.43 ) );
				// normal = normalizeResult85;
			#endif


			vec3 viewdir = normalize(v_ViewDir);
			vec3 lightDir = normalize(u_SunLight.direction);

			vec4 albedoTextureColor = vec4(1.0);
			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor;
			#endif
			
			vec2 texcoord = vec2(v_Texcoord0.x, 1.0 - v_Texcoord0.y);

			#ifdef LAYER1_TEXTURE
				vec2 texcoordL1 = TransformUV(v_Texcoord0, u_PaintLayer1TilingOffset);
				vec4 paintLayer1Color = texture2D(u_PaintLayer1Texture, texcoordL1);
				paintLayer1Color = paintLayer1Color*(1.0 - u_fade_factor) + u_fade_factor * u_fade_color;
				// 层级1的颜色混合
				albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer1Color.a) + paintLayer1Color.rgb;
				albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer1Color.a) + paintLayer1Color.a * paintLayer1Color.a;
				#ifdef LAYER1_COLOR
					albedoTextureColor *= u_PaintLayer1Color;
				#endif
			#endif

			#ifdef LAYER2_TEXTURE
				#ifdef MASK1_TEXTURE
					// 第一层有mask的情况
					vec2 texcoordL2 = TransformUV(v_Texcoord0, u_PaintLayer2TilingOffset);

					vec4 paintLayer2Color = texture2D(u_PaintLayer2Texture, texcoordL2);
					//遮罩贴图
					vec4 paintMask2Color = texture2D(u_PaintMask2Texture, texcoordL2);

					paintLayer2Color.a = paintMask2Color.a;
					
					paintLayer2Color = paintLayer2Color*(1.0 - u_fade_factor) + u_fade_factor * u_fade_color;
					// 层级2的颜色混合
	
					albedoTextureColor.rgb = albedoTextureColor.rgb * paintLayer2Color.a + paintLayer2Color.rgb * (1.0 - paintLayer2Color.a);
					albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.a;
				#else
					// 计算层级2的颜色
					vec2 texcoordL2 = TransformUV(v_Texcoord0, u_PaintLayer2TilingOffset);
					vec4 paintLayer2Color = texture2D(u_PaintLayer2Texture, texcoordL2);
					paintLayer2Color = paintLayer2Color*(1.0 - u_fade_factor) + u_fade_factor * u_fade_color;
					// 层级2的颜色混合
					albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
					albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.a;
				#endif
			#endif
			

			#ifdef REFLECT_CUBE
				vec3 reflectionColor = ReflectCubeMap(viewdir, normal, v_worldPos, u_reflection_box_center, u_reflection_box_size);
				//菲涅尔反射
				float _FresnelScale = u_Metallic*2.0 + 0.01;
				float vn = clamp(1.01 - dot(viewdir, normal), 0.0, 1.0);
				float fresnel = pow(vn, _FresnelScale);

				vec3 fresnellColor = reflectionColor * fresnel + albedoTextureColor.rgb * (1.0 - fresnel);

				albedoTextureColor.rgb = albedoTextureColor.rgb*(1.0 - u_Smoothness) + fresnellColor * u_Smoothness;
			#endif


		#ifdef ALPHATEST
			if(albedoTextureColor.a <= 0.1){
				discard;
			}
		#endif
		
			//屏蔽掉卡通色转换, 使用模型原始颜色
			vec3 albedoColor = albedoTextureColor.rgb;		
			
			// // 阴影计算部分计算
			// // 1.0 -> 0.0
			// float nl = max(dot(normal, -lightDir), 0.0);
			// // +0.01是避免阴影边界等于0时 shadow_allin && shadow_partin 相同
            // float shadow_boundary = u_ShadowBoundary + 0.01;
            // float shadow_allin = step(nl, u_ShadowRange - shadow_boundary*0.5);
            // float shadow_partin = step(nl, u_ShadowRange + shadow_boundary*0.5);
            // //分析:  allin时:  shadow_allin == 1.0;  shadow_partin == 1.0;
            // //      partin时: shadow_allin == 0.0; shadow_partin = 1.0;
            // //      none时:   shadow_allin == 0.0; shadow_partin = 0.0;
            // float shadow = shadow_allin + (u_ShadowRange + shadow_boundary*0.5 - nl)/shadow_boundary * (shadow_partin - shadow_allin);

			float nl = max(dot(normal, -lightDir), 0.0);
			float shadow = 1.0 - nl;
			shadow *= u_ShadowIntensity * 1.2;
			vec3 albedoAreaColor = (1.0 - shadow) * albedoColor;
			vec3 shadowAreaColor = shadow * albedoColor * u_ShadowColor.rgb;
			
			//高光部分计算
			float specular = pow(nl,(u_SpecularRange + 0.01)*10.0);
			vec3 speculAreaColor = (1.0 - shadow) * albedoColor * u_SpecularIntensity * specular * u_SpecularColor.rgb;
			//混合漫反射 + 高光 + 阴影
			vec3 finalColor = albedoAreaColor + speculAreaColor + shadowAreaColor;

			// gl_FragColor.rgb = finalColor;

			//阴影补光计算
            float secondShadowRange = 1.0 - u_Second_ShadowRange;
            float secondShadowBoundary = u_Second_ShadowBoundary + 0.01;
            float negativeNl = max(dot(normal, lightDir), 0.0);
            float secShadowAllin = step(secondShadowRange + secondShadowBoundary*0.5, negativeNl);
            float secShadowPartin = step(secondShadowRange - secondShadowBoundary*0.5, negativeNl);
            //分析:
            //allin时: secShadowAllin == 1.0; secShadowPartin = 1.0;
            //partin时: secShadowAllin == 0.0; secShadowPartin = 1.0;
            //none时: secShadowAllin == 0.0; secShadowPartin = 0.0
            float shadow_second = secShadowAllin + (negativeNl - (secondShadowRange - secondShadowBoundary*0.5))/secondShadowBoundary * (secShadowPartin - secShadowAllin);
            //
			vec3 secondShadowArenaColor = shadow_second*albedoColor*u_Second_ShadowColor.rgb*u_Second_ShadowIntensity;
			finalColor += secondShadowArenaColor;
			//边缘高光计算(附加条件， 光照方向才有)
			float nv = 1.0 - abs(dot(normal, viewdir));
            float hf_nvl = nv * nl;
            float positive_hrange = 1.0 - u_Edge_HighlightRange;
            float hightLightBoundary = u_Edge_HighlightBoundary + 0.01;
            float higAllIn = step(positive_hrange + hightLightBoundary*0.5, hf_nvl);
            float higPartIn = step(positive_hrange - hightLightBoundary*0.5, hf_nvl);
            //分析:
            //allin时: higAllIn = 1.0; higPartIn = 1.0;
            //partin时: higAllIn = 0.0;higPartIn = 1.0;
            //none时: higAllIn = 0.0;higPartIn = 0.0;
            float edgehf = higAllIn + (hf_nvl - (positive_hrange - hightLightBoundary*0.5))/hightLightBoundary * (higPartIn - higAllIn);

			vec3 edgeHighlightColor = edgehf *albedoColor* u_Edge_HighlightColor.rgb*u_Edge_HighlightIntensity*2.0;
			finalColor += edgeHighlightColor;

			#ifdef WHOLE_ALPHA
				//叠加全局透明度
				gl_FragColor = vec4(finalColor.rgb, albedoTextureColor.a*u_alpha);
			#else
				gl_FragColor = vec4(finalColor.rgb, albedoTextureColor.a);
			#endif
			
			#ifdef SPOTLIGHT
				//用于判断方向
				float dotValue = dot(normal, -u_SpotLight.direction);
				//是否在同方向上
				float inDir = step(0.0, dotValue);

				vec3 lightVec = v_PositionWorld - u_SpotLight.position;
				vec3 normalLightVec = lightVec/length(lightVec);
				float cosCur = dot(u_SpotLight.direction, normalLightVec);
				float cosSeta = cos(u_SpotLight.spot);
				//
				float inSpot = step(cosSeta, cosCur) * ((cosCur - cosSeta)/(1.0-cosSeta));
				inSpot = clamp(inSpot, 0.0, 1.0);

				vec3 spotColor = gl_FragColor.rgb * inSpot * inDir * 0.5;
				vec3 sunColor = u_SunLight.color * gl_FragColor.rgb;
				gl_FragColor.rgb = spotColor + sunColor;
			#else
				gl_FragColor.rgb *= u_SunLight.color;
			#endif
		}
	
		void main()
		{
			#ifdef CASTSHADOW
				main_castshadow();
			#else
				#ifdef SHADERDEFINE_DRAWING_MASK
					main_paint_mask();
				#else
					main_normal();
				#endif
			#endif
		}`;
          subShader.addShaderPass(vs2, ps2, stateMap);
      }
      get cull() {
          return this._shaderValues.getInt(BagMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(BagMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(BagMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(BagMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(BagMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(BagMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(BagMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(BagMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(BagMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(BagMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(BagMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(BagMaterial.DEPTH_WRITE, value);
      }
      get renderMode() {
          return this.__render_mode__;
      }
      set renderMode(value) {
          this.__render_mode__ = value;
          switch (value) {
              case BagMaterial.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case BagMaterial.RENDERMODE_OPAQUE_CULL_NONE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case BagMaterial.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case BagMaterial.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case BagMaterial.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case BagMaterial.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              default:
                  this.renderQueue = value;
          }
      }
      get albedoColor() {
          return this._shaderValues.getVector(BagMaterial.ALBEDOCOLOR);
      }
      set albedoColor(value) {
          if (value) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          this._shaderValues.setVector(BagMaterial.ALBEDOCOLOR, value);
      }
      get shadowColor() {
          return this._shaderValues.getVector(BagMaterial.SHADOWCOLOR);
      }
      set shadowColor(value) {
          this._shaderValues.setVector(BagMaterial.SHADOWCOLOR, value);
      }
      get shadowRange() {
          return this._shaderValues.getNumber(BagMaterial.SHADOWRANGE);
      }
      set shadowRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SHADOWRANGE, value);
      }
      get shadowIntensity() {
          return this._shaderValues.getNumber(BagMaterial.SHADOWINTENSITY);
      }
      set shadowIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SHADOWINTENSITY, value);
      }
      get shadowBoundary() {
          return this._shaderValues.getNumber(BagMaterial.SHADOWBOUNDARY);
      }
      set shadowBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SHADOWBOUNDARY, value);
      }
      get specularRange() {
          return this._shaderValues.getNumber(BagMaterial.SPECULARRANGE);
      }
      set specularRange(value) {
          value = Math.max(0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SPECULARRANGE, value);
      }
      set specularIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SPECULARINTENSITY, value);
      }
      get specularIntensity() {
          return this._shaderValues.getNumber(BagMaterial.SPECULARINTENSITY);
      }
      get specularColor() {
          return this._shaderValues.getVector(BagMaterial.SPECULARCOLOR);
      }
      set specularColor(value) {
          this._shaderValues.setVector(BagMaterial.SPECULARCOLOR, value);
      }
      get secondShadowColor() {
          return this._shaderValues.getVector(BagMaterial.SECOND_SHADOWCOLOR);
      }
      set secondShadowColor(value) {
          this._shaderValues.setVector(BagMaterial.SECOND_SHADOWCOLOR, value);
      }
      get secondShadowRange() {
          return this._shaderValues.getNumber(BagMaterial.SECOND_SHADOWRANGE);
      }
      set secondShadowRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SECOND_SHADOWRANGE, value);
      }
      get secondShadowIntensity() {
          return this._shaderValues.getNumber(BagMaterial.SECOND_SHADOWINTENSITY);
      }
      set secondShadowIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SECOND_SHADOWINTENSITY, value);
      }
      get secondShadowBoundary() {
          return this._shaderValues.getNumber(BagMaterial.SECOND_SHADOWBOUNDARY);
      }
      set secondShadowBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.SECOND_SHADOWBOUNDARY, value);
      }
      get EdgeHightColor() {
          return this._shaderValues.getVector(BagMaterial.EDGE_HIGHLIGHT_COLOR);
      }
      set EdgeHightColor(value) {
          this._shaderValues.setVector(BagMaterial.EDGE_HIGHLIGHT_COLOR, value);
      }
      get EdgeHightRange() {
          return this._shaderValues.getNumber(BagMaterial.EDGE_HIGHLIGHT_RANGE);
      }
      set EdgeHightRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.EDGE_HIGHLIGHT_RANGE, value);
      }
      get EdgeHightIntensity() {
          return this._shaderValues.getNumber(BagMaterial.EDGE_HIGHLIGHT_INTENSITY);
      }
      set EdgeHightIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.EDGE_HIGHLIGHT_INTENSITY, value);
      }
      get EdgeHightBoundary() {
          return this._shaderValues.getNumber(BagMaterial.EDGE_HIGHLIGHT_BOUNDARY);
      }
      set EdgeHightBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(BagMaterial.EDGE_HIGHLIGHT_BOUNDARY, value);
      }
      get alpha() {
          return this._shaderValues.getNumber(BagMaterial.WHOLE_ALPHA);
      }
      set alpha(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          this._shaderValues.setNumber(BagMaterial.WHOLE_ALPHA, value);
      }
      get paintMask2Texture() {
          return this._shaderValues.getTexture(BagMaterial.PAINT_MASK2_TEXTURE);
      }
      set paintMask2Texture(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_MASK2_TEXTURE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_MASK2_TEXTURE);
          }
          this._shaderValues.setTexture(BagMaterial.PAINT_MASK2_TEXTURE, value);
      }
      get paintLayer1Texture() {
          return this._shaderValues.getTexture(BagMaterial.PAINT_LAYER1_TEXTURE);
      }
      set paintLayer1Texture(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_LAYER1_TEXTURE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_LAYER1_TEXTURE);
          }
          this._shaderValues.setTexture(BagMaterial.PAINT_LAYER1_TEXTURE, value);
      }
      get paintLayer1TilingOffset() {
          return this._shaderValues.getVector(BagMaterial.PAINT_LAYER1_TILINGOFFSET);
      }
      set paintLayer1TilingOffset(value) {
          this._shaderValues.setVector(BagMaterial.PAINT_LAYER1_TILINGOFFSET, value);
      }
      set paintLayer1Color(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_LAYER1_COLOR);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_LAYER1_COLOR);
          }
          this._shaderValues.setVector(BagMaterial.PAINT_LAYER1_COLOR, value);
      }
      get paintLayer1Color() {
          return this._shaderValues.getVector(BagMaterial.PAINT_LAYER1_COLOR);
      }
      get paintLayer2Texture() {
          return this._shaderValues.getTexture(BagMaterial.PAINT_LAYER2_TEXTURE);
      }
      set paintLayer2Texture(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_LAYER2_TEXTURE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_LAYER2_TEXTURE);
          }
          this._shaderValues.setTexture(BagMaterial.PAINT_LAYER2_TEXTURE, value);
      }
      get paintLayer2TilingOffset() {
          return this._shaderValues.getVector(BagMaterial.PAINT_LAYER2_TILINGOFFSET);
      }
      set paintLayer2TilingOffset(value) {
          this._shaderValues.setVector(BagMaterial.PAINT_LAYER2_TILINGOFFSET, value);
      }
      get normalTexture() {
          return this._shaderValues.getTexture(BagMaterial.NORMAL_TEXTURE);
      }
      set normalTexture(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_NORMALTEXTURE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_NORMALTEXTURE);
          }
          this._shaderValues.setTexture(BagMaterial.NORMAL_TEXTURE, value);
      }
      get normalTextureScale() {
          return this._shaderValues.getNumber(BagMaterial.NORMAL_SCALE);
      }
      set normalTextureScale(value) {
          this._shaderValues.setNumber(BagMaterial.NORMAL_SCALE, value);
          if (value > 0.01) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_NORMALTEXTURE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_NORMALTEXTURE);
          }
      }
      get normalTextureTillingOffset() {
          return this._shaderValues.getVector(BagMaterial.NORMAL_TILLING_OFFSET);
      }
      set normalTextureTillingOffset(value) {
          this._shaderValues.setVector(BagMaterial.NORMAL_TILLING_OFFSET, value);
      }
      get detailNormalTexture() {
          return this._shaderValues.getTexture(BagMaterial.DETAIL_NORMAL_TEXTURE);
      }
      set detailNormalTexture(value) {
          if (value != null) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
          }
          this._shaderValues.setTexture(BagMaterial.DETAIL_NORMAL_TEXTURE, value);
      }
      get detailNormalTextureTillingOffset() {
          return this._shaderValues.getVector(BagMaterial.DETAIL_NORMAL_TILLING_OFFSET);
      }
      set detailNormalTextureTillingOffset(value) {
          this._shaderValues.setVector(BagMaterial.DETAIL_NORMAL_TILLING_OFFSET, value);
      }
      get detailNormalTextureScale() {
          return this._shaderValues.getNumber(BagMaterial.DETAIL_NORMAL_SCALE);
      }
      set detailNormalTextureScale(value) {
          this._shaderValues.setNumber(BagMaterial.DETAIL_NORMAL_SCALE, value);
      }
      get reflectionCube() {
          return this._shaderValues.getTexture(BagMaterial.REFLECTION_CUBE);
      }
      set reflectionCube(value) {
          if (value) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_REFLECT_CUBE);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_REFLECT_CUBE);
          }
          this._shaderValues.setTexture(BagMaterial.REFLECTION_CUBE, value);
      }
      get smoothness() {
          return this._shaderValues.getNumber(BagMaterial.SMOOTHNESS);
      }
      set smoothness(value) {
          this._shaderValues.setNumber(BagMaterial.SMOOTHNESS, value);
      }
      get reflectionBoxCenter() {
          return this._shaderValues.getVector3(BagMaterial.REFLECTION_BOX_CENTER);
      }
      set reflectionBoxCenter(value) {
          this._shaderValues.setVector3(BagMaterial.REFLECTION_BOX_CENTER, value);
      }
      get reflectionBoxSize() {
          return this._shaderValues.getVector3(BagMaterial.REFLECTION_BOX_SIZE);
      }
      set reflectionBoxSize(value) {
          this._shaderValues.setVector3(BagMaterial.REFLECTION_BOX_SIZE, value);
      }
      get metallic() {
          return this._shaderValues.getNumber(BagMaterial.METALLIC);
      }
      set metallic(value) {
          this._shaderValues.setNumber(BagMaterial.METALLIC, value);
      }
      set bPickZero(value) {
          if (value) {
              this._defineDatas.add(BagMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
          }
          else {
              this._defineDatas.remove(BagMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
          }
      }
      set FadeColor(value) {
          this._shaderValues.setVector(BagMaterial.FADE_COLOR, value);
      }
      set FadeFactor(value) {
          this._shaderValues.setNumber(BagMaterial.FADE_FACTOR, value);
      }
      getCanEditorParamList() {
          return [
              { name: `albedoColor`, desc: `基础色`, type: EditorType.color },
              { name: `shadowColor`, desc: `阴影颜色`, type: EditorType.color },
              { name: `shadowIntensity`, desc: `阴影强度`, type: EditorType.slider, range: [0, 1] },
              { name: `specularColor`, desc: `高光颜色`, type: EditorType.color },
              { name: `specularRange`, desc: `高光范围`, type: EditorType.slider, range: [0, 1] },
              { name: `specularIntensity`, desc: `高光强度`, type: EditorType.slider, range: [0, 1] },
              { name: `secondShadowColor`, desc: `补光颜色`, type: EditorType.color },
              { name: `secondShadowRange`, desc: `补光范围`, type: EditorType.slider, range: [0, 1] },
              { name: `secondShadowIntensity`, desc: `补光强度`, type: EditorType.slider, range: [0, 1] },
              { name: `secondShadowBoundary`, desc: `补光边界模糊`, type: EditorType.slider, range: [0, 1] },
              { name: `EdgeHightColor`, desc: `边缘高光颜色`, type: EditorType.color },
              { name: `EdgeHightRange`, desc: `边缘高光范围`, type: EditorType.slider, range: [0, 1] },
              { name: `EdgeHightIntensity`, desc: `边缘高光强度`, type: EditorType.slider, range: [0, 1] },
              { name: `EdgeHightBoundary`, desc: `边缘高光边界模糊`, type: EditorType.slider, range: [0, 1] },
              { name: `detailNormalTextureScale`, desc: `细节法线强度`, type: EditorType.slider, range: [0, 5] },
              { name: `detailNormalTextureTillingOffset`, desc: `细节法线uv`, type: EditorType.vec4 },
              { name: `smoothness`, desc: `光滑程度`, type: EditorType.slider, range: [0, 1] },
              { name: `metallic`, desc: `金属度`, type: EditorType.slider, range: [0, 1] },
          ];
      }
  }
  BagMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  BagMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  BagMaterial.SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_ShadowRange");
  BagMaterial.SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_ShadowIntensity");
  BagMaterial.SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_ShadowBoundary");
  BagMaterial.SECOND_SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_Second_ShadowColor");
  BagMaterial.SECOND_SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_Second_ShadowRange");
  BagMaterial.SECOND_SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_Second_ShadowIntensity");
  BagMaterial.SECOND_SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_Second_ShadowBoundary");
  BagMaterial.EDGE_HIGHLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_Edge_HighlightColor");
  BagMaterial.EDGE_HIGHLIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_Edge_HighlightRange");
  BagMaterial.EDGE_HIGHLIGHT_INTENSITY = Laya.Shader3D.propertyNameToID("u_Edge_HighlightIntensity");
  BagMaterial.EDGE_HIGHLIGHT_BOUNDARY = Laya.Shader3D.propertyNameToID("u_Edge_HighlightBoundary");
  BagMaterial.SPECULARRANGE = Laya.Shader3D.propertyNameToID("u_SpecularRange");
  BagMaterial.SPECULARINTENSITY = Laya.Shader3D.propertyNameToID("u_SpecularIntensity");
  BagMaterial.SPECULARCOLOR = Laya.Shader3D.propertyNameToID("u_SpecularColor");
  BagMaterial.DIRECTIONLIGHTDIRECTION = Laya.Shader3D.propertyNameToID("u_SunLight.direction");
  BagMaterial.DIRECTIONLIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_SunLight.color");
  BagMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  BagMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  BagMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  BagMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  BagMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  BagMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  BagMaterial.NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  BagMaterial.NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  BagMaterial.NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_NormalTillingOffset");
  BagMaterial.DETAIL_NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_DetailNormalTexture");
  BagMaterial.DETAIL_NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_DetailNormalTillingOffset");
  BagMaterial.DETAIL_NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_DetailNormalScale");
  BagMaterial.REFLECTION_CUBE = Laya.Shader3D.propertyNameToID("u_reflection_cube");
  BagMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  BagMaterial.METALLIC = Laya.Shader3D.propertyNameToID("u_Metallic");
  BagMaterial.REFLECTION_BOX_CENTER = Laya.Shader3D.propertyNameToID("u_reflection_box_center");
  BagMaterial.REFLECTION_BOX_SIZE = Laya.Shader3D.propertyNameToID("u_reflection_box_size");
  BagMaterial.FADE_FACTOR = Laya.Shader3D.propertyNameToID("u_fade_factor");
  BagMaterial.FADE_COLOR = Laya.Shader3D.propertyNameToID("u_fade_color");
  BagMaterial.PAINT_MASK2_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintMask2Texture");
  BagMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  BagMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  BagMaterial.PAINT_LAYER2_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer2Texture");
  BagMaterial.PAINT_LAYER2_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer2TilingOffset");
  BagMaterial.PAINT_LAYER1_COLOR = Laya.Shader3D.propertyNameToID("u_PaintLayer1Color");
  BagMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  BagMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  BagMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  BagMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  BagMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  BagMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  BagMaterial.RENDERMODE_OPAQUE = 1;
  BagMaterial.RENDERMODE_CUTOUT = 2;
  BagMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  BagMaterial.RENDERMODE_TRANSPARENT = 4;
  BagMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  BagMaterial.RENDERMODE_OPAQUE_CULL_NONE = 6;

  class NormalMaterial extends Laya.Material {
      constructor() {
          super();
          this.setShaderName("NormalMaterial");
          this._shaderValues.setNumber(NormalMaterial.ALBEDOIDENTITY, 0.5);
          this._shaderValues.setVector(NormalMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this.alpha = 1;
      }
      static __init__() {
          NormalMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
          NormalMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
          NormalMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
          NormalMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
          NormalMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
      }
      static initShader() {
          NormalMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': Laya.VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
          };
          var uniformMap = {
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_AlbedoTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoIdentity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_Bones': Laya.Shader3D.PERIOD_CUSTOM,
              'u_alpha': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowMap': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightvpMatrix': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightmapScaleOffset': Laya.Shader3D.PERIOD_SPRITE,
              'u_LightMap': Laya.Shader3D.PERIOD_SPRITE,
              'u_TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowInnerRadius': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowOuterRadius': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowPoint1': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowPoint2': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowFactor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightMapFactor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpotLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.range': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.spot': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.position': Laya.Shader3D.PERIOD_SCENE,
          };
          var NormalMaterial3D = Laya.Shader3D.add("NormalMaterial");
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          NormalMaterial3D.addSubShader(subShader);
          var vs1 = `
		attribute vec4 a_Position; 
		attribute vec3 a_Normal; 
		attribute vec2 a_Texcoord0;
		uniform mat4 u_MvpMatrix; 
		uniform mat4 u_WorldMat;
		uniform vec3 u_CameraPos;
		varying vec2 v_Texcoord0;    
		varying vec3 v_PositionWorld;

		#ifdef BONE
			const int c_MaxBoneCount = 24;
			attribute vec4 a_BoneIndices;
			attribute vec4 a_BoneWeights;
			uniform mat4 u_Bones[c_MaxBoneCount];
		#endif
        
        #ifdef TILINGOFFSET
            uniform vec4 u_TilingOffset;
		#endif
		
        vec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {
            vec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);
            transTexcoord.y+=1.0;
            return transTexcoord;
        }

		void main() 
		{ 
			#ifdef BONE
				mat4 skinTransform=mat4(0.0);
				skinTransform += u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
				skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
				skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
				skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
				vec4 position = skinTransform * a_Position;
				gl_Position=u_MvpMatrix * position;
				mat3 worldMat=mat3(u_WorldMat * skinTransform);
			#else
				gl_Position=u_MvpMatrix * a_Position;
				mat3 worldMat=mat3(u_WorldMat);
			#endif

            #ifdef TILINGOFFSET
                v_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);
            #else
                v_Texcoord0=a_Texcoord0;
			#endif	
			
			#ifdef BONE
				v_PositionWorld=(u_WorldMat*position).xyz;
			#else
				v_PositionWorld=(u_WorldMat*a_Position).xyz;
			#endif

			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
		}`;
          var ps1 = `
		// #ifdef FSHIGHPRECISION 
		//    precision highp float; 
		// #else 
		//    precision mediump float; 
		// #endif 
		precision lowp float;

		varying vec3 v_PositionWorld;
	
		varying vec2 v_Texcoord0; 

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
		#endif
		uniform sampler2D u_AlbedoTexture;
		uniform float u_AlbedoIdentity;
		uniform vec4 u_AlbedoColor;

		void main_normal(){
			vec4 albedoTextureColor = vec4(1.0);
			#ifdef ALBEDOTEXTURE
				albedoTextureColor = texture2D(u_AlbedoTexture, v_Texcoord0);
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor * u_AlbedoIdentity;
			#endif

			#ifdef ALPHATEST
			if(albedoTextureColor.a <= 0.1){
				discard;
			}
			#endif

			#ifdef WHOLE_ALPHA
				//叠加全局透明度
				gl_FragColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a*u_alpha);
			#else
				gl_FragColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a);
			#endif

		}
	
		void main() 
		{ 
			main_normal();
		}`;
          subShader.addShaderPass(vs1, ps1, stateMap);
      }
      get albedoTexture() {
          return this._shaderValues.getTexture(NormalMaterial.ALBEDOTEXTURE);
      }
      set albedoTexture(value) {
          if (value) {
              this._shaderValues.addDefine(NormalMaterial.SHADERDEFINE_ALBEDOTEXTURE);
          }
          else {
              this._shaderValues.removeDefine(NormalMaterial.SHADERDEFINE_ALBEDOTEXTURE);
          }
          this._shaderValues.setTexture(NormalMaterial.ALBEDOTEXTURE, value);
      }
      get albedoColor() {
          return this._shaderValues.getVector(NormalMaterial.ALBEDOCOLOR);
      }
      set albedoColor(value) {
          if (value) {
              this._defineDatas.add(NormalMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          else {
              this._defineDatas.remove(NormalMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          this._shaderValues.setVector(NormalMaterial.ALBEDOCOLOR, value);
      }
      get albedoIdentity() {
          return this._shaderValues.getNumber(NormalMaterial.ALBEDOIDENTITY);
      }
      set albedoIdentity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(NormalMaterial.ALBEDOIDENTITY, value);
      }
      get tilingOffset() {
          return this._shaderValues.getVector(NormalMaterial.TILINGOFFSET);
      }
      set tilingOffset(value) {
          if (value) {
              if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
                  this._shaderValues.addDefine(NormalMaterial.SHADERDEFINE_TILINGOFFSET);
              else
                  this._shaderValues.removeDefine(NormalMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          else {
              this._shaderValues.removeDefine(NormalMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          this._shaderValues.setVector(NormalMaterial.TILINGOFFSET, value);
      }
      get alpha() {
          return this._shaderValues.getNumber(NormalMaterial.WHOLE_ALPHA);
      }
      set alpha(value) {
          if (value != null) {
              this._defineDatas.add(NormalMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          else {
              this._defineDatas.remove(NormalMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          this._shaderValues.setNumber(NormalMaterial.WHOLE_ALPHA, value);
      }
      get cull() {
          return this._shaderValues.getInt(NormalMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(NormalMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(NormalMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(NormalMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(NormalMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(NormalMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(NormalMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(NormalMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(NormalMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(NormalMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(NormalMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(NormalMaterial.DEPTH_WRITE, value);
      }
      set renderMode(value) {
          switch (value) {
              case NormalMaterial.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case NormalMaterial.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case NormalMaterial.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case NormalMaterial.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case NormalMaterial.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case NormalMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_ONE_MINUS_DST_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LEQUAL;
                  break;
              default:
                  throw new Error("NormalMaterial : renderMode value error.");
          }
      }
  }
  NormalMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  NormalMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  NormalMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  NormalMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  NormalMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  NormalMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  NormalMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  NormalMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  NormalMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  NormalMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  NormalMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  NormalMaterial.RENDERMODE_OPAQUE = 1;
  NormalMaterial.RENDERMODE_CUTOUT = 2;
  NormalMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  NormalMaterial.RENDERMODE_TRANSPARENT = 4;
  NormalMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  NormalMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD = 6;

  class LightMapMaterial extends Laya.Material {
      constructor() {
          super();
          this.setShaderName("lightMapMaterial");
          this._shaderValues.setNumber(LightMapMaterial.ALBEDOIDENTITY, 0.5);
          this._shaderValues.setVector(LightMapMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this.alpha = 1;
          this.lightMapFactor = 1;
      }
      static __init__() {
          LightMapMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
          LightMapMaterial.SHADERDEFINE_REALTIME_SHADOW = Laya.Shader3D.getDefineByName("REALTIME_SHADOW");
          LightMapMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
          LightMapMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
          LightMapMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
          LightMapMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
      }
      static initShader() {
          LightMapMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': Laya.VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
          };
          var uniformMap = {
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_AlbedoTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoIdentity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_Bones': Laya.Shader3D.PERIOD_CUSTOM,
              'u_alpha': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowMap': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightvpMatrix': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightmapScaleOffset': Laya.Shader3D.PERIOD_SPRITE,
              'u_LightMap': Laya.Shader3D.PERIOD_SPRITE,
              'u_TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowInnerRadius': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowOuterRadius': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowPoint1': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowPoint2': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowFactor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightMapFactor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpotLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.range': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.spot': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.position': Laya.Shader3D.PERIOD_SCENE,
          };
          var lightMapMaterial3D = Laya.Shader3D.add("lightMapMaterial");
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          lightMapMaterial3D.addSubShader(subShader);
          var vs1 = `
		attribute vec4 a_Position; 
		attribute vec3 a_Normal; 
		attribute vec2 a_Texcoord0;
		uniform mat4 u_MvpMatrix; 
		uniform mat4 u_WorldMat;
		uniform vec3 u_CameraPos;
		varying vec2 v_Texcoord0;    
		varying vec3 v_PositionWorld;

		#ifdef CASTSHADOW
			varying vec4 v_posView;
		#endif
        
        #ifdef REALTIME_SHADOW
            uniform mat4 u_LightvpMatrix;
            varying vec4 v_LightGLPosition; 
        #endif

		#ifdef BONE
			const int c_MaxBoneCount = 24;
			attribute vec4 a_BoneIndices;
			attribute vec4 a_BoneWeights;
			uniform mat4 u_Bones[c_MaxBoneCount];
		#endif

		#if defined(LIGHTMAP)&&defined(UV1)
			attribute vec2 a_Texcoord1;
		#endif

		#ifdef LIGHTMAP
			uniform vec4 u_LightmapScaleOffset;
			varying vec2 v_LightMapUV;
        #endif
        
        #ifdef TILINGOFFSET
            uniform vec4 u_TilingOffset;
		#endif
		
        vec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {
            vec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);
            transTexcoord.y+=1.0;
            return transTexcoord;
        }

		void main() 
		{ 
			#ifdef BONE
				mat4 skinTransform=mat4(0.0);
				skinTransform += u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
				skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
				skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
				skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
				vec4 position = skinTransform * a_Position;
				gl_Position=u_MvpMatrix * position;
				mat3 worldMat=mat3(u_WorldMat * skinTransform);
			#else
				gl_Position=u_MvpMatrix * a_Position;
				mat3 worldMat=mat3(u_WorldMat);
			#endif

            #ifdef TILINGOFFSET
                v_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);
            #else
                v_Texcoord0=a_Texcoord0;
			#endif	
			
			#ifdef BONE
				v_PositionWorld=(u_WorldMat*position).xyz;
			#else
				v_PositionWorld=(u_WorldMat*a_Position).xyz;
			#endif

			#ifdef LIGHTMAP
				#ifdef SCALEOFFSETLIGHTINGMAPUV
					#ifdef UV1
						v_LightMapUV=vec2(a_Texcoord1.x,1.0-a_Texcoord1.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;
					#else
						v_LightMapUV=vec2(a_Texcoord0.x,1.0-a_Texcoord0.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;
					#endif 
					v_LightMapUV.y=1.0-v_LightMapUV.y;
				#else
					#ifdef UV1
						v_LightMapUV=a_Texcoord1;
					#else
						v_LightMapUV=a_Texcoord0;
					#endif 
				#endif 
			#endif

            #ifdef REALTIME_SHADOW
                v_LightGLPosition = u_LightvpMatrix * vec4(v_PositionWorld, 1.0);
			#endif

			#ifdef CASTSHADOW
				v_posView = gl_Position.xyzw;
			#endif

			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
		}`;
          var ps1 = `
		// #ifdef FSHIGHPRECISION 
		//    precision highp float; 
		// #else 
		//    precision mediump float; 
		// #endif 
		precision lowp float;

		varying vec3 v_PositionWorld;
	
		varying vec2 v_Texcoord0; 
		struct DirectionLight
		{
			vec3 color;
			vec3 direction;
		};
		uniform DirectionLight u_SunLight;

		#ifdef SPOTLIGHT
			struct SpotLight {
				vec3 color;
				vec3 position;
				float range;
				vec3 direction;
				float spot;
			};
			uniform SpotLight u_SpotLight;
		#endif
        
        #ifdef REALTIME_SHADOW
            uniform sampler2D u_ShadowMap;
            varying vec4 v_LightGLPosition;
        #endif

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
		#endif
		uniform samplerCube u_reflection_cube;
		uniform float u_reflection_factor;
		uniform sampler2D u_AlbedoTexture;
		uniform float u_AlbedoIdentity;
		uniform vec4 u_AlbedoColor;

		#ifdef LIGHTMAP
			varying vec2 v_LightMapUV;
			uniform sampler2D u_LightMap;
			uniform float u_LightMapFactor;
		#endif

		#ifdef CASTSHADOW
			varying vec4 v_posView;
		#endif
		
		vec3 DecodeLightmap(vec4 color) {
			return color.rgb*color.a*5.0;
		}

		void main_castshadow(){
			#ifdef CASTSHADOW
				float z = v_posView.z/v_posView.w;
				z = z*0.5 + 0.5;
				gl_FragColor = vec4(0.0, 0, z, 1.0);
			#endif
		}

		void main_normal(){
			vec4 albedoTextureColor = vec4(1.0);
			#ifdef ALBEDOTEXTURE
				albedoTextureColor = texture2D(u_AlbedoTexture, v_Texcoord0);
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor * u_AlbedoIdentity;
			#endif

			#ifdef ALPHATEST
			if(albedoTextureColor.a <= 0.1){
				discard;
			}
			#endif

			#ifdef LIGHTMAP    
				albedoTextureColor.rgb *= DecodeLightmap(texture2D(u_LightMap, v_LightMapUV)) * u_LightMapFactor;
			#endif
            
            //计算阴影
            #ifdef REALTIME_SHADOW
                vec3 vText = v_LightGLPosition.xyz / v_LightGLPosition.w;
				vText.xyz = vText.xyz * 0.5 + 0.5;
                vText.y = 1.0 - vText.y;
				float shadowDepth = texture2D(u_ShadowMap, vText.xy).z-0.001;

				float temp = step(vText.z, shadowDepth);
                albedoTextureColor.rgb *= vec3(0.93 * (1.0 - temp) + temp);
			#endif

			#ifdef WHOLE_ALPHA
				//叠加全局透明度
				gl_FragColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a*u_alpha);
			#else
				gl_FragColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a);
			#endif

			#ifdef SPOTLIGHT
				float distance = distance(v_PositionWorld.xz, u_SpotLight.position.xz);
				float inRange = step(distance, u_SpotLight.range);
				float inTransition = step(distance, u_SpotLight.range+0.1);
				float factor = (distance - u_SpotLight.range)/0.1;

				float spotValue = 1.0*inRange + (1.0 - factor) * (inTransition - inRange);
				vec3 spotColor = u_SpotLight.color * gl_FragColor.rgb * spotValue;
				
				vec3 sunColor = u_SunLight.color * gl_FragColor.rgb;

				gl_FragColor.rgb = spotColor + sunColor;
				// gl_FragColor.rgb = vec3(distance);
			#else
				gl_FragColor.rgb *= u_SunLight.color;
			#endif
		}
	
		void main() 
		{ 
			#ifdef CASTSHADOW
				main_castshadow();
			#else
				main_normal();
			#endif
		}`;
          subShader.addShaderPass(vs1, ps1, stateMap);
      }
      get albedoTexture() {
          return this._shaderValues.getTexture(LightMapMaterial.ALBEDOTEXTURE);
      }
      set albedoTexture(value) {
          if (value) {
              this._shaderValues.addDefine(LightMapMaterial.SHADERDEFINE_ALBEDOTEXTURE);
          }
          else {
              this._shaderValues.removeDefine(LightMapMaterial.SHADERDEFINE_ALBEDOTEXTURE);
          }
          this._shaderValues.setTexture(LightMapMaterial.ALBEDOTEXTURE, value);
      }
      get albedoColor() {
          return this._shaderValues.getVector(LightMapMaterial.ALBEDOCOLOR);
      }
      set albedoColor(value) {
          if (value) {
              this._defineDatas.add(LightMapMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          else {
              this._defineDatas.remove(LightMapMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          this._shaderValues.setVector(LightMapMaterial.ALBEDOCOLOR, value);
      }
      get albedoIdentity() {
          return this._shaderValues.getNumber(LightMapMaterial.ALBEDOIDENTITY);
      }
      set albedoIdentity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(LightMapMaterial.ALBEDOIDENTITY, value);
      }
      get shadowMap() {
          return this._shaderValues.getTexture(LightMapMaterial.SHADOW_MAP);
      }
      set shadowMap(value) {
          if (value) {
              this._defineDatas.add(LightMapMaterial.SHADERDEFINE_REALTIME_SHADOW);
          }
          else {
              this._defineDatas.remove(LightMapMaterial.SHADERDEFINE_REALTIME_SHADOW);
          }
          this._shaderValues.setTexture(LightMapMaterial.SHADOW_MAP, value);
      }
      get lightvp() {
          return this._shaderValues.getMatrix4x4(LightMapMaterial.LIGHT_VP);
      }
      set lightvp(value) {
          this._shaderValues.setMatrix4x4(LightMapMaterial.LIGHT_VP, value);
      }
      get tilingOffset() {
          return this._shaderValues.getVector(LightMapMaterial.TILINGOFFSET);
      }
      set tilingOffset(value) {
          if (value) {
              if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
                  this._shaderValues.addDefine(LightMapMaterial.SHADERDEFINE_TILINGOFFSET);
              else
                  this._shaderValues.removeDefine(LightMapMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          else {
              this._shaderValues.removeDefine(LightMapMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          this._shaderValues.setVector(LightMapMaterial.TILINGOFFSET, value);
      }
      get alpha() {
          return this._shaderValues.getNumber(LightMapMaterial.WHOLE_ALPHA);
      }
      set alpha(value) {
          if (value != null) {
              this._defineDatas.add(LightMapMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          else {
              this._defineDatas.remove(LightMapMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          this._shaderValues.setNumber(LightMapMaterial.WHOLE_ALPHA, value);
      }
      get lightMapFactor() {
          return this._shaderValues.getNumber(LightMapMaterial.LIGHT_MAP_FACTOR);
      }
      set lightMapFactor(value) {
          this._shaderValues.setNumber(LightMapMaterial.LIGHT_MAP_FACTOR, value);
      }
      get cull() {
          return this._shaderValues.getInt(LightMapMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(LightMapMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(LightMapMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(LightMapMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(LightMapMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(LightMapMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(LightMapMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(LightMapMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(LightMapMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(LightMapMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(LightMapMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(LightMapMaterial.DEPTH_WRITE, value);
      }
      set renderMode(value) {
          switch (value) {
              case LightMapMaterial.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case LightMapMaterial.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case LightMapMaterial.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case LightMapMaterial.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case LightMapMaterial.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              default:
                  throw new Error("LightMapMaterial : renderMode value error.");
          }
      }
  }
  LightMapMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  LightMapMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  LightMapMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  LightMapMaterial.SHADOW_MAP = Laya.Shader3D.propertyNameToID("u_ShadowMap");
  LightMapMaterial.LIGHT_VP = Laya.Shader3D.propertyNameToID("u_LightvpMatrix");
  LightMapMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  LightMapMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  LightMapMaterial.LIGHT_MAP_FACTOR = Laya.Shader3D.propertyNameToID("u_LightMapFactor");
  LightMapMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  LightMapMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  LightMapMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  LightMapMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  LightMapMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  LightMapMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  LightMapMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  LightMapMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  LightMapMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  LightMapMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  LightMapMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  LightMapMaterial.RENDERMODE_OPAQUE = 1;
  LightMapMaterial.RENDERMODE_CUTOUT = 2;
  LightMapMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  LightMapMaterial.RENDERMODE_TRANSPARENT = 4;
  LightMapMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;

  class PaintMaterial extends Laya.Material {
      constructor() {
          super();
          this.setShaderName("PaintMaterial");
          this.alpha = 1;
      }
      static __init__() {
          PaintMaterial.SHADERDEFINE_PAGE_BASE = Laya.Shader3D.getDefineByName("PAGE_BASE");
          PaintMaterial.SHADERDEFINE_PAINT_TEXTURE = Laya.Shader3D.getDefineByName("PAINT_TEXTURE");
          PaintMaterial.SHADERDEFINE_PAINT_TILINGOFFSET = Laya.Shader3D.getDefineByName("PAINT_TILINGOFFSET");
          PaintMaterial.SHADERDEFINE_PAINT_MASK = Laya.Shader3D.getDefineByName("PAINT_MASK");
          PaintMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
      }
      static initShader() {
          PaintMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': Laya.VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
          };
          var uniformMap = {
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_alpha': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PageBase': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintTilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintMask': Laya.Shader3D.PERIOD_MATERIAL,
          };
          var PaintMaterial3D = Laya.Shader3D.add("PaintMaterial");
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          PaintMaterial3D.addSubShader(subShader);
          var vs1 = `
		attribute vec4 a_Position; 
		attribute vec3 a_Normal; 
		attribute vec2 a_Texcoord0;
		uniform mat4 u_MvpMatrix; 
		uniform mat4 u_WorldMat;
		uniform vec3 u_CameraPos;
		varying vec2 v_Texcoord0;

		void main() 
		{ 
			gl_Position=u_MvpMatrix * a_Position;
			mat3 worldMat=mat3(u_WorldMat);

            v_Texcoord0=a_Texcoord0;

			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
		}`;
          var ps1 = `
		// #ifdef FSHIGHPRECISION 
		//    precision highp float; 
		// #else 
		//    precision mediump float; 
		// #endif 
        precision lowp float;
	
        varying vec2 v_Texcoord0; 
        
        #ifdef PAGE_BASE
            uniform sampler2D u_PageBase;
        #endif

        #ifdef PAINT_TEXTURE
			uniform sampler2D u_PaintTexture;
        #endif
        
        #ifdef PAINT_TILINGOFFSET
			uniform vec4 u_PaintTilingOffset;
        #endif
        
        #ifdef PAINT_MASK
			uniform sampler2D u_PaintMask;
		#endif

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
        #endif
        
        vec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {
            vec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);
            transTexcoord.y+=1.0;
            return transTexcoord;
        }

		void main_normal(){
			vec4 albedoTextureColor = vec4(0.0);
		
			#if defined(PAGE_BASE)&&defined(PAINT_TEXTURE)&&defined(PAINT_MASK)
				vec4 baseColor = texture2D(u_PageBase, v_Texcoord0);

				#ifdef PAINT_TILINGOFFSET
					vec2 texcoordL1 = TransformUV(v_Texcoord0, u_PaintTilingOffset);
					vec4 paintColor = texture2D(u_PaintTexture, texcoordL1);
				#else
					vec4 paintColor = texture2D(u_PaintTexture, v_Texcoord0);
				#endif

				vec4 maskColor = texture2D(u_PaintMask, v_Texcoord0);

				// albedoTextureColor.rgba = baseColor * (1.0 - maskColor.a) + paintColor * maskColor.a;
				albedoTextureColor.rgb = baseColor.rgb * (1.0 - maskColor.a) + paintColor.rgb * maskColor.a;
				albedoTextureColor.a = baseColor.a * (1.0 - maskColor.a) + paintColor.a * maskColor.a;
			#endif

			#ifdef ALPHATEST
			if(albedoTextureColor.a <= 0.1){
				discard;
			}
			#endif

			#ifdef WHOLE_ALPHA
				//叠加全局透明度
				gl_FragColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a*u_alpha);
			#else
				gl_FragColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a);
			#endif
		}
	
		void main() 
		{ 
			main_normal();
		}`;
          subShader.addShaderPass(vs1, ps1, stateMap);
      }
      get pageBase() {
          return this._shaderValues.getTexture(PaintMaterial.PAGE_BASE);
      }
      set pageBase(value) {
          if (value) {
              this._shaderValues.addDefine(PaintMaterial.SHADERDEFINE_PAGE_BASE);
          }
          else {
              this._shaderValues.removeDefine(PaintMaterial.SHADERDEFINE_PAGE_BASE);
          }
          this._shaderValues.setTexture(PaintMaterial.PAGE_BASE, value);
      }
      get paintTexture() {
          return this._shaderValues.getTexture(PaintMaterial.PAINT_TEXTURE);
      }
      set paintTexture(value) {
          if (value) {
              this._shaderValues.addDefine(PaintMaterial.SHADERDEFINE_PAINT_TEXTURE);
          }
          else {
              this._shaderValues.removeDefine(PaintMaterial.SHADERDEFINE_PAINT_TEXTURE);
          }
          this._shaderValues.setTexture(PaintMaterial.PAINT_TEXTURE, value);
      }
      get paintMask() {
          return this._shaderValues.getTexture(PaintMaterial.PAINT_MASK);
      }
      set paintMask(value) {
          if (value) {
              this._shaderValues.addDefine(PaintMaterial.SHADERDEFINE_PAINT_MASK);
          }
          else {
              this._shaderValues.removeDefine(PaintMaterial.SHADERDEFINE_PAINT_MASK);
          }
          this._shaderValues.setTexture(PaintMaterial.PAINT_MASK, value);
      }
      get paintTilingOffset() {
          return this._shaderValues.getVector(PaintMaterial.PAINT_TILINGOFFSET);
      }
      set paintTilingOffset(value) {
          if (value) {
              if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
                  this._shaderValues.addDefine(PaintMaterial.SHADERDEFINE_PAINT_TILINGOFFSET);
              else
                  this._shaderValues.removeDefine(PaintMaterial.SHADERDEFINE_PAINT_TILINGOFFSET);
          }
          else {
              this._shaderValues.removeDefine(PaintMaterial.SHADERDEFINE_PAINT_TILINGOFFSET);
          }
          this._shaderValues.setVector(PaintMaterial.PAINT_TILINGOFFSET, value);
      }
      get alpha() {
          return this._shaderValues.getNumber(PaintMaterial.WHOLE_ALPHA);
      }
      set alpha(value) {
          if (value != null) {
              this._defineDatas.add(PaintMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          else {
              this._defineDatas.remove(PaintMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          this._shaderValues.setNumber(PaintMaterial.WHOLE_ALPHA, value);
      }
      get cull() {
          return this._shaderValues.getInt(PaintMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(PaintMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(PaintMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(PaintMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(PaintMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(PaintMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(PaintMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(PaintMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(PaintMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(PaintMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(PaintMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(PaintMaterial.DEPTH_WRITE, value);
      }
      set renderMode(value) {
          switch (value) {
              case PaintMaterial.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case PaintMaterial.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case PaintMaterial.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case PaintMaterial.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case PaintMaterial.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case PaintMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_ONE_MINUS_DST_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LEQUAL;
                  break;
              default:
                  throw new Error("PaintMaterial : renderMode value error.");
          }
      }
  }
  PaintMaterial.PAGE_BASE = Laya.Shader3D.propertyNameToID("u_PageBase");
  PaintMaterial.PAINT_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintTexture");
  PaintMaterial.PAINT_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintTilingOffset");
  PaintMaterial.PAINT_MASK = Laya.Shader3D.propertyNameToID("u_PaintMask");
  PaintMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  PaintMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  PaintMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  PaintMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  PaintMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  PaintMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  PaintMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  PaintMaterial.RENDERMODE_OPAQUE = 1;
  PaintMaterial.RENDERMODE_CUTOUT = 2;
  PaintMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  PaintMaterial.RENDERMODE_TRANSPARENT = 4;
  PaintMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  PaintMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD = 6;

  class CustomPBRSkinMaterial extends Laya.PBRMaterial {
      constructor() {
          super();
          this.setShaderName("CustomPBRSkinShader");
          this._shaderValues.setVector(CustomPBRSkinMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SHADOWRANGE, 0.002);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SHADOWINTENSITY, 0.98);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SHADOWBOUNDARY, 0.015);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPECULARRANGE, 0.99);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPECULARINTENSITY, 0.09);
          this._shaderValues.setVector(CustomPBRSkinMaterial.SPECULARCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.OUTLINEWIDTH, 0.001);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.OUTLINELIGHTNESS, 0.25);
          this._shaderValues.setVector(CustomPBRSkinMaterial.OUTLINECOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this._shaderValues.setVector(CustomPBRSkinMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this._shaderValues.setVector(CustomPBRSkinMaterial.SECOND_SHADOWCOLOR, new Laya.Vector4(1, 1, 1, 1));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SECOND_SHADOWRANGE, 0.00);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SECOND_SHADOWINTENSITY, 0.98);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SECOND_SHADOWBOUNDARY, 0.0);
          this._shaderValues.setVector(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_COLOR, new Laya.Vector4(0, 1, 0, 1));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_RANGE, 0.00);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_INTENSITY, 0.98);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_BOUNDARY, 0.0);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.RANDOM_DISCARD_FACTOR, 1.0);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH, 0.25);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPMETALLIC, 0.0);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPSMOOTHNESS, 1.13);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPNOISEBUMP, 1.2);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPNOISEBUMPTILING, 8.0);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPNOISEBUMPBASICAO, 2.0);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPSHADOWATTEN, 0.9);
          this._shaderValues.setVector(CustomPBRSkinMaterial.SPEMISSIONCOLORBACK, new Laya.Vector4(0.65, 0.53, 0.53, 1.0));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY, 0.5);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPBORDEROFFSETAO, -0.43);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSLUCENCY, 5.0);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSSHADOW, 0.496);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION, 0.273);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSSCATTERING, 2.2);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSDIRECT, 0.651);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSAMBIENT, 0.715);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPRED3SOFFSET, 0.41);
          this._shaderValues.setVector(CustomPBRSkinMaterial.SPRED3SCOLOR, new Laya.Vector4(1.0, 0.0, 0.0, 1.0));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.NORMALTEXTURESCALE, 1.0);
      }
      static __init__() {
          CustomPBRSkinMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
          CustomPBRSkinMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
          CustomPBRSkinMaterial.SHADERDEFINE_MASKTEXTURE = Laya.Shader3D.getDefineByName("MASKTEXTURE");
          CustomPBRSkinMaterial.SHADERDEFINE_MASKDETAILTEXTURE = Laya.Shader3D.getDefineByName("MASKDETAILTEXTURE");
          CustomPBRSkinMaterial.SHADERDEFINE_RAMPMAPTEXTURE = Laya.Shader3D.getDefineByName("RAMPMAPTEXTURE");
          CustomPBRSkinMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
          CustomPBRSkinMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
      }
      static initShader() {
          CustomPBRSkinMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Tangent0': Laya.VertexMesh.MESH_TANGENT0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': Laya.VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
              'a_MvpMatrix': Laya.VertexMesh.MESH_MVPMATRIX_ROW0,
              'a_WorldMat': Laya.VertexMesh.MESH_WORLDMATRIX_ROW0
          };
          var uniformMap = {
              'u_Bones': Laya.Shader3D.PERIOD_CUSTOM,
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_LightmapScaleOffset': Laya.Shader3D.PERIOD_SPRITE,
              'u_LightMap': Laya.Shader3D.PERIOD_SPRITE,
              'u_LightMapDirection': Laya.Shader3D.PERIOD_SPRITE,
              'u_SimpleAnimatorTexture': Laya.Shader3D.PERIOD_SPRITE,
              'u_SimpleAnimatorParams': Laya.Shader3D.PERIOD_SPRITE,
              'u_SimpleAnimatorTextureSize': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_EmissionColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ParallaxTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_OcclusionTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_EmissionTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Smoothness': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SmoothnessScale': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPOcclusionStrength': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPMetallic': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPSmoothness': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPNoiseBump': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPNoiseBumpTiling': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPNoiseBumpBasicAO': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPShadowAtten': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPEmissionColorBack': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPEmissionColorBackIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPBorderOffsetAO': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalScale': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ParallaxScale': Laya.Shader3D.PERIOD_MATERIAL,
              'u_TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_MaskTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_MaskDetailTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_RampMapTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRedTranslucency': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRedTransShadow': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRedTransNormalDistortion': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRedTransScattering': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRedTransDirect': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRedTransAmbient': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRed3SOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPRed3SColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ReflectTexture': Laya.Shader3D.PERIOD_SCENE,
              'u_ReflectIntensity': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientColor': Laya.Shader3D.PERIOD_SCENE,
              'u_FogStart': Laya.Shader3D.PERIOD_SCENE,
              'u_FogRange': Laya.Shader3D.PERIOD_SCENE,
              'u_FogColor': Laya.Shader3D.PERIOD_SCENE,
              'u_DirationLightCount': Laya.Shader3D.PERIOD_SCENE,
              'u_LightBuffer': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowBias': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowLightDirection': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowMap': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowParams': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowSplitSpheres': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowMatrices': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowMapSize': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotShadowMap': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotViewProjectMatrix': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowLightPosition': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHAr': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHAg': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHAb': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHBr': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHBg': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHBb': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientSHC': Laya.Shader3D.PERIOD_SCENE,
              'u_ReflectionProbe': Laya.Shader3D.PERIOD_SCENE,
              'u_ReflectCubeHDRParams': Laya.Shader3D.PERIOD_SCENE,
              'u_DirectionLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_DirectionLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
          };
          var PBRShadowCasterPS$1 = "#ifdef GL_FRAGMENT_PRECISION_HIGH\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}";
          var PBRShadowCasterVS$1 = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS =  shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}";
          var vs1 = `
        #include "Lighting.glsl";
        #include "Shadow.glsl";
        // #include "PBRVSInput.glsl";
        //#include "PBRVertex.glsl";

        attribute vec4 a_Position;

        #ifdef GPU_INSTANCE
            attribute mat4 a_MvpMatrix;
            attribute mat4 a_WorldMat;
        #else
            uniform mat4 u_MvpMatrix;
            uniform mat4 u_WorldMat;
        #endif

        #ifdef BONE
            const int c_MaxBoneCount = 24;
            attribute vec4 a_BoneIndices;
            attribute vec4 a_BoneWeights;
            uniform mat4 u_Bones[c_MaxBoneCount];
        #endif

        attribute vec3 a_Normal;
        varying vec3 v_Normal; 

        #if defined(NORMALTEXTURE)||defined(PARALLAXTEXTURE)
            attribute vec4 a_Tangent0;
            varying vec3 v_Tangent;
            varying vec3 v_Binormal;
            // #ifdef PARALLAXTEXTURE
            //         varying vec3 v_ViewDirForParallax;
            // #endif
            #endif

        #if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)||(defined(LIGHTMAP)&&defined(UV))
            attribute vec2 a_Texcoord0;
            varying vec2 v_Texcoord0;
        #endif

        uniform vec3 u_CameraPos;
        varying vec3 v_EyeVec;
        varying vec3 v_PositionWorld;
        varying float v_posViewZ;

        #if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
            varying vec4 v_ShadowCoord;
        #endif

        #ifdef TILINGOFFSET
            uniform vec4 u_TilingOffset;
        #endif

        void vertexForward()
        {
            vec4 position;
            #ifdef BONE
                mat4 skinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
                skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
                skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
                skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
                position=skinTransform*a_Position;
            #else
                position=a_Position;
            #endif

            #ifdef GPU_INSTANCE
                gl_Position = a_MvpMatrix * position;
            #else
                gl_Position = u_MvpMatrix * position;
            #endif

            mat4 worldMat;
            #ifdef GPU_INSTANCE
                worldMat = a_WorldMat;
            #else
                worldMat = u_WorldMat;
            #endif

            v_PositionWorld=(worldMat*position).xyz;

            v_Texcoord0=a_Texcoord0;

            v_EyeVec =u_CameraPos-v_PositionWorld;//will normalize per-pixel

            mat3 worldInvMat;
            #ifdef BONE
                worldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));
            #else
                worldInvMat=INVERSE_MAT(mat3(worldMat));
            #endif

            v_Normal=normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem.

            #ifdef NORMALTEXTURE
                v_Tangent=normalize(a_Tangent0.xyz*worldInvMat);
                v_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;
            #endif

            #if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
                v_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
            #endif

        }
        
        #if defined(CASTSHADOW)
            varying vec4 v_posView;
        #endif
        void main()
        {
            vertexForward();
            #if defined(CASTSHADOW)
                v_posView = gl_Position.xyzw;
            #endif
            gl_Position=remapGLPositionZ(gl_Position);
        }`;
          var ps1 = `
        #ifdef GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif
        
        #include "Lighting.glsl";
        #include "Shadow.glsl";
        #include "LayaPBRBRDF.glsl";
        #include "GlobalIllumination.glsl";

        #ifdef ALPHATEST
            uniform float u_AlphaTestValue;
        #endif

        uniform vec4 u_AlbedoColor;

        #ifdef NORMALTEXTURE
            uniform sampler2D u_NormalTexture;
            uniform float u_NormalScale;
        #endif

        #ifdef ALBEDOTEXTURE
            uniform sampler2D u_AlbedoTexture;
            vec4 albedoTextureColor;
        #endif

        #ifdef MASKTEXTURE
            uniform sampler2D u_MaskTexture;
            vec4 maskTextureColor;
        #endif
        #ifdef MASKDETAILTEXTURE
            uniform sampler2D u_MaskDetailTexture;
        #endif
        
        #ifdef RAMPMAPTEXTURE
            uniform sampler2D u_RampMapTexture; 
        #endif

        uniform vec3 u_SpecularColor;

        uniform float u_Smoothness;
        uniform float u_SmoothnessScale;

        #if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)
            varying vec2 v_Texcoord0;
        #endif

        varying vec3 v_Normal; 

       #if defined(DIRECTIONLIGHT)

            #if defined(LEGACYSINGLELIGHTING)
                uniform DirectionLight u_SunLight;
            #else
                uniform int u_DirationLightCount;
                uniform sampler2D u_LightBuffer;
            #endif
                
        #endif

        varying vec3 v_EyeVec;

        #ifdef NORMALTEXTURE
            varying vec3 v_Tangent;
            varying vec3 v_Binormal;
        #endif

        #if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
            varying vec4 v_ShadowCoord;

        #endif

        uniform float u_SPOcclusionStrength;
        uniform float u_SPMetallic;
        uniform float u_SPSmoothness;
        uniform float u_SPNoiseBump;
        uniform float u_SPNoiseBumpTiling;
        uniform float u_SPNoiseBumpBasicAO;
        uniform float u_SPShadowAtten;
        uniform vec4 u_SPEmissionColorBack;
        uniform float u_SPEmissionColorBackIntensity;
        uniform float u_SPBorderOffsetAO;

        vec3 albedoRgb;

        #if defined(RAMPMAPTEXTURE)&&defined(MASKTEXTURE)
        uniform float u_SPRedTranslucency;
        uniform float u_SPRedTransShadow;
        uniform float u_SPRedTransNormalDistortion;
        uniform float u_SPRedTransScattering;
        uniform float u_SPRedTransDirect;
        uniform float u_SPRedTransAmbient;
        uniform float u_SPRed3SOffset;
        uniform vec4 u_SPRed3SColor;
        #endif

        mediump float lerpOneTo(mediump float b, mediump float t)
        {
            mediump float oneMinusT = 1.0 - t;
            return oneMinusT + b * t;
        }

        mediump float getAlpha(vec2 uv)
        {
                #ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA
                return u_AlbedoColor.a;
            #else
                #ifdef ALBEDOTEXTURE
                    return albedoTextureColor.a * u_AlbedoColor.a;
                #else
                    return u_AlbedoColor.a;
                #endif
            #endif
        }

        mediump float getOcclusion(vec2 uv)
        {
            #ifdef MASKTEXTURE
                mediump float occ = maskTextureColor.b;//texture2D(u_MaskTexture, uv).b;
                return lerpOneTo(occ, u_SPOcclusionStrength);
            #else
                return u_SPOcclusionStrength;
            #endif 
        }

        mediump vec3 albedo(vec2 uv)
        {
            #ifdef ALBEDOTEXTURE
                return u_AlbedoColor.rgb * albedoTextureColor.rgb;
            #else
                return u_AlbedoColor.rgb;
            #endif
            
        }
        float random(float x, float y){
			return fract(cos(x * (12.9898) + y * (4.1414)) * 43758.5453);
		}
        mediump vec2 getMetallicGloss(vec2 uv)
        {
            mediump vec2 ms;//x is metallic,y is smoothness
            //lhcadd
            
            #ifdef MASKTEXTURE
                //vec4 maskRgb = texture2D(u_MaskTexture, uv);
                ms.y =maskTextureColor.r*u_SPSmoothness;

                ms.x =maskTextureColor.g*u_SPMetallic;;//ms.x =maskTextureColor.g*u_SPMetallic;
            #else 
                ms.y = u_SPSmoothness;

                ms.x =u_SPMetallic;//0.7639677;//0.7639677/2.0;
            #endif
            
            return ms;
        }

        #ifdef NORMALTEXTURE
            mediump vec3 unpackScaleNormal(mediump vec3 packednormal, mediump float bumpScale)
            {
                mediump vec3 normal = packednormal.xyz * 2.0 - 1.0;
                normal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.
                normal.xy *= bumpScale;
                return normal;
            }
            
            vec4 lerpVec4(vec4 a, vec4 b, float w) {
                if(w<=0.0){
                    return a;
                }else if(w>=1.0){
                    return b;
                }else{
                    return w*b +(1.0-w)*a;
                }
            }
            vec3 lerpVec3(vec3 a, vec3 b, float w) {
                if(w<=0.0){
                    return a;
                }else if(w>=1.0){
                    return b;
                }else{
                    return w*b +(1.0-w)*a;
                }
            }

            mediump vec3 normalInTangentSpace(vec2 texcoords)
            {
                mediump vec3 normalTangent = unpackScaleNormal(texture2D(u_NormalTexture, texcoords).rgb,u_NormalScale);
                
                //这里让阴影左移，边缘留光
                #if defined(MASKTEXTURE) && defined(MASKDETAILTEXTURE)
                    float _NoiseBump = u_SPNoiseBump;//0.3;
                    vec3 color93 = vec3(0.5019608,0.5019608,1.0) ;//////////: vec4(0.2158605,0.2158605,1,0);
                    vec2 detailTexcoords=TransformUV(texcoords,vec4(u_SPNoiseBumpTiling,u_SPNoiseBumpTiling,0.0,0.0));
                    vec4 tex2DNode60 = texture2D( u_MaskDetailTexture, detailTexcoords );
                    // vec4 tex2DNode21 = texture2D( u_MaskTexture, texcoords );//maskTextureColor
                    float lerpRatio =  clamp( ( _NoiseBump * ( 1.0 - ( maskTextureColor.g * u_SPNoiseBumpBasicAO ) ) ) ,0.0,1.0);
                    vec3 lerpResult94 = lerpVec3( color93 , tex2DNode60.rgb ,lerpRatio);
                    // vec4 break95 = lerpResult94;
                    vec3 appendResult78 = (vec3(( normalTangent.r + lerpResult94.r ) , ( lerpResult94.g + normalTangent.g ) , ( normalTangent.b + tex2DNode60.b )));
                    vec3 normalizeResult85 = normalize( ( 2.0 * appendResult78 ) + u_SPBorderOffsetAO );
                    // o.Normal = normalizeResult85;
                    normalTangent = normalizeResult85;
                
                #endif
                
                
                return normalTangent;
            }
        #endif

        struct FragmentCommonData{
            vec3 diffColor;
            vec3 specColor;
            float oneMinusReflectivity;
            float smoothness;
        };
        
        #ifndef SETUP_BRDF_INPUT
        #define SETUP_BRDF_INPUT metallicSetup//default is metallicSetup,also can be other.    specularSetup / metallicSetup
        #endif
        
        const mediump vec4 dielectricSpecularColor = vec4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301);
        
        mediump vec3 diffuseAndSpecularFromMetallic(mediump vec3 albedo,mediump float metallic, out mediump vec3 specColor, out mediump float oneMinusReflectivity)
        {
                specColor = mix(dielectricSpecularColor.rgb, albedo, metallic);
            oneMinusReflectivity= dielectricSpecularColor.a*(1.0-metallic);//diffuse proportion
            return albedo * oneMinusReflectivity;
        }
        
        mediump float specularStrength(mediump vec3 specular)
        {
            return max (max (specular.r, specular.g), specular.b);
        }
        
        // Diffuse/Spec Energy conservation
        mediump vec3 energyConservationBetweenDiffuseAndSpecular (mediump vec3 albedo, mediump vec3 specColor, out mediump float oneMinusReflectivity)
        {
                oneMinusReflectivity = 1.0 - specularStrength(specColor);
            return albedo * (vec3(1.0) - specColor);
        }
        
        #ifdef TRANSPARENTBLEND
            mediump vec3 preMultiplyAlpha (mediump vec3 diffColor, mediump float alpha, mediump float oneMinusReflectivity,out mediump float modifiedAlpha)
            {
                // Transparency 'removes' from Diffuse component
                diffColor *= alpha;
                // Reflectivity 'removes' from the rest of components, including Transparency
                // modifiedAlpha = 1.0-(1.0-alpha)*(1.0-reflectivity) = 1.0-(oneMinusReflectivity - alpha*oneMinusReflectivity) = 1.0-oneMinusReflectivity + alpha*oneMinusReflectivity
                modifiedAlpha = 1.0 - oneMinusReflectivity + alpha*oneMinusReflectivity;
                return diffColor;
            }
        #endif
        
        FragmentCommonData metallicSetup(vec2 uv)
        {
            mediump vec2 metallicGloss = getMetallicGloss(uv);
            mediump float metallic = metallicGloss.x;
            mediump float smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.
            mediump float oneMinusReflectivity;
            mediump vec3 specColor;
            mediump vec3 diffColor = diffuseAndSpecularFromMetallic(albedoRgb, metallic,/*out*/specColor,/*out*/oneMinusReflectivity);
        
            FragmentCommonData o;
            o.diffColor = diffColor;
            o.specColor = specColor;
            o.oneMinusReflectivity = oneMinusReflectivity;
            o.smoothness = smoothness;
            return o;
        }
        
        LayaGI fragmentGI(float smoothness,vec3 eyeVec,mediump float occlusion,mediump vec2 lightmapUV,vec3 worldnormal)
        {
            LayaGIInput giInput;
        
            vec3 worldViewDir = -eyeVec;
            mediump vec4 uvwRoughness;
            uvwRoughness.rgb = reflect(worldViewDir, worldnormal);//reflectUVW
            uvwRoughness.a= smoothnessToPerceptualRoughness(smoothness);//perceptualRoughness
        
            return layaGlobalIllumination(giInput,occlusion, worldnormal, uvwRoughness);
        }
        
        vec3 perPixelWorldNormalByNormalTanget(vec2 uv,vec3 normal,vec3 binormal,vec3 tangent,vec3 normalTangent)
        {
            #ifdef NORMALTEXTURE
                vec3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z);
                
            #else
                vec3 normalWorld = normalize(normal);
            #endif
                return normalWorld;
        }
        
        void fragmentForward()
        {
            vec2 uv;
            #if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)
                    uv = v_Texcoord0;
            #endif

            #ifdef ALBEDOTEXTURE
                albedoTextureColor = texture2D(u_AlbedoTexture,uv);
            #endif
            
            mediump float alpha = getAlpha(uv);
            #ifdef ALPHATEST
                if(alpha<u_AlphaTestValue)
                    discard;
            #endif

            albedoRgb = albedo(uv);

            #ifdef MASKTEXTURE
                maskTextureColor = texture2D(u_MaskTexture,uv);
            #endif

            FragmentCommonData o = SETUP_BRDF_INPUT(uv);
            
            vec3 binormal;
            vec3 tangent;
            #ifdef NORMALTEXTURE
                tangent = v_Tangent;
                binormal = v_Binormal;
            #endif

            vec3 normal = v_Normal;
            vec3 normalTangent=normalInTangentSpace(uv);
            vec3 normalWorld = perPixelWorldNormalByNormalTanget(uv,normal,binormal,tangent,normalTangent);//In FS if the normal use mediump before normalize will cause precision prolem in mobile device.
            vec3 eyeVec = normalize(v_EyeVec);

            // DirectionLight directionLight0 = getDirectionLight(u_LightBuffer,1);
            // vec3 lightDir = normalize(directionLight0.direction);
            // vec3 lightColor = normalize(directionLight0.color);
            
            #ifdef TRANSPARENTBLEND
                o.diffColor=preMultiplyAlpha(o.diffColor,alpha,o.oneMinusReflectivity,/*out*/alpha);// shader relies on pre-multiply alpha-blend (srcBlend = One, dstBlend = OneMinusSrcAlpha)
            #endif

            mediump float occlusion = getOcclusion(uv);
            mediump vec2 lightMapUV;
           
            float perceptualRoughness = smoothnessToPerceptualRoughness(o.smoothness);
            float roughness = perceptualRoughnessToRoughness(perceptualRoughness);
            float nv = abs(dot(normalWorld, eyeVec));
            LayaGI gi =fragmentGI(o.smoothness,eyeVec,occlusion,lightMapUV,normalWorld);
            vec4 color = LAYA_BRDF_GI(o.diffColor,o.specColor,o.oneMinusReflectivity,o.smoothness,perceptualRoughness,roughness,nv,normalWorld,eyeVec,gi);
            

            vec3 lightDir = vec3(-0.3090169948284817,0.0,0.9510565161477913);;
            vec3 lightColor=vec3(0.5, 0.5, 0.5);


            #ifdef DIRECTIONLIGHT
                #if defined(LEGACYSINGLELIGHTING)
                    #ifdef CALCULATE_SHADOWS
                    
                            #ifdef SHADOW_CASCADE
                                vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
                            #else
                                vec4 shadowCoord = v_ShadowCoord;
                            #endif
                            sampleShadowmap(shadowCoord);
                        
                    #endif
                    DirectionLight directionLight;
                    directionLight.color=u_SunLight.color;
                    directionLight.direction = u_SunLight.direction;
    
                    LayaLight dirLight = layaDirectionLightToLight(directionLight,1.0);
                    color+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);
    
                    // dirLightFirst =  u_SunLight.direction;
                    // dirLightSecond =  vec3(-0.3090169948284817,0.0,0.9510565161477913);
                #else
                    for (int i = 0; i < MAX_LIGHT_COUNT; i++) 
                    {
                        float shadowAttenuation = 1.0;
                        if(i >= u_DirationLightCount)
                            break;
                        #ifdef CALCULATE_SHADOWS
                            if(i == 0)
                            {
                                #ifdef SHADOW_CASCADE
                                    vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
                                #else
                                    vec4 shadowCoord = v_ShadowCoord;
                                #endif
                                shadowAttenuation *= sampleShadowmap(shadowCoord);
                            }
                        #endif
                        DirectionLight directionLight = getDirectionLight(u_LightBuffer,i);
                        LayaLight dirLight = layaDirectionLightToLight(directionLight,shadowAttenuation);
                        color+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);
    
                    }
                #endif
            #endif
                
           
            
            vec3 emissionColorBack = u_SPEmissionColorBack.rgb;// vec3(0.65,0.53,0.53);
            
			float emissionClampRatio = u_SPEmissionColorBackIntensity;//clamp( (dotResult*emmissionOffset + 0.5),0.0,1.0 );
            vec3 emissionColorResult = ( ( 1.0 - emissionClampRatio ) * albedoRgb * emissionColorBack ).rgb;
            color.rgb += emissionColorResult;


            ////////////////////////////
            
            #if defined(RAMPMAPTEXTURE)&&defined(MASKTEXTURE)
             
                
                vec3 emissionWorldNormal = perPixelWorldNormalByNormalTanget(uv,normal,binormal,tangent,vec3( 0.0, 0.0, 1.0 ));
                float dotResult32 = dot( lightDir , emissionWorldNormal );//lightDir
                float temp_output_35_0 = clamp( (dotResult32*u_SPRed3SOffset + 0.5),0.0,1.0 );
                
                vec2 temp_cast_3 = vec2(temp_output_35_0,temp_output_35_0);

                vec4 tex2dNodeRamp = texture2D(u_RampMapTexture, temp_cast_3);

                vec4 customTranslucencyBasicColor = maskTextureColor.g * u_SPRed3SColor * tex2dNodeRamp * (dotResult32*0.85 + 0.27);
                vec3 customTranslucencyColor = vec3(clamp( customTranslucencyBasicColor.r,0.0,1.0 ),clamp( customTranslucencyBasicColor.g,0.0,1.0 ),clamp( customTranslucencyBasicColor.b,0.0,1.0 ));


                vec3 lightColorCaculated =  lerpVec3(lightColor.rgb, vec3(1.0,1.0,1.0), u_SPRedTransShadow );
                vec3 lightDirCaculated = lightDir + normalTangent * u_SPRedTransNormalDistortion;
                float transVdotL = pow( clamp( dot( eyeVec, -lightDirCaculated ),0.0,1.0 ), u_SPRedTransScattering );
                vec3 translucency = lightColorCaculated * (transVdotL * u_SPRedTransDirect + o.oneMinusReflectivity * u_SPRedTransAmbient) * customTranslucencyColor;
                vec4 c = vec4(albedoRgb * translucency * u_SPRedTranslucency,0.0);
                color+=c;
            #endif
            ////////////////////////////
            
            gl_FragColor=vec4(color.rgb,alpha);
        }

        #if defined(CASTSHADOW)
		varying vec4 v_posView;
		#endif

        void main_castshadow(){
			#ifdef CASTSHADOW
				float z = v_posView.z/v_posView.w;
				z = z*0.5 + 0.5;
				gl_FragColor = vec4(0.0, 0, z, 1.0);
			#endif
		}

        void main()
        {
            #ifdef CASTSHADOW
                main_castshadow();
            #else
                fragmentForward();
            #endif
        }`;
          var shader3D = Laya.Shader3D.add("CustomPBRSkinShader", attributeMap, uniformMap, true);
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          shader3D.addSubShader(subShader);
          subShader.addShaderPass(vs1, ps1, stateMap, "Forward");
          if (GameConst.bHighShadowQuality) {
              subShader.addShaderPass(PBRShadowCasterVS$1, PBRShadowCasterPS$1, stateMap, "ShadowCaster");
          }
      }
      get normalTextureScale() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.NORMALTEXTURESCALE);
      }
      set normalTextureScale(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.NORMALTEXTURESCALE, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.NORMALTEXTURESCALE, value);
      }
      get maskTexture() {
          return this._shaderValues.getTexture(CustomPBRSkinMaterial.MASKTEXTURE);
      }
      set maskTexture(value) {
          if (value)
              this._defineDatas.add(CustomPBRSkinMaterial.SHADERDEFINE_MASKTEXTURE);
          else
              this._defineDatas.remove(CustomPBRSkinMaterial.SHADERDEFINE_MASKTEXTURE);
          this._shaderValues.setTexture(CustomPBRSkinMaterial.MASKTEXTURE, value);
      }
      get maskDetailTexture() {
          return this._shaderValues.getTexture(CustomPBRSkinMaterial.MASKDETAILTEXTURE);
      }
      set maskDetailTexture(value) {
          if (value)
              this._defineDatas.add(CustomPBRSkinMaterial.SHADERDEFINE_MASKDETAILTEXTURE);
          else
              this._defineDatas.remove(CustomPBRSkinMaterial.SHADERDEFINE_MASKDETAILTEXTURE);
          this._shaderValues.setTexture(CustomPBRSkinMaterial.MASKDETAILTEXTURE, value);
      }
      get rampMapTexture() {
          return this._shaderValues.getTexture(CustomPBRSkinMaterial.RAMPMAPTEXTURE);
      }
      set rampMapTexture(value) {
          if (value)
              this._defineDatas.add(CustomPBRSkinMaterial.SHADERDEFINE_RAMPMAPTEXTURE);
          else
              this._defineDatas.remove(CustomPBRSkinMaterial.SHADERDEFINE_RAMPMAPTEXTURE);
          this._shaderValues.setTexture(CustomPBRSkinMaterial.RAMPMAPTEXTURE, value);
      }
      get shadowColor() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.SHADOWCOLOR);
      }
      set shadowColor(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.SHADOWCOLOR, value);
      }
      get shadowRange() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SHADOWRANGE);
      }
      set shadowRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SHADOWRANGE, value);
      }
      get shadowIntensity() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SHADOWINTENSITY);
      }
      set shadowIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SHADOWINTENSITY, value);
      }
      get shadowBoundary() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SHADOWBOUNDARY);
      }
      set shadowBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SHADOWBOUNDARY, value);
      }
      get specularRange() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPECULARRANGE);
      }
      set specularRange(value) {
          value = Math.max(0.9, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPECULARRANGE, value);
      }
      set specularIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPECULARINTENSITY, value);
      }
      get specularIntensity() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPECULARINTENSITY);
      }
      get specularColor() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.SPECULARCOLOR);
      }
      set specularColor(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.SPECULARCOLOR, value);
      }
      get outlineWidth() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.OUTLINEWIDTH);
      }
      set outlineWidth(value) {
          value = Math.max(0.0, Math.min(0.05, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.OUTLINEWIDTH, value);
      }
      get outlineColor() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.OUTLINECOLOR);
      }
      set outlineColor(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.OUTLINECOLOR, value);
      }
      get outlineLightness() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.OUTLINELIGHTNESS);
      }
      set outlineLightness(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.OUTLINELIGHTNESS, value);
      }
      get secondShadowColor() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.SECOND_SHADOWCOLOR);
      }
      set secondShadowColor(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.SECOND_SHADOWCOLOR, value);
      }
      get secondShadowRange() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SECOND_SHADOWRANGE);
      }
      set secondShadowRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SECOND_SHADOWRANGE, value);
      }
      get secondShadowIntensity() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SECOND_SHADOWINTENSITY);
      }
      set secondShadowIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SECOND_SHADOWINTENSITY, value);
      }
      get secondShadowBoundary() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SECOND_SHADOWBOUNDARY);
      }
      set secondShadowBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SECOND_SHADOWBOUNDARY, value);
      }
      get EdgeHightColor() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_COLOR);
      }
      set EdgeHightColor(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_COLOR, value);
      }
      get EdgeHightRange() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_RANGE);
      }
      set EdgeHightRange(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_RANGE, value);
      }
      get EdgeHightIntensity() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_INTENSITY);
      }
      set EdgeHightIntensity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_INTENSITY, value);
      }
      get EdgeHightBoundary() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_BOUNDARY);
      }
      set EdgeHightBoundary(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(CustomPBRSkinMaterial.EDGE_HIGHLIGHT_BOUNDARY, value);
      }
      get SPOcclusionStrength() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH);
      }
      set SPOcclusionStrength(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH, value);
      }
      get SPMetallic() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPMETALLIC);
      }
      set SPMetallic(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPMETALLIC, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPMETALLIC, value);
      }
      get SPSmoothness() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPSMOOTHNESS);
      }
      set SPSmoothness(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPSMOOTHNESS, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPSMOOTHNESS, value);
      }
      get SPNoiseBump() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPNOISEBUMP);
      }
      set SPNoiseBump(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPNOISEBUMP, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPNOISEBUMP, value);
      }
      get SPNoiseBumpTiling() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPNOISEBUMPTILING);
      }
      set SPNoiseBumpTiling(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPNOISEBUMPTILING, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPNOISEBUMPTILING, value);
      }
      get SPNoiseBumpBasicAO() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPNOISEBUMPBASICAO);
      }
      set SPNoiseBumpBasicAO(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPNOISEBUMPBASICAO, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPNOISEBUMPBASICAO, value);
      }
      get SPShadowAtten() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPSHADOWATTEN);
      }
      set SPShadowAtten(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPSHADOWATTEN, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPSHADOWATTEN, value);
      }
      get SPEmissionColorBack() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.SPEMISSIONCOLORBACK);
      }
      set SPEmissionColorBack(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.SPEMISSIONCOLORBACK, value);
      }
      get SPEmissionColorBackIntensity() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY);
      }
      set SPEmissionColorBackIntensity(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY, value);
      }
      get SPBorderOffsetAO() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPBORDEROFFSETAO);
      }
      set SPBorderOffsetAO(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPBORDEROFFSETAO, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPBORDEROFFSETAO, value);
      }
      get SPRedTranslucency() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPREDTRANSLUCENCY);
      }
      set SPRedTranslucency(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPREDTRANSLUCENCY, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSLUCENCY, value);
      }
      get SPRedTransShadow() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPREDTRANSSHADOW);
      }
      set SPRedTransShadow(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPREDTRANSSHADOW, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSSHADOW, value);
      }
      get SPRedTransNormalDistortion() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION);
      }
      set SPRedTransNormalDistortion(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION, value);
      }
      get SPRedTransScattering() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPREDTRANSSCATTERING);
      }
      set SPRedTransScattering(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPREDTRANSSCATTERING, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSSCATTERING, value);
      }
      get SPRedTransDirect() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPREDTRANSDIRECT);
      }
      set SPRedTransDirect(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPREDTRANSDIRECT, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSDIRECT, value);
      }
      get SPRedTransAmbient() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPREDTRANSAMBIENT);
      }
      set SPRedTransAmbient(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPREDTRANSAMBIENT, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPREDTRANSAMBIENT, value);
      }
      get SPRed3SOffset() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.SPRED3SOFFSET);
      }
      set SPRed3SOffset(value) {
          value = this.clampKeyValueByKey(CustomPBRSkinMaterial.SPRED3SOFFSET, value);
          this._shaderValues.setNumber(CustomPBRSkinMaterial.SPRED3SOFFSET, value);
      }
      get SPRed3SColor() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.SPRED3SCOLOR);
      }
      set SPRed3SColor(value) {
          this._shaderValues.setVector(CustomPBRSkinMaterial.SPRED3SCOLOR, value);
      }
      getShaderValueRangeWithKey(key) {
          switch (key) {
              case CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH:
                  return [0.0, 2.0];
                  break;
              case CustomPBRSkinMaterial.SPMETALLIC:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.SPSMOOTHNESS:
                  return [0.0, 2.0];
                  break;
              case CustomPBRSkinMaterial.SPNOISEBUMP:
                  return [0.0, 2.0];
                  break;
              case CustomPBRSkinMaterial.SPNOISEBUMPTILING:
                  return [0.0, 16.0];
                  break;
              case CustomPBRSkinMaterial.SPNOISEBUMPBASICAO:
                  return [0.0, 5.0];
                  break;
              case CustomPBRSkinMaterial.SPSHADOWATTEN:
                  return [0.0, 2.0];
                  break;
              case CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.SPBORDEROFFSETAO:
                  return [-2.0, 2.0];
                  break;
              case CustomPBRSkinMaterial.SPREDTRANSLUCENCY:
                  return [0.0, 50.0];
                  break;
              case CustomPBRSkinMaterial.SPREDTRANSSHADOW:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.SPREDTRANSSCATTERING:
                  return [1.0, 50.0];
                  break;
              case CustomPBRSkinMaterial.SPREDTRANSDIRECT:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.SPREDTRANSAMBIENT:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.SPRED3SOFFSET:
                  return [0.0, 1.0];
                  break;
              case CustomPBRSkinMaterial.NORMALTEXTURESCALE:
                  return [0.0, 2.0];
                  break;
              default:
                  break;
          }
          return [0.0, 1.0];
      }
      clampKeyValueByKey(key, value) {
          return Math.max(this.getShaderValueRangeWithKey(key)[0], Math.min(this.getShaderValueRangeWithKey(key)[1], value));
      }
      get tilingOffset() {
          return this._shaderValues.getVector(CustomPBRSkinMaterial.TILINGOFFSET);
      }
      set tilingOffset(value) {
          if (value) {
              if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
                  this._defineDatas.add(CustomPBRSkinMaterial.SHADERDEFINE_TILINGOFFSET);
              else
                  this._defineDatas.remove(CustomPBRSkinMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          else {
              this._defineDatas.remove(CustomPBRSkinMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          this._shaderValues.setVector(CustomPBRSkinMaterial.TILINGOFFSET, value);
      }
      get cull() {
          return this._shaderValues.getInt(CustomPBRSkinMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(CustomPBRSkinMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(CustomPBRSkinMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(CustomPBRSkinMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(CustomPBRSkinMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(CustomPBRSkinMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(CustomPBRSkinMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(CustomPBRSkinMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(CustomPBRSkinMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(CustomPBRSkinMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(CustomPBRSkinMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(CustomPBRSkinMaterial.DEPTH_WRITE, value);
      }
      get randomDiscardFactor() {
          return this._shaderValues.getNumber(CustomPBRSkinMaterial.RANDOM_DISCARD_FACTOR);
      }
      set randomDiscardFactor(value) {
          this._shaderValues.setNumber(CustomPBRSkinMaterial.RANDOM_DISCARD_FACTOR, value);
      }
      get materialType() {
          return CustomMaterialType.pbrSkin;
      }
      get renderMode() {
          return this.__render_mode__;
      }
      set renderMode(value) {
          this.__render_mode__ = value;
          switch (value) {
              case CustomMaterialRenderMode.unknown:
              case CustomMaterialRenderMode.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_OPAQUE_CULL_NONE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              default:
                  throw new Error("CustomMaterialRenderMode : renderMode value error.");
          }
      }
      getCanEditorParamList() {
          return [
              { name: `SPOcclusionStrength`, desc: `遮挡强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH) },
              { name: `SPMetallic`, desc: `金属度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPMETALLIC) },
              { name: `SPSmoothness`, desc: `光滑度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPSMOOTHNESS) },
              { name: `SPNoiseBump`, desc: `噪点影响值1`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPNOISEBUMP) },
              { name: `SPNoiseBumpTiling`, desc: `细节贴图平铺度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPNOISEBUMPTILING) },
              { name: `SPNoiseBumpBasicAO`, desc: `噪点影响值2`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPNOISEBUMPBASICAO) },
              { name: `SPShadowAtten`, desc: `阴影强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPSHADOWATTEN) },
              { name: `SPEmissionColorBackIntensity`, desc: `自发光底色强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY) },
              { name: `SPBorderOffsetAO`, desc: `偏移度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPBORDEROFFSETAO) },
              { name: `SPRedTranslucency`, desc: `皮肤透光度影响值`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPREDTRANSLUCENCY) },
              { name: `SPRedTransShadow`, desc: `皮肤暗部影响值`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPREDTRANSSHADOW) },
              { name: `SPRedTransNormalDistortion`, desc: `法线影响值`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION) },
              { name: `SPRedTransScattering`, desc: `透光散射1`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPREDTRANSSCATTERING) },
              { name: `SPRedTransDirect`, desc: `透光散射2`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPREDTRANSDIRECT) },
              { name: `SPRedTransAmbient`, desc: `反射度影响值`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPREDTRANSAMBIENT) },
              { name: `SPRed3SOffset`, desc: `法线偏移影响值`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.SPRED3SOFFSET) },
              { name: `SPEmissionColorBack`, desc: `SPEmissionColorBack`, type: EditorType.color },
              { name: `SPRed3SColor`, desc: `SPRed3SColor`, type: EditorType.color },
              { name: `albedoColor`, desc: `albedoColor`, type: EditorType.color },
              { name: `normalTextureScale`, desc: `法线强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRSkinMaterial.NORMALTEXTURESCALE) },
          ];
      }
  }
  CustomPBRSkinMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  CustomPBRSkinMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  CustomPBRSkinMaterial.NORMALTEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  CustomPBRSkinMaterial.NORMALTEXTURESCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  CustomPBRSkinMaterial.MASKTEXTURE = Laya.Shader3D.propertyNameToID("u_MaskTexture");
  CustomPBRSkinMaterial.MASKDETAILTEXTURE = Laya.Shader3D.propertyNameToID("u_MaskDetailTexture");
  CustomPBRSkinMaterial.RAMPMAPTEXTURE = Laya.Shader3D.propertyNameToID("u_RampMapTexture");
  CustomPBRSkinMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  CustomPBRSkinMaterial.AMBIENTCOLOR = Laya.Shader3D.propertyNameToID("u_AmbientColor");
  CustomPBRSkinMaterial.OUTLINEWIDTH = Laya.Shader3D.propertyNameToID("u_OutlineWidth");
  CustomPBRSkinMaterial.OUTLINELIGHTNESS = Laya.Shader3D.propertyNameToID("u_OutlineLightness");
  CustomPBRSkinMaterial.OUTLINECOLOR = Laya.Shader3D.propertyNameToID("u_OutlineColor");
  CustomPBRSkinMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  CustomPBRSkinMaterial.SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_ShadowRange");
  CustomPBRSkinMaterial.SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_ShadowIntensity");
  CustomPBRSkinMaterial.SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_ShadowBoundary");
  CustomPBRSkinMaterial.SECOND_SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_Second_ShadowColor");
  CustomPBRSkinMaterial.SECOND_SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_Second_ShadowRange");
  CustomPBRSkinMaterial.SECOND_SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_Second_ShadowIntensity");
  CustomPBRSkinMaterial.SECOND_SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_Second_ShadowBoundary");
  CustomPBRSkinMaterial.EDGE_HIGHLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_Edge_HighlightColor");
  CustomPBRSkinMaterial.EDGE_HIGHLIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_Edge_HighlightRange");
  CustomPBRSkinMaterial.EDGE_HIGHLIGHT_INTENSITY = Laya.Shader3D.propertyNameToID("u_Edge_HighlightIntensity");
  CustomPBRSkinMaterial.EDGE_HIGHLIGHT_BOUNDARY = Laya.Shader3D.propertyNameToID("u_Edge_HighlightBoundary");
  CustomPBRSkinMaterial.SPECULARRANGE = Laya.Shader3D.propertyNameToID("u_SpecularRange");
  CustomPBRSkinMaterial.SPECULARINTENSITY = Laya.Shader3D.propertyNameToID("u_SpecularIntensity");
  CustomPBRSkinMaterial.SPECULARCOLOR = Laya.Shader3D.propertyNameToID("u_SpecularColor");
  CustomPBRSkinMaterial.RANDOM_DISCARD_FACTOR = Laya.Shader3D.propertyNameToID(`u_RandomDiscardFactor`);
  CustomPBRSkinMaterial.SPOCCLUSIONSTRENGTH = Laya.Shader3D.propertyNameToID(`u_SPOcclusionStrength`);
  CustomPBRSkinMaterial.SPMETALLIC = Laya.Shader3D.propertyNameToID(`u_SPMetallic`);
  CustomPBRSkinMaterial.SPSMOOTHNESS = Laya.Shader3D.propertyNameToID(`u_SPSmoothness`);
  CustomPBRSkinMaterial.SPNOISEBUMP = Laya.Shader3D.propertyNameToID(`u_SPNoiseBump`);
  CustomPBRSkinMaterial.SPNOISEBUMPTILING = Laya.Shader3D.propertyNameToID(`u_SPNoiseBumpTiling`);
  CustomPBRSkinMaterial.SPNOISEBUMPBASICAO = Laya.Shader3D.propertyNameToID(`u_SPNoiseBumpBasicAO`);
  CustomPBRSkinMaterial.SPSHADOWATTEN = Laya.Shader3D.propertyNameToID(`u_SPShadowAtten`);
  CustomPBRSkinMaterial.SPEMISSIONCOLORBACK = Laya.Shader3D.propertyNameToID(`u_SPEmissionColorBack`);
  CustomPBRSkinMaterial.SPEMISSIONCOLORBACKINTENSITY = Laya.Shader3D.propertyNameToID(`u_SPEmissionColorBackIntensity`);
  CustomPBRSkinMaterial.SPBORDEROFFSETAO = Laya.Shader3D.propertyNameToID(`u_SPBorderOffsetAO`);
  CustomPBRSkinMaterial.SPREDTRANSLUCENCY = Laya.Shader3D.propertyNameToID(`u_SPRedTranslucency`);
  CustomPBRSkinMaterial.SPREDTRANSSHADOW = Laya.Shader3D.propertyNameToID(`u_SPRedTransShadow`);
  CustomPBRSkinMaterial.SPREDTRANSNORMALDISTORTION = Laya.Shader3D.propertyNameToID(`u_SPRedTransNormalDistortion`);
  CustomPBRSkinMaterial.SPREDTRANSSCATTERING = Laya.Shader3D.propertyNameToID(`u_SPRedTransScattering`);
  CustomPBRSkinMaterial.SPREDTRANSDIRECT = Laya.Shader3D.propertyNameToID(`u_SPRedTransDirect`);
  CustomPBRSkinMaterial.SPREDTRANSAMBIENT = Laya.Shader3D.propertyNameToID(`u_SPRedTransAmbient`);
  CustomPBRSkinMaterial.SPRED3SOFFSET = Laya.Shader3D.propertyNameToID(`u_SPRed3SOffset`);
  CustomPBRSkinMaterial.SPRED3SCOLOR = Laya.Shader3D.propertyNameToID(`u_SPRed3SColor`);
  CustomPBRSkinMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  CustomPBRSkinMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  CustomPBRSkinMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  CustomPBRSkinMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  CustomPBRSkinMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  CustomPBRSkinMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");

  class CustomPBRHairMaterial extends Laya.Material {
      constructor() {
          super();
          this.setShaderName("CustomPBRHairShader");
          this._shaderValues.setVector(CustomPBRHairMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPMETALLIC, 0.0);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPSMOOTHNESS, 1);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPUTILING, 1.4);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPPBRINSTENSITY, 0.2);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPHAIRALBEDOAO, 0.597);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYBIASG, -1.6);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYBIASR, 0.36);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPHAIRSPECULARAO, 0.694);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYRANG1, 7.0);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYRANG2, 781.0);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPHLFREPOWER, 2.0);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPSPECULARINDARKALPHA, 0.0588);
          this._shaderValues.setVector(CustomPBRHairMaterial.SPR1SPECALURCOLOR, new Laya.Vector4(0.3, 0.18, 0.18, 0.0));
          this._shaderValues.setVector(CustomPBRHairMaterial.SPR2SPECALURCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 0.0));
          this._shaderValues.setVector(CustomPBRHairMaterial.SPSPECULARINDARK, new Laya.Vector4(0.247, 0.235, 0.294, 0.0588));
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPPBRFINALLIGHTRATIO, 1.0);
          this._shaderValues.setNumber(CustomPBRHairMaterial.NORMALTEXTURESCALE, 1.0);
      }
      static __init__() {
          CustomPBRHairMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
          CustomPBRHairMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
          CustomPBRHairMaterial.SHADERDEFINE_MASKTEXTURE = Laya.Shader3D.getDefineByName("MASKTEXTURE");
          CustomPBRHairMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
          CustomPBRHairMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
          CustomPBRHairMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
          CustomPBRHairMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
      }
      static initShader() {
          CustomPBRHairMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Tangent0': Laya.VertexMesh.MESH_TANGENT0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': Laya.VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
              'a_MvpMatrix': Laya.VertexMesh.MESH_MVPMATRIX_ROW0,
              'a_WorldMat': Laya.VertexMesh.MESH_WORLDMATRIX_ROW0
          };
          var uniformMap = {
              'u_Bones': Laya.Shader3D.PERIOD_CUSTOM,
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPSmoothness': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPMetallic': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalScale': Laya.Shader3D.PERIOD_MATERIAL,
              'u_MaskTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Metallic': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ReflectTexture': Laya.Shader3D.PERIOD_SCENE,
              'u_ReflectIntensity': Laya.Shader3D.PERIOD_SCENE,
              'u_AmbientColor': Laya.Shader3D.PERIOD_SCENE,
              'u_DirationLightCount': Laya.Shader3D.PERIOD_SCENE,
              'u_DirectionLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_DirectionLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SPUTiling': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPPBRInstensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPHairAlbedoAO': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPAnisotropyBiasG': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPAnisotropyBiasR': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPHairSpecularAO': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPAnisotropyRang1': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPAnisotropyRang2': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPHLFrePower': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPSpecularInDarkAlpha': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPR1SpecalurColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPR2SpecalurColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPSpecularInDark': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SPPBRFinalLightRatio': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
          };
          var vs1 = `

        #ifdef GRAPHICS_API_GLES3
            #define INVERSE_MAT(mat) inverse(mat)
        #else
            #define INVERSE_MAT(mat) inverseMat(mat)
        #endif

        attribute vec4 a_Position;

        #ifdef GPU_INSTANCE
            attribute mat4 a_MvpMatrix;
            attribute mat4 a_WorldMat;
        #else
            uniform mat4 u_MvpMatrix;
            uniform mat4 u_WorldMat;
        #endif

        #ifdef BONE
            const int c_MaxBoneCount = 24;
            attribute vec4 a_BoneIndices;
            attribute vec4 a_BoneWeights;
            uniform mat4 u_Bones[c_MaxBoneCount];
        #endif

        attribute vec3 a_Normal;
        varying vec3 v_Normal; 

        #if defined(NORMALTEXTURE)
            attribute vec4 a_Tangent0;
            varying vec3 v_Tangent;
            varying vec3 v_Binormal;

        #endif

        attribute vec2 a_Texcoord0;
        varying vec2 v_Texcoord0;


        uniform vec3 u_CameraPos;
        varying vec3 v_EyeVec;
        varying vec3 v_PositionWorld;

        #ifndef GRAPHICS_API_GLES3
            mat3 inverseMat(mat3 m) {
                float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
                float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
                float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];

                float b01 = a22 * a11 - a12 * a21;
                float b11 = -a22 * a10 + a12 * a20;
                float b21 = a21 * a10 - a11 * a20;

                float det = a00 * b01 + a01 * b11 + a02 * b21;

                return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
                    b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
                b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
            }
        #endif
        
        void vertexForward()
        {
            vec4 position;
            #ifdef BONE
                mat4 skinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
                skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
                skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
                skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
                position=skinTransform*a_Position;
            #else
                position=a_Position;
            #endif

            mat4 worldMat;
            #ifdef GPU_INSTANCE
                gl_Position = a_MvpMatrix * position;
                worldMat = a_WorldMat;
            #else
                gl_Position = u_MvpMatrix * position;
                worldMat = u_WorldMat;
            #endif

            v_PositionWorld=(worldMat*position).xyz;

            v_Texcoord0=a_Texcoord0;

            v_EyeVec =u_CameraPos-v_PositionWorld;//will normalize per-pixelattribute vec2 a_Texcoord0;
            

            mat3 worldInvMat;
            #ifdef BONE
                worldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));
            #else
                worldInvMat=INVERSE_MAT(mat3(worldMat));
            #endif

            v_Normal=normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem.

            #ifdef NORMALTEXTURE
                v_Tangent=normalize(a_Tangent0.xyz*worldInvMat);
                v_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;
            #endif

        }

                
        #if defined(CASTSHADOW)
			varying vec4 v_posView;
		#endif
        
        void main()
        {
            vertexForward();
                        
			#if defined(CASTSHADOW)
                v_posView = gl_Position.xyzw;
            #endif
            gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
        }`;
          var ps1 = `
        #ifdef GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif

        struct DirectionLight {
			vec3 color;
            vec3 direction;
        };

        #ifdef ALPHATEST
            uniform float u_AlphaTestValue;
        #endif

        uniform vec4 u_AlbedoColor;

        #ifdef NORMALTEXTURE
            uniform sampler2D u_NormalTexture;
            uniform float u_NormalScale;
            
        #endif

        #ifdef ALBEDOTEXTURE
            uniform sampler2D u_AlbedoTexture;
        #endif

        varying vec3 v_Tangent;
        varying vec3 v_Binormal;
        varying vec2 v_Texcoord0;

        #ifdef MASKTEXTURE
            uniform sampler2D u_MaskTexture;
        #endif

        uniform float u_Metallic;

        uniform float u_SPSmoothness;
        uniform float u_SPMetallic;

        varying vec3 v_Normal; 

        #if defined(DIRECTIONLIGHT)
            uniform DirectionLight u_SunLight;
        #endif

        varying vec3 v_EyeVec;

		uniform sampler2D u_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;

        varying vec3 v_PositionWorld;

        vec4 albedoRgba;


        uniform float u_SPUTiling;
        uniform float u_SPPBRInstensity;
        uniform float u_SPHairAlbedoAO;
        uniform float u_SPAnisotropyBiasG;
        uniform float u_SPAnisotropyBiasR;
        uniform float u_SPHairSpecularAO;
        uniform float u_SPAnisotropyRang1;
        uniform float u_SPAnisotropyRang2;
        uniform float u_SPHLFrePower;
        uniform float u_SPSpecularInDarkAlpha;
        uniform vec4 u_SPR1SpecalurColor;
        uniform vec4 u_SPR2SpecalurColor;
        uniform vec4 u_SPSpecularInDark;
        uniform float u_SPPBRFinalLightRatio;

        vec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {
			vec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);
            transTexcoord.y+=1.0;
            return transTexcoord;
        }
        
        mediump float lerpOneTo(mediump float b, mediump float t)
        {
            mediump float oneMinusT = 1.0 - t;
            return oneMinusT + b * t;
        }

        mediump vec4 albedo(vec2 uv)
        {
            vec2 appendResult264 = (vec2(u_SPUTiling , 1.0));
			vec2 uv_TexCoord261 = uv * appendResult264;
			vec4 tex2DNode65 =texture2D(u_MaskTexture, uv_TexCoord261);
			float lerpResult269 = lerpOneTo( tex2DNode65.b , u_SPHairAlbedoAO);
            vec3 temp_output_231_0 = ( lerpResult269 * u_AlbedoColor.rgb );
            

            vec3 originRgb;
            #ifdef ALBEDOTEXTURE
                originRgb = temp_output_231_0.rgb * texture2D(u_AlbedoTexture, uv).rgb;
            #else
                originRgb = temp_output_231_0.rgb;
            #endif

            vec4 computeRgba = vec4(originRgb.rgb,u_AlbedoColor.a);

			#ifdef LAYER1_TEXTURE
				vec2 texcoordL1 = TransformUV(uv, u_PaintLayer1TilingOffset);
				vec4 paintLayer1Color = texture2D(u_PaintLayer1Texture, texcoordL1);
				
				computeRgba.rgb = computeRgba.rgb * (1.0 - paintLayer1Color.a) + paintLayer1Color.rgb;
				computeRgba.a = computeRgba.a * (1.0 - paintLayer1Color.a) + paintLayer1Color.a * paintLayer1Color.a;
            #endif

            return computeRgba;

        }

        
        mediump vec3 unpackScaleNormal(mediump vec3 packednormal, mediump float bumpScale)
        {
            mediump vec3 normal = packednormal.xyz * 2.0 - 1.0;
            normal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.
            normal.xy *= bumpScale;
            return normal;
        }
        vec4 lerpVec4(vec4 a, vec4 b, float w) {
            if(w<=0.0){
                return a;
            }else if(w>=1.0){
                return b;
            }else{
                return w*b +(1.0-w)*a;
            }
        }

        #ifdef NORMALTEXTURE

            mediump vec3 normalInTangentSpace(vec2 texcoords)
            {
                return unpackScaleNormal(texture2D(u_NormalTexture, texcoords).rgb,u_NormalScale);
            }
       
            vec3 perPixelWorldNormal(vec2 uv,vec3 normal,vec3 binormal,vec3 tangent)
            {
                #ifdef NORMALTEXTURE
                    mediump vec3 normalTangent=normalInTangentSpace(uv);
                    vec3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z);
                    
                #else
                    vec3 normalWorld = normalize(normal);
                #endif
                    return normalWorld;
            }
        #endif

        vec3 perPixelWorldNormalByNormalTanget(vec2 uv,vec3 normal,vec3 binormal,vec3 tangent,vec3 normalTangent)
        {
            #ifdef NORMALTEXTURE
                vec3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z);
                
            #else
                vec3 normalWorld = normalize(normal);
            #endif
                return normalWorld;
        }
        
        void main_paint_mask(){
			gl_FragColor = vec4(v_Texcoord0.xy,0.0,1.0);
        }
        
        void fragmentForward()
        {
            vec2 uv;
            #if defined(ALBEDOTEXTURE)||defined(NORMALTEXTURE)
                    uv = v_Texcoord0;
            #endif
            
            albedoRgba = albedo(uv);

            mediump float alpha = albedoRgba.a;
            #ifdef ALPHATEST
                if(alpha<u_AlphaTestValue)
                    discard;
            #endif
            
            vec3 binormal;
            vec3 tangent;
            #ifdef NORMALTEXTURE
                tangent = v_Tangent;
                binormal = v_Binormal;
            #endif

            vec3 normal = v_Normal;
            
            vec3 dirLightFirst =  u_SunLight.direction;
            vec3 dirLightSecond =  vec3(-0.3090169948284817,0.0,0.9510565161477913);

            vec4 color = vec4(albedoRgba.rgb*(1.0+u_SPPBRInstensity),1.0);

            #ifdef DIRECTIONLIGHT
                float shadowAttenuationGlobal = 1.0;

                vec3 surfResult105 = vec3(color.rgb);

                vec4 _SpecularInDark = u_SPSpecularInDark;
                _SpecularInDark.a = u_SPSpecularInDarkAlpha;

                vec2 appendResult264 = (vec2(u_SPUTiling , 1.0));
                vec2 uv_TexCoord261 = uv * appendResult264;
                vec4 tex2DNode176 = texture2D(u_MaskTexture, uv_TexCoord261);

                vec3 albedoResult = albedoRgba.rgb;

                vec3 clampResult226 = vec3(clamp(surfResult105.r,0.0,1.0),clamp(surfResult105.g,0.0,1.0),clamp(surfResult105.b,0.0,1.0));
                vec3 lerpResult125 = vec3(mix(albedoResult.r,clampResult226.r,u_SPPBRInstensity),mix(albedoResult.g,clampResult226.g,u_SPPBRInstensity),mix(albedoResult.b,clampResult226.b,u_SPPBRInstensity));
                
                vec3 ase_worldBitangent = perPixelWorldNormalByNormalTanget(uv,normal,binormal,tangent,vec3( 0.0, 1.0, 0.0 ));
                vec3 ase_worldNormal = perPixelWorldNormalByNormalTanget(uv,normal,binormal,tangent,vec3( 0.0, 0.0, 1.0 ));

                vec3 ase_normWorldNormal = ase_worldNormal;
                vec3 normalizeResult243 = normalize(dirLightSecond);

                vec3 lightDir = normalize(dirLightFirst);
                
                vec3 normalizeResult246 =lightDir;
                float dotResult156 = dot( ( ase_worldBitangent + ( ase_normWorldNormal * ( ( tex2DNode176.r * u_SPAnisotropyBiasR ) + ( tex2DNode176.g * u_SPAnisotropyBiasG ) ) ) ) , normalizeResult246 );
                float temp_output_186_0 = sqrt( sqrt( ( 1.0 - ( dotResult156 * dotResult156 ) ) ) );
                
                float lerpResult274 = lerpOneTo(tex2DNode176.b , u_SPHairSpecularAO);
                vec3 ase_worldViewDir = normalizeResult243;
                float dotResult117 = dot( ase_worldViewDir , ase_worldNormal );
                vec4 temp_output_76_0 = ( ( ( pow( temp_output_186_0 , u_SPAnisotropyRang1 ) * u_SPR1SpecalurColor ) + ( pow( temp_output_186_0 , ( u_SPAnisotropyRang2 * tex2DNode176.r ) ) * u_SPR2SpecalurColor * tex2DNode176.r ) ) * lerpResult274 * pow( dotResult117 , u_SPHLFrePower ) );
                
                float lightAttenRatio = mix(shadowAttenuationGlobal,1.0,_SpecularInDark.a);
                vec4 lerpResult279 = lerpVec4( ( _SpecularInDark * temp_output_76_0 ) , temp_output_76_0 , lightAttenRatio);
                
                vec4 color241 = vec4(1.51,1.51,1.51,0) ;
                vec3 clampResult240 = vec3(clamp(lerpResult279.r,0.0,color241.r),clamp(lerpResult279.g,0.0,color241.g),clamp(lerpResult279.b,0.0,color241.b));
                clampResult240 = clampResult240.rgb*u_SPPBRFinalLightRatio;
                color.rgb = ( lerpResult125 + clampResult240 ).rgb;
            #endif

            gl_FragColor=vec4(color.rgb,alpha);
        }

        #if defined(CASTSHADOW)
		    varying vec4 v_posView;
		#endif

        void main_castshadow(){
			#ifdef CASTSHADOW
				float z = v_posView.z/v_posView.w;
				z = z*0.5 + 0.5;
				gl_FragColor = vec4(0.0, 0, z, 1.0);
			#endif
		}


        void main()
        {
            #ifdef CASTSHADOW
                main_castshadow();
            #else
                #ifdef SHADERDEFINE_DRAWING_MASK
                    main_paint_mask();
                #else
                    fragmentForward();
                #endif
            #endif
        }`;
          var shader3D = Laya.Shader3D.add("CustomPBRHairShader", attributeMap, uniformMap, true);
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          shader3D.addSubShader(subShader);
          subShader.addShaderPass(vs1, ps1, stateMap, "Forward");
      }
      get normalTexture() {
          return this._shaderValues.getTexture(CustomPBRHairMaterial.NORMALTEXTURE);
      }
      set normalTexture(value) {
          if (value)
              this._defineDatas.add(CustomPBRHairMaterial.SHADERDEFINE_NORMALTEXTURE);
          else
              this._defineDatas.remove(CustomPBRHairMaterial.SHADERDEFINE_NORMALTEXTURE);
          this._shaderValues.setTexture(CustomPBRHairMaterial.NORMALTEXTURE, value);
      }
      get normalTextureScale() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.NORMALTEXTURESCALE);
      }
      set normalTextureScale(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.NORMALTEXTURESCALE, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.NORMALTEXTURESCALE, value);
      }
      get maskTexture() {
          return this._shaderValues.getTexture(CustomPBRHairMaterial.MASKTEXTURE);
      }
      set maskTexture(value) {
          if (value)
              this._defineDatas.add(CustomPBRHairMaterial.SHADERDEFINE_MASKTEXTURE);
          else
              this._defineDatas.remove(CustomPBRHairMaterial.SHADERDEFINE_MASKTEXTURE);
          this._shaderValues.setTexture(CustomPBRHairMaterial.MASKTEXTURE, value);
      }
      get albedoColor() {
          return this._shaderValues.getVector(CustomPBRHairMaterial.ALBEDOCOLOR);
      }
      set albedoColor(value) {
          this._shaderValues.setVector(CustomPBRHairMaterial.ALBEDOCOLOR, value);
      }
      get paintLayer1Texture() {
          return this._shaderValues.getTexture(CustomPBRHairMaterial.PAINT_LAYER1_TEXTURE);
      }
      set paintLayer1Texture(value) {
          if (value != null) {
              this._defineDatas.add(CustomPBRHairMaterial.SHADERDEFINE_LAYER1_TEXTURE);
          }
          else {
              this._defineDatas.remove(CustomPBRHairMaterial.SHADERDEFINE_LAYER1_TEXTURE);
          }
          this._shaderValues.setTexture(CustomPBRHairMaterial.PAINT_LAYER1_TEXTURE, value);
      }
      get paintLayer1TilingOffset() {
          return this._shaderValues.getVector(CustomPBRHairMaterial.PAINT_LAYER1_TILINGOFFSET);
      }
      set paintLayer1TilingOffset(value) {
          this._shaderValues.setVector(CustomPBRHairMaterial.PAINT_LAYER1_TILINGOFFSET, value);
      }
      getShaderValueRangeWithKey(key) {
          switch (key) {
              case CustomPBRHairMaterial.SPUTILING:
                  return [0.0, 2.0];
                  break;
              case CustomPBRHairMaterial.SPANISOTROPYBIASG:
                  return [-2.0, 2.0];
                  break;
              case CustomPBRHairMaterial.SPANISOTROPYBIASR:
                  return [-2.0, 2.0];
                  break;
              case CustomPBRHairMaterial.SPANISOTROPYRANG1:
                  return [0.0, 100.0];
                  break;
              case CustomPBRHairMaterial.SPANISOTROPYRANG2:
                  return [0.0, 1000.0];
                  break;
              case CustomPBRHairMaterial.SPHLFREPOWER:
                  return [0.0, 5.0];
                  break;
              case CustomPBRHairMaterial.NORMALTEXTURESCALE:
                  return [0.0, 2.0];
                  break;
              case CustomPBRHairMaterial.SPPBRFINALLIGHTRATIO:
                  return [0.0, 2.0];
                  break;
              default:
                  break;
          }
          return [0.0, 1.0];
      }
      clampKeyValueByKey(key, value) {
          return Math.max(this.getShaderValueRangeWithKey(key)[0], Math.min(this.getShaderValueRangeWithKey(key)[1], value));
      }
      get SPMetallic() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPMETALLIC);
      }
      set SPMetallic(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPMETALLIC, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPMETALLIC, value);
      }
      get SPSmoothness() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPSMOOTHNESS);
      }
      set SPSmoothness(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPSMOOTHNESS, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPSMOOTHNESS, value);
      }
      get SPUTiling() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPUTILING);
      }
      set SPUTiling(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPUTILING, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPUTILING, value);
      }
      get SPPBRInstensity() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPPBRINSTENSITY);
      }
      set SPPBRInstensity(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPPBRINSTENSITY, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPPBRINSTENSITY, value);
      }
      get SPHairAlbedoAO() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPHAIRALBEDOAO);
      }
      set SPHairAlbedoAO(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPHAIRALBEDOAO, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPHAIRALBEDOAO, value);
      }
      get SPAnisotropyBiasG() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPANISOTROPYBIASG);
      }
      set SPAnisotropyBiasG(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPANISOTROPYBIASG, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYBIASG, value);
      }
      get SPAnisotropyBiasR() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPANISOTROPYBIASR);
      }
      set SPAnisotropyBiasR(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPANISOTROPYBIASR, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYBIASR, value);
      }
      get SPHairSpecularAO() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPHAIRSPECULARAO);
      }
      set SPHairSpecularAO(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPHAIRSPECULARAO, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPHAIRSPECULARAO, value);
      }
      get SPAnisotropyRang1() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPANISOTROPYRANG1);
      }
      set SPAnisotropyRang1(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPANISOTROPYRANG1, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYRANG1, value);
      }
      get SPAnisotropyRang2() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPANISOTROPYRANG2);
      }
      set SPAnisotropyRang2(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPANISOTROPYRANG2, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPANISOTROPYRANG2, value);
      }
      get SPHLFrePower() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPHLFREPOWER);
      }
      set SPHLFrePower(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPHLFREPOWER, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPHLFREPOWER, value);
      }
      get SPSpecularInDarkAlpha() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPSPECULARINDARKALPHA);
      }
      set SPSpecularInDarkAlpha(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPSPECULARINDARKALPHA, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPSPECULARINDARKALPHA, value);
      }
      get SPR1SpecalurColor() {
          return this._shaderValues.getVector(CustomPBRHairMaterial.SPR1SPECALURCOLOR);
      }
      set SPR1SpecalurColor(value) {
          this._shaderValues.setVector(CustomPBRHairMaterial.SPR1SPECALURCOLOR, value);
      }
      get SPR2SpecalurColor() {
          return this._shaderValues.getVector(CustomPBRHairMaterial.SPR2SPECALURCOLOR);
      }
      set SPR2SpecalurColor(value) {
          this._shaderValues.setVector(CustomPBRHairMaterial.SPR2SPECALURCOLOR, value);
      }
      get SPSpecularInDark() {
          return this._shaderValues.getVector(CustomPBRHairMaterial.SPSPECULARINDARK);
      }
      set SPSpecularInDark(value) {
          this._shaderValues.setVector(CustomPBRHairMaterial.SPSPECULARINDARK, value);
      }
      get SPPBRFinalLightRatio() {
          return this._shaderValues.getNumber(CustomPBRHairMaterial.SPPBRFINALLIGHTRATIO);
      }
      set SPPBRFinalLightRatio(value) {
          value = this.clampKeyValueByKey(CustomPBRHairMaterial.SPPBRFINALLIGHTRATIO, value);
          this._shaderValues.setNumber(CustomPBRHairMaterial.SPPBRFINALLIGHTRATIO, value);
      }
      get tilingOffset() {
          return this._shaderValues.getVector(CustomPBRHairMaterial.TILINGOFFSET);
      }
      set tilingOffset(value) {
          if (value) {
              if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
                  this._defineDatas.add(CustomPBRHairMaterial.SHADERDEFINE_TILINGOFFSET);
              else
                  this._defineDatas.remove(CustomPBRHairMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          else {
              this._defineDatas.remove(CustomPBRHairMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          this._shaderValues.setVector(CustomPBRHairMaterial.TILINGOFFSET, value);
      }
      get cull() {
          return this._shaderValues.getInt(CustomPBRHairMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(CustomPBRHairMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(CustomPBRHairMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(CustomPBRHairMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(CustomPBRHairMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(CustomPBRHairMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(CustomPBRHairMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(CustomPBRHairMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(CustomPBRHairMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(CustomPBRHairMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(CustomPBRHairMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(CustomPBRHairMaterial.DEPTH_WRITE, value);
      }
      get materialType() {
          return CustomMaterialType.pbrHair;
      }
      get renderMode() {
          return this.__render_mode__;
      }
      set renderMode(value) {
          this.__render_mode__ = value;
          switch (value) {
              case CustomMaterialRenderMode.unknown:
              case CustomMaterialRenderMode.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_OPAQUE_CULL_NONE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case CustomMaterialRenderMode.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              default:
                  throw new Error("CustomMaterialRenderMode : renderMode value error.");
          }
      }
      getCanEditorParamList() {
          return [
              { name: `SPUTiling`, desc: `平铺度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPUTILING) },
              { name: `SPPBRInstensity`, desc: `原本pbr色强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPPBRINSTENSITY) },
              { name: `SPHairAlbedoAO`, desc: `材质色强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPHAIRALBEDOAO) },
              { name: `SPAnisotropyBiasG`, desc: `Mask贴图中G值强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPANISOTROPYBIASG) },
              { name: `SPAnisotropyBiasR`, desc: `Mask贴图中R值强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPANISOTROPYBIASR) },
              { name: `SPHairSpecularAO`, desc: `Mask贴图中B值强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPHAIRSPECULARAO) },
              { name: `SPAnisotropyRang1`, desc: `第一种混合高光颜色强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPANISOTROPYRANG1) },
              { name: `SPAnisotropyRang2`, desc: `第二种混合高光颜色强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPANISOTROPYRANG2) },
              { name: `SPHLFrePower`, desc: `光线强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPHLFREPOWER) },
              { name: `SPSpecularInDarkAlpha`, desc: `暗部色强度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPSPECULARINDARKALPHA) },
              { name: `SPMetallic`, desc: `金属度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPMETALLIC) },
              { name: `SPSmoothness`, desc: `光滑度`, type: EditorType.slider, range: this.getShaderValueRangeWithKey(CustomPBRHairMaterial.SPSMOOTHNESS) },
          ];
      }
  }
  CustomPBRHairMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  CustomPBRHairMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  CustomPBRHairMaterial.NORMALTEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  CustomPBRHairMaterial.NORMALTEXTURESCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  CustomPBRHairMaterial.MASKTEXTURE = Laya.Shader3D.propertyNameToID("u_MaskTexture");
  CustomPBRHairMaterial.AMBIENTCOLOR = Laya.Shader3D.propertyNameToID("u_AmbientColor");
  CustomPBRHairMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  CustomPBRHairMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  CustomPBRHairMaterial.SPMETALLIC = Laya.Shader3D.propertyNameToID(`u_SPMetallic`);
  CustomPBRHairMaterial.SPSMOOTHNESS = Laya.Shader3D.propertyNameToID(`u_SPSmoothness`);
  CustomPBRHairMaterial.SPUTILING = Laya.Shader3D.propertyNameToID("u_SPUTiling");
  CustomPBRHairMaterial.SPPBRINSTENSITY = Laya.Shader3D.propertyNameToID("u_SPPBRInstensity");
  CustomPBRHairMaterial.SPHAIRALBEDOAO = Laya.Shader3D.propertyNameToID("u_SPHairAlbedoAO");
  CustomPBRHairMaterial.SPANISOTROPYBIASG = Laya.Shader3D.propertyNameToID("u_SPAnisotropyBiasG");
  CustomPBRHairMaterial.SPANISOTROPYBIASR = Laya.Shader3D.propertyNameToID("u_SPAnisotropyBiasR");
  CustomPBRHairMaterial.SPHAIRSPECULARAO = Laya.Shader3D.propertyNameToID("u_SPHairSpecularAO");
  CustomPBRHairMaterial.SPANISOTROPYRANG1 = Laya.Shader3D.propertyNameToID("u_SPAnisotropyRang1");
  CustomPBRHairMaterial.SPANISOTROPYRANG2 = Laya.Shader3D.propertyNameToID("u_SPAnisotropyRang2");
  CustomPBRHairMaterial.SPHLFREPOWER = Laya.Shader3D.propertyNameToID("u_SPHLFrePower");
  CustomPBRHairMaterial.SPSPECULARINDARKALPHA = Laya.Shader3D.propertyNameToID("u_SPSpecularInDarkAlpha");
  CustomPBRHairMaterial.SPR1SPECALURCOLOR = Laya.Shader3D.propertyNameToID("u_SPR1SpecalurColor");
  CustomPBRHairMaterial.SPR2SPECALURCOLOR = Laya.Shader3D.propertyNameToID("u_SPR2SpecalurColor");
  CustomPBRHairMaterial.SPSPECULARINDARK = Laya.Shader3D.propertyNameToID("u_SPSpecularInDark");
  CustomPBRHairMaterial.SPPBRFINALLIGHTRATIO = Laya.Shader3D.propertyNameToID("u_SPPBRFinalLightRatio");
  CustomPBRHairMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  CustomPBRHairMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  CustomPBRHairMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  CustomPBRHairMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  CustomPBRHairMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  CustomPBRHairMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");

  var ul;
  (function (ul) {
      function _convert(match, nosign) {
          if (nosign) {
              match.sign = '';
          }
          else {
              match.sign = match.negative ? '-' : match.sign;
          }
          var l = match.min - match.argument.length + 1 - match.sign.length;
          var pad = new Array(l < 0 ? 0 : l).join(match.pad);
          if (!match.left) {
              if (match.pad == "0" || nosign) {
                  return match.sign + pad + match.argument;
              }
              else {
                  return pad + match.sign + match.argument;
              }
          }
          else {
              if (match.pad == "0" || nosign) {
                  return match.sign + match.argument + pad.replace(/0/g, ' ');
              }
              else {
                  return match.sign + match.argument + pad;
              }
          }
      }
      function format(...args) {
          if (typeof args == "undefined") {
              return null;
          }
          if (args.length < 1) {
              return null;
          }
          if (typeof args[0] != "string") {
              return null;
          }
          if (typeof RegExp == "undefined") {
              return null;
          }
          var string = args[0];
          var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
          var matches = new Array();
          var strings = new Array();
          var convCount = 0;
          var stringPosStart = 0;
          var stringPosEnd = 0;
          var matchPosEnd = 0;
          var newString = '';
          var match = null;
          while (match = exp.exec(string)) {
              if (match[9]) {
                  convCount += 1;
              }
              stringPosStart = matchPosEnd;
              stringPosEnd = exp.lastIndex - match[0].length;
              strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
              matchPosEnd = exp.lastIndex;
              matches[matches.length] = {
                  match: match[0],
                  left: match[3] ? true : false,
                  sign: match[4] || '',
                  pad: match[5] || ' ',
                  min: match[6] || 0,
                  precision: match[8],
                  code: match[9] || '%',
                  negative: parseInt(args[convCount]) < 0 ? true : false,
                  argument: String(args[convCount])
              };
          }
          strings[strings.length] = string.substring(matchPosEnd);
          if (matches.length == 0) {
              return string;
          }
          if ((args.length - 1) < convCount) {
              return null;
          }
          var code = null;
          var match = null;
          var substitution = null;
          var i = null;
          for (i = 0; i < matches.length; i++) {
              if (matches[i].code == '%') {
                  substitution = '%';
              }
              else if (matches[i].code == 'b') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
                  substitution = _convert(matches[i], true);
              }
              else if (matches[i].code == 'c') {
                  matches[i].argument = String(String.fromCharCode(Math.abs(parseInt(matches[i].argument))));
                  substitution = _convert(matches[i], true);
              }
              else if (matches[i].code == 'd') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
                  substitution = _convert(matches[i]);
              }
              else if (matches[i].code == 'f') {
                  matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
                  substitution = _convert(matches[i]);
              }
              else if (matches[i].code == 'o') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
                  substitution = _convert(matches[i]);
              }
              else if (matches[i].code == 's') {
                  matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length);
                  substitution = _convert(matches[i], true);
              }
              else if (matches[i].code == 'x') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                  substitution = _convert(matches[i]);
              }
              else if (matches[i].code == 'X') {
                  matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
                  substitution = _convert(matches[i]).toUpperCase();
              }
              else {
                  substitution = matches[i].match;
              }
              newString += strings[i];
              newString += substitution;
          }
          newString += strings[i];
          return newString;
      }
      ul.format = format;
      function formatDate(date, fmt) {
          var o = {
              "M+": date.getMonth() + 1,
              "d+": date.getDate(),
              "h+": date.getHours(),
              "m+": date.getMinutes(),
              "s+": date.getSeconds(),
              "q+": Math.floor((date.getMonth() + 3) / 3),
              "S": date.getMilliseconds()
          };
          if (/(y+)/.test(fmt))
              fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
          for (var k in o)
              if (new RegExp("(" + k + ")").test(fmt))
                  fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
          return fmt;
      }
      ul.formatDate = formatDate;
      function _dump(arr, level) {
          var dumped_text = "";
          if (!level)
              level = 0;
          var level_padding = "";
          for (var j = 0; j < level + 1; j++)
              level_padding += "    ";
          if (typeof (arr) == 'object') {
              for (var item in arr) {
                  var value = arr[item];
                  if (typeof (value) == 'object') {
                      dumped_text += level_padding + "'" + item + "' ...\n";
                      dumped_text += _dump(value, level + 1);
                  }
                  else {
                      dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                  }
              }
          }
          else {
              dumped_text = "===>" + arr + "<===(" + typeof (arr) + ")";
          }
          return dumped_text;
      }
      function dump(data, tag, level) {
          let text = _dump(data);
          console.log("dump-begin", tag);
          console.log(text);
          console.log("dump-end");
      }
      ul.dump = dump;
      function getType(obj) {
          let toString = Object.prototype.toString;
          let map = {
              '[object Boolean]': 'boolean',
              '[object Number]': 'number',
              '[object String]': 'string',
              '[object Function]': 'function',
              '[object Array]': 'array',
              '[object Date]': 'date',
              '[object RegExp]': 'regExp',
              '[object Undefined]': 'undefined',
              '[object Null]': 'null',
              '[object Object]': 'object'
          };
          return map[toString.call(obj)];
      }
      ul.getType = getType;
      function clone(data) {
          let type = getType(data);
          let obj;
          if (type === 'object') {
              obj = {};
          }
          else if (type === 'array') {
              obj = [];
          }
          else {
              return data;
          }
          if (type === 'array') {
              for (let i = 0, len = data.length; i < len; i++) {
                  obj.push(clone(data[i]));
              }
          }
          else if (type === 'object') {
              for (let key in data) {
                  obj[key] = clone(data[key]);
              }
          }
          return obj;
      }
      ul.clone = clone;
      function length(data) {
          let type = getType(data);
          if (type === "array") {
              let length = 0;
              for (const key in data) {
                  const element = data[key];
                  if (element) {
                      length++;
                  }
              }
              return length;
          }
          else if (type === "object") {
              let length = 0;
              for (const key in data) {
                  const element = data[key];
                  if (element) {
                      length++;
                  }
              }
              return length;
          }
          else {
              return 0;
          }
      }
      ul.length = length;
      function clamp(cur, min, max) {
          if (cur < min) {
              cur = min;
          }
          if (cur > max) {
              cur = max;
          }
          return cur;
      }
      ul.clamp = clamp;
  })(ul || (ul = {}));

  class mgrLoader extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static get Pool() {
          if (!this.__pool__)
              this.__pool__ = new PoolManager;
          return this.__pool__;
      }
      static isLoadedWithModelId(modeId) {
          let modeData = {};
          if (!modeData) {
              return false;
          }
          let url = `${modeData.modelPath}${modeData.modelName}.lh`;
          if (this.allRess[url]) {
              return true;
          }
          return false;
      }
      static loadModeWithModeId(modeId, callback, caller, tag) {
          let modeData = {};
          if (!modeData) {
              console.warn("[error]:找不到模型配置:" + modeId);
              callback(false);
              return;
          }
          let url = `${modeData.modelPath}${modeData.modelName}.lh`;
          if (this.allRess[url]) {
              callback(true);
              return;
          }
          ;
          this.LoadRes(url, (bSuccessful) => {
              if (bSuccessful) {
                  let model = this.allRess[url];
                  model["__modelId"] = modeId;
                  callback(true);
              }
              else {
                  callback(false);
              }
          }, caller, tag);
      }
      static getModeWithModeId(modeId) {
          let modeData = {};
          if (!modeData) {
              console.warn("[error]:找不到模型配置:" + modeId);
              return new Laya.Sprite3D;
          }
          let res = this.GetRes(`${modeData.modelPath}${modeData.modelName}.lh`, modeId);
          if (!res) {
              console.warn("[error]:资源尚未加载" + modeId);
              res = new Laya.Sprite3D;
          }
          return res;
      }
      static GetRes(url, modelId) {
          let res = this.allRess[url];
          if (res) {
              let _instantiateRes = Laya.Sprite3D.instantiate(res.res);
              _instantiateRes["__modelId"] = modelId;
              return _instantiateRes;
          }
          return null;
      }
      static LoadRes(url, callback, caller, tag) {
          Laya.Sprite3D.load(url, new Laya.Handler(this, (res) => {
              if (res) {
                  this.allRess[url] = {
                      tag: tag,
                      res: res,
                  };
                  if (!caller) {
                      return;
                  }
                  else if (caller instanceof Laya.Node) {
                      if (!caller.parent) {
                          return;
                      }
                  }
                  else if (caller["destroyed"]) {
                      return;
                  }
                  callback(true);
              }
              else {
                  if (!caller) {
                      return;
                  }
                  else if (caller instanceof Laya.Node) {
                      if (!caller.parent) {
                          return;
                      }
                  }
                  else if (caller["destroyed"]) {
                      return;
                  }
                  console.warn("[error] 加载资源失败 再次尝试: " + url);
                  Timer.callLater(0.01, () => {
                      this.LoadRes(url, callback, caller, tag);
                  }, this);
              }
          }));
      }
      static Load3dScene(sceneId, callback, caller, tag) {
          let sceneData = {};
          let url = `${sceneData.scenePath}${sceneData.sceneName}.ls`;
          Laya.Scene3D.load(url, new Laya.Handler(this, (res) => {
              if (res) {
                  if (!caller) {
                      return;
                  }
                  else if (caller instanceof Laya.Node) {
                      if (!caller.parent) {
                          return;
                      }
                  }
                  else if (caller["destroyed"]) {
                      return;
                  }
                  callback(res);
              }
              else {
                  if (!caller) {
                      return;
                  }
                  else if (caller instanceof Laya.Node) {
                      if (!caller.parent) {
                          return;
                      }
                  }
                  else if (caller["destroyed"]) {
                      return;
                  }
                  console.warn("[error] 加载资源失败 再次尝试: " + url);
                  Timer.callLater(0.01, () => {
                      this.Load3dScene(sceneId, callback, caller, tag);
                  }, this);
              }
          }));
      }
      static releaseAllRes(tag) {
      }
      static autoReleaseRes() {
          return;
      }
      static releseAllResourceByModelId(modelId) {
          let modelData = {};
          let url = `${modelData.modelPath}${modelData.modelName}.lh`;
          Laya.loader.load(url, new Laya.Handler(this, (json) => {
              let resourceUrls = this.findAllResources(json);
              for (let index = 0; index < resourceUrls.length; index++) {
                  const url = resourceUrls[index];
                  let resource = Laya.Resource.getResourceByURL(url);
                  if (resource) {
                      resource.destroy();
                      console.log(`释放资源: ${url}`);
                  }
              }
          }), null, Laya.Loader.JSON);
      }
      static findAllResources(json) {
          let resources = [];
          for (const k in json) {
              let content = json[k];
              if (content) {
                  let type = ul.getType(content);
                  if (type === "object" || type == `array`) {
                      resources = resources.concat(this.findAllResources(content));
                  }
                  else {
                      let resourceKeys = [
                          'mesh',
                          'material',
                          'path',
                          'clipPath',
                          'meshPath'
                      ];
                      if (resourceKeys.indexOf(k) >= 0) {
                          resources.push(content);
                      }
                  }
              }
          }
          return resources;
      }
      static get2dRes(url) {
          return Laya.Loader.getRes(url);
      }
      static Load2dRes(url, type, caller, callback, progress) {
          if (type == Laya.Loader.PREFAB || type == Laya.Loader.JSON) {
              if (!/.json/.test(url))
                  url += ".json";
          }
          if (/http/.test(url) || /https/.test(url)) {
          }
          else {
              if (url.substring(0, url.indexOf("/")) != "res")
                  url = "res/" + url;
          }
          if (mgrLoader.get2dRes(url)) {
              callback && callback(mgrLoader.get2dRes(url));
              return;
          }
          Laya.loader.load(url, new Laya.Handler(this, (res) => {
              if (!this.checkCaller(caller))
                  return;
              if (!res) {
                  Timer.callLater(0.3, () => {
                      console.warn("[error] 加载资源失败 再次尝试: " + url);
                      this.Load2dRes(url, type, caller, callback, progress);
                  }, caller);
              }
              else {
                  callback(res);
              }
          }), new Laya.Handler(this, (pr) => {
              progress && progress(pr);
          }), type);
      }
      static checkCaller(caller) {
          if (!caller) {
              return false;
          }
          else if (caller["destroyed"]) {
              return false;
          }
          return true;
      }
      static processRemoteResLoad() {
          if (this.curLoadingRemoteResInfo) {
              console.log(`正在加载远程资源...: url:${this.curLoadingRemoteResInfo.url}`);
              return;
          }
          else {
              if (this.RemoteResLoadQueue.length <= 0) {
                  return;
              }
              else {
                  this.curLoadingRemoteResInfo = this.RemoteResLoadQueue.shift();
                  console.log(`开始加载远程资源:${this.curLoadingRemoteResInfo.url}`);
                  try {
                      this.loadRemoteResQg(this.curLoadingRemoteResInfo.url, (err, tex) => {
                          if (this.curLoadingRemoteResInfo.bHaveCaller && !this.checkCaller(this.curLoadingRemoteResInfo.caller)) {
                              console.log(`远程资源:${this.curLoadingRemoteResInfo.url} 调用者销毁`);
                              this.curLoadingRemoteResInfo = null;
                              return;
                          }
                          if (err) {
                              console.log(`远程资源加载失败: 放在队尾重试: ${this.curLoadingRemoteResInfo.url}`);
                              this.RemoteResLoadQueue.push(this.curLoadingRemoteResInfo);
                              this.curLoadingRemoteResInfo = null;
                          }
                          else {
                              console.log(`远程资源加载成功: ${this.curLoadingRemoteResInfo.url}`);
                              this.curLoadingRemoteResInfo.callback(err, tex);
                          }
                      });
                  }
                  catch (error) {
                      console.log(error);
                      console.log(`远程资源加载失败: 放在队尾重试: ${this.curLoadingRemoteResInfo.url}`);
                      this.RemoteResLoadQueue.push(this.curLoadingRemoteResInfo);
                      this.curLoadingRemoteResInfo = null;
                  }
              }
          }
      }
      static loadRemoteResQg(url, callback) {
          if (this.__cachedRemoteTexture[url]) {
              callback(null, this.__cachedRemoteTexture[url]);
              return;
          }
          let img = new Image();
          let loadedCallback = () => {
              img.removeEventListener("load", loadedCallback);
              img.removeEventListener("error", errorCallback);
              console.log("IMAGE 加载成功!!", url);
              let texture = new Laya.Texture2D();
              texture.loadImageSource(texture);
              this.__cachedRemoteTexture[url] = texture;
              callback(null, texture);
          };
          let errorCallback = () => {
              img.removeEventListener("load", loadedCallback);
              img.removeEventListener("error", errorCallback);
              console.log("IMAGE 加载失败!!", url);
              callback({ error: "error" }, null);
          };
          img.addEventListener('load', loadedCallback);
          img.addEventListener('error', errorCallback);
          img.src = url;
      }
      static loadFont(fontName, label, callback) {
          if (!label)
              return;
          if (this.loadedFontname[fontName]) {
              label.font = fontName;
              let tmp = label.text;
              label.text = "";
              label.text = tmp;
              return;
          }
          console.log(`开始加载字体:${fontName}`);
          let bmFont = new Laya.BitmapFont();
          bmFont.loadFont(`res/font/${fontName}.fnt`, new Laya.Handler(this, () => {
              Laya.Text.registerBitmapFont(fontName, bmFont);
              this.loadedFontname[fontName] = true;
              if (!label || label.destroyed)
                  return;
              label.font = fontName;
              let tmp = label.text;
              label.text = "";
              label.text = tmp;
          }));
      }
      static batchLoadResources(modelIds, animationIds, images, caller, callback) {
      }
      static loadImg(sp, path, bAdaptTextureSize = false, callback) {
          if (!sp) {
              callback && callback();
              return;
          }
          ;
          if (!path) {
              callback && callback();
              return;
          }
          ;
          mgrLoader.Load2dRes(path, Laya.Loader.IMAGE, sp, (texture) => {
              sp.texture = null;
              sp[`skin`] = null;
              sp.graphics.clear(true);
              if (bAdaptTextureSize) {
                  sp.width = texture.sourceWidth;
                  sp.height = texture.sourceHeight;
              }
              sp.graphics.drawImage(texture, 0, 0, sp.width, sp.height);
              callback && callback();
          });
      }
      static loadAdImg(sp, path) {
          if (!sp) {
              return;
          }
          ;
          if (!path) {
              return;
          }
          ;
          mgrLoader.Load2dRes(path, Laya.Loader.IMAGE, sp, (texture) => {
              let orgWidth = sp.width;
              let orgHeight = sp.height;
              let curWidth = texture.sourceWidth;
              let curHeight = texture.sourceHeight;
              let factorX = orgWidth / curWidth;
              let factorY = orgHeight / curHeight;
              let factor = Math.min(factorX, factorY);
              let width = curWidth * factor;
              let height = curHeight * factor;
              sp.texture = null;
              sp.graphics.clear(true);
              let offsetX = 0;
              let offsetY = 0;
              if (sp["anchorX"] && sp["anchorX"] > 0) {
                  offsetX = sp["anchorX"] * (width - sp.width);
                  offsetY = sp["anchorY"] * (height - sp.height);
              }
              sp.graphics.drawImage(texture, 0 - offsetX, 0 - offsetY, width, height);
          });
      }
  }
  mgrLoader.allRess = {};
  mgrLoader.RemoteResLoadQueue = [];
  mgrLoader.curLoadingRemoteResInfo = null;
  mgrLoader.__cachedRemoteTexture = {};
  mgrLoader.loadedFontname = {};

  class FliterMaterial extends Laya.Material {
      constructor() {
          super();
          this.setShaderName("FliterMaterial");
          this._shaderValues.setVector(FliterMaterial.SHADOWCOLOR, new Laya.Vector4(0.1, 0.1, 0.1, 1));
          this._shaderValues.setNumber(FliterMaterial.SHADOWRANGE, 0.002);
          this._shaderValues.setNumber(FliterMaterial.SHADOWINTENSITY, 1);
          this._shaderValues.setNumber(FliterMaterial.SHADOWBOUNDARY, 0.5);
          this._shaderValues.setNumber(FliterMaterial.SPECULARRANGE, 0.3);
          this._shaderValues.setNumber(FliterMaterial.SPECULARINTENSITY, 0.5);
          this._shaderValues.setVector(FliterMaterial.SPECULARCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this._shaderValues.setNumber(FliterMaterial.ALBEDOIDENTITY, 0.5);
          this._shaderValues.setVector(FliterMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
          this.alpha = 1;
      }
      static __init__() {
          FliterMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
          FliterMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
          FliterMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
          FliterMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
          FliterMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
          FliterMaterial.SHADERDEFINE_FLITER_TEXTURE = Laya.Shader3D.getDefineByName("FLITER_TEXTURE");
          FliterMaterial.SHADERDEFINE_FLITER_R_TEXTURE = Laya.Shader3D.getDefineByName("FLITER_R_TEXTURE");
          FliterMaterial.SHADERDEFINE_FLITER_G_TEXTURE = Laya.Shader3D.getDefineByName("FLITER_G_TEXTURE");
          FliterMaterial.SHADERDEFINE_FLITER_B_TEXTURE = Laya.Shader3D.getDefineByName("FLITER_B_TEXTURE");
          FliterMaterial.SHADERDEFINE_FLITER_A_TEXTURE = Laya.Shader3D.getDefineByName("FLITER_A_TEXTURE");
          FliterMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
          FliterMaterial.SHADERDEFINE_NORMAL_R_TEXTURE = Laya.Shader3D.getDefineByName("NORMAL_R_TEXTURE");
          FliterMaterial.SHADERDEFINE_NORMAL_G_TEXTURE = Laya.Shader3D.getDefineByName("NORMAL_G_TEXTURE");
          FliterMaterial.SHADERDEFINE_NORMAL_B_TEXTURE = Laya.Shader3D.getDefineByName("NORMAL_B_TEXTURE");
          FliterMaterial.SHADERDEFINE_NORMAL_A_TEXTURE = Laya.Shader3D.getDefineByName("NORMAL_A_TEXTURE");
      }
      static initShader() {
          FliterMaterial.__init__();
          var stateMap = {
              's_Cull': Laya.Shader3D.RENDER_STATE_CULL,
              's_Blend': Laya.Shader3D.RENDER_STATE_BLEND,
              's_BlendSrc': Laya.Shader3D.RENDER_STATE_BLEND_SRC,
              's_BlendDst': Laya.Shader3D.RENDER_STATE_BLEND_DST,
              's_DepthTest': Laya.Shader3D.RENDER_STATE_DEPTH_TEST,
              's_DepthWrite': Laya.Shader3D.RENDER_STATE_DEPTH_WRITE
          };
          var attributeMap = {
              'a_Position': Laya.VertexMesh.MESH_POSITION0,
              'a_Normal': Laya.VertexMesh.MESH_NORMAL0,
              'a_Texcoord0': Laya.VertexMesh.MESH_TEXTURECOORDINATE0,
              'a_Texcoord1': Laya.VertexMesh.MESH_TEXTURECOORDINATE1,
              'a_BoneWeights': Laya.VertexMesh.MESH_BLENDWEIGHT0,
              'a_BoneIndices': Laya.VertexMesh.MESH_BLENDINDICES0,
              'a_Tangent0': Laya.VertexMesh.MESH_TANGENT0,
          };
          var uniformMap = {
              'u_MvpMatrix': Laya.Shader3D.PERIOD_SPRITE,
              'u_WorldMat': Laya.Shader3D.PERIOD_SPRITE,
              'u_CameraPos': Laya.Shader3D.PERIOD_CAMERA,
              'u_AlbedoTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoIdentity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_AlbedoColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowBoundary': Laya.Shader3D.PERIOD_MATERIAL,
              'u_ShadowIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularRange': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularColor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpecularIntensity': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SunLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SunLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowBias': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowLightDirection': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowMap': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowParams': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowSplitSpheres': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowMatrices': Laya.Shader3D.PERIOD_SCENE,
              'u_ShadowMapSize': Laya.Shader3D.PERIOD_SCENE,
              'u_NormalTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalRTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalGTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_NormalBTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_Bones': Laya.Shader3D.PERIOD_CUSTOM,
              'u_alpha': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightvpMatrix': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightmapScaleOffset': Laya.Shader3D.PERIOD_SPRITE,
              'u_LightMap': Laya.Shader3D.PERIOD_SPRITE,
              'u_TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowInnerRadius': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowOuterRadius': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowPoint1': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowPoint2': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FakeShadowFactor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_LightMapFactor': Laya.Shader3D.PERIOD_MATERIAL,
              'u_SpotLight.color': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.direction': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.range': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.spot': Laya.Shader3D.PERIOD_SCENE,
              'u_SpotLight.position': Laya.Shader3D.PERIOD_SCENE,
              'u_FliterTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterRTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterGTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterBTexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterATexture': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterRTilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterGTilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterBTilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
              'u_FliterATilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
          };
          var NormalMaterial3D = Laya.Shader3D.add("FliterMaterial");
          var subShader = new Laya.SubShader(attributeMap, uniformMap);
          NormalMaterial3D.addSubShader(subShader);
          var vs1 = `
        #include "Lighting.glsl";
        #include "Shadow.glsl";

        attribute vec4 a_Tangent0;
		attribute vec4 a_Position; 
		attribute vec3 a_Normal; 
		attribute vec2 a_Texcoord0;
		uniform mat4 u_MvpMatrix; 
		uniform mat4 u_WorldMat;
		uniform vec3 u_CameraPos;
		varying vec2 v_Texcoord0;    
		varying vec3 v_PositionWorld;
        
        varying vec3 v_Normal;

		#ifdef BONE
			const int c_MaxBoneCount = 24;
			attribute vec4 a_BoneIndices;
			attribute vec4 a_BoneWeights;
			uniform mat4 u_Bones[c_MaxBoneCount];
		#endif

        #if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
            varying vec4 v_ShadowCoord;
        #endif
        
        #ifdef TILINGOFFSET
            uniform vec4 u_TilingOffset;
		#endif

        varying vec3 T;
		varying vec3 B;

		void main() 
		{ 
			#ifdef BONE
				mat4 skinTransform=mat4(0.0);
				skinTransform += u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;
				skinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;
				skinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;
				skinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;
				vec4 position = skinTransform * a_Position;
				gl_Position=u_MvpMatrix * position;
				mat3 worldMat=mat3(u_WorldMat * skinTransform);
			#else
				gl_Position=u_MvpMatrix * a_Position;
				mat3 worldMat=mat3(u_WorldMat);
                vec4 position = a_Position;
			#endif

            mat3 worldInvMat = INVERSE_MAT(worldMat);

            v_Normal=normalize(a_Normal*worldInvMat);

            #ifdef TILINGOFFSET
                v_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);
            #else
                v_Texcoord0=a_Texcoord0;
			#endif	
			
			#ifdef BONE
				v_PositionWorld=(u_WorldMat*position).xyz;
			#else
				v_PositionWorld=(u_WorldMat*a_Position).xyz;
			#endif

            vec3 positionWS=(u_WorldMat*position).xyz;

            #if defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE)
                v_PositionWorld = positionWS;
            #endif

            #if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
                v_ShadowCoord = getShadowCoord(vec4(positionWS,1.0));
            #endif

            T = normalize(worldMat*a_Tangent0.xyz);
			B = cross(v_Normal,T)*a_Tangent0.w;

			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
		}`;
          var ps1 = `
        #if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理，而我们的解析是不认内置宏的，导致被删掉，所以改成 if defined 了
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif

        #include "Lighting.glsl";
        #include "Shadow.glsl";

		varying vec3 v_PositionWorld;
	
		varying vec2 v_Texcoord0; 

        varying vec3 v_Normal;

        #if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
	        varying vec4 v_ShadowCoord;
        #endif

		uniform DirectionLight u_SunLight;

        #ifdef SPOTLIGHT
			uniform SpotLight u_SpotLight;
		#endif

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
		#endif
		uniform sampler2D u_AlbedoTexture;
		uniform float u_AlbedoIdentity;
        uniform vec4 u_AlbedoColor;
        
        #ifdef FLITER_TEXTURE
            uniform sampler2D u_FliterTexture;
        #endif

        #ifdef FLITER_R_TEXTURE
            uniform sampler2D u_FliterRTexture;
            uniform vec4 u_FliterRTilingOffset;
        #endif
        
        #ifdef FLITER_G_TEXTURE
            uniform sampler2D u_FliterGTexture;
            uniform vec4 u_FliterGTilingOffset;
        #endif
        
        #ifdef FLITER_B_TEXTURE
            uniform sampler2D u_FliterBTexture;
            uniform vec4 u_FliterBTilingOffset;
        #endif

        #ifdef FLITER_A_TEXTURE
            uniform sampler2D u_FliterATexture;
            uniform vec4 u_FliterATilingOffset;
        #endif

        #ifdef NORMALTEXTURE
			uniform sampler2D u_NormalTexture;
            uniform vec4 u_NormalTillingOffset;
		#endif

        #ifdef NORMAL_R_TEXTURE
            uniform sampler2D u_NormalRTexture;
        #endif

        #ifdef NORMAL_G_TEXTURE
            uniform sampler2D u_NormalGTexture;
        #endif

        #ifdef NORMAL_B_TEXTURE
            uniform sampler2D u_NormalBTexture;
        #endif

        uniform vec4 u_ShadowColor;
		uniform float u_ShadowRange;
		uniform float u_ShadowIntensity;
		uniform float u_ShadowBoundary;
		uniform float u_SpecularRange;
		uniform float u_SpecularIntensity;
		uniform vec4 u_SpecularColor;

        varying vec3 T;
		varying vec3 B;

        mediump vec3 unpackScaleNormal(mediump vec3 packednormal)
		{
			mediump vec3 normal = packednormal.xyz * 2.0 - 1.0;
			normal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.
			return normal;
		}

        mediump vec3 normalInTangentSpace(sampler2D tt2d, vec2 texcoords)
		{
			mediump vec3 normalTangent = unpackScaleNormal(texture2D(tt2d, texcoords).rgb);
			return normalTangent;
		}

		void main_normal(){
            vec3 normal;

            normal = normalize(v_Normal);

            mat3 TBN = mat3(T, B, v_Normal);

            #ifdef NORMALTEXTURE   
				vec2 normalTexcoord = TransformUV(v_Texcoord0, u_NormalTillingOffset);
				normal = normalInTangentSpace(u_NormalTexture, normalTexcoord);
				normal = TBN * normal;
			#endif

			vec4 albedoTextureColor = vec4(0.0);
            
            #ifdef FLITER_TEXTURE
                vec4 fliterTextureColor = texture2D(u_FliterTexture, v_Texcoord0);
                #ifdef FLITER_R_TEXTURE
                    vec2 fliterRTexcoord = TransformUV(v_Texcoord0, u_FliterRTilingOffset);
                    vec4 fliterRTextureColor = texture2D(u_FliterRTexture, fliterRTexcoord);
                    albedoTextureColor += fliterTextureColor.r * fliterRTextureColor;
                    #ifdef NORMAL_R_TEXTURE
                        vec2 normalRTexcoord = TransformUV(v_Texcoord0, u_FliterRTilingOffset);
                        normal = normalInTangentSpace(u_NormalRTexture, normalRTexcoord);
                        normal = TBN * normal;
                    #endif
                #endif
                #ifdef FLITER_G_TEXTURE
                    vec2 fliterGTexcoord = TransformUV(v_Texcoord0, u_FliterGTilingOffset);
                    vec4 fliterGTextureColor = texture2D(u_FliterGTexture, fliterGTexcoord);
                    albedoTextureColor += fliterTextureColor.g * fliterGTextureColor;
                    #ifdef NORMAL_G_TEXTURE
                        vec2 normalGTexcoord = TransformUV(v_Texcoord0, u_FliterGTilingOffset);
                        normal = normalInTangentSpace(u_NormalGTexture, normalGTexcoord);
                        normal = TBN * normal;
                    #endif
                #endif
                #ifdef FLITER_B_TEXTURE
                    vec2 fliterBTexcoord = TransformUV(v_Texcoord0, u_FliterBTilingOffset);
                    vec4 fliterBTextureColor = texture2D(u_FliterBTexture, fliterBTexcoord);
                    albedoTextureColor += fliterTextureColor.b * fliterBTextureColor;
                    #ifdef NORMAL_B_TEXTURE
                        vec2 normalBTexcoord = TransformUV(v_Texcoord0, u_FliterBTilingOffset);
                        normal = normalInTangentSpace(u_NormalBTexture, normalBTexcoord);
                        normal = TBN * normal;
                    #endif
                #endif
                #ifdef FLITER_A_TEXTURE
                    vec2 fliterATexcoord = TransformUV(v_Texcoord0, u_FliterATilingOffset);
                    vec4 fliterATextureColor = texture2D(u_FliterATexture, fliterATexcoord);
                    albedoTextureColor += fliterTextureColor.a * fliterATextureColor;
                #endif
            #endif

            #ifdef SPOTLIGHT
				float distance = distance(v_PositionWorld.xz, u_SpotLight.position.xz);
				float inRange = step(distance, u_SpotLight.range);
				float inTransition = step(distance, u_SpotLight.range+0.1);
				float factor = (distance - u_SpotLight.range)/0.1;

				float spotValue = 1.0*inRange + (1.0 - factor) * (inTransition - inRange);
				vec3 spotColor = u_SpotLight.color * gl_FragColor.rgb * spotValue;

				vec3 sunColor = u_SunLight.color * gl_FragColor.rgb;

				gl_FragColor.rgb = spotColor + sunColor;
				// gl_FragColor.rgb = vec3(distance);
			#else
				gl_FragColor.rgb *= u_SunLight.color;
			#endif

            vec3 lightDir = normalize(u_SunLight.direction);

            // 阴影计算部分计算
			// 1.0 -> 0.0
			float nl = max(dot(normal, -lightDir), 0.0);

			// +0.01是避免阴影边界等于0时 shadow_allin && shadow_partin 相同

            float shadow_boundary = u_ShadowBoundary + 0.01;
            float shadow_allin = step(nl, u_ShadowRange - shadow_boundary*0.5);
            float shadow_partin = step(nl, u_ShadowRange + shadow_boundary*0.5);

            //分析:  allin时:  shadow_allin == 1.0;  shadow_partin == 1.0;
            //      partin时: shadow_allin == 0.0; shadow_partin = 1.0;
            //      none时:   shadow_allin == 0.0; shadow_partin = 0.0;

            float shadow = shadow_allin + (u_ShadowRange + shadow_boundary*0.5 - nl)/shadow_boundary * (shadow_partin - shadow_allin);

            vec3 albedoColor = albedoTextureColor.rgb;

			shadow *= u_ShadowIntensity;
			vec3 albedoAreaColor = (1.0 - shadow) * albedoColor;
			vec3 shadowAreaColor = shadow * albedoColor * u_ShadowColor.rgb;

            #if defined(CALCULATE_SHADOWS)
                #ifdef SHADOW_CASCADE
                    vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
                #else
                    vec4 shadowCoord = v_ShadowCoord;
                #endif
                float shadowAttenuation = sampleShadowmap(shadowCoord);
                albedoAreaColor *= shadowAttenuation;
            #endif

			//高光部分计算
			float specular = pow(nl,(u_SpecularRange + 0.01)*10.0);
			vec3 speculAreaColor = (1.0 - shadow) * albedoColor * u_SpecularIntensity * specular * u_SpecularColor.rgb;
			//混合漫反射 + 高光 + 阴影
			vec3 finalColor = albedoAreaColor + speculAreaColor + shadowAreaColor;


            #ifdef WHOLE_ALPHA
				//叠加全局透明度
				gl_FragColor = vec4(finalColor.rgb, albedoTextureColor.a*u_alpha);
			#else
				gl_FragColor = vec4(finalColor.rgb, albedoTextureColor.a);
			#endif
		}
	
		void main() 
		{ 
			main_normal();
		}`;
          subShader.addShaderPass(vs1, ps1, stateMap);
      }
      get albedoTexture() {
          return this._shaderValues.getTexture(FliterMaterial.ALBEDOTEXTURE);
      }
      set albedoTexture(value) {
          if (value) {
              this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_ALBEDOTEXTURE);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_ALBEDOTEXTURE);
          }
          this._shaderValues.setTexture(FliterMaterial.ALBEDOTEXTURE, value);
      }
      get fliterTexture() {
          return this._shaderValues.getTexture(FliterMaterial.FLITER_TEXTURE);
      }
      set fliterTexture(value) {
          if (value) {
              this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_FLITER_TEXTURE);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_FLITER_TEXTURE);
          }
          this._shaderValues.setTexture(FliterMaterial.FLITER_TEXTURE, value);
      }
      get fliterRTexture() {
          return this._shaderValues.getTexture(FliterMaterial.FLITER_R_TEXTURE);
      }
      set fliterRTexture(value) {
          if (value) {
              this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_FLITER_R_TEXTURE);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_FLITER_R_TEXTURE);
          }
          this._shaderValues.setTexture(FliterMaterial.FLITER_R_TEXTURE, value);
      }
      get fliterGTexture() {
          return this._shaderValues.getTexture(FliterMaterial.FLITER_G_TEXTURE);
      }
      set fliterGTexture(value) {
          if (value) {
              this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_FLITER_G_TEXTURE);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_FLITER_G_TEXTURE);
          }
          this._shaderValues.setTexture(FliterMaterial.FLITER_G_TEXTURE, value);
      }
      get fliterBTexture() {
          return this._shaderValues.getTexture(FliterMaterial.FLITER_B_TEXTURE);
      }
      set fliterBTexture(value) {
          if (value) {
              this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_FLITER_B_TEXTURE);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_FLITER_B_TEXTURE);
          }
          this._shaderValues.setTexture(FliterMaterial.FLITER_B_TEXTURE, value);
      }
      get fliterATexture() {
          return this._shaderValues.getTexture(FliterMaterial.FLITER_A_TEXTURE);
      }
      set fliterATexture(value) {
          if (value) {
              this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_FLITER_A_TEXTURE);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_FLITER_A_TEXTURE);
          }
          this._shaderValues.setTexture(FliterMaterial.FLITER_A_TEXTURE, value);
      }
      get FliterRTillingOffset() {
          return this._shaderValues.getVector(FliterMaterial.FLITER_R_TILINGOFFSET);
      }
      set FliterRTillingOffset(value) {
          this._shaderValues.setVector(FliterMaterial.FLITER_R_TILINGOFFSET, value);
      }
      get FliterGTillingOffset() {
          return this._shaderValues.getVector(FliterMaterial.FLITER_G_TILINGOFFSET);
      }
      set FliterGTillingOffset(value) {
          this._shaderValues.setVector(FliterMaterial.FLITER_G_TILINGOFFSET, value);
      }
      get FliterBTillingOffset() {
          return this._shaderValues.getVector(FliterMaterial.FLITER_B_TILINGOFFSET);
      }
      set FliterBTillingOffset(value) {
          this._shaderValues.setVector(FliterMaterial.FLITER_B_TILINGOFFSET, value);
      }
      get FliterATillingOffset() {
          return this._shaderValues.getVector(FliterMaterial.FLITER_A_TILINGOFFSET);
      }
      set FliterATillingOffset(value) {
          this._shaderValues.setVector(FliterMaterial.FLITER_A_TILINGOFFSET, value);
      }
      getNormalTexture(index) {
          return this._shaderValues.getTexture(index);
      }
      setNormalTexture(index, define, value) {
          if (value != null) {
              this._defineDatas.add(define);
          }
          else {
              this._defineDatas.remove(define);
          }
          this._shaderValues.setTexture(index, value);
      }
      getNormalTextureTillingOffset(index) {
          return this._shaderValues.getVector(index);
      }
      setNormalTextureTillingOffset(index, value) {
          this._shaderValues.setVector(index, value);
      }
      get albedoColor() {
          return this._shaderValues.getVector(FliterMaterial.ALBEDOCOLOR);
      }
      set albedoColor(value) {
          if (value) {
              this._defineDatas.add(FliterMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          else {
              this._defineDatas.remove(FliterMaterial.SHADERDEFINE_ALBEDOCOLOR);
          }
          this._shaderValues.setVector(FliterMaterial.ALBEDOCOLOR, value);
      }
      get albedoIdentity() {
          return this._shaderValues.getNumber(FliterMaterial.ALBEDOIDENTITY);
      }
      set albedoIdentity(value) {
          value = Math.max(0.0, Math.min(1.0, value));
          this._shaderValues.setNumber(FliterMaterial.ALBEDOIDENTITY, value);
      }
      get tilingOffset() {
          return this._shaderValues.getVector(FliterMaterial.TILINGOFFSET);
      }
      set tilingOffset(value) {
          if (value) {
              if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
                  this._shaderValues.addDefine(FliterMaterial.SHADERDEFINE_TILINGOFFSET);
              else
                  this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          else {
              this._shaderValues.removeDefine(FliterMaterial.SHADERDEFINE_TILINGOFFSET);
          }
          this._shaderValues.setVector(FliterMaterial.TILINGOFFSET, value);
      }
      get alpha() {
          return this._shaderValues.getNumber(FliterMaterial.WHOLE_ALPHA);
      }
      set alpha(value) {
          if (value != null) {
              this._defineDatas.add(FliterMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          else {
              this._defineDatas.remove(FliterMaterial.SHADERDEFINE_WHOLE_ALPHA);
          }
          this._shaderValues.setNumber(FliterMaterial.WHOLE_ALPHA, value);
      }
      get cull() {
          return this._shaderValues.getInt(FliterMaterial.CULL);
      }
      set cull(value) {
          this._shaderValues.setInt(FliterMaterial.CULL, value);
      }
      get blend() {
          return this._shaderValues.getInt(FliterMaterial.BLEND);
      }
      set blend(value) {
          this._shaderValues.setInt(FliterMaterial.BLEND, value);
      }
      get blendSrc() {
          return this._shaderValues.getInt(FliterMaterial.BLEND_SRC);
      }
      set blendSrc(value) {
          this._shaderValues.setInt(FliterMaterial.BLEND_SRC, value);
      }
      get blendDst() {
          return this._shaderValues.getInt(FliterMaterial.BLEND_DST);
      }
      set blendDst(value) {
          this._shaderValues.setInt(FliterMaterial.BLEND_DST, value);
      }
      get depthTest() {
          return this._shaderValues.getInt(FliterMaterial.DEPTH_TEST);
      }
      set depthTest(value) {
          this._shaderValues.setInt(FliterMaterial.DEPTH_TEST, value);
      }
      get depthWrite() {
          return this._shaderValues.getBool(FliterMaterial.DEPTH_WRITE);
      }
      set depthWrite(value) {
          this._shaderValues.setBool(FliterMaterial.DEPTH_WRITE, value);
      }
      set renderMode(value) {
          switch (value) {
              case FliterMaterial.RENDERMODE_OPAQUE:
                  this.alphaTest = false;
                  this.renderQueue = Laya.Material.RENDERQUEUE_OPAQUE;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case FliterMaterial.RENDERMODE_CUTOUT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case FliterMaterial.RENDERMODE_CUTOUT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_ALPHATEST;
                  this.alphaTest = true;
                  this.depthWrite = true;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_DISABLE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case FliterMaterial.RENDERMODE_TRANSPARENT:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case FliterMaterial.RENDERMODE_TRANSPARENT_CULL_NONE:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_NONE;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_SRC_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              case FliterMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD:
                  this.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT;
                  this.alphaTest = false;
                  this.depthWrite = false;
                  this.cull = Laya.RenderState.CULL_BACK;
                  this.blend = Laya.RenderState.BLEND_ENABLE_ALL;
                  this.blendSrc = Laya.RenderState.BLENDPARAM_ONE_MINUS_DST_ALPHA;
                  this.blendDst = Laya.RenderState.BLENDPARAM_ONE;
                  this.depthTest = Laya.RenderState.DEPTHTEST_LESS;
                  break;
              default:
                  throw new Error("FliterMaterial : renderMode value error.");
          }
      }
  }
  FliterMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  FliterMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  FliterMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  FliterMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  FliterMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  FliterMaterial.DIRECTIONLIGHTDIRECTION = Laya.Shader3D.propertyNameToID("u_SunLight.direction");
  FliterMaterial.DIRECTIONLIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_SunLight.color");
  FliterMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  FliterMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  FliterMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  FliterMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  FliterMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  FliterMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  FliterMaterial.SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_ShadowRange");
  FliterMaterial.SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_ShadowIntensity");
  FliterMaterial.SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_ShadowBoundary");
  FliterMaterial.SPECULARRANGE = Laya.Shader3D.propertyNameToID("u_SpecularRange");
  FliterMaterial.SPECULARINTENSITY = Laya.Shader3D.propertyNameToID("u_SpecularIntensity");
  FliterMaterial.SPECULARCOLOR = Laya.Shader3D.propertyNameToID("u_SpecularColor");
  FliterMaterial.NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  FliterMaterial.NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_NormalTillingOffset");
  FliterMaterial.NORMAL_R_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalRTexture");
  FliterMaterial.NORMAL_G_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalGTexture");
  FliterMaterial.NORMAL_B_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalBTexture");
  FliterMaterial.FLITER_TEXTURE = Laya.Shader3D.propertyNameToID("u_FliterTexture");
  FliterMaterial.FLITER_R_TEXTURE = Laya.Shader3D.propertyNameToID("u_FliterRTexture");
  FliterMaterial.FLITER_R_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_FliterRTilingOffset");
  FliterMaterial.FLITER_G_TEXTURE = Laya.Shader3D.propertyNameToID("u_FliterGTexture");
  FliterMaterial.FLITER_G_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_FliterGTilingOffset");
  FliterMaterial.FLITER_B_TEXTURE = Laya.Shader3D.propertyNameToID("u_FliterBTexture");
  FliterMaterial.FLITER_B_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_FliterBTilingOffset");
  FliterMaterial.FLITER_A_TEXTURE = Laya.Shader3D.propertyNameToID("u_FliterATexture");
  FliterMaterial.FLITER_A_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_FliterATilingOffset");
  FliterMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  FliterMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  FliterMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  FliterMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  FliterMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  FliterMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  FliterMaterial.RENDERMODE_OPAQUE = 1;
  FliterMaterial.RENDERMODE_CUTOUT = 2;
  FliterMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  FliterMaterial.RENDERMODE_TRANSPARENT = 4;
  FliterMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  FliterMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD = 6;

  const KEY_MATERIAL_INFO_VERSION = "KEY_MATERIAL_INFO_VERSION";
  const MATERIAL_INFO_VERSION = 1;
  class mgrMaterial extends Manager {
      static onLoad() {
          super.onLoad();
          LightMapMaterial.initShader();
          BagMaterial.initShader();
          NormalMaterial.initShader();
          HeightFogMaterial.initShader();
          PaintMaterial.initShader();
          CustomPBRSkinMaterial.initShader();
          CustomPBRHairMaterial.initShader();
          FliterMaterial.initShader();
          if (!this.EMPTY_TEX2D) {
              var pixels = new Uint8Array(4);
              pixels[0] = 0;
              pixels[1] = 0;
              pixels[2] = 0;
              pixels[3] = 0;
              let empty = new Laya.Texture2D(1, 1, Laya.Texture2D.FORMAT_R8G8B8A8, false, false);
              empty.setPixels(pixels);
              empty.lock = true;
              this.EMPTY_TEX2D = empty;
          }
          this.loadFromText();
          if (Global.H5_TEST) {
              ResLoader.loadRes("res/cfg/editorConfig.json", Laya.Loader.JSON, (res) => {
                  if (res) {
                      if (res[KEY_MATERIAL_INFO_VERSION] == MATERIAL_INFO_VERSION) {
                          this.editorConfig = res;
                      }
                  }
              });
          }
      }
      static loadFromText() {
          ResLoader.loadRes("res/cfg/3dConfig.txt", Laya.Loader.TEXT, (res) => {
              if (res) {
                  let dataStr = Tools.decompressFromBase64(res);
                  if (dataStr) {
                      let data = JSON.parse(dataStr);
                      if (data[KEY_MATERIAL_INFO_VERSION] == MATERIAL_INFO_VERSION) {
                          this.materialInfos = data.materialInfos;
                          this.dynamicBoneInfos = data.dynamicBoneInfos;
                          this.lightRotation = data.lightRotation;
                          this.resetPanel3DLight();
                      }
                      return;
                  }
              }
              this.loadFromJson();
          });
      }
      static loadFromJson() {
          console.log("加载3dConfig.json --- 未压缩格式");
          ResLoader.loadRes("res/cfg/3dConfig.json", Laya.Loader.JSON, (data) => {
              if (data) {
                  if (data[KEY_MATERIAL_INFO_VERSION] == MATERIAL_INFO_VERSION) {
                      this.materialInfos = data.materialInfos;
                      this.dynamicBoneInfos = data.dynamicBoneInfos;
                      this.lightRotation = data.lightRotation;
                      this.resetPanel3DLight();
                  }
              }
          });
      }
      static getSaveData() {
          let data = {
              materialInfos: this.materialInfos,
              dynamicBoneInfos: this.dynamicBoneInfos,
              lightRotation: this.lightRotation,
          };
          data[KEY_MATERIAL_INFO_VERSION] = MATERIAL_INFO_VERSION;
          let jsonStr = JSON.stringify(data);
          let base64Str = Tools.compressToBase64(jsonStr);
          return [jsonStr, base64Str];
      }
      static saveToLocal() {
          if (GameRemoteRouter.instance) {
              let [jsonStr, base64Str] = this.getSaveData();
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: `res/cfg/3dConfig.txt`,
                      data: base64Str,
                  },
              });
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: `res/cfg/3dConfig.json`,
                      data: jsonStr,
                  },
              });
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: `res/cfg/editorConfig.json`,
                      data: this.editorConfig,
                  },
              });
              this.resetPanel3DLight();
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存数据成功！");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器！");
          }
      }
      static resetPanel3DLight() {
          let rot = this.lightRotation;
          if (rot && rot.length == 3) {
              PanelBase3D.setDefaultLightEular(rot[0], rot[1], rot[2]);
          }
      }
      static setMaterialInfos(value) {
          this.materialInfos = value;
      }
      static setDynamicBoneInfos(value) {
          this.dynamicBoneInfos = value;
      }
      static setMaterial(modelId, nodeName, matIndex, materialInfo) {
          if (!this.materialInfos[modelId])
              this.materialInfos[modelId] = {};
          if (!this.materialInfos[modelId][nodeName])
              this.materialInfos[modelId][nodeName] = {};
          this.materialInfos[modelId][nodeName][matIndex] = materialInfo;
      }
      static getMaterial(modelId, nodeName, matIndex, autoCreate = true) {
          if (!this.materialInfos[modelId]) {
              if (autoCreate) {
                  this.materialInfos[modelId] = {};
              }
              else {
                  return null;
              }
          }
          if (!this.materialInfos[modelId][nodeName]) {
              if (autoCreate) {
                  this.materialInfos[modelId][nodeName] = {};
              }
              else {
                  return null;
              }
          }
          if (!this.materialInfos[modelId][nodeName][matIndex] && autoCreate) {
              this.materialInfos[modelId][nodeName][matIndex] = this.getDefaultCartonMateril();
          }
          return this.materialInfos[modelId][nodeName][matIndex];
      }
      static getDefaultCartonMateril() {
          return {
              albedoColor: [1, 1, 1, 1],
              shadowRange: 0.5,
              shadowIntensity: 1,
              shadowColor: [0, 0, 0, 1],
              shadowBoundary: 0.5,
              specularRange: 0,
              specularIntensity: 0,
              specularColor: [1, 1, 1, 1],
              secondShadowRange: 0,
              secondShadowIntensity: 1,
              secondShadowBoundary: 0,
              secondShadowColor: [1, 1, 1, 1],
              EdgeHightRange: 0,
              EdgeHightBoundary: 0,
              EdgeHightColor: [1, 1, 1, 1],
              EdgeHightIntensity: 1,
              renderMode: BagMaterial.RENDERMODE_OPAQUE,
              alpha: 1,
              normalTextureScale: 0,
              detailNormalTexture: null,
              detailNormalTextureScale: 1,
              detailNormalTextureTillingOffset: [1, 1, 0, 0],
              smoothness: 0,
              metallic: 0,
          };
      }
      static setCustomShader(model, modelId, autoCreate = true, root) {
          if (!model)
              return [];
          let materials = [];
          for (let i = 0; i < model.numChildren; i++) {
              let child = model.getChildAt(i);
              let path = "";
              if (root) {
                  path = root + "/" + child.name;
              }
              else {
                  path = child.name;
              }
              let renderer = child[`skinnedMeshRenderer`] || child[`meshRenderer`];
              if (renderer) {
                  let material = this.__setCustomMaterial(renderer, modelId, path, autoCreate);
                  materials = materials.concat(material);
              }
              this.setCustomShader(child, modelId, autoCreate, path);
          }
          return materials;
      }
      static setCustomShaderByName(model, modelId, autoCreate = true, root, childName) {
          if (!model)
              return [];
          let materials = [];
          for (let i = 0; i < model.numChildren; i++) {
              let child = model.getChildAt(i);
              if (!childName || child.name == childName) {
                  let path = "";
                  if (root) {
                      path = root + "/" + child.name;
                  }
                  else {
                      path = child.name;
                  }
                  let renderer = child[`skinnedMeshRenderer`] || child[`meshRenderer`];
                  if (renderer) {
                      let material = this.__setCustomMaterial(renderer, modelId, path, autoCreate);
                      materials = materials.concat(material);
                  }
                  this.setCustomShaderByName(child, modelId, autoCreate, path);
              }
          }
          return materials;
      }
      static __setCustomMaterial(render, modelId, nodeName, autoCreate) {
          let newMaterials = [];
          let sharedMaterials = render.sharedMaterials;
          for (let i = 0; i < sharedMaterials.length; i++) {
              const oldMaterial = sharedMaterials[i];
              let materialData = mgrMaterial.getMaterial(modelId, nodeName, i, autoCreate);
              if (!materialData) {
                  newMaterials[i] = oldMaterial;
                  continue;
              }
              if (oldMaterial instanceof BagMaterial) {
                  newMaterials[i] = oldMaterial;
              }
              else {
                  newMaterials[i] = this.createCustomShader(oldMaterial);
              }
              this.fillMaterialData(newMaterials[i], materialData);
          }
          render.sharedMaterials = newMaterials;
          return newMaterials;
      }
      static createCustomShader(oldMaterial) {
          let newMaterial = new BagMaterial();
          newMaterial.name = oldMaterial.name;
          if (oldMaterial.albedoTexture) {
              newMaterial.paintLayer1Texture = oldMaterial.albedoTexture;
          }
          newMaterial.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
          return newMaterial;
      }
      static fillMaterialData(newMaterial, materialData) {
          if (!newMaterial || !materialData)
              return;
          Tools.forEachMap(materialData, function (key, value) {
              if (value instanceof Array) {
                  newMaterial[key] = new Laya.Vector4(value[0], value[1], value[2], 1);
              }
              else if (typeof value == "string") {
                  if (value.startsWith("url://")) {
                      ResLoader.loadTexture2D(value.substr(6), function (text2d) {
                          if (!text2d)
                              return;
                          if (newMaterial.destroyed)
                              return;
                          if (text2d.wrapModeU != Laya.WarpMode.Repeat) {
                              text2d.wrapModeU = Laya.WarpMode.Repeat;
                              text2d.wrapModeV = Laya.WarpMode.Repeat;
                              text2d.filterMode = Laya.FilterMode.Bilinear;
                              text2d.generateMipmap();
                          }
                          newMaterial[key] = text2d;
                      });
                  }
                  else {
                      console.error(`mgrMaterial.fillMaterialData 未知数据类型key:${key} value:${value}`);
                  }
              }
              else {
                  newMaterial[key] = value;
              }
          });
      }
      static setBagMaterial(model, id) {
          if (!model)
              return null;
          let renderer = model[`skinnedMeshRenderer`] || model[`meshRenderer`];
          if (renderer) {
              let material = this.__setBagMaterial(renderer, id);
              return material;
          }
          return null;
      }
      static __setBagMaterial(render, id) {
          let oldMaterial;
          let bagMaterial;
          let newMaterials = [];
          console.log("__setBagMaterial", render.sharedMaterials);
          for (let i = 0; i < render.sharedMaterials.length; i++) {
              const mat = render.sharedMaterials[i];
              if (i == 0) {
                  oldMaterial = mat;
                  if (oldMaterial instanceof BagMaterial) {
                      bagMaterial = oldMaterial;
                  }
                  else {
                      bagMaterial = new BagMaterial;
                  }
                  newMaterials.push(bagMaterial);
              }
              else {
                  newMaterials.push(mat);
              }
          }
          render.sharedMaterials = newMaterials;
          let materialData = this.bagMaterialInfos[id];
          if (!materialData) {
              materialData = {
                  shadowRange: 0.5,
                  shadowIntensity: 0.1,
                  shadowColor: [0, 0, 0, 1],
                  shadowBoundary: 0.5,
                  specularRange: 0.1,
                  specularIntensity: 1,
                  specularColor: [1, 1, 1, 1],
                  secondShadowRange: 0,
                  secondShadowIntensity: 0,
                  secondShadowColor: [1, 1, 1, 1],
                  secondShadowBoundary: 0,
                  EdgeHightRange: 0,
                  EdgeHightIntensity: 0,
                  EdgeHightColor: [1, 1, 1, 1],
                  EdgeHightBoundary: 0,
                  renderMode: BagMaterial.RENDERMODE_CUTOUT_CULL_NONE,
                  alpha: 1,
                  detailNormalTexture: "",
                  normalTextureScale: 0,
                  detailNormalTextureScale: 1,
                  detailNormalTextureTillingOffset: [1, 1, 0, 0],
                  smoothness: 0,
                  metallic: 0,
              };
          }
          bagMaterial.name = oldMaterial.name;
          bagMaterial.shadowIntensity = materialData.shadowIntensity;
          bagMaterial.shadowRange = materialData.shadowRange;
          materialData.shadowColor && materialData.shadowColor.length > 0 && (bagMaterial.shadowColor = new Laya.Vector4(materialData.shadowColor[0], materialData.shadowColor[1], materialData.shadowColor[2], 1.0));
          bagMaterial.shadowBoundary = materialData.shadowBoundary;
          bagMaterial.specularRange = materialData.specularRange;
          bagMaterial.specularIntensity = materialData.specularIntensity;
          materialData.specularColor && materialData.specularColor.length > 0 && (bagMaterial.specularColor = new Laya.Vector4(materialData.specularColor[0], materialData.specularColor[1], materialData.specularColor[2], 1.0));
          bagMaterial.secondShadowIntensity = materialData.secondShadowIntensity;
          bagMaterial.secondShadowRange = materialData.secondShadowRange;
          materialData.secondShadowColor && materialData.secondShadowColor.length > 0 && (bagMaterial.secondShadowColor = new Laya.Vector4(materialData.secondShadowColor[0], materialData.secondShadowColor[1], materialData.secondShadowColor[2], 1.0));
          bagMaterial.secondShadowBoundary = materialData.secondShadowBoundary;
          bagMaterial.EdgeHightIntensity = materialData.EdgeHightIntensity;
          bagMaterial.EdgeHightRange = materialData.EdgeHightRange;
          materialData.EdgeHightColor && materialData.EdgeHightColor.length > 0 && (bagMaterial.EdgeHightColor = new Laya.Vector4(materialData.EdgeHightColor[0], materialData.EdgeHightColor[1], materialData.EdgeHightColor[2], 1.0));
          bagMaterial.EdgeHightBoundary = materialData.EdgeHightBoundary;
          bagMaterial.renderMode = materialData.renderMode;
          bagMaterial.alpha = materialData.alpha;
          bagMaterial.normalTextureScale = materialData.normalTextureScale;
          bagMaterial.detailNormalTextureScale = materialData.detailNormalTextureScale;
          bagMaterial.smoothness = materialData.smoothness;
          bagMaterial.metallic = materialData.metallic;
          bagMaterial.bPickZero = false;
          let llft = materialData.detailNormalTextureTillingOffset;
          bagMaterial.detailNormalTextureTillingOffset = new Laya.Vector4(llft[0], llft[1], llft[2], llft[3]);
          if (materialData.detailNormalTexture) {
              mgrLoader.batchLoadResources([], [], [materialData.detailNormalTexture], this, () => {
                  let texture = mgrLoader.get2dRes(materialData.detailNormalTexture);
                  let text2d = texture.bitmap;
                  if (text2d.wrapModeU != Laya.WarpMode.Repeat) {
                      text2d.wrapModeU = Laya.WarpMode.Repeat;
                      text2d.wrapModeV = Laya.WarpMode.Repeat;
                      text2d.filterMode = Laya.FilterMode.Bilinear;
                      text2d.generateMipmap();
                  }
                  bagMaterial.detailNormalTexture = texture;
              });
          }
          return bagMaterial;
      }
      static precompileshader(callback) {
          ResLoader.loadRes("res/cfg/shaderCompile.txt", Laya.Loader.TEXT, (res) => {
              if (res) {
                  let dataStr = Tools.decompressFromBase64(res);
                  if (!dataStr) {
                      callback && callback();
                      return;
                  }
                  let data;
                  try {
                      data = JSON.parse(dataStr);
                  }
                  catch (error) {
                      Logger.catchError("precompileshader:", error);
                      callback && callback();
                      return;
                  }
                  if (!data || data.length == 0) {
                      callback && callback();
                      return;
                  }
                  for (let i = 0; i < data.length; i++) {
                      const element = data[i];
                      Laya.Shader3D.compileShaderByDefineNames(element.shaderName, element.subShaderIndex, element.passIndex, element.defineNames);
                  }
                  callback && callback();
              }
              else {
                  callback();
              }
          });
      }
      static enableShaderDebugMode() {
          Laya.Shader3D.debugMode = true;
      }
      static disableShaderDebugMode() {
          Laya.Shader3D.debugMode = false;
      }
      static recordShaderCompileInfo() {
          if (!GameRemoteRouter.instance) {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
          }
          else {
              Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "shader 预编译信息存档!");
              GameRemoteRouter.instance.sendMsgToServer({
                  route: "keepInFile",
                  data: {
                      filePath: `res/cfg/shaderCompile.json`,
                      data: this.shaderCompileInfo,
                  },
              });
          }
      }
      static findNodeByPath(node, path, debug) {
          var list = path.split("/");
          for (var i = 0; i < list.length; i++) {
              node = node.getChildByName(list[i]);
              if (node == null) {
                  console.log("findNodeByPath: Not found", list[i]);
                  return null;
              }
              if (debug) {
                  console.log("-->", list[i]);
              }
          }
          return node;
      }
      static startRecordModelCompileInfo() {
          if (!Laya.Browser.onPC)
              return;
          this.enableShaderDebugMode();
          Laya.Shader3D.debugShaderVariantCollection.clear();
      }
      static endRecordModelCompileInfo(modelId) {
          if (!Laya.Browser.onPC)
              return;
          this.shaderCompileInfo[modelId] = [];
          for (let i = 0; i < Laya.Shader3D.debugShaderVariantCollection.variantCount; i++) {
              let shadervariant = Laya.Shader3D.debugShaderVariantCollection.getByIndex(i);
              let shaderName = shadervariant.shader.name;
              let obj = {};
              obj.shaderName = shaderName;
              obj.defineNames = shadervariant.defineNames;
              obj.passIndex = shadervariant.passIndex;
              obj.subShaderIndex = shadervariant.subShaderIndex;
              this.shaderCompileInfo[modelId].push(obj);
          }
          this.recordShaderCompileInfo();
      }
      static precompileShaderByModelId(modelId) {
          let compileInfo = this.shaderCompileInfo[modelId] || [];
          console.log(`编译shader: ${modelId}!!!`, compileInfo);
          for (let i = 0; i < compileInfo.length; i++) {
              const element = compileInfo[i];
              Laya.Shader3D.compileShaderByDefineNames(element.shaderName, element.subShaderIndex, element.passIndex, element.defineNames);
          }
          console.log(`编译shader完毕: ${modelId}!!!`);
      }
  }
  mgrMaterial.bagMaterialInfos = {};
  mgrMaterial.strapsMaterialInfos = {};
  mgrMaterial.materialInfos = {};
  mgrMaterial.lightRotation = [];
  mgrMaterial.editorConfig = { camera: {} };
  mgrMaterial.shaderCompileInfo = {};

  class mgrReview extends Manager {
      static onLoad() {
          super.onLoad();
      }
      static loadRecord() {
          super.loadRecord();
          let record = FileRecord.getData("review") || {};
          this.lastAlertTime = record.lastAlertTime || 0;
          this.lastReviewTime = record.lastReviewTime || 0;
      }
      static saveRecord() {
          super.saveRecord();
          let record = {
              lastAlertTime: this.lastAlertTime || 0,
              lastReviewTime: this.lastReviewTime || 0,
          };
          FileRecord.setData("review", record);
      }
      static tryShowReviewDialog() {
          if (!Laya.Browser.onIOS) {
              return false;
          }
          if (!this.canShowInvite()) {
              return;
          }
          if (Tools.isOneDay(Timer.now, this.lastAlertTime || 0)) {
              console.log("[warn] mgrReview.tryShowReviewDialog today already alerted");
              return;
          }
          this.showReviewDialog();
      }
      static canShowInvite() {
          let random = Tools.random(0, 100);
          if (random < db.cop_db.show_invite_ratio) {
              return true;
          }
          else {
              console.log("邀评概率不足");
              return false;
          }
      }
      static isShowInviteButton() {
          if (!Laya.Browser.onIOS) {
              return false;
          }
          if (!window[`conch`]) {
              return false;
          }
          let os = window[`conchConfig`].getOS();
          if (os != "Conch-ios") {
              console.log("[warn] mgrReview.tryShowReviewDialog mgrSdk.bHasReviewModule is false");
              return false;
          }
          if (mgrGame.getItemCount(999) > 0) {
              return false;
          }
          return true;
      }
      static showReviewDialog() {
          this.lastAlertTime = Timer.now;
          this.saveRecord();
          mgrSdk.openReview();
      }
      static isInvite() {
          if (this.lastReviewTime != 0) {
              return true;
          }
          return false;
      }
      static markUnreview() {
          this.lastAlertTime = 0;
          this.lastReviewTime = 0;
          this.saveRecord();
      }
  }

  class ManagerLoader {
      static get isLoading() {
          return this.state == 1;
      }
      static get isComplete() {
          return this.state == 2;
      }
      static onLoad(callback) {
          if (this.state == 0) {
              this.state = 1;
              this.loadAllMgr(callback);
          }
      }
      static loadAllMgr(callback) {
          BaseFacade.loadAllMgr();
          mgrKV.__init();
          mgrSound.__init();
          mgrMaterial.__init();
          mgrDebug.__init();
          mgrTip.__init();
          mgrChannel.__init();
          mgrTime.__init();
          mgrGame.__init();
          mgrSign.__init();
          mgrGuide.__init();
          mgrVideoRecorder.__init();
          mgrLoader.__init();
          mgrTask.__init();
          mgrShop.__init();
          mgrReview.__init();
          mgrOffline.__init();
          mgrSign.__init();
          mgrTower.__init();
          mgrHolyItem.__init();
          mgrPrayBox.__init();
          mgrPrayCoin.__init();
          mgrTalent.__init();
          mgrMonster.__init();
          mgrGain.__init();
          mgrFB.__init();
          mgrSecret.__init();
          mgrExchange.__init();
          mgrSmelter.__init();
          mgrFinalWar.__init();
          mgrDailyDamage.__init();
          mgrAllEquip.__init();
          mgrNetwork.__init();
          mgrTaskSeven.__init();
          mgrExplore.__init();
          mgrSubscription.__init();
          mgrCollect.__init();
          mgrNewyear.__init();
          mgrMail.__init();
          Manager.loadAllManagers(() => {
              this.state = 2;
              Global.sendMsg(BASE_MSG.BASE_MGR_LOADED);
              callback && callback(true);
              BaseFacade.startAll();
          });
      }
  }
  ManagerLoader.state = 0;

  class HumanBone {
      constructor() {
          this.overloadAnimationClip();
          this.overloadAnimator();
      }
      overloadAnimationClip() {
          Laya3D[`enableNative3D`] = () => { };
          Laya3D[`_loadAnimationClip`] = (loader) => {
              loader.on(Laya.Event.LOADED, null, function (data) {
                  loader._cache = loader._createCache;
                  var clip = Laya.AnimationClip._parse(data, loader._propertyParams, loader._constructParams);
                  Laya3D[`_endLoad`](loader, clip);
                  let startIndex = clip.url.lastIndexOf("/") + 1;
                  let endIndex = clip.url.lastIndexOf(".");
                  let name = clip.url.slice(startIndex, endIndex);
                  let temps = name.split("-");
                  name = temps[0];
                  if (HumanBone.allHumanBoneConfig[name]) {
                      clip[`avatar_height`] = HumanBone.allHumanBoneConfig[name].rootPos.y;
                  }
              });
              loader.load(loader.url, Laya.Loader.BUFFER, false, null, true);
          };
          Laya.Loader.parserMap[Laya3D.ANIMATIONCLIP] = Laya3D[`_loadAnimationClip`];
          Laya.AnimationClip.prototype[`_evaluateClipDatasRealTime`] = function (nodes, playCurTime, realTimeCurrentFrameIndexes, addtive, frontPlay, outDatas, name, humanBoneConfig, humanScaleInfo) {
              humanBoneConfig = humanBoneConfig || { boneMap: {} };
              humanScaleInfo = humanScaleInfo || { boneMap: {}, wholeRatio: 1 };
              for (var i = 0, n = nodes.count; i < n; i++) {
                  var node = nodes.getNodeByIndex(i);
                  var type = node.type;
                  var nextFrameIndex;
                  var keyFrames = node._keyFrames;
                  var keyFramesCount = keyFrames.length;
                  var frameIndex = realTimeCurrentFrameIndexes[i];
                  var nodeName = node._ownerPath[node._ownerPath.length - 1];
                  if (frontPlay) {
                      if ((frameIndex !== -1) && (playCurTime < keyFrames[frameIndex].time)) {
                          frameIndex = -1;
                          realTimeCurrentFrameIndexes[i] = frameIndex;
                      }
                      nextFrameIndex = frameIndex + 1;
                      while (nextFrameIndex < keyFramesCount) {
                          if (keyFrames[nextFrameIndex].time > playCurTime)
                              break;
                          frameIndex++;
                          nextFrameIndex++;
                          realTimeCurrentFrameIndexes[i] = frameIndex;
                      }
                  }
                  else {
                      nextFrameIndex = frameIndex + 1;
                      if ((nextFrameIndex !== keyFramesCount) && (playCurTime > keyFrames[nextFrameIndex].time)) {
                          frameIndex = keyFramesCount - 1;
                          realTimeCurrentFrameIndexes[i] = frameIndex;
                      }
                      nextFrameIndex = frameIndex + 1;
                      while (frameIndex > -1) {
                          if (keyFrames[frameIndex].time < playCurTime)
                              break;
                          frameIndex--;
                          nextFrameIndex--;
                          realTimeCurrentFrameIndexes[i] = frameIndex;
                      }
                  }
                  var isEnd = nextFrameIndex === keyFramesCount;
                  switch (type) {
                      case 0:
                          if (frameIndex !== -1) {
                              var frame = keyFrames[frameIndex];
                              if (isEnd) {
                                  outDatas[i] = frame.value;
                              }
                              else {
                                  var nextFarme = keyFrames[nextFrameIndex];
                                  var d = nextFarme.time - frame.time;
                                  var t;
                                  if (d !== 0)
                                      t = (playCurTime - frame.time) / d;
                                  else
                                      t = 0;
                                  outDatas[i] = this[`_hermiteInterpolate`](frame, nextFarme, t, d);
                              }
                          }
                          else {
                              outDatas[i] = keyFrames[0].value;
                          }
                          if (addtive)
                              outDatas[i] = outDatas[i] - keyFrames[0].value;
                          break;
                      case 1:
                      case 4:
                          var clipData = outDatas[i];
                          if (humanBoneConfig.boneMap[nodeName]) {
                              clipData.x = humanBoneConfig.boneMap[nodeName].x;
                              clipData.y = humanBoneConfig.boneMap[nodeName].y;
                              clipData.z = humanBoneConfig.boneMap[nodeName].z;
                          }
                          else {
                              if (nodeName == "Bip001" && this[`avatar_height`] && humanBoneConfig.rootPos) {
                                  let originHeight = this[`avatar_height`];
                                  this[`_evaluateFrameNodeVector3DatasRealTime`](keyFrames, frameIndex, isEnd, playCurTime, clipData, humanScaleInfo.boneMap[nodeName], "pos");
                                  let tpos = humanBoneConfig.rootPos;
                                  let factor = (tpos.y / originHeight) * humanScaleInfo.wholeRatio;
                                  clipData.x *= factor;
                                  clipData.y *= factor;
                                  clipData.z *= factor;
                              }
                              else {
                                  this[`_evaluateFrameNodeVector3DatasRealTime`](keyFrames, frameIndex, isEnd, playCurTime, clipData, humanScaleInfo.boneMap[nodeName], "pos");
                              }
                          }
                          if (humanScaleInfo.boneMap[nodeName]) {
                              if (!humanScaleInfo.boneMap[nodeName].bAddtive) {
                                  clipData.x += humanScaleInfo.boneMap[nodeName].pos.x;
                                  clipData.y += humanScaleInfo.boneMap[nodeName].pos.y;
                                  clipData.z += humanScaleInfo.boneMap[nodeName].pos.z;
                              }
                          }
                          if (addtive) {
                              var firstFrameValue = keyFrames[0].value;
                              clipData.x -= firstFrameValue.x;
                              clipData.y -= firstFrameValue.y;
                              clipData.z -= firstFrameValue.z;
                          }
                          break;
                      case 2:
                          var clipQuat = outDatas[i];
                          this[`_evaluateFrameNodeQuaternionDatasRealTime`](keyFrames, frameIndex, isEnd, playCurTime, clipQuat, humanScaleInfo.boneMap[nodeName], "rotation");
                          if (humanScaleInfo.boneMap[nodeName]) {
                              if (!humanScaleInfo.boneMap[nodeName].bAddtive) {
                                  var tempQuat = Laya.AnimationClip[`_tempQuaternion0`];
                                  tempQuat.x = humanScaleInfo.boneMap[nodeName].rotation.x;
                                  tempQuat.y = humanScaleInfo.boneMap[nodeName].rotation.y;
                                  tempQuat.z = humanScaleInfo.boneMap[nodeName].rotation.z;
                                  tempQuat.w = humanScaleInfo.boneMap[nodeName].rotation.w;
                                  Laya.Quaternion.multiply(clipQuat, tempQuat, clipQuat);
                              }
                          }
                          if (addtive) {
                              var tempQuat = Laya.AnimationClip[`_tempQuaternion0`];
                              var firstFrameValueQua = keyFrames[0].value;
                              Laya.Utils3D[`quaternionConjugate`](firstFrameValueQua, tempQuat);
                              Laya.Quaternion.multiply(tempQuat, clipQuat, clipQuat);
                          }
                          break;
                      case 3:
                          clipData = outDatas[i];
                          this[`_evaluateFrameNodeVector3DatasRealTime`](keyFrames, frameIndex, isEnd, playCurTime, clipData, humanScaleInfo.boneMap[nodeName], "scale");
                          if (humanScaleInfo.boneMap[nodeName]) {
                              if (!humanScaleInfo.boneMap[nodeName].bAddtive) {
                                  clipData.x *= humanScaleInfo.boneMap[nodeName].scale.x;
                                  clipData.y *= humanScaleInfo.boneMap[nodeName].scale.y;
                                  clipData.z *= humanScaleInfo.boneMap[nodeName].scale.z;
                              }
                          }
                          if (addtive) {
                              firstFrameValue = keyFrames[0].value;
                              clipData.x /= firstFrameValue.x;
                              clipData.y /= firstFrameValue.y;
                              clipData.z /= firstFrameValue.z;
                          }
                          break;
                      default:
                          throw "AnimationClip:unknown node type.";
                  }
              }
          };
      }
      overloadAnimator() {
          Laya.Animator.prototype[`_updateClipDatas`] = function (animatorState, addtive, playStateInfo, scale, name) {
              var clip = animatorState._clip;
              var clipDuration = clip._duration;
              var curPlayTime = animatorState.clipStart * clipDuration + playStateInfo._normalizedPlayTime * playStateInfo._duration;
              var currentFrameIndices = animatorState._currentFrameIndices;
              var frontPlay = playStateInfo._elapsedTime > playStateInfo._lastElapsedTime;
              clip._evaluateClipDatasRealTime(clip._nodes, curPlayTime, currentFrameIndices, addtive, frontPlay, animatorState._realtimeDatas, name, HumanBone.allHumanBoneConfig[this.owner.name], this[`humanScaleInfo`]);
          };
      }
  }

  class SceneInit extends SceneBase {
      constructor() {
          super();
      }
      getTaskManager() {
          let taskManager = new TaskManager();
          taskManager.addCall(this.initNative);
          taskManager.addCall(this.initMsg.bind(this));
          taskManager.addCall(this.initSdk1);
          taskManager.addCall(this.initGameSetting);
          taskManager.addCall(this.initGameCfg);
          taskManager.addCall(this.initBaseModule);
          taskManager.addCall(this.initSdk2);
          taskManager.addCall(this.initBaseRes.bind(this), 6);
          taskManager.addCall(this.initManager);
          taskManager.addCall(this.initShader);
          taskManager.addCall(this.initGameFont.bind(this));
          taskManager.addCall(this.initGameBulletConfig.bind(this));
          taskManager.addCall(this.initGameAnimationConfig.bind(this));
          taskManager.addCall(this.initGameSpineConfig.bind(this));
          taskManager.addCall(this.initGameHitAreaConfig.bind(this));
          taskManager.addCall(this.initGameTowerImageConfig.bind(this));
          this.taskManager = taskManager;
          return taskManager;
      }
      initNative(resolve) {
          SDKBridge.init();
          Timer.callLoop(0.05, function (timer) {
              if (mgrNative.isAllowStartGame()) {
                  timer.stop();
                  resolve();
              }
          }, true);
      }
      initMsg(resolve) {
          resolve();
      }
      initGameSetting(resolve) {
          Laya.stage.on(Laya.Event.KEY_DOWN, this, function (e) {
              Global.sendMsg(BASE_MSG.SYS_KEY_DOWN, e);
          });
          Laya.stage.on(Laya.Event.KEY_UP, this, function (e) {
              Global.sendMsg(BASE_MSG.SYS_KEY_UP, e);
          });
          resolve();
      }
      initGameCfg(resolve) {
          CfgLoader.init(function (suc) {
              let advDbMap = db.get_adv_db_map();
              let advBanerIntDbMap = db.get_adv_banner_int_db_map();
              Tools.forEachMap(advBanerIntDbMap, (k, v) => {
                  advDbMap[v.advName] = v;
              });
              Level.parseConfig();
              resolve();
          });
      }
      initBoneCfg(resolve) {
          let path = "res/cfg/humanConfig.txt";
          Laya.loader.load(path, Laya.Handler.create(this, function () {
              HumanBone.allHumanBoneConfig = Laya.loader.getRes(path);
              resolve();
          }), null, Laya.Loader.JSON);
      }
      initBaseModule(resolve) {
          FileRecord.init();
          resolve();
      }
      initSdk1(resolve) {
          mgrSdk.init();
          resolve();
      }
      initSdk2(resolve) {
          mgrAdv.init();
          mgrSdk.setVersion(CHN_DATA);
          mgrStatis.init();
          mgrAdv.setNativeUi("PanelLocalInterstitial", "PanelLocalBanner", "PanelWait");
          Timer.callLoop(0.05, function (timer) {
              if (mgrSdk.isChnResult || (timer.span * timer.count) >= 10) {
                  timer.stop();
                  Global.sendMsg(MSG.SDK_INIT);
                  Global.registerListeners(this, {
                      MSG_SDK_GET_USER_CLOUD_STORAGE_REAULT: (data) => {
                          if (data.bSuccess) {
                              FileRecord.receiveCloudRecord(data.storage, resolve);
                          }
                          else {
                              resolve();
                          }
                      }
                  });
                  FileRecord.requestGetCloudStorage();
              }
          }, true);
      }
      initBaseRes(resolve) {
          let loader = new TaskManager();
          loader.setParent(this.taskManager);
          loader.setLoadingCallback(resolve);
          loader.addFguiPackage("res/fgui/base");
          loader.loadAll();
      }
      initGameFont(resolve) {
          let path = Laya.URL.formatURL("res/font/font_comm.ttf");
          let stage = window["tt"] || window["wx"] || window["qq"];
          if (!window["tt"] && (window["wx"] || window["qq"])) {
              path = Laya.URL.customFormat("res/font/font_comm.ttf");
          }
          if (stage && stage.loadFont) {
              window["font_comm"] = stage.loadFont(path);
              resolve();
          }
          else {
              if (!Laya.Browser.onPC && mgrNative.isHtml5Platform()) {
                  resolve();
              }
              else {
                  Laya.loader.load(path, Laya.Handler.create(this, resolve), null, Laya.Loader.TTF);
              }
          }
      }
      initGameBulletConfig(resolve) {
          FactoryBullet.loadConfig(resolve);
      }
      initGameSpineConfig(resolve) {
          PointHelper.loadConfig(resolve);
      }
      initGameAnimationConfig(resolve) {
          AnimationHelper.loadConfig(resolve);
      }
      initGameHitAreaConfig(resolve) {
          HitAreaHelper.loadConfig(resolve);
      }
      initGameTowerImageConfig(resolve) {
          TowerImageHelper.loadConfig(resolve);
      }
      initManager(resolve) {
          ManagerLoader.onLoad(function (suc) {
              resolve();
          });
      }
      initPool(resolve) {
          resolve();
      }
      initShader(resolve) {
          resolve();
      }
      onEnter(params) {
          if (SceneInit._started) {
              console.error("SceneInit 只能启动一次!");
          }
          SceneInit._started = true;
          if (db.cop_db.is_sdk_start_game_by_touch) {
              Director.runScene(SceneSplash);
          }
          else {
              Director.runScene(SceneGame);
          }
      }
      onExit() {
      }
  }
  SceneInit._started = false;

  class Start extends Laya.Script {
      constructor() {
          super();
          this._loop = 0;
          this._time = 0;
      }
      onAwake() {
          console.log("--->>:onAwake");
          Global.require = requireModule;
          registerClass();
          Laya.loader.retryNum = 3;
          Timer.initTime();
          TweenSystem.create();
          EffectFactory.init();
          GameRegister.regist();
          fgui.UIConfig.packageFileExtension = "xml";
          fgui.UIConfig.buttonSound = "btn";
          fgui.GRoot.inst.playOneShotSound = function (filename) {
              mgrSound.playSound(filename);
          };
      }
      onEnable() {
          console.log("--->>:onEnable");
      }
      onStart() {
          console.log("--->>:onStart");
          Laya.loader.load("url_path.json", new Laya.Handler(this, (urlConfig) => {
              // if (urlConfig.path && !Laya.Browser.onPC) {
              //     Laya.URL.basePath = urlConfig.path;
              // }
              fgui.UIPackage.loadPackage("res/fgui/load", Laya.Handler.create(this, () => {
                  Director.initScene();
                  Director.openPanelWithSingleton("PanelLoading");
                  new UpdaterScript(this.owner, (msg) => {
                      Global.sendMsg(msg);
                      if (msg == UPDATER_UI_MSG.ENTER_NEXT_SCENE) {
                          Director.runScene(SceneInit, "PanelLoading");
                          var bgImage = this.owner.getChildByName("bg");
                          if (bgImage) {
                              bgImage.visible = false;
                          }
                      }
                  }).startUpdate();
              }));
          }));
      }
      onUpdate() {
          Timer.updateTime();
          this._loop++;
          let delta = Timer.time - this._time;
          if (delta < 0.5)
              return;
          Global.FPS = (this._loop / delta) | 0;
          this._loop = 0;
          this._time = Timer.time;
      }
      onDisable() {
          console.log("--->>:onDisable");
      }
  }

  class GameConfig {
      constructor() {
      }
      static init() {
          var reg = Laya.ClassUtils.regClass;
          reg("script/ulframework/component/UIRoot.ts", UIRoot);
          reg("Start.ts", Start);
      }
  }
  GameConfig.width = 768;
  GameConfig.height = 1280;
  GameConfig.scaleMode = "fixedwidth";
  GameConfig.screenMode = "none";
  GameConfig.alignV = "top";
  GameConfig.alignH = "left";
  GameConfig.startScene = "SceneMain.scene";
  GameConfig.sceneRoot = "";
  GameConfig.debug = false;
  GameConfig.stat = false;
  GameConfig.physicsDebug = false;
  GameConfig.exportSceneToJson = true;
  GameConfig.init();

  /**
   * - 时间: 2020年3月11日15:27:29
   * - by: Liuwei
   * - cause: 在魅族上有文字错乱的bug.
   * - 修改方式:  在文本构造函数中 修改 cacheAs = "bitmap";
   * 
   * - 本适配文件需要放在Laya.ResourceVersion.enable调用之前创建
   */
  const B_ALL_TEXT_RENDER_CACHE_AS_BITMAP = false;
  class ULAdapter {


      constructor() {
          Laya = window.Laya;
          this.adpatChannel();
          this.adpatLaya();
          this.adpatFgui();
          this.adaptLoader();
      }


      // 适配渠道
      adpatChannel() {
          //1.即刻玩华为花屏问题
          window._setupVertexArrayObject = function (gl) {
              var original_getSupportedExtensions = gl.getSupportedExtensions;
              gl.getSupportedExtensions = function getSupportedExtensions() {
                  var list = original_getSupportedExtensions.call(this) || [];
                  if (list.indexOf("OES_vertex_array_object") < 0) {
                      list.push("OES_vertex_array_object");
                  }
                  return list;
              };
              var original_getExtension = gl.getExtension;
              gl.getExtension = function getExtension(name) {
                  var ext = original_getExtension.call(this, name);
                  //ul runtime bug start
                  if (typeof loadRuntime !== "undefined" && name === "OES_vertex_array_object") {
                      ext = undefined;
                  }
                  //ul runtime bug end
                  if (ext) {
                      return ext;
                  }
                  if (name !== "OES_vertex_array_object") {
                      return null;
                  }
                  if (!this.__OESVertexArrayObject) {
                      console.log("Setup OES_vertex_array_object polyfill");
                      this.__OESVertexArrayObject = new OESVertexArrayObject(this);
                  }
                  return this.__OESVertexArrayObject;
              };
          };

          //version 解压问题
          Laya.ResourceVersion.enable = (manifestFile, callback, type = 2) => {
              Laya.ResourceVersion.type = type;
              Laya.ResourceVersion[`__callback__`] = callback;
              Laya.ResourceVersion[`__manifestFile__`] = manifestFile;

              Laya.ILaya.loader.load(manifestFile, Laya.Handler.create(null, Laya.ResourceVersion.onManifestLoaded, [callback]), null, Laya.Loader.BUFFER);
          };
          Laya.ResourceVersion.onManifestLoaded = (callback, data) => {
              let pako = window['pako'];
              try {
                  let text = pako.ungzip(data, { to: "string" });
                  data = JSON.parse(text);

                  Laya.ResourceVersion.manifest = data;
                  Laya.URL.customFormat = Laya.ResourceVersion.addVersionPrefix;
                  callback.run();
                  if (!data) {
                      console.warn("资源版本清单文件不存在，不使用资源版本管理。忽略ERR_FILE_NOT_FOUND错误。");
                  }
              } catch (error) {
                  // 加载失败
                  Laya.Loader.loadedMap = [];
                  Laya.ResourceVersion.onManifestLoaded = (callback, data) => {
                      Laya.ResourceVersion.manifest = data;
                      Laya.URL.customFormat = Laya.ResourceVersion.addVersionPrefix;
                      callback.run();
                      if (!data) {
                          console.warn("资源版本清单文件不存在，不使用资源版本管理。忽略ERR_FILE_NOT_FOUND错误。");
                      }
                  };

                  let manifestFile = Laya.ResourceVersion[`__manifestFile__`];
                  let callback = Laya.ResourceVersion[`__callback__`];
                  Laya.ILaya.loader.load(manifestFile, Laya.Handler.create(null, Laya.ResourceVersion.onManifestLoaded, [callback]), null, Laya.Loader.JSON);
              }
          };
          //解决魅族文字花屏问题
          class ULText extends Laya.Text {
              constructor() {
                  super();
                  if (B_ALL_TEXT_RENDER_CACHE_AS_BITMAP) {
                      this.cacheAs = "bitmap";
                      this.font = "Arial";
                  }
              }
          }

          class ULLabel extends Laya.Label {
              constructor(text = "") {
                  super(text);
                  if (B_ALL_TEXT_RENDER_CACHE_AS_BITMAP) {
                      this.cacheAs = "bitmap";
                      this.font = "Arial";
                  }
              }
          }
          Laya.Label = ULLabel;
          Laya.Text = ULText;

          //适配启用(头条 微信 oppo  vivo  百度 qq)
          // wx/
          Laya.MiniAdpter && (Laya.MiniAdpter.autoCacheFile = true);
          Laya.MiniAdpter && (Laya.MiniAdpter.AutoCacheDownFile = true);
          //headline
          Laya.TTMiniAdapter && (Laya.TTMiniAdapter.autoCacheFile = true);
          Laya.TTMiniAdapter && (Laya.TTMiniAdapter.AutoCacheDownFile = true);
          //qq
          Laya.QQMiniAdapter && (Laya.QQMiniAdapter.autoCacheFile = true);
          Laya.QQMiniAdapter && (Laya.QQMiniAdapter.AutoCacheDownFile = true);
          // qg
          Laya.QGMiniAdapter && (Laya.QGMiniAdapter.autoCacheFile = true);
          Laya.QGMiniAdapter && (Laya.QGMiniAdapter.AutoCacheDownFile = true);
          // vivo
          Laya.VVMiniAdapter && (Laya.VVMiniAdapter.autoCacheFile = true);
          Laya.VVMiniAdapter && (Laya.VVMiniAdapter.AutoCacheDownFile = true);
          // baidu
          Laya.BMiniAdapter && (Laya.BMiniAdapter.autoCacheFile = true);
          Laya.BMiniAdapter && (Laya.BMiniAdapter.AutoCacheDownFile = true);
          // xiaomi
          Laya.KGMiniAdapter && (Laya.KGMiniAdapter.autoCacheFile = true);
          Laya.KGMiniAdapter && (Laya.KGMiniAdapter.AutoCacheDownFile = true);
      }


      // 适配Laya
      adpatLaya() {
          var Config3D = Laya.Config3D;
          var Scene3D = Laya.Scene3D;
          var Scene3DShaderDeclaration = Laya.Scene3DShaderDeclaration;
          var Vector3 = Laya.Vector3;
          var Cluster = Laya.Cluster;
          //解决多光源下, spotLight没有参数的问题
          class ULScene3D extends window.Laya.Scene3D {
              _prepareSceneToRender() {
                  var shaderValues = this._shaderValues;
                  var multiLighting = Config3D._config._multiLighting;
                  if (multiLighting) {
                      var ligTex = Scene3D._lightTexture;
                      var ligPix = Scene3D._lightPixles;
                      const pixelWidth = ligTex.width;
                      const floatWidth = pixelWidth * 4;
                      var curCount = 0;
                      var dirCount = this._directionLights._length;
                      var dirElements = this._directionLights._elements;
                      if (dirCount > 0) {
                          var sunLightIndex = this._directionLights.getBrightestLight();
                          this._mainDirectionLight = dirElements[sunLightIndex];
                          this._directionLights.normalLightOrdering(sunLightIndex);
                          for (var i = 0; i < dirCount; i++, curCount++) {
                              var dirLight = dirElements[i];
                              var dir = dirLight._direction;
                              var intCor = dirLight._intensityColor;
                              var off = floatWidth * curCount;
                              Vector3.scale(dirLight.color, dirLight._intensity, intCor);
                              dirLight.transform.worldMatrix.getForward(dir);
                              Vector3.normalize(dir, dir);
                              ligPix[off] = intCor.x;
                              ligPix[off + 1] = intCor.y;
                              ligPix[off + 2] = intCor.z;
                              ligPix[off + 4] = dir.x;
                              ligPix[off + 5] = dir.y;
                              ligPix[off + 6] = dir.z;
                              if (i == 0) {
                                  shaderValues.setVector3(Scene3D.SUNLIGHTDIRCOLOR, intCor);
                                  shaderValues.setVector3(Scene3D.SUNLIGHTDIRECTION, dir);
                              }
                          }
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
                      }
                      var poiCount = this._pointLights._length;
                      if (poiCount > 0) {
                          var poiElements = this._pointLights._elements;
                          var mainPointLightIndex = this._pointLights.getBrightestLight();
                          this._mainPointLight = poiElements[mainPointLightIndex];
                          this._pointLights.normalLightOrdering(mainPointLightIndex);
                          for (var i = 0; i < poiCount; i++, curCount++) {
                              var poiLight = poiElements[i];
                              var pos = poiLight.transform.position;
                              var intCor = poiLight._intensityColor;
                              var off = floatWidth * curCount;
                              Vector3.scale(poiLight.color, poiLight._intensity, intCor);
                              ligPix[off] = intCor.x;
                              ligPix[off + 1] = intCor.y;
                              ligPix[off + 2] = intCor.z;
                              ligPix[off + 3] = poiLight.range;
                              ligPix[off + 4] = pos.x;
                              ligPix[off + 5] = pos.y;
                              ligPix[off + 6] = pos.z;
                          }
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
                      }
                      var spoCount = this._spotLights._length;
                      if (spoCount > 0) {
                          var spoElements = this._spotLights._elements;
                          var mainSpotLightIndex = this._spotLights.getBrightestLight();
                          this._mainSpotLight = spoElements[mainSpotLightIndex];
                          this._spotLights.normalLightOrdering(mainSpotLightIndex);
                          for (var i = 0; i < spoCount; i++, curCount++) {
                              var spoLight = spoElements[i];
                              var dir = spoLight._direction;
                              var pos = spoLight.transform.position;
                              var intCor = spoLight._intensityColor;
                              var off = floatWidth * curCount;
                              Vector3.scale(spoLight.color, spoLight._intensity, intCor);
                              spoLight.transform.worldMatrix.getForward(dir);
                              Vector3.normalize(dir, dir);
                              ligPix[off] = intCor.x;
                              ligPix[off + 1] = intCor.y;
                              ligPix[off + 2] = intCor.z;
                              ligPix[off + 3] = spoLight.range;
                              ligPix[off + 4] = pos.x;
                              ligPix[off + 5] = pos.y;
                              ligPix[off + 6] = pos.z;
                              ligPix[off + 7] = spoLight.spotAngle * Math.PI / 180;
                              ligPix[off + 8] = dir.x;
                              ligPix[off + 9] = dir.y;
                              ligPix[off + 10] = dir.z;
                          }
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
                      }
                      (curCount > 0) && (ligTex.setSubPixels(0, 0, pixelWidth, curCount, ligPix, 0));
                      shaderValues.setTexture(Scene3D.LIGHTBUFFER, ligTex);
                      shaderValues.setInt(Scene3D.DIRECTIONLIGHTCOUNT, this._directionLights._length);
                      shaderValues.setTexture(Scene3D.CLUSTERBUFFER, Cluster.instance._clusterTexture);

                      if (this._spotLights._length > 0) {
                          var spotLight = this._spotLights._elements[0];
                          this._mainSpotLight = spotLight;
                          Vector3.scale(spotLight.color, spotLight._intensity, spotLight._intensityColor);
                          shaderValues.setVector3(Scene3D.SPOTLIGHTCOLOR, spotLight._intensityColor);
                          shaderValues.setVector3(Scene3D.SPOTLIGHTPOS, spotLight.transform.position);
                          spotLight.transform.worldMatrix.getForward(spotLight._direction);
                          Vector3.normalize(spotLight._direction, spotLight._direction);
                          shaderValues.setVector3(Scene3D.SPOTLIGHTDIRECTION, spotLight._direction);
                          shaderValues.setNumber(Scene3D.SPOTLIGHTRANGE, spotLight.range);
                          shaderValues.setNumber(Scene3D.SPOTLIGHTSPOTANGLE, spotLight.spotAngle * Math.PI / 180);
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
                      }
                  }
                  else {
                      if (this._directionLights._length > 0) {
                          var dirLight = this._directionLights._elements[0];
                          this._mainDirectionLight = dirLight;
                          Vector3.scale(dirLight.color, dirLight._intensity, dirLight._intensityColor);
                          dirLight.transform.worldMatrix.getForward(dirLight._direction);
                          Vector3.normalize(dirLight._direction, dirLight._direction);
                          shaderValues.setVector3(Scene3D.LIGHTDIRCOLOR, dirLight._intensityColor);
                          shaderValues.setVector3(Scene3D.LIGHTDIRECTION, dirLight._direction);
                          shaderValues.setVector3(Scene3D.SUNLIGHTDIRCOLOR, dirLight._intensityColor);
                          shaderValues.setVector3(Scene3D.SUNLIGHTDIRECTION, dirLight._direction);
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
                      }
                      if (this._pointLights._length > 0) {
                          var poiLight = this._pointLights._elements[0];
                          this._mainPointLight = poiLight;
                          Vector3.scale(poiLight.color, poiLight._intensity, poiLight._intensityColor);
                          shaderValues.setVector3(Scene3D.POINTLIGHTCOLOR, poiLight._intensityColor);
                          shaderValues.setVector3(Scene3D.POINTLIGHTPOS, poiLight.transform.position);
                          shaderValues.setNumber(Scene3D.POINTLIGHTRANGE, poiLight.range);
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
                      }
                      if (this._spotLights._length > 0) {
                          var spotLight = this._spotLights._elements[0];
                          this._mainSpotLight = spotLight;
                          Vector3.scale(spotLight.color, spotLight._intensity, spotLight._intensityColor);
                          shaderValues.setVector3(Scene3D.SPOTLIGHTCOLOR, spotLight._intensityColor);
                          shaderValues.setVector3(Scene3D.SPOTLIGHTPOS, spotLight.transform.position);
                          spotLight.transform.worldMatrix.getForward(spotLight._direction);
                          Vector3.normalize(spotLight._direction, spotLight._direction);
                          shaderValues.setVector3(Scene3D.SPOTLIGHTDIRECTION, spotLight._direction);
                          shaderValues.setNumber(Scene3D.SPOTLIGHTRANGE, spotLight.range);
                          shaderValues.setNumber(Scene3D.SPOTLIGHTSPOTANGLE, spotLight.spotAngle * Math.PI / 180);
                          shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
                      }
                      else {
                          shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
                      }
                  }
              }
          }

          window.Laya.Scene3D = ULScene3D;

          class ULStage extends Laya.Stage {
              render(context, x, y) {
                  if (this._frameRate === Stage.FRAME_SLOW && Browser.now() - this._frameStartTime <= 20) {
                      return;
                  }

                  if (window.conch) {
                      this.renderToNative(context, x, y);
                      return;
                  }
                  if (this._frameRate === Stage.FRAME_SLEEP) {
                      var now = Browser.now();
                      if (now - this._frameStartTime >= 1000)
                          this._frameStartTime = now;
                      else
                          return;
                  }
                  else {
                      if (!this._visible) {
                          this._renderCount++;
                          if (this._renderCount % 5 === 0) {
                              CallLater.I._update();
                              Stat.loopCount++;
                              RenderInfo.loopCount = Stat.loopCount;
                              this._updateTimers();
                          }
                          return;
                      }
                      this._frameStartTime = Browser.now();
                      RenderInfo.loopStTm = this._frameStartTime;
                  }
                  this._renderCount++;
                  var frameMode = this._frameRate === Stage.FRAME_MOUSE ? (((this._frameStartTime - this._mouseMoveTime) < 2000) ? Stage.FRAME_FAST : Stage.FRAME_SLOW) : this._frameRate;
                  var isFastMode = (frameMode !== Stage.FRAME_SLOW);
                  var isDoubleLoop = (this._renderCount % 2 === 0);
                  Stat.renderSlow = !isFastMode;
                  // if (!isFastMode && !isDoubleLoop)
                  //     return;
                  CallLater.I._update();
                  Stat.loopCount++;
                  RenderInfo.loopCount = Stat.loopCount;
                  if (this.renderingEnabled) {
                      for (var i = 0, n = this._scene3Ds.length; i < n; i++)
                          this._scene3Ds[i]._update();
                      context.clear();
                      super.render(context, x, y);
                      Stat._StatRender.renderNotCanvas(context, x, y);
                  }
                  if (this.renderingEnabled) {
                      Stage.clear(this._bgColor);
                      context.flush();
                      VectorGraphManager.instance && VectorGraphManager.getInstance().endDispose();
                  }
                  this._updateTimers();
              }
          }

          window.Laya.Stage = ULStage;
      }


      // 适配fgui
      adpatFgui() {
          // 阻止fgui列表的touch down事件继续冒泡
          // by LDW 2020-11-20
          var scroll_panel_mouseDown = fgui.ScrollPane.prototype["__mouseDown"];
          fgui.ScrollPane.prototype["__mouseDown"] = function (e) {
              e.stopPropagation();
              scroll_panel_mouseDown.apply(this);
          };


          // 定义Image的width和height，使得Image被点击时可以进行hit判定
          // by LDW 2020-11-22
          Object.defineProperty(fgui.Image.prototype, "width", {
              configurable: true,
              enumerable: true,
              get: function () {
                  return this._width;
              },
              set: function (value) {
                  if (this["_width"] !== value) {
                      this.set_width(value);
                      this.markChanged(1);
                  }
              }
          });

          Object.defineProperty(fgui.Image.prototype, "height", {
              configurable: true,
              enumerable: true,
              get: function () {
                  return this._height;
              },
              set: function (value) {
                  if (this["_height"] !== value) {
                      this.set_height(value);
                      this.markChanged(1);
                  }
              }
          });


          // 将按钮的缩放效果改为tween动画
          // by LDW 2020-11-23
          var GButton = fgui.GButton;
          var button_setState = GButton.prototype["setState"];
          GButton.prototype["setState"] = function (val) {
              if (this._downEffect == 2) {
                  if (this._buttonController)
                      this._buttonController.selectedPage = val;

                  if (val == GButton.DOWN || val == GButton.SELECTED_OVER || val == GButton.SELECTED_DISABLED) {
                      if (!this._downScaled) {
                          if (this["_originScaleX"] == null) {
                              this["_originScaleX"] = this.scaleX;
                              this["_originScaleY"] = this.scaleY;
                          }

                          Laya.Tween.to(this, { scaleX: this["_originScaleX"] * this._downEffectValue, scaleY: this["_originScaleY"] * this._downEffectValue }, 50);
                          this._downScaled = true;
                      }
                  }
                  else {
                      if (this._downScaled) {
                          Laya.Tween.to(this, { scaleX: this["_originScaleX"], scaleY: this["_originScaleY"] }, 50, Laya.Ease.backOut);
                          this._downScaled = false;
                      }
                  }
              } else {
                  button_setState.apply(this, arguments);
              }
          };
      }


      //适配资源加载
      adaptLoader() {
          function isMatch(data) {
              let array = new Uint8Array(data);
              let matchArr = [31, 139, 8, 0];
              for (let i = 0; i < matchArr.length; i++) {
                  const element = matchArr[i];
                  if (element !== array[i]) {
                      return false;
                  }
              }
              return true;
          }

          // 自动解压二进制
          let origin_onloaded = Laya.Loader.prototype.onLoaded;
          Laya.Loader.prototype.onLoaded = function (data = null) {
              var type = this._type;
              //需要对二进制文件进行解压操作
              if (type == Laya.Loader.BUFFER) {
                  var url = this._url;
                  // 针对特定类型处理
                  if (url.endsWith(".sk") || url.endsWith(".lani")) {
                      //压缩头判定版本
                      if (isMatch(data)) {
                          //匹配到了压缩头
                          data = pako.ungzip(data);
                          // console.log("解压", url);
                      }
                  }
              }
              origin_onloaded.call(this, data);
          };

      }
  }

  const B_ALL_TEXT_RENDER_CACHE_AS_BITMAP$1 = false;
  class Main {
      constructor() {
          window[`notCacheList`] = [];
          if (!window["vivo_checkMediaPausedReason"]) {
              window["vivo_checkMediaPausedReason"] = function () { };
          }
          window["FONT_OFFSET_Y"] = 0;
          let confit = new Config3D();
          confit.enableMultiLight = false;
          if (window["Laya3D"])
              Laya3D.init(GameConfig.width, GameConfig.height, confit);
          else
              Laya.init(GameConfig.width, GameConfig.height, Laya["WebGL"]);
          Laya["Physics"] && Laya["Physics"].enable();
          Laya["DebugPanel"] && Laya["DebugPanel"].enable();
          Laya.stage.scaleMode = GameConfig.scaleMode;
          Laya.stage.screenMode = GameConfig.screenMode;
          Laya.stage.alignV = GameConfig.alignV;
          Laya.stage.alignH = GameConfig.alignH;
          Laya.URL.exportSceneToJson = GameConfig.exportSceneToJson;
          Laya.MiniAdpter && (Laya.MiniAdpter.autoCacheFile = true);
          Laya.MiniAdpter && (Laya.MiniAdpter.AutoCacheDownFile = true);
          Laya.QGMiniAdapter && (Laya.QGMiniAdapter.autoCacheFile = true);
          Laya.QGMiniAdapter && (Laya.QGMiniAdapter.AutoCacheDownFile = true);
          Laya.VVMiniAdapter && (Laya.VVMiniAdapter.autoCacheFile = true);
          Laya.VVMiniAdapter && (Laya.VVMiniAdapter.AutoCacheDownFile = true);
          Laya.BMiniAdapter && (Laya.BMiniAdapter.autoCacheFile = true);
          Laya.BMiniAdapter && (Laya.BMiniAdapter.AutoCacheDownFile = true);
          Laya.KGMiniAdapter && (Laya.KGMiniAdapter.autoCacheFile = true);
          Laya.KGMiniAdapter && (Laya.KGMiniAdapter.AutoCacheDownFile = true);
          if (GameConfig.debug || Laya.Utils.getQueryString("debug") == "true")
              Laya.enableDebugPanel();
          if (GameConfig.physicsDebug && Laya["PhysicsDebugDraw"])
              Laya["PhysicsDebugDraw"].enable();
          if (GameConfig.stat)
              Laya.Stat.show();
          Laya.alertGlobalError(true);
          if (!B_ALL_TEXT_RENDER_CACHE_AS_BITMAP$1) {
              Laya.TextRender.forceSplitRender = true;
          }
          new ULAdapter();
          Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION);
          Laya.MouseManager.multiTouchEnabled = true;
          GameRegister.fixSpritedrawToTexture();
          GameRegister.fixFgui();
      }
      onVersionLoaded() {
          Laya.AtlasInfoManager.enable("fileconfig.json", Laya.Handler.create(this, this.onConfigLoaded));
      }
      onConfigLoaded() {
          // GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
          var sprite = new Laya.Sprite();
            sprite.loadImage("downloading.jpg");
            sprite.width=Laya.stage.width,
            sprite.height=Laya.stage.height,
            sprite.pivot(sprite.width / 2, sprite.height / 2);
            sprite.pos(Laya.stage.width / 2, Laya.stage.height / 2);
            Laya.stage.addChild(sprite);
          //   Laya.timer.once(200, this, function() {
          //       sprite.removeSelf();
          //   });
          Advertisement.initVal();
          if (window.qg) {
          console.log("22222222222222222222222222222222222222222222222222");
          let self = this;
          let i = Laya.LocalStorage.getItem("isDit");
          if (null == i || "" == i) {
              console.log("3333333333333333333333333333333333333333333333333333333");
              // var downloadTask = qg.downloadFile({
              var downloadTask = qg$1.download({
                  //资源下载==============================================
                  url: "https://duoduoyou.com.cn/CDN/Zytt/tatashouweizhan/molihuoxianlianmeng/bin.zip",
                  success: function (data) {
                      console.log("444444444444444444444444444444444444444444444444444");
                      console.log(`handling success, tempFilePath = ${data.tempFilePath}`);
                      qg$1.unzipFile({
                          // const fs = qg.getFileSystemManager()
                          // fs.unzip({
                              //解压资源=====================================================
                              // zipFilePath:data.tempFilePath,
                              // targetPath:qg$1.env.USER_DATA_PATH + "/bin/",
                              srcUri: data.tempFilePath,
                              dstUri: qg$1$1.env.USER_DATA_PATH + "/bin/",
                          success: function (uri) {
                              sprite.removeSelf();
                              console.log("55555555555555555555555555555555555555555555555555555555");
                              console.log(`handling success: ${uri}`);
                              console.log(qg$1.env.USER_DATA_PATH + "/bin/");
                              Laya.URL.basePath = qg$1.env.USER_DATA_PATH + "/bin/";
                              GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
                              Laya.LocalStorage.setItem("isDit",1);
                              Advertisement.insertAdverV2();
                          },
                          fail: function (data, code) {
                              console.log(`handling fail, code = ${code}`);
                          }
                      });
                  },
                  fail: function (data, code) {
                      console.log(`handling fail, code = ${code}`);
                  }
              });

              downloadTask.onProgressUpdate(function (msg) {
                  console.log('SSSSSSSSSSSSSSSSS');
                  var progress = msg["progress"];
                  console.log(progress + "%");
              });
          }
          else {
              Laya.URL.basePath = qg$1.env.USER_DATA_PATH + "/bin/";
              GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
          }
      }
      else {
          Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION);
      }
      }
      }
  new Main();

  // if (window.qg) {
  //     console.log("22222222222222222222222222222222222222222222222222");
  //     let self = this;
  //     let i = Laya.LocalStorage.getItem("isDit");
  //     if (null == i || "" == i) {
  //         console.log("3333333333333333333333333333333333333333333333333333333");
  //         // var downloadTask = qg.downloadFile({
  //         var downloadTask = qg.download({
  //             //资源下载==============================================
  //             url: "https://duoduoyou.com.cn/CDN/xiaozhugonglue/bin.zip",
  //             success: function (data) {
  //                 console.log("444444444444444444444444444444444444444444444444444");
  //                 console.log(`handling success, tempFilePath = ${data.tempFilePath}`);
  //                 qg.unzipFile({
  //                     // const fs = qg.getFileSystemManager()
  //                     // fs.unzip({
  //                           //解压资源=====================================================
  //                         // zipFilePath:data.tempFilePath,
  //                         // targetPath:qg$1.env.USER_DATA_PATH + "/bin/",
  //                           srcUri: data.tempFilePath,
  //                           dstUri: qg$1.env.USER_DATA_PATH + "/bin/",
  //                     success: function (uri) {
  //                         console.log("55555555555555555555555555555555555555555555555555555555");
  //                         console.log(`handling success: ${uri}`);
  //                         console.log(qg.env.USER_DATA_PATH + "/bin/")
  //                         Laya.URL.basePath = qg.env.USER_DATA_PATH + "/bin/";
  //                         GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
  //                         Laya.LocalStorage.setItem("isDit",1);
  //                     },
  //                     fail: function (data, code) {
  //                         console.log(`handling fail, code = ${code}`)
  //                     }
  //                 })
  //             },
  //             fail: function (data, code) {
  //                 console.log(`handling fail, code = ${code}`)
  //             }
  //         });

  //         downloadTask.onProgressUpdate(function (msg) {
  //             console.log('SSSSSSSSSSSSSSSSS');
  //             var progress = msg["progress"];
  //             console.log(progress + "%");
  //         });
  //     }
  //     else {
  //         Laya.URL.basePath = qg.env.USER_DATA_PATH + "/bin/";
  //         GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
  //     }
  // }
  // else {
  //     Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION)
  // }
  // // GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
  // }

}());
